chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,130 @@
|
||||
import os
|
||||
from contextlib import asynccontextmanager
|
||||
|
||||
from fastapi import FastAPI, HTTPException
|
||||
from pydantic import BaseModel
|
||||
|
||||
from agents import Agent, Runner
|
||||
from agents.mcp import MCPServer, MCPServerManager, MCPServerStreamableHttp
|
||||
from agents.model_settings import ModelSettings
|
||||
|
||||
MCP_SERVER_URL = os.getenv("MCP_SERVER_URL", "http://localhost:8000/mcp")
|
||||
INACTIVE_MCP_SERVER_URL = os.getenv("INACTIVE_MCP_SERVER_URL", "http://localhost:8001/mcp")
|
||||
APP_HOST = "127.0.0.1"
|
||||
APP_PORT = 9001
|
||||
USE_MCP_MANAGER = os.getenv("USE_MCP_MANAGER", "1") != "0"
|
||||
|
||||
|
||||
class AddRequest(BaseModel):
|
||||
a: int
|
||||
b: int
|
||||
|
||||
|
||||
class RunRequest(BaseModel):
|
||||
input: str
|
||||
|
||||
|
||||
class ReconnectRequest(BaseModel):
|
||||
failed_only: bool = True
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
server = MCPServerStreamableHttp({"url": MCP_SERVER_URL})
|
||||
inactive_server = MCPServerStreamableHttp({"url": INACTIVE_MCP_SERVER_URL})
|
||||
servers = [server, inactive_server]
|
||||
if USE_MCP_MANAGER:
|
||||
async with MCPServerManager(
|
||||
servers=servers,
|
||||
connect_in_parallel=True,
|
||||
) as manager:
|
||||
app.state.mcp_manager = manager
|
||||
app.state.mcp_servers = servers
|
||||
yield
|
||||
return
|
||||
|
||||
await server.connect()
|
||||
app.state.mcp_servers = servers
|
||||
app.state.active_servers = [server]
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
await server.cleanup()
|
||||
|
||||
|
||||
app = FastAPI(lifespan=lifespan)
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
async def health() -> dict[str, object]:
|
||||
if USE_MCP_MANAGER:
|
||||
manager: MCPServerManager = app.state.mcp_manager
|
||||
return {
|
||||
"connected_servers": [server.name for server in manager.active_servers],
|
||||
"failed_servers": [server.name for server in manager.failed_servers],
|
||||
}
|
||||
|
||||
active_servers = _get_active_servers()
|
||||
return {
|
||||
"connected_servers": [server.name for server in active_servers],
|
||||
"failed_servers": [],
|
||||
}
|
||||
|
||||
|
||||
@app.get("/tools")
|
||||
async def list_tools() -> dict[str, object]:
|
||||
active_servers = _get_active_servers()
|
||||
if not active_servers:
|
||||
return {"tools": []}
|
||||
tools = await active_servers[0].list_tools()
|
||||
return {"tools": [tool.name for tool in tools]}
|
||||
|
||||
|
||||
@app.post("/add")
|
||||
async def add(req: AddRequest) -> dict[str, object]:
|
||||
active_servers = _get_active_servers()
|
||||
if not active_servers:
|
||||
raise HTTPException(status_code=503, detail="No MCP servers available")
|
||||
result = await active_servers[0].call_tool("add", {"a": req.a, "b": req.b})
|
||||
return {"result": result.model_dump(mode="json")}
|
||||
|
||||
|
||||
@app.post("/run")
|
||||
async def run_agent(req: RunRequest) -> dict[str, object]:
|
||||
if not os.getenv("OPENAI_API_KEY"):
|
||||
raise HTTPException(status_code=400, detail="OPENAI_API_KEY is required")
|
||||
|
||||
servers = _get_active_servers()
|
||||
if not servers:
|
||||
raise HTTPException(status_code=503, detail="No MCP servers available")
|
||||
|
||||
agent = Agent(
|
||||
name="FastAPI Agent",
|
||||
instructions="Use the MCP tools when needed.",
|
||||
mcp_servers=servers,
|
||||
model_settings=ModelSettings(tool_choice="auto"),
|
||||
)
|
||||
result = await Runner.run(starting_agent=agent, input=req.input)
|
||||
return {"output": result.final_output}
|
||||
|
||||
|
||||
@app.post("/reconnect")
|
||||
async def reconnect(req: ReconnectRequest) -> dict[str, object]:
|
||||
if not USE_MCP_MANAGER:
|
||||
raise HTTPException(status_code=400, detail="MCPServerManager is disabled")
|
||||
manager: MCPServerManager = app.state.mcp_manager
|
||||
servers = await manager.reconnect(failed_only=req.failed_only)
|
||||
return {"connected_servers": [server.name for server in servers]}
|
||||
|
||||
|
||||
def _get_active_servers() -> list[MCPServer]:
|
||||
if USE_MCP_MANAGER:
|
||||
manager: MCPServerManager = app.state.mcp_manager
|
||||
return list(manager.active_servers)
|
||||
return list(app.state.active_servers)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
|
||||
uvicorn.run(app, host=APP_HOST, port=APP_PORT)
|
||||
Reference in New Issue
Block a user