"""ADK Execution Runner for GCP Solution Architecture Agent. Uses google.adk.runners.Runner integrated with PostgresSessionService, PostgresArtifactRepository, and PostgreSQL database state updates. """ import logging import uuid from typing import Any, Dict, Optional from app.adk.agents import build_adk_multi_agent_system from app.adk.artifacts import PostgresArtifactRepository from app.adk.compat import Runner from app.adk.sessions import PostgresSessionService from app.config import get_settings from app.database import get_db_manager from app.skills.loader import SkillLoader logger = logging.getLogger(__name__) class ADKAgentRunner: """Production-ready ADK Execution Runner.""" def __init__(self, skill_loader: SkillLoader | None = None) -> None: settings = get_settings() self.skill_loader = skill_loader or SkillLoader(settings.SKILLS_DIR) self.skill_loader.load_skills() self.session_service = PostgresSessionService() self.artifact_repo = PostgresArtifactRepository(settings.BASE_DIR) self.db_manager = get_db_manager() self.orchestrator = build_adk_multi_agent_system( self.skill_loader, max_iterations=settings.ADK_MAX_LOOP_ITERATIONS, ) self.runner = Runner(agent=self.orchestrator, session_service=self.session_service) def run_execution(self, session_id: Optional[str] = None, request_summary: str = "", target_dir: str = ".") -> Dict[str, Any]: """Execute multi-agent workflow using ADK runner with PostgreSQL state persistence.""" sid = session_id or str(uuid.uuid4()) execution_id = str(uuid.uuid4()) initial_input = { "execution_id": execution_id, "workflow_request": request_summary or "Event-driven regional HTTP application reference architecture", "target_dir": target_dir, "active_skills": [], } logger.info("Starting ADK runner execution %s for session %s", execution_id, sid) # Run through ADK Runner result_state = self.runner.run(session_id=sid, input_state=initial_input) # Save artifacts to disk & PostgreSQL database saved_artifacts = self.artifact_repo.save_solution_artifacts(execution_id, result_state) # Record execution in PostgreSQL database self.db_manager.save_workflow_execution( execution_id=execution_id, session_id=sid, status="completed" if result_state.get("validation_passed") else "failed", current_phase=result_state.get("current_phase", "package"), loop_count=result_state.get("total_loop_iterations", 1), request_summary=request_summary, results={ "validation_passed": result_state.get("validation_passed", False), "active_skills": result_state.get("active_skills", []), "artifacts_saved": len(saved_artifacts), }, ) return { "execution_id": execution_id, "session_id": sid, "status": "success" if result_state.get("validation_passed") else "completed_with_warnings", "validation_passed": result_state.get("validation_passed", False), "total_loop_iterations": result_state.get("total_loop_iterations", 1), "current_phase": result_state.get("current_phase", "package"), "artifacts": { "source_discovery_doc": result_state.get("source_discovery_doc"), "source_mermaid_diagram": result_state.get("source_mermaid_diagram"), "requirements_doc": result_state.get("requirements_doc"), "architecture_doc": result_state.get("architecture_doc"), "mermaid_diagram": result_state.get("mermaid_diagram"), "terraform_code": result_state.get("terraform_code"), "validation_results": result_state.get("validation_results"), "solution_guide": result_state.get("solution_guide"), }, "active_skills": result_state.get("active_skills", []), }