仪表盘聚合逻辑从 stats.py router 下沉到 metrics.py 的 compute_dashboard 纯函数。_settled 重命名为 settled_runs 并公开,_ts 重命名为 _sortable_ts。 router 从 40 行聚合逻辑缩到 5 行,只负责数据获取和序列化。 - 新增 compute_dashboard(runs, scenario_names, target_names) -> dict - 新增 settled_runs(runs) 公开接口(原 _settled) - trend 端点同步迁移到 settled_runs - 5 个新测试覆盖 dashboard 聚合逻辑
57 lines
1.8 KiB
Python
57 lines
1.8 KiB
Python
"""API routes for statistics and dashboard data."""
|
|
|
|
from fastapi import APIRouter, Depends
|
|
from sqlmodel import Session
|
|
|
|
from agenteval.evaluation.metrics import compute_dashboard, settled_runs
|
|
from agenteval.storage.model_config_repository import ModelConfigRepository
|
|
from agenteval.storage.repository import RunRepository, ScenarioRepository, TargetRepository
|
|
from agenteval.web.deps import get_db
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/dashboard")
|
|
def dashboard(session: Session = Depends(get_db)) -> dict:
|
|
targets = TargetRepository(session).list_all()
|
|
scenario_names = ScenarioRepository(session).name_map()
|
|
runs = RunRepository(session).list_all()
|
|
model_configs = ModelConfigRepository(session).list_all()
|
|
|
|
target_names = {t.id: t.name for t in targets}
|
|
|
|
dashboard_data = compute_dashboard(runs, scenario_names, target_names)
|
|
return {
|
|
"targets_count": len(targets),
|
|
"scenarios_count": len(scenario_names),
|
|
"model_configs_count": len(model_configs),
|
|
**dashboard_data,
|
|
}
|
|
|
|
|
|
@router.get("/trend")
|
|
def trend(days: int = 30, session: Session = Depends(get_db)) -> list[dict]:
|
|
from collections import defaultdict
|
|
|
|
from agenteval.evaluation.metrics import aggregate_runs
|
|
|
|
runs = RunRepository(session).list_all()
|
|
|
|
daily: dict[str, list] = defaultdict(list)
|
|
for run in settled_runs(runs):
|
|
if run.started_at:
|
|
daily[run.started_at.strftime("%Y-%m-%d")].append(run)
|
|
|
|
sorted_dates = sorted(daily.keys())[-days:]
|
|
points = []
|
|
for d in sorted_dates:
|
|
agg = aggregate_runs(daily[d])
|
|
if agg["pass_rate"] is None: # e.g. only cancelled runs that day
|
|
continue
|
|
points.append({
|
|
"date": d,
|
|
"pass_rate": round(agg["pass_rate"] * 100, 1),
|
|
"run_count": agg["run_count"],
|
|
})
|
|
return points
|