feat(session-async): add /api/score/session_async with incremental session report aggregation
- New POST /api/score/session_async endpoint: same session_id calls append to one shared report
- New GET /api/score/sessions/{session_id}: returns call_count, metric_means, all job records
- New GET /api/score/session/jobs/{job_id}: individual call status
- SessionScoreJobManager: deterministic run_id from session_id, per-session mutex for CSV append, advisor regenerated on every call
- SessionScoreRequest (extends ScoreRequest + session_id), SessionScoreJobResponse, SessionStatus models added
- 24 new tests, all passing
chore(weighted-score): comment out 综合加权得分 display and computation
- report.js: hide 综合加权得分 card in report detail page
- score_jobs.js: hide 综合 chip in async job list
- report_builder.py: overall_ws=None (computation disabled)
- summary.py: weighted_score summary line disabled
- evaluator.py: weighted_score/sample_weight columns no longer written to scores.csv
- score.py /api/score: weighted_score always returns null
- score_job_manager.py + session_score_manager.py: weighted=None
- Updated 3 tests to match new behaviour (6 pre-existing failures unchanged)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -531,6 +531,50 @@ class AsyncScoreJobResponse(BaseModel):
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Session async 评分模型
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class SessionScoreRequest(ScoreRequest):
|
||||
"""Request body for session-grouped async scoring.
|
||||
|
||||
All calls sharing the same session_id are accumulated into one report.
|
||||
Each call adds a new sample row to the session's scores.csv.
|
||||
"""
|
||||
|
||||
session_id: str = Field(
|
||||
description=(
|
||||
"会话唯一标识符。相同 session_id 的多次调用合并为同一报告,"
|
||||
"每次调用新增一个样本行,指标均值和优化建议在每次调用后增量更新。"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
class SessionScoreJobResponse(BaseModel):
|
||||
"""Immediate 202 response after submitting a session scoring call."""
|
||||
|
||||
job_id: str = Field(description="本次调用的任务唯一标识符。")
|
||||
session_id: str = Field(description="会话标识符。")
|
||||
run_id: str = Field(description="本 session 对应的报告 Run ID,可在「运行列表」中查看。")
|
||||
status: str = Field(default="queued", description="初始状态:queued。")
|
||||
call_count: int = Field(default=1, description="本 session 当前累计调用次数(包含本次)。")
|
||||
|
||||
|
||||
class SessionStatus(BaseModel):
|
||||
"""Aggregate status and metrics for a scoring session."""
|
||||
|
||||
session_id: str = Field(description="会话标识符。")
|
||||
run_id: str = Field(description="对应报告目录的 Run ID。")
|
||||
call_count: int = Field(description="本 session 累计调用次数。")
|
||||
metric_means: dict[str, float | None] = Field(
|
||||
default_factory=dict, description="所有已累积样本的各指标均值。"
|
||||
)
|
||||
latest_finished_at: str = Field(default="", description="最近一次评分完成时间(ISO 8601 UTC)。")
|
||||
jobs: list[AsyncScoreJobStatus] = Field(
|
||||
default_factory=list, description="本 session 所有调用记录,按创建时间排序。"
|
||||
)
|
||||
|
||||
|
||||
class AsyncScoreJobStatus(BaseModel):
|
||||
"""State of one async score job (queued → running → completed/failed)."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user