api_server.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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 examples.legacy_adapters import LegacyExampleResolver, configure_legacy_content_adapters
  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. configure_legacy_content_adapters()
  70. # ===== 注册路由 =====
  71. # Examples API(GET /api/examples)
  72. app.include_router(examples_router)
  73. # Trace 上传 API(POST /api/traces/upload)
  74. app.include_router(upload_router)
  75. # Trace 执行 API(POST + GET /running,需配置 Runner)
  76. # 注意:run_router 必须在 api_router 之前注册,否则 GET /running 会被 /{trace_id} 捕获
  77. app.include_router(run_router)
  78. # 经验 API(GET /api/experiences,需配置 Runner)
  79. app.include_router(experiences_router)
  80. # Trace 查询 API(GET)
  81. app.include_router(api_router)
  82. # Trace WebSocket(实时推送)
  83. app.include_router(ws_router)
  84. # Logs WebSocket(日志推送)
  85. app.include_router(logs_router)
  86. @app.on_event("startup")
  87. async def on_startup():
  88. """服务器启动时执行状态对齐"""
  89. from agent.trace.run_api import reconcile_traces
  90. await reconcile_traces()
  91. @app.websocket("/ws_ping")
  92. async def ws_ping(websocket: WebSocket):
  93. await websocket.accept()
  94. await websocket.send_text("pong")
  95. await websocket.close()
  96. # ===== 健康检查 =====
  97. @app.get("/health")
  98. async def health_check():
  99. """健康检查"""
  100. return {
  101. "status": "ok",
  102. "service": "Agent Step Tree API",
  103. "version": "1.0.0"
  104. }
  105. # ===== 启动服务 =====
  106. if __name__ == "__main__":
  107. logger.info("Starting API server...")
  108. uvicorn.run(
  109. "api_server:app",
  110. host="0.0.0.0",
  111. port=8000,
  112. reload=True, # 开发模式
  113. log_level="info"
  114. )