"""FastAPI server exposing two AG-UI agents: POST /fixed/ . multi-step launch wizard using fixed A2UI schemas POST /dynamic/ . dynamic A2UI surfaces generated at runtime Run with: uvicorn main:app --port 8123 --reload """ from __future__ import annotations import os import uvicorn from ag_ui_langgraph import add_langgraph_fastapi_endpoint from copilotkit import LangGraphAGUIAgent from dotenv import load_dotenv from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware load_dotenv() # Patch ag-ui-langgraph's multimodal converter so PDF text shipped via # CopilotChat attachments survives the trip to OpenAI. Must run BEFORE # the agent graphs are imported so the agents pick up the patched # converter at first message conversion. from src.multimodal_middleware import install as _install_doc_inlining # noqa: E402 _install_doc_inlining() from src.dynamic_agent import graph as dynamic_graph # noqa: E402 from src.fixed_agent import graph as fixed_graph # noqa: E402 app = FastAPI(title="A2UI Demo Agents") app.add_middleware( CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"], ) # LangGraph's default recursion_limit is 25. ag_ui_langgraph builds its own # RunnableConfig per run, which overrides any `.with_config()` we bind at # compile time on the graph. Pass recursion_limit here so it's honored. # 50 is plenty for our two-tool flow; bump higher only if a deeper agent # loop is genuinely needed. _AGENT_CONFIG = {"recursion_limit": 50} add_langgraph_fastapi_endpoint( app=app, agent=LangGraphAGUIAgent( name="fixed_agent", description="Multi-step launch wizard with fixed A2UI schemas.", graph=fixed_graph, config=_AGENT_CONFIG, ), path="/fixed", ) add_langgraph_fastapi_endpoint( app=app, agent=LangGraphAGUIAgent( name="dynamic_agent", description="Dynamic A2UI surfaces generated by a secondary LLM.", graph=dynamic_graph, config=_AGENT_CONFIG, ), path="/dynamic", ) @app.get("/") def root(): return { "ok": True, "agents": { "fixed_agent": "/fixed/", "dynamic_agent": "/dynamic/", }, } def main(): uvicorn.run( "main:app", host="0.0.0.0", port=int(os.environ.get("PORT", "8123")), reload=True, ) if __name__ == "__main__": main()