api_server.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. """
  2. API Server - FastAPI 应用入口
  3. 聚合所有模块的 API 路由:
  4. - GET /api/traces — 查询(trace/api.py)
  5. - POST /api/traces — 执行控制(trace/run_api.py,需配置 Runner)
  6. - WS /api/traces/{id}/watch — 实时推送(trace/websocket.py)
  7. - GET /api/experiences — 经验查询(trace/run_api.py,需配置 Runner)
  8. """
  9. import logging
  10. import json
  11. import os
  12. from dotenv import load_dotenv
  13. load_dotenv()
  14. from fastapi import FastAPI, Request, WebSocket
  15. from fastapi.middleware.cors import CORSMiddleware
  16. import uvicorn
  17. from agent.trace import FileSystemTraceStore
  18. from agent.trace.api import router as api_router, set_trace_store as set_api_trace_store
  19. from agent.trace.run_api import (
  20. router as run_router,
  21. experiences_router,
  22. set_runner,
  23. set_project_environment_resolver,
  24. )
  25. from agent.trace.project_environment import LegacyExampleResolver
  26. from agent.trace.websocket import router as ws_router, set_trace_store as set_ws_trace_store
  27. from agent.trace.examples_api import router as examples_router
  28. from agent.trace.logs_websocket import router as logs_router, setup_websocket_logging
  29. from agent.trace.upload_api import router as upload_router, set_trace_store as set_upload_trace_store
  30. # ===== 日志配置 =====
  31. logging.basicConfig(
  32. level=logging.INFO,
  33. format="%(asctime)s [%(levelname)s] %(name)s: %(message)s"
  34. )
  35. logger = logging.getLogger(__name__)
  36. # 设置WebSocket日志推送
  37. setup_websocket_logging(level=logging.INFO)
  38. # ===== FastAPI 应用 =====
  39. app = FastAPI(
  40. title="Agent API",
  41. description="Agent 查询 + 执行 API",
  42. version="1.0.0"
  43. )
  44. # CORS 配置(允许前端跨域访问)
  45. app.add_middleware(
  46. CORSMiddleware,
  47. allow_origins=["*"], # 生产环境应限制具体域名
  48. allow_credentials=True,
  49. allow_methods=["*"],
  50. allow_headers=["*"],
  51. )
  52. # ===== 初始化存储 =====
  53. # 使用文件系统存储(支持跨进程和持久化)
  54. trace_store = FileSystemTraceStore(base_path=".trace")
  55. # 注入到 step_tree 模块
  56. set_api_trace_store(trace_store)
  57. set_ws_trace_store(trace_store)
  58. set_upload_trace_store(trace_store)
  59. # ===== 可选:配置 Runner(启用执行 API)=====
  60. # 如需启用 POST /api/traces(新建/运行/停止/反思),取消以下注释并配置 LLM:
  61. from agent.core.runner import AgentRunner
  62. from agent.llm import create_openrouter_llm_call
  63. runner = AgentRunner(
  64. trace_store=trace_store,
  65. llm_call=create_openrouter_llm_call(model="anthropic/claude-sonnet-4.5"),
  66. )
  67. set_runner(runner)
  68. set_project_environment_resolver(LegacyExampleResolver())
  69. # ===== 注册路由 =====
  70. # Examples API(GET /api/examples)
  71. app.include_router(examples_router)
  72. # Trace 上传 API(POST /api/traces/upload)
  73. app.include_router(upload_router)
  74. # Trace 执行 API(POST + GET /running,需配置 Runner)
  75. # 注意:run_router 必须在 api_router 之前注册,否则 GET /running 会被 /{trace_id} 捕获
  76. app.include_router(run_router)
  77. # 经验 API(GET /api/experiences,需配置 Runner)
  78. app.include_router(experiences_router)
  79. # Trace 查询 API(GET)
  80. app.include_router(api_router)
  81. # Trace WebSocket(实时推送)
  82. app.include_router(ws_router)
  83. # Logs WebSocket(日志推送)
  84. app.include_router(logs_router)
  85. @app.on_event("startup")
  86. async def on_startup():
  87. """服务器启动时执行状态对齐"""
  88. from agent.trace.run_api import reconcile_traces
  89. await reconcile_traces()
  90. @app.websocket("/ws_ping")
  91. async def ws_ping(websocket: WebSocket):
  92. await websocket.accept()
  93. await websocket.send_text("pong")
  94. await websocket.close()
  95. # ===== 健康检查 =====
  96. @app.get("/health")
  97. async def health_check():
  98. """健康检查"""
  99. return {
  100. "status": "ok",
  101. "service": "Agent Step Tree API",
  102. "version": "1.0.0"
  103. }
  104. # ===== 启动服务 =====
  105. if __name__ == "__main__":
  106. logger.info("Starting API server...")
  107. uvicorn.run(
  108. "api_server:app",
  109. host="0.0.0.0",
  110. port=8000,
  111. reload=True, # 开发模式
  112. log_level="info"
  113. )