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

@@ -908,6 +908,85 @@ def test_reports_do_not_execute_formulas_or_invent_pass(isolated):
assert "未验证".encode() in doc.read("word/document.xml")
@pytest.mark.parametrize("result_status", ["passed", "failed", "blocked", "inconclusive"])
def test_report_without_output_body_uses_effective_verdict_and_evidence(isolated, result_status):
job = isolated.jobs(service.create_batch(payload())["id"])[0]
isolated.save_job({**job, "status": "completed"})
folder = reports.TRACES_PATH / job["session_id"]
folder.mkdir(parents=True)
(folder / "run_outcome.json").write_text(
json.dumps(
{
"task_status": "completed",
"test_result": {
"status": result_status,
"reason": "实际验收依据",
"evidence": ["记录中的证据"],
},
}
),
encoding="utf-8",
)
report = reports.session_report(job["session_id"])
assert report["verdict"] in report["content"]
assert "实际验收依据" in report["content"]
assert "记录中的证据" in report["content"]
assert "未保存独立输出正文" in report["content"]
assert "没有保存最终结论" not in report["content"]
assert report["test_result"]["status"] == result_status
def test_report_without_output_body_keeps_human_review_authoritative(isolated):
job = isolated.jobs(service.create_batch(payload())["id"])[0]
isolated.save_job({**job, "status": "completed"})
folder = reports.TRACES_PATH / job["session_id"]
folder.mkdir(parents=True)
(folder / "run_outcome.json").write_text(
json.dumps(
{
"test_result": {"status": "passed", "reason": "AI 原判通过"},
}
),
encoding="utf-8",
)
isolated.save_case_review(job["session_id"], "failed", "用户确认实际结果不符合预期")
report = reports.session_report(job["session_id"])
assert "人工确认" in report["content"]
assert "用户确认实际结果不符合预期" in report["content"]
assert "AI 原判通过" not in report["content"]
assert report["test_result"]["status"] == "failed"
def test_report_projects_stored_android_receipts_without_rewriting_history(isolated):
from tests.unit.data_engine.test_evidence_sources import android_receipt
sid = isolated.jobs(service.create_batch(payload())["id"])[0]["session_id"]
receipt = android_receipt()["payload"]["result"]
raw_payload = json.dumps({"args": {"action": "screenshot"}, "result": json.dumps(receipt)})
with sqlite3.connect(isolated.path) as conn:
conn.execute(
"INSERT INTO sessions(session_id,initial_goal,start_time,status) VALUES (?,?,?,?)",
(sid, "跨端截图", 1, "completed"),
)
conn.execute(
"INSERT INTO steps(step_id,session_id,step_number) VALUES (?,?,?)", ("s", sid, 1)
)
conn.execute(
"INSERT INTO traces(trace_id,session_id,step_id,type,name,timestamp,status,payload) VALUES (?,?,?,?,?,?,?,?)",
("capture", sid, "s", "tool", "android_file", 2, "success", raw_payload),
)
report = reports.session_report(sid)
source = report["evidence_sources"]["sources"][0]
assert source["kind"] == "android"
assert source["references"][0]["trace_id"] == "capture"
assert report["evidence_sources"]["unattributed_step_count"] == 0
with sqlite3.connect(isolated.path) as conn:
assert (
conn.execute("SELECT payload FROM traces WHERE trace_id='capture'").fetchone()[0]
== raw_payload
)
def test_failed_report_exposes_logged_reason_and_formats_chinese_markdown(isolated):
job = isolated.jobs(service.create_batch(payload())["id"])[0]
isolated.save_job({**job, "status": "failed"})