From d89e51ab0d81f98f9d63385d7460216b0d0637c1 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:45:05 +0530 Subject: [PATCH 01/31] feat: add planner agent --- ai/agents/planner.py | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 ai/agents/planner.py diff --git a/ai/agents/planner.py b/ai/agents/planner.py new file mode 100644 index 0000000..9dbb584 --- /dev/null +++ b/ai/agents/planner.py @@ -0,0 +1,4 @@ +# Planner Agent + +def plan(task: str): + return {"tasks": [task]} \ No newline at end of file From a9557403aa10d059e9f76c4fa75eafedcb4ed841 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:45:16 +0530 Subject: [PATCH 02/31] feat: add orchestrator --- ai/workflows/orchestrator.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ai/workflows/orchestrator.py diff --git a/ai/workflows/orchestrator.py b/ai/workflows/orchestrator.py new file mode 100644 index 0000000..99e1427 --- /dev/null +++ b/ai/workflows/orchestrator.py @@ -0,0 +1,5 @@ +# Orchestrator + +def run(task: str): + from ai.agents.planner import plan + return plan(task) \ No newline at end of file From e3aa40e4cbfb0d63ae72d22645385647402354b6 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:45:38 +0530 Subject: [PATCH 03/31] feat: add CI workflow --- .github/workflows/ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..c9fd2d2 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,8 @@ +name: CI +on: [pull_request] +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: echo "CI Running" \ No newline at end of file From 57600761ad70101eb49d449bc9067f73487ec45e Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:47:38 +0530 Subject: [PATCH 04/31] feat: add developer agent with Claude integration scaffold --- ai/agents/developer.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 ai/agents/developer.py diff --git a/ai/agents/developer.py b/ai/agents/developer.py new file mode 100644 index 0000000..cc9f587 --- /dev/null +++ b/ai/agents/developer.py @@ -0,0 +1,26 @@ +# Developer Agent (Claude Integration) + +import os + +class DeveloperAgent: + def __init__(self, client=None): + self.client = client # Claude client placeholder + + def generate_code(self, task: str, context: str = "") -> str: + """ + Generate code using Claude (pseudo implementation) + """ + prompt = f""" +You are a senior software engineer. + +Context: +{context} + +Task: +{task} + +Generate clean, production-ready code. +""" + + # Placeholder for Claude API call + return f"# Generated code for: {task}\n" From af42dbbc6e01e6592f33400cc49ee160f9478fa2 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:47:48 +0530 Subject: [PATCH 05/31] feat: add developer prompt template --- ai/prompts/developer.prompt.txt | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 ai/prompts/developer.prompt.txt diff --git a/ai/prompts/developer.prompt.txt b/ai/prompts/developer.prompt.txt new file mode 100644 index 0000000..d4a8676 --- /dev/null +++ b/ai/prompts/developer.prompt.txt @@ -0,0 +1,9 @@ +You are a senior software engineer. + +Rules: +- Follow existing codebase structure +- Reuse components if available +- Write clean, modular, production-ready code +- Include types and basic validation + +Output only code. From fa5757e8fc8dc4f0fcb891d25e5c1c0b053161d3 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:51:12 +0530 Subject: [PATCH 06/31] feat: add GitHub PR automation service --- ai/services/github_service.py | 47 +++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 ai/services/github_service.py diff --git a/ai/services/github_service.py b/ai/services/github_service.py new file mode 100644 index 0000000..13dfc7c --- /dev/null +++ b/ai/services/github_service.py @@ -0,0 +1,47 @@ +# GitHub PR Automation Service + +import requests +import os + +GITHUB_API = "https://api.github.com" + +class GitHubService: + def __init__(self, token: str, repo: str): + self.token = token + self.repo = repo + self.headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json" + } + + def create_branch(self, branch_name: str, base: str = "main"): + ref_url = f"{GITHUB_API}/repos/{self.repo}/git/ref/heads/{base}" + base_ref = requests.get(ref_url, headers=self.headers).json() + sha = base_ref["object"]["sha"] + + create_ref_url = f"{GITHUB_API}/repos/{self.repo}/git/refs" + data = { + "ref": f"refs/heads/{branch_name}", + "sha": sha + } + requests.post(create_ref_url, headers=self.headers, json=data) + + def create_file(self, path: str, content: str, message: str, branch: str): + url = f"{GITHUB_API}/repos/{self.repo}/contents/{path}" + data = { + "message": message, + "content": content.encode("utf-8").decode("utf-8"), + "branch": branch + } + requests.put(url, headers=self.headers, json=data) + + def create_pr(self, title: str, body: str, head: str, base: str = "main"): + url = f"{GITHUB_API}/repos/{self.repo}/pulls" + data = { + "title": title, + "body": body, + "head": head, + "base": base + } + response = requests.post(url, headers=self.headers, json=data) + return response.json() From 39bdf4c6d718cea0edb01675cd9acbe20f3de975 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:53:33 +0530 Subject: [PATCH 07/31] feat: add QA agent for self-healing loop --- ai/agents/qa.py | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 ai/agents/qa.py diff --git a/ai/agents/qa.py b/ai/agents/qa.py new file mode 100644 index 0000000..28f9af7 --- /dev/null +++ b/ai/agents/qa.py @@ -0,0 +1,11 @@ +# QA Agent (Self-Healing Loop) + +class QAAgent: + def analyze_failure(self, logs: str) -> str: + """Analyze CI/CD logs and return a fix suggestion""" + return f"Fix issues based on logs: {logs}" + + def apply_fix(self, developer, task: str, logs: str) -> str: + """Re-run developer agent with fix context""" + fix_task = self.analyze_failure(logs) + return developer.generate_code(f"{task}\nFix: {fix_task}") From f10ab1784aad0cb62a9239d26b388247590e16fa Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:53:49 +0530 Subject: [PATCH 08/31] feat: add self-healing workflow loop --- ai/workflows/self_heal.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 ai/workflows/self_heal.py diff --git a/ai/workflows/self_heal.py b/ai/workflows/self_heal.py new file mode 100644 index 0000000..57c8653 --- /dev/null +++ b/ai/workflows/self_heal.py @@ -0,0 +1,12 @@ +# Self-Healing Workflow + +from ai.agents.qa import QAAgent +from ai.agents.developer import DeveloperAgent + + +def self_heal(task: str, logs: str): + qa = QAAgent() + dev = DeveloperAgent() + + fixed_code = qa.apply_fix(dev, task, logs) + return fixed_code From 68de58174c4c104cd8b800ae68314ee50e5c2f61 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 17:59:16 +0530 Subject: [PATCH 09/31] feat: add context engine (RAG scaffold) --- ai/context/context_engine.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 ai/context/context_engine.py diff --git a/ai/context/context_engine.py b/ai/context/context_engine.py new file mode 100644 index 0000000..b8bba7e --- /dev/null +++ b/ai/context/context_engine.py @@ -0,0 +1,27 @@ +# Context Engine (RAG for Repo Awareness) + +from typing import List + +class ContextEngine: + def __init__(self): + # Placeholder for vector DB / embeddings + self.index = {} + + def index_repo(self, files: dict): + """Index repository files (simple in-memory for now)""" + for path, content in files.items(): + self.index[path] = content + + def search(self, query: str, top_k: int = 3) -> List[str]: + """Naive search (replace with embeddings later)""" + results = [] + for path, content in self.index.items(): + if query.lower() in content.lower(): + results.append((path, content)) + + return [r[1] for r in results[:top_k]] + + def get_context(self, task: str) -> str: + """Fetch relevant context for a task""" + snippets = self.search(task) + return "\n\n".join(snippets) From ae2fe6e6f1d8de5404d60dd2b21deb30b375b833 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:04:54 +0530 Subject: [PATCH 10/31] feat: add FAISS vector store for embeddings --- ai/context/vector_store.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ai/context/vector_store.py diff --git a/ai/context/vector_store.py b/ai/context/vector_store.py new file mode 100644 index 0000000..6a0ad35 --- /dev/null +++ b/ai/context/vector_store.py @@ -0,0 +1,17 @@ +# Vector Store using FAISS (local) + +import faiss +import numpy as np + +class VectorStore: + def __init__(self, dim=384): + self.index = faiss.IndexFlatL2(dim) + self.texts = [] + + def add(self, embeddings, texts): + self.index.add(np.array(embeddings).astype('float32')) + self.texts.extend(texts) + + def search(self, query_embedding, top_k=3): + D, I = self.index.search(np.array([query_embedding]).astype('float32'), top_k) + return [self.texts[i] for i in I[0] if i < len(self.texts)] From ed0d6d6b0432a61ad21f56b0b25dd09f1f1cc4be Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:05:29 +0530 Subject: [PATCH 11/31] feat: add embedding model using sentence-transformers --- ai/context/embedding_model.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 ai/context/embedding_model.py diff --git a/ai/context/embedding_model.py b/ai/context/embedding_model.py new file mode 100644 index 0000000..0336aad --- /dev/null +++ b/ai/context/embedding_model.py @@ -0,0 +1,12 @@ +# Embedding Model (placeholder) + +from sentence_transformers import SentenceTransformer + +class EmbeddingModel: + def __init__(self, model_name='all-MiniLM-L6-v2'): + self.model = SentenceTransformer(model_name) + + def encode(self, texts): + if isinstance(texts, str): + texts = [texts] + return self.model.encode(texts).tolist() From 72deb5dd4ef050e3280ea9ffc851d7023e842f2a Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:06:02 +0530 Subject: [PATCH 12/31] feat: add context engine v2 with embeddings --- ai/context/context_engine_v2.py | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 ai/context/context_engine_v2.py diff --git a/ai/context/context_engine_v2.py b/ai/context/context_engine_v2.py new file mode 100644 index 0000000..bd493ef --- /dev/null +++ b/ai/context/context_engine_v2.py @@ -0,0 +1,19 @@ +# Context Engine V2 (Embeddings + Vector DB) + +from ai.context.vector_store import VectorStore +from ai.context.embedding_model import EmbeddingModel + +class ContextEngineV2: + def __init__(self): + self.vector_store = VectorStore() + self.embedder = EmbeddingModel() + + def index_repo(self, files: dict): + texts = list(files.values()) + embeddings = self.embedder.encode(texts) + self.vector_store.add(embeddings, texts) + + def get_context(self, task: str, top_k=3): + query_embedding = self.embedder.encode(task)[0] + results = self.vector_store.search(query_embedding, top_k) + return "\n\n".join(results) From a93270278307f62f60dd1983376e0df192928a5f Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:16:06 +0530 Subject: [PATCH 13/31] feat: add UI agent --- ai/agents/ui_agent.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ai/agents/ui_agent.py diff --git a/ai/agents/ui_agent.py b/ai/agents/ui_agent.py new file mode 100644 index 0000000..d6ff80b --- /dev/null +++ b/ai/agents/ui_agent.py @@ -0,0 +1,5 @@ +# UI Agent + +class UIAgent: + def generate_ui(self, task, context=""): + return f"// UI code for: {task}" \ No newline at end of file From 69fbc3a754d751cce61434325c839c7a5035c3d6 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:16:25 +0530 Subject: [PATCH 14/31] feat: add API agent --- ai/agents/api_agent.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ai/agents/api_agent.py diff --git a/ai/agents/api_agent.py b/ai/agents/api_agent.py new file mode 100644 index 0000000..36326bb --- /dev/null +++ b/ai/agents/api_agent.py @@ -0,0 +1,5 @@ +# API Agent + +class APIAgent: + def generate_api(self, task, context=""): + return f"# API code for: {task}" \ No newline at end of file From 14dde1a2f6e452468a305fd8872c73c5e71b7c62 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:16:50 +0530 Subject: [PATCH 15/31] feat: add DB agent --- ai/agents/db_agent.py | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 ai/agents/db_agent.py diff --git a/ai/agents/db_agent.py b/ai/agents/db_agent.py new file mode 100644 index 0000000..f4d8235 --- /dev/null +++ b/ai/agents/db_agent.py @@ -0,0 +1,5 @@ +# DB Agent + +class DBAgent: + def generate_schema(self, task, context=""): + return f"-- DB schema for: {task}" \ No newline at end of file From 0809921260712d7114caaf7d07b1cf019e8caf34 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:16:58 +0530 Subject: [PATCH 16/31] feat: add multi-agent orchestrator for UI API DB --- ai/workflows/multi_agent_orchestrator.py | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 ai/workflows/multi_agent_orchestrator.py diff --git a/ai/workflows/multi_agent_orchestrator.py b/ai/workflows/multi_agent_orchestrator.py new file mode 100644 index 0000000..61d90f9 --- /dev/null +++ b/ai/workflows/multi_agent_orchestrator.py @@ -0,0 +1,21 @@ +# Multi-Agent Orchestrator + +from ai.agents.ui_agent import UIAgent +from ai.agents.api_agent import APIAgent +from ai.agents.db_agent import DBAgent + + +def run_full_feature(task: str): + ui = UIAgent() + api = APIAgent() + db = DBAgent() + + ui_code = ui.generate_ui(task) + api_code = api.generate_api(task) + db_schema = db.generate_schema(task) + + return { + "ui": ui_code, + "api": api_code, + "db": db_schema + } From fb5b263ec7f6f38eb5a6e526b10688b6d2df6d7d Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:18:07 +0530 Subject: [PATCH 17/31] =?UTF-8?q?feat:=20add=20dependency-aware=20orchestr?= =?UTF-8?q?ator=20(DB=20=E2=86=92=20API=20=E2=86=92=20UI=20chaining)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ai/workflows/dependency_orchestrator.py | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 ai/workflows/dependency_orchestrator.py diff --git a/ai/workflows/dependency_orchestrator.py b/ai/workflows/dependency_orchestrator.py new file mode 100644 index 0000000..f4b1a04 --- /dev/null +++ b/ai/workflows/dependency_orchestrator.py @@ -0,0 +1,28 @@ +# Dependency-Aware Orchestrator (DB → API → UI) + +from ai.agents.db_agent import DBAgent +from ai.agents.api_agent import APIAgent +from ai.agents.ui_agent import UIAgent + + +def run_feature(task: str): + db = DBAgent() + api = APIAgent() + ui = UIAgent() + + # Step 1: Generate DB Schema + db_schema = db.generate_schema(task) + + # Step 2: API uses DB schema + api_context = f"DB Schema:\n{db_schema}" + api_code = api.generate_api(task, context=api_context) + + # Step 3: UI uses API contract + ui_context = f"API Code:\n{api_code}" + ui_code = ui.generate_ui(task, context=ui_context) + + return { + "db": db_schema, + "api": api_code, + "ui": ui_code + } From 098052f72eed5c1a676248e335a9a20e2a4886fa Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:18:57 +0530 Subject: [PATCH 18/31] feat: add schema extractor for structured DB parsing --- ai/contracts/schema_extractor.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 ai/contracts/schema_extractor.py diff --git a/ai/contracts/schema_extractor.py b/ai/contracts/schema_extractor.py new file mode 100644 index 0000000..1791117 --- /dev/null +++ b/ai/contracts/schema_extractor.py @@ -0,0 +1,23 @@ +# Schema Extractor (Structured DB Parsing) + +import re + +class SchemaExtractor: + def extract(self, db_schema: str): + """Extract tables and fields from SQL-like schema""" + tables = {} + current_table = None + + for line in db_schema.splitlines(): + line = line.strip() + + if line.lower().startswith("create table"): + current_table = line.split()[2] + tables[current_table] = [] + + elif current_table and line and not line.startswith("--"): + field = re.split(r"\s+", line)[0] + if field.lower() not in ["primary", "foreign", ")"]: + tables[current_table].append(field) + + return tables From d118e129d25676f759fbc38afa9976cea2ed5141 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:19:06 +0530 Subject: [PATCH 19/31] feat: add API contract generator --- ai/contracts/api_contract.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 ai/contracts/api_contract.py diff --git a/ai/contracts/api_contract.py b/ai/contracts/api_contract.py new file mode 100644 index 0000000..44d3fe4 --- /dev/null +++ b/ai/contracts/api_contract.py @@ -0,0 +1,16 @@ +# API Contract Generator + +class APIContract: + def generate(self, task: str, schema: dict): + """Generate structured API contract from schema""" + endpoints = [] + + for table, fields in schema.items(): + endpoints.append({ + "endpoint": f"/{table}", + "method": "POST", + "request": fields, + "response": ["id"] + fields + }) + + return endpoints From 26ac1c58f7349dfd127b90738f3d07a608ea51ea Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:19:14 +0530 Subject: [PATCH 20/31] feat: add UI contract generator --- ai/contracts/ui_contract.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 ai/contracts/ui_contract.py diff --git a/ai/contracts/ui_contract.py b/ai/contracts/ui_contract.py new file mode 100644 index 0000000..65a667d --- /dev/null +++ b/ai/contracts/ui_contract.py @@ -0,0 +1,15 @@ +# UI Contract Generator + +class UIContract: + def generate(self, api_contracts): + """Generate UI bindings from API contracts""" + ui_bindings = [] + + for api in api_contracts: + ui_bindings.append({ + "form": api["endpoint"], + "fields": api["request"], + "submit_to": api["endpoint"] + }) + + return ui_bindings From d1f5584d41a205481a8e580f8a37f6bb7a4deb99 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:19:50 +0530 Subject: [PATCH 21/31] feat: add contract-aware orchestrator --- ai/workflows/contract_orchestrator.py | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 ai/workflows/contract_orchestrator.py diff --git a/ai/workflows/contract_orchestrator.py b/ai/workflows/contract_orchestrator.py new file mode 100644 index 0000000..dfcadae --- /dev/null +++ b/ai/workflows/contract_orchestrator.py @@ -0,0 +1,39 @@ +# Contract-Aware Orchestrator + +from ai.agents.db_agent import DBAgent +from ai.agents.api_agent import APIAgent +from ai.agents.ui_agent import UIAgent +from ai.contracts.schema_extractor import SchemaExtractor +from ai.contracts.api_contract import APIContract +from ai.contracts.ui_contract import UIContract + + +def run_feature(task: str): + db = DBAgent() + api = APIAgent() + ui = UIAgent() + + extractor = SchemaExtractor() + api_contract_gen = APIContract() + ui_contract_gen = UIContract() + + # Step 1: DB Schema + db_schema = db.generate_schema(task) + schema = extractor.extract(db_schema) + + # Step 2: API Contract + api_contracts = api_contract_gen.generate(task, schema) + api_code = api.generate_api(task, context=str(api_contracts)) + + # Step 3: UI Contract + ui_contracts = ui_contract_gen.generate(api_contracts) + ui_code = ui.generate_ui(task, context=str(ui_contracts)) + + return { + "schema": schema, + "api_contracts": api_contracts, + "ui_contracts": ui_contracts, + "db": db_schema, + "api": api_code, + "ui": ui_code + } From 699ffac4405a9c12f86c3bcd7b68bd7c4764fd3a Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:21:57 +0530 Subject: [PATCH 22/31] feat: add contract validation layer --- ai/validation/contract_validator.py | 40 +++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 ai/validation/contract_validator.py diff --git a/ai/validation/contract_validator.py b/ai/validation/contract_validator.py new file mode 100644 index 0000000..9aa8b4d --- /dev/null +++ b/ai/validation/contract_validator.py @@ -0,0 +1,40 @@ +# Contract Validator + +class ContractValidator: + def validate_api_against_schema(self, schema: dict, api_contracts: list): + errors = [] + + for api in api_contracts: + endpoint = api.get("endpoint", "").strip("/") + if endpoint not in schema: + errors.append(f"API endpoint {endpoint} not in schema") + continue + + schema_fields = set(schema[endpoint]) + request_fields = set(api.get("request", [])) + + missing = request_fields - schema_fields + if missing: + errors.append(f"Fields {missing} not in schema for {endpoint}") + + return errors + + def validate_ui_against_api(self, api_contracts: list, ui_contracts: list): + errors = [] + + api_map = {api["endpoint"]: api for api in api_contracts} + + for ui in ui_contracts: + endpoint = ui.get("submit_to") + if endpoint not in api_map: + errors.append(f"UI endpoint {endpoint} not found in API") + continue + + api_fields = set(api_map[endpoint].get("request", [])) + ui_fields = set(ui.get("fields", [])) + + mismatch = ui_fields - api_fields + if mismatch: + errors.append(f"UI fields {mismatch} not in API for {endpoint}") + + return errors From d81d20abe23ac8bf3ade9cedea4740f39e374520 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:22:39 +0530 Subject: [PATCH 23/31] feat: add automated test generator --- ai/testing/test_generator.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 ai/testing/test_generator.py diff --git a/ai/testing/test_generator.py b/ai/testing/test_generator.py new file mode 100644 index 0000000..d6a9ce1 --- /dev/null +++ b/ai/testing/test_generator.py @@ -0,0 +1,28 @@ +# Automated Test Generator + +class TestGenerator: + def generate_api_tests(self, api_contracts: list): + tests = [] + + for api in api_contracts: + test = f""" +def test_{api['endpoint'].strip('/')}(): + payload = {{{', '.join([f'\"{f}\": \"test\"' for f in api['request']])}}} + response = client.post('{api['endpoint']}', json=payload) + assert response.status_code == 200 +""" + tests.append(test) + + return "\n".join(tests) + + def generate_ui_tests(self, ui_contracts: list): + tests = [] + + for ui in ui_contracts: + test = f""" +def test_ui_{ui['form'].strip('/')}(): + assert render_form('{ui['form']}') is not None +""" + tests.append(test) + + return "\n".join(tests) From 826afc5b724ec0fa19376ae223d8a9939a3f5bef Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:22:53 +0530 Subject: [PATCH 24/31] feat: add validation and test orchestrator --- ai/workflows/validation_orchestrator.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 ai/workflows/validation_orchestrator.py diff --git a/ai/workflows/validation_orchestrator.py b/ai/workflows/validation_orchestrator.py new file mode 100644 index 0000000..23d54d3 --- /dev/null +++ b/ai/workflows/validation_orchestrator.py @@ -0,0 +1,22 @@ +# Validation + Test Orchestrator + +from ai.validation.contract_validator import ContractValidator +from ai.testing.test_generator import TestGenerator + + +def validate_and_generate_tests(schema, api_contracts, ui_contracts): + validator = ContractValidator() + tester = TestGenerator() + + api_errors = validator.validate_api_against_schema(schema, api_contracts) + ui_errors = validator.validate_ui_against_api(api_contracts, ui_contracts) + + api_tests = tester.generate_api_tests(api_contracts) + ui_tests = tester.generate_ui_tests(ui_contracts) + + return { + "api_errors": api_errors, + "ui_errors": ui_errors, + "api_tests": api_tests, + "ui_tests": ui_tests + } From b662a855cd94861df3affbfc555becec14cebe81 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:24:49 +0530 Subject: [PATCH 25/31] feat: add sprint manager for AI Agile orchestration --- ai/agile/sprint_manager.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 ai/agile/sprint_manager.py diff --git a/ai/agile/sprint_manager.py b/ai/agile/sprint_manager.py new file mode 100644 index 0000000..259f696 --- /dev/null +++ b/ai/agile/sprint_manager.py @@ -0,0 +1,33 @@ +# Sprint Manager (AI Agile) + +from ai.workflows.contract_orchestrator import run_feature as run_contract_flow +from ai.workflows.validation_orchestrator import validate_and_generate_tests + +class SprintManager: + def __init__(self): + self.backlog = [] + + def create_backlog(self, feature: str): + # naive decomposition; replace with Planner agent later + self.backlog = [ + f"Design DB for {feature}", + f"Build API for {feature}", + f"Build UI for {feature}" + ] + return self.backlog + + def run_sprint(self, feature: str): + # End-to-end execution using contract-aware flow + result = run_contract_flow(feature) + + validation = validate_and_generate_tests( + result.get("schema", {}), + result.get("api_contracts", []), + result.get("ui_contracts", []) + ) + + return { + "feature": feature, + "artifacts": result, + "validation": validation + } From 551723811ada058aa9b1dd15647666f34412fd34 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:25:03 +0530 Subject: [PATCH 26/31] feat: add gate orchestrator with contract, test, and judge gates --- ai/agile/gate_orchestrator.py | 45 +++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 ai/agile/gate_orchestrator.py diff --git a/ai/agile/gate_orchestrator.py b/ai/agile/gate_orchestrator.py new file mode 100644 index 0000000..47a1a08 --- /dev/null +++ b/ai/agile/gate_orchestrator.py @@ -0,0 +1,45 @@ +# Gate Orchestrator (Quality Gates) + +class GateOrchestrator: + def __init__(self, threshold_score: int = 8): + self.threshold_score = threshold_score + + def run_contract_gate(self, validation): + api_errors = validation.get("api_errors", []) + ui_errors = validation.get("ui_errors", []) + return { + "passed": len(api_errors) == 0 and len(ui_errors) == 0, + "errors": api_errors + ui_errors + } + + def run_test_gate(self, validation): + # Placeholder: assume tests generated; CI should execute them + api_tests = validation.get("api_tests") + ui_tests = validation.get("ui_tests") + return { + "passed": bool(api_tests) and bool(ui_tests), + "errors": [] if (api_tests and ui_tests) else ["Missing tests"] + } + + def run_llm_judge(self, artifacts): + # Placeholder scoring; replace with real LLM-as-judge + score = 8 + return { + "passed": score >= self.threshold_score, + "score": score + } + + def decide(self, validation, artifacts): + contract_gate = self.run_contract_gate(validation) + if not contract_gate["passed"]: + return {"action": "fix", "reason": contract_gate} + + test_gate = self.run_test_gate(validation) + if not test_gate["passed"]: + return {"action": "fix", "reason": test_gate} + + judge = self.run_llm_judge(artifacts) + if not judge["passed"]: + return {"action": "fix", "reason": judge} + + return {"action": "merge", "reason": {"score": judge["score"]}} From e9a2c2011d0731677a3ebc20974830ce59d77f43 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:25:53 +0530 Subject: [PATCH 27/31] feat: add full pipeline orchestrator with QA loop and merge decision --- ai/agile/pipeline_orchestrator.py | 40 +++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 ai/agile/pipeline_orchestrator.py diff --git a/ai/agile/pipeline_orchestrator.py b/ai/agile/pipeline_orchestrator.py new file mode 100644 index 0000000..f220309 --- /dev/null +++ b/ai/agile/pipeline_orchestrator.py @@ -0,0 +1,40 @@ +# Full Pipeline Orchestrator (CI + Auto Merge + QA Feedback) + +from ai.agile.sprint_manager import SprintManager +from ai.agile.gate_orchestrator import GateOrchestrator +from ai.agents.qa import QAAgent + +class PipelineOrchestrator: + def __init__(self): + self.sprint = SprintManager() + self.gates = GateOrchestrator() + self.qa = QAAgent() + + def run(self, feature: str, max_retries: int = 2): + attempt = 0 + + while attempt <= max_retries: + result = self.sprint.run_sprint(feature) + + decision = self.gates.decide( + result["validation"], + result["artifacts"] + ) + + if decision["action"] == "merge": + return { + "status": "merged", + "attempt": attempt, + "details": decision + } + + # QA feedback loop + logs = str(decision["reason"]) + self.qa.apply_fix(None, feature, logs) + + attempt += 1 + + return { + "status": "failed", + "attempts": attempt + } From 65fc56e6be41898fe2ae5a3a598b3ae9ab60941a Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:26:08 +0530 Subject: [PATCH 28/31] feat: add CI pipeline for AI validation and tests --- .github/workflows/ai_pipeline.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/ai_pipeline.yml diff --git a/.github/workflows/ai_pipeline.yml b/.github/workflows/ai_pipeline.yml new file mode 100644 index 0000000..351cca5 --- /dev/null +++ b/.github/workflows/ai_pipeline.yml @@ -0,0 +1,25 @@ +name: AI Pipeline + +on: + pull_request: + +jobs: + ai-validation: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + + - name: Install Python + uses: actions/setup-python@v4 + with: + python-version: '3.10' + + - name: Install dependencies + run: pip install pytest + + - name: Run Tests + run: pytest || exit 1 + + - name: AI Gate Check + run: echo "AI gates passed" From b9069658c2ea2369d3d2f204c6e71497df51cde4 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:27:04 +0530 Subject: [PATCH 29/31] feat: add LLM judge module --- ai/review/llm_judge.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 ai/review/llm_judge.py diff --git a/ai/review/llm_judge.py b/ai/review/llm_judge.py new file mode 100644 index 0000000..5f87dd3 --- /dev/null +++ b/ai/review/llm_judge.py @@ -0,0 +1,18 @@ +# LLM Judge (Real Scoring Placeholder) + +import os + +class LLMJudge: + def __init__(self, client=None): + self.client = client + + def evaluate(self, artifacts: dict) -> dict: + """Call LLM to evaluate code quality (mock for now)""" + # TODO: integrate Claude/OpenAI API + score = 8 + feedback = "Code structure is acceptable" + return { + "score": score, + "feedback": feedback, + "passed": score >= 8 + } From 09a6f16ff34e382d99ba1840459e5204a37a4614 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:27:19 +0530 Subject: [PATCH 30/31] feat: add GitHub auto merge service --- ai/services/github_merge.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 ai/services/github_merge.py diff --git a/ai/services/github_merge.py b/ai/services/github_merge.py new file mode 100644 index 0000000..917cb1b --- /dev/null +++ b/ai/services/github_merge.py @@ -0,0 +1,17 @@ +# GitHub Auto Merge Service + +import requests + +class GitHubMergeService: + def __init__(self, token: str, repo: str): + self.token = token + self.repo = repo + self.headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/vnd.github+json" + } + + def merge_pr(self, pr_number: int): + url = f"https://api.github.com/repos/{self.repo}/pulls/{pr_number}/merge" + response = requests.put(url, headers=self.headers) + return response.json() From 048bec778ff0ca900305c74aa8e0526f18723183 Mon Sep 17 00:00:00 2001 From: Nilotpal Saha Date: Wed, 1 Apr 2026 18:27:32 +0530 Subject: [PATCH 31/31] feat: add observability monitor --- ai/observability/monitor.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 ai/observability/monitor.py diff --git a/ai/observability/monitor.py b/ai/observability/monitor.py new file mode 100644 index 0000000..4081404 --- /dev/null +++ b/ai/observability/monitor.py @@ -0,0 +1,12 @@ +# Observability Monitor + +import datetime + +class Monitor: + def track(self, event: str, data: dict = None): + timestamp = datetime.datetime.utcnow().isoformat() + print({ + "timestamp": timestamp, + "event": event, + "data": data or {} + })