feat: release 2.4.0 with original cases and automatic human review

This commit is contained in:
chenmingxuan committed 2026-10-28 17:25:08 +08:00
1 parent baf069854b
commit 4dc2057d43
66 files changed
+1390 -206

No files matched your search

+30 -11
View File
@@ -36,7 +36,7 @@ from artemis.runtime.case_result import RESULT_LABELS, resolve_case_result
from apps.admin_console.services.case_review import reviewed_result
EXPORT_ROOT = WORKSPACE_ROOT / "artifacts" / "reports"
BATCH_ARCHIVE_SIGNATURE = "artemis-batch-layout-2"
BATCH_ARCHIVE_SIGNATURE = "artemis-batch-layout-3"
def batch_archive_signature(batch_id: str | None = None) -> str:
@@ -234,11 +234,14 @@ def session_report(session_id: str, db_path=None) -> dict:
if status in {"failed", "interrupted"} and verification.startswith("未验证"):
verification = "未验证(任务异常终止)"
if not content:
content = (
"本任务未生成最终结论。请查看异常原因和已记录的执行步骤。"
if status in {"failed", "interrupted"}
else "本任务没有保存最终结论。以下内容仅来自已记录的执行状态和证据。"
)
lines = ["本任务未保存独立输出正文。", f"当前有效判定:{verification}"]
if test_result:
if test_result.get("reason"):
lines.append(f"判定依据:{test_result['reason']}")
lines.extend(f"- {item}" for item in test_result.get("evidence") or [])
elif error:
lines.append(f"异常原因:{error}")
content = "\n\n".join(lines)
return {
"id": session_id,
**guidance_details(session_id, db_path=repo.db_path),
@@ -264,6 +267,7 @@ def session_report(session_id: str, db_path=None) -> dict:
"category": case.get("category", ""),
"subcategory": case.get("subcategory", ""),
"preconditions": case.get("preconditions", ""),
"original_case": case.get("original_case"),
"task_config": case.get("task_config") or {},
"task_extensions": task_extensions.report_sections(session_id, store),
}
@@ -330,17 +334,24 @@ def source_text(value: dict) -> str:
for item in value.get("sources", []):
references = ", ".join(
" / ".join(
f"{key}={ref[key]}" for key in ("step_id", "call_id", "source_id") if ref.get(key)
f"{key}={ref[key]}"
for key in ("step_id", "call_id", "source_id", "trace_id")
if ref.get(key)
)
or "编号未记录"
for ref in item.get("references", [])
)
variation = "(来源标签随步骤变化,详见原始步骤)" if item.get("label_varies") else ""
lines.append(
f"{labels.get(item['kind'], '其他')} · {item['label'] or item['target_id']} · {references}"
f"{labels.get(item['kind'], '其他')} · {item['label'] or item['target_id']}"
f"{variation} · {references}"
)
if value.get("sources_omitted"):
lines.append(f"另 {value['sources_omitted']} 个来源见原始步骤记录。")
lines.append(f"来源未完整记录的步骤:{value.get('unattributed_step_count', '未知')}。")
lines.append(
f"未关联到单一来源的步骤:{value.get('unattributed_step_count', '未知')}。"
"窗口枚举等操作可能没有单一目标;此计数不表示截图丢失。"
)
lines.append(value.get("note") or "来源清单不代表断言已验证。")
return "\n".join(lines)
@@ -367,6 +378,15 @@ def metadata(report: dict) -> list[tuple]:
("检测项目", report.get("category") or "—"),
("测试子项", report.get("subcategory") or "—"),
("前置约束提取", report.get("preconditions") or "—"),
*(
[
("原始用例 · 预置条件", report["original_case"].get("preconditions") or "未填写"),
("原始用例 · 操作步骤", report["original_case"].get("steps") or "未填写"),
("原始用例 · 预期结果", report["original_case"].get("expected") or "未填写"),
]
if report.get("original_case") is not None
else []
),
("任务配置", config_text(report.get("task_config"))),
("任务目标", report["goal"]),
("预期结果", report["expected"] or "未指定"),
@@ -949,8 +969,7 @@ def session_videos(report: dict) -> list[tuple[Path, str]]:
return []
source = Path(str(candidate)).resolve()
trace_root = TRACES_PATH.resolve()
# Workers save recordings in their finalized web_<time>_<id>_PASS/FAIL
# folder. The recording row already ties that path to this session.
# The recording row already ties the finalized trace folder to this session.
if not source.is_relative_to(trace_root):
return []
# A resumed recording lives under resume_NNNN; the initial recording is