# -*- coding: utf-8 -*- """main.py Automatically generated by Colab. Original file is located at https://colab.research.google.com/drive/1dfhQA9-peYN1-9q7ueAUF974jYXx3bKQ """ from typing import Dict, Any, Optional, List from fastapi import FastAPI # FastAPI: lightweight, high-performance web framework from pydantic import BaseModel, Field # Pydantic models enforce input/output schemas from tools import get_tools # your deterministic toolbelt (modernization, resilience, etc.) from agent import ( # agent core: LLM brain, memory, prompt, runner create_agent, run_infra_resilience_agent, ReasoningTrace ) app = FastAPI( # create the app instance title="InfraResilience Agent API", # helpful metadata (shows in /docs) version="0.1.0", description="Modernization + Resilience planning agent (LangChain + MCP + Tools)." ) # ---------- Request / Response Schemas (Pydantic) ---------- class AnalyzeStackRequest(BaseModel): """Input contract for /analyze-stack.""" legacy_stack: Dict[str, Any] = Field(..., description="Legacy stack as a dict (scheduler, language, architecture, dependencies, etc.)") outage_scenario: Optional[str] = Field(None, description="Optional failure scenario to plan resilience tests (e.g., 'Oracle DB down 30 min').") class AnalyzeStackResponse(BaseModel): """Output contract for /analyze-stack.""" modernization_plan: List[str] # actionable modernization bullets resilience_strategy: List[str] # resilience drills/test ideas reasoning_summary: str # short, user-facing reasoning summary reasoning_trace: List[str] # coarse trace for observability (not raw CoT) # ---------- Single agent instance (cheap + thread-safe for dev) ---------- TOOLS = get_tools() # build your tool list once at startup AGENT = create_agent(TOOLS) # wire LLM + tools + memory (MCP) # ---------- Route: POST /analyze-stack ---------- @app.post("/analyze-stack", response_model=AnalyzeStackResponse) def analyze_stack(payload: AnalyzeStackRequest) -> AnalyzeStackResponse: """ Accepts a legacy stack + optional outage scenario, invokes the agent, and returns modernization + resilience guidance. """ trace = ReasoningTrace() # lightweight trace for clients (observability) trace.add("API request accepted. Dispatching to agent.") result = run_infra_resilience_agent( # call your brain with the structured inputs agent_executor=AGENT, legacy_stack=payload.legacy_stack, outage_scenario=payload.outage_scenario, trace=trace, ) return AnalyzeStackResponse(**result) # pydantic enforces shape/types on the way out # ---------- Optional: simple health endpoint ---------- @app.get("/healthz") def health() -> Dict[str, str]: """K8s/ECS-friendly liveness probe.""" return {"status": "ok"}