from pathlib import Path from dotenv import load_dotenv from fastapi import FastAPI, HTTPException from fastapi.middleware.cors import CORSMiddleware from fastapi.responses import FileResponse from fastapi.staticfiles import StaticFiles from .engine import WorkflowEngine from .models import ResumeRequest, RunResponse, StartRequest, Workflow load_dotenv() app = FastAPI(title="Agentic Workflow Lab", version="1.0.0") app.add_middleware(CORSMiddleware, allow_origins=["http://localhost:5173"], allow_methods=["*"], allow_headers=["*"]) engine = WorkflowEngine() @app.get("/api/health") def health() -> dict[str, str]: return {"status": "ok"} @app.post("/api/run", response_model=RunResponse) def run(request: StartRequest) -> RunResponse: try: return engine.start(request) except Exception as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc @app.post("/api/resume", response_model=RunResponse) def resume(request: ResumeRequest) -> RunResponse: try: return engine.resume(request.run_id, request.response) except Exception as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc @app.post("/api/workflows/validate", response_model=Workflow) def validate_workflow(workflow: Workflow) -> Workflow: try: engine._validate(workflow) return workflow except Exception as exc: raise HTTPException(status_code=400, detail=str(exc)) from exc dist = Path(__file__).resolve().parents[1] / "frontend" / "dist" if dist.exists(): app.mount("/assets", StaticFiles(directory=dist / "assets"), name="assets") @app.get("/{path:path}") def spa(path: str) -> FileResponse: requested = dist / path return FileResponse(requested if requested.is_file() else dist / "index.html")