"""Report submission phase: executing → completed.""" from typing import Any from sqlmodel import Session from agenteval.intelligent_eval.lifecycle._core import IntelligentEvalTransitionError, resolve_write from agenteval.intelligent_eval.models import IntelligentEval, IntelligentEvalSessionStatus, IntelligentEvalStatus from agenteval.intelligent_eval.repository import IntelligentEvalRepository, IntelligentEvalSessionRepository def submit_report(session: Session, eval_id: str, report: dict[str, Any]) -> IntelligentEval: """OpenClaw 提交结构化报告:executing → completed。 报告结构校验在路由层(pydantic),此处只负责落库与状态迁移。提交前必须 满足:存在会话时须全部到达终态(completed/failed/expired)——否则拒绝, 杜绝"评估 completed 但 completed_sessions=0(进度 0%)"的不一致。 ADR-0011:卡死的 running 会话由 expire_stale_running_sessions 置 expired (不完整证据),不再阻塞报告提交。 """ repo = IntelligentEvalRepository(session) eval_sessions = IntelligentEvalSessionRepository(session).list_by_eval(eval_id) if any(s.status == IntelligentEvalSessionStatus.RUNNING for s in eval_sessions): raise IntelligentEvalTransitionError("存在进行中的会话,不能提交报告") # ADR-0011:submit 边界把 scores 归一到 {overall, dimensions} 单一规范结构 if report.get("scores"): from agenteval.intelligent_eval.report import normalize_scores report = {**report, "scores": normalize_scores(report["scores"])} result = repo._submit_report_if_executing(eval_id, report) return resolve_write( eval_id, result, expected=IntelligentEvalStatus.EXECUTING, target=IntelligentEvalStatus.COMPLETED, )