# -*- coding: utf-8 -*- """Agent control-plane FastAPI surface.""" from __future__ import annotations from contextlib import asynccontextmanager from pathlib import Path from typing import AsyncGenerator from fastapi import FastAPI from backend.apps.cors import add_cors_middleware from backend.api import agents_router, guard_router, workspaces_router, runs_router from backend.agents import AgentFactory, WorkspaceManager, get_registry # Global instances (initialized on startup) agent_factory: AgentFactory | None = None workspace_manager: WorkspaceManager | None = None def _build_scope_payload(project_root: Path) -> dict[str, object]: return { "design_time_registry": { "root": str(project_root / "workspaces"), "meaning": "Persistent control-plane workspace registry", }, "runtime_assets": { "root": str(project_root / "runs"), "meaning": "Run-scoped runtime state and agent assets", }, "agent_route_note": ( "Runtime routes use `/api/runs/{run_id}/agents/...`. " "Legacy `/api/workspaces/{workspace_id}/agents/...` routes are deprecated " "but remain for backward compatibility." ), } def create_app(project_root: Path | None = None) -> FastAPI: """Create the agent control-plane app.""" resolved_project_root = project_root or Path(__file__).resolve().parents[2] @asynccontextmanager async def lifespan(_app: FastAPI) -> AsyncGenerator[None, None]: """Initialize design-time workspace and registry state for the control plane.""" global agent_factory, workspace_manager workspace_manager = WorkspaceManager(project_root=resolved_project_root) agent_factory = AgentFactory(project_root=resolved_project_root) agent_factory.workspaces_root.mkdir(parents=True, exist_ok=True) registry = get_registry() print("✓ 大时代 API started") print(f" - Design workspaces root: {agent_factory.workspaces_root}") print(f" - Registered agents: {registry.get_agent_count()}") yield print("✓ 大时代 API shutting down") app = FastAPI( title="大时代 Agent Service", description="REST API for the 大时代 multi-agent control plane", version="0.1.0", lifespan=lifespan, ) add_cors_middleware(app) @app.get("/health") async def health_check() -> dict[str, object]: """Health check endpoint.""" registry = get_registry() return { "status": "healthy", "version": "0.1.0", "agents_registered": registry.get_agent_count(), "workspaces_available": ( len(workspace_manager.list_workspaces()) if workspace_manager else 0 ), "scope_roots": _build_scope_payload(resolved_project_root), } @app.get("/api/status") async def api_status() -> dict[str, object]: """Get API status and registry information.""" registry = get_registry() return { "status": "operational", "registry": registry.get_stats(), "scope": _build_scope_payload(resolved_project_root), } app.include_router(workspaces_router) app.include_router(agents_router) app.include_router(runs_router) app.include_router(guard_router) return app app = create_app() if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000)