P0 修复: - runtimeStore: 添加缺失的 lastDayHistory 字段 - Gateway/RuntimeService: 状态同步改为内存优先,消除 glob 竞态 - App.jsx: 从 3075 行重构到 ~500 行,提取 8 个独立文件 P1 修复: - CORS: 4 个服务改为从环境变量读取允许 origins - MarketStore: 改为模块级单例模式 - Domain 层: 删除 trading thin wrapper,保留 news 真实逻辑 - 测试: 补齐 77 个 gateway/runtime 测试 新增文件: - backend/tests/test_gateway.py (43 tests) - frontend/src/hooks/useWebSocketHandler.js - frontend/src/hooks/useStockRequestCallbacks.js - frontend/src/hooks/useAgentCallbacks.js - frontend/src/hooks/useRuntimeCallbacks.js - frontend/src/hooks/useWatchlistCallbacks.js - frontend/src/components/TickerBar.jsx - frontend/src/components/HeaderRight.jsx - frontend/src/components/ChartTabs.jsx Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
96 lines
2.9 KiB
Python
96 lines
2.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""Agent control-plane FastAPI surface."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from contextlib import asynccontextmanager
|
|
from pathlib import Path
|
|
from typing import AsyncGenerator
|
|
|
|
from fastapi import FastAPI
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|
|
|
from backend.api import agents_router, guard_router, workspaces_router
|
|
from backend.agents import AgentFactory, WorkspaceManager, get_registry
|
|
from backend.config.env_config import get_cors_origins
|
|
|
|
# Global instances (initialized on startup)
|
|
agent_factory: AgentFactory | None = None
|
|
workspace_manager: WorkspaceManager | None = None
|
|
|
|
|
|
def create_app(project_root: Path | None = None) -> FastAPI:
|
|
"""Create the agent control-plane app."""
|
|
resolved_project_root = project_root or Path(__file__).resolve().parents[2]
|
|
|
|
@asynccontextmanager
|
|
async def lifespan(_app: FastAPI) -> AsyncGenerator[None, None]:
|
|
"""Initialize workspace and registry state for the control plane."""
|
|
global agent_factory, workspace_manager
|
|
|
|
workspace_manager = WorkspaceManager(project_root=resolved_project_root)
|
|
agent_factory = AgentFactory(project_root=resolved_project_root)
|
|
agent_factory.workspaces_root.mkdir(parents=True, exist_ok=True)
|
|
|
|
registry = get_registry()
|
|
print("✓ EvoTraders API started")
|
|
print(f" - Workspaces root: {agent_factory.workspaces_root}")
|
|
print(f" - Registered agents: {registry.get_agent_count()}")
|
|
|
|
yield
|
|
|
|
print("✓ EvoTraders API shutting down")
|
|
|
|
app = FastAPI(
|
|
title="EvoTraders Agent Service",
|
|
description="REST API for the EvoTraders multi-agent control plane",
|
|
version="0.1.0",
|
|
lifespan=lifespan,
|
|
)
|
|
|
|
app.add_middleware(
|
|
CORSMiddleware,
|
|
allow_origins=get_cors_origins(),
|
|
allow_credentials=True,
|
|
allow_methods=["*"],
|
|
allow_headers=["*"],
|
|
)
|
|
|
|
@app.get("/health")
|
|
async def health_check() -> dict[str, object]:
|
|
"""Health check endpoint."""
|
|
registry = get_registry()
|
|
return {
|
|
"status": "healthy",
|
|
"version": "0.1.0",
|
|
"agents_registered": registry.get_agent_count(),
|
|
"workspaces_available": (
|
|
len(workspace_manager.list_workspaces())
|
|
if workspace_manager
|
|
else 0
|
|
),
|
|
}
|
|
|
|
@app.get("/api/status")
|
|
async def api_status() -> dict[str, object]:
|
|
"""Get API status and registry information."""
|
|
registry = get_registry()
|
|
return {
|
|
"status": "operational",
|
|
"registry": registry.get_stats(),
|
|
}
|
|
|
|
app.include_router(workspaces_router)
|
|
app.include_router(agents_router)
|
|
app.include_router(guard_router)
|
|
return app
|
|
|
|
|
|
app = create_app()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import uvicorn
|
|
|
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|