AgentEvalTool/backend/agenteval/web/routers/reports.py
sinohqb 770d260750
Some checks failed
CI / test (push) Failing after 39s
feat(report): compare requires same scenario version (ticket 05)
对比报告可比性收紧为同场景同考纲版本(ADR-0001):跨版本 API 返回 400
(detail 含双方版本号),报告生成层抛 ValueError;前端对比候选按
同场景 + 同版本过滤,A 变更后自动清空不可比的 B。文档"尚未实现"标注移除。
2026-07-29 11:21:52 +08:00

80 lines
2.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""API routes for evaluation reports."""
from fastapi import APIRouter, Depends, HTTPException, Query, Response
from sqlmodel import Session
from agenteval.evaluation.report import (
generate_compare_report,
generate_report,
render_html_report,
render_json_report,
render_markdown_report,
)
from agenteval.storage.repository import RunRepository
from agenteval.web.deps import get_db
router = APIRouter()
@router.get("/compare")
def get_compare_report(
run1: str = Query(..., description="First run ID"),
run2: str = Query(..., description="Second run ID"),
session: Session = Depends(get_db),
) -> dict:
repo = RunRepository(session)
run_a = repo.get(run1)
run_b = repo.get(run2)
if not run_a:
raise HTTPException(status_code=404, detail=f"run not found: {run1}")
if not run_b:
raise HTTPException(status_code=404, detail=f"run not found: {run2}")
if run_a.scenario_id != run_b.scenario_id:
raise HTTPException(status_code=400, detail="对比报告要求两个运行使用相同场景")
if run_a.scenario_version != run_b.scenario_version:
raise HTTPException(
status_code=400,
detail=f"对比报告要求相同的场景考纲版本A: v{run_a.scenario_version}, B: v{run_b.scenario_version}"
"考纲变更前后的运行不可比",
)
return generate_compare_report(run1, run2, session)
@router.get("/{run_id}")
def get_report(run_id: str, session: Session = Depends(get_db)) -> dict:
run = RunRepository(session).get(run_id)
if not run:
raise HTTPException(status_code=404, detail="run not found")
return generate_report(run_id, session)
@router.get("/{run_id}/html")
def get_html_report(run_id: str, session: Session = Depends(get_db)) -> Response:
run = RunRepository(session).get(run_id)
if not run:
raise HTTPException(status_code=404, detail="run not found")
html = render_html_report(run_id, session)
return Response(content=html, media_type="text/html")
@router.get("/{run_id}/json")
def get_json_report(run_id: str, session: Session = Depends(get_db)) -> Response:
run = RunRepository(session).get(run_id)
if not run:
raise HTTPException(status_code=404, detail="run not found")
json_text = render_json_report(run_id, session)
return Response(content=json_text, media_type="application/json")
@router.get("/{run_id}/markdown")
def get_markdown_report(run_id: str, session: Session = Depends(get_db)) -> Response:
run = RunRepository(session).get(run_id)
if not run:
raise HTTPException(status_code=404, detail="run not found")
md = render_markdown_report(run_id, session)
return Response(
content=md,
media_type="text/markdown; charset=utf-8",
headers={"Content-Disposition": f'attachment; filename="report-{run_id}.md"'},
)