MINDI-1.5-Vision-Coder / src /agents /orchestrator.py
Faaz
feat: initial project scaffold for MINDI 1.5 Vision-Coder
553fbf7
"""
MINDI 1.5 Vision-Coder — Agent Orchestrator
Coordinates multiple AI agents (Code Gen, Vision Critic, Search, Sandbox)
to produce, evaluate, and refine generated code.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from enum import Enum
from pathlib import Path
from typing import Any, Optional
class AgentRole(str, Enum):
"""Roles for MINDI's agent system."""
CODE_GENERATOR = "code_generator"
UI_CRITIC = "ui_critic"
SEARCH_AGENT = "search_agent"
SANDBOX_RUNNER = "sandbox_runner"
ERROR_FIXER = "error_fixer"
@dataclass
class AgentMessage:
"""A message passed between agents in the orchestration pipeline."""
role: AgentRole
content: str
metadata: dict[str, Any] = field(default_factory=dict)
artifacts: list[Path] = field(default_factory=list)
@dataclass
class GenerationResult:
"""Final output from the agent pipeline."""
code: str
language: str
file_path: str
critique: Optional[str] = None
search_context: Optional[str] = None
sandbox_output: Optional[str] = None
iterations: int = 1
success: bool = True
errors: list[str] = field(default_factory=list)
class AgentOrchestrator:
"""
Orchestrates the MINDI agent pipeline:
1. User prompt arrives
2. Search Agent gathers relevant docs/packages
3. Code Generator produces Next.js + Tailwind + TS code
4. Sandbox Runner tests the code in isolation
5. Vision Critic screenshots the output and evaluates UI/UX
6. Error Fixer resolves any issues
7. Loop until quality threshold or max iterations
"""
def __init__(
self,
max_iterations: int = 3,
quality_threshold: float = 0.85,
log_dir: Optional[Path] = None,
) -> None:
self.max_iterations = max_iterations
self.quality_threshold = quality_threshold
self.log_dir = log_dir or Path("./logs/agents")
self.log_dir.mkdir(parents=True, exist_ok=True)
self.history: list[AgentMessage] = []
async def run_pipeline(
self,
user_prompt: str,
context: Optional[dict[str, Any]] = None,
) -> GenerationResult:
"""
Execute the full agent pipeline for a user request.
This is the main entry point — called by the FastAPI backend.
Each step will be implemented as we build each agent module.
"""
self.history.clear()
context = context or {}
# Step 1: Search for relevant documentation
search_result = await self._run_search(user_prompt)
# Step 2: Generate code
code_result = await self._generate_code(user_prompt, search_result)
# Step 3: Test in sandbox
sandbox_result = await self._run_sandbox(code_result)
# Step 4: Vision critique (if sandbox produced a screenshot)
critique_result = await self._run_critique(code_result, sandbox_result)
# Step 5: Fix errors if any
final_code = code_result
iterations = 1
while iterations < self.max_iterations:
if sandbox_result.get("success") and critique_result.get("score", 0) >= self.quality_threshold:
break
final_code = await self._fix_errors(
final_code, sandbox_result, critique_result
)
sandbox_result = await self._run_sandbox(final_code)
critique_result = await self._run_critique(final_code, sandbox_result)
iterations += 1
return GenerationResult(
code=final_code,
language="typescript",
file_path="page.tsx",
critique=critique_result.get("feedback"),
search_context=search_result.get("context"),
sandbox_output=sandbox_result.get("output"),
iterations=iterations,
success=sandbox_result.get("success", False),
)
async def _run_search(self, prompt: str) -> dict[str, Any]:
"""Search for relevant docs and packages. Implemented in src/search/."""
# Placeholder — will be wired to SearchAgent
return {"context": "", "sources": []}
async def _generate_code(self, prompt: str, search_ctx: dict[str, Any]) -> str:
"""Generate code using the fine-tuned model. Implemented in src/inference/."""
# Placeholder — will be wired to inference pipeline
return ""
async def _run_sandbox(self, code: str) -> dict[str, Any]:
"""Run code in sandbox. Implemented in src/sandbox/."""
# Placeholder — will be wired to SandboxRunner
return {"success": False, "output": "", "screenshot": None}
async def _run_critique(self, code: str, sandbox: dict[str, Any]) -> dict[str, Any]:
"""Critique UI via vision. Implemented in src/agents/ui_critic.py."""
# Placeholder — will be wired to VisionCritic
return {"score": 0.0, "feedback": ""}
async def _fix_errors(
self, code: str, sandbox: dict[str, Any], critique: dict[str, Any]
) -> str:
"""Fix errors in code. Implemented in src/agents/error_fixer.py."""
# Placeholder — will be wired to ErrorFixer
return code