feat: add shared test acceptance and release 1.5.0

This commit is contained in:
chenmingxuan committed 2026-10-12 12:33:55 +08:00
1 parent 3fbcdfefea
commit ec2c1265d3
35 files changed
+826 -51

No files matched your search

+23 -2
View File
@@ -46,6 +46,7 @@ from pydantic import BaseModel, Field, ValidationError
from artemis.core.tool_failure import ToolFailure, is_tool_failure
from artemis.constants import CHECKER_MAX_ITERATIONS
from artemis.runtime.case_result import CaseTestResult, normalize_case_result
from artemis.context import ArtemisContext
from artemis.data_engine.context_vars import CURRENT_TRACE_ID
from artemis.data_engine.trace import trace, trace_langchain_tool
@@ -98,6 +99,10 @@ class CheckVerdict(BaseModel):
class CheckReport(BaseModel):
verdicts: list[CheckVerdict] = Field(default_factory=list)
test_result: CaseTestResult | None = Field(
default=None,
description="Final review only: overall test verdict against the user's prompt and guidance, independent of execution completion.",
)
unmet_subgoals: list[str] = Field(
default_factory=list,
description=(
@@ -287,6 +292,7 @@ def assemble_checker_prompt_segments(
segments.append(prompts.get("anchor_guide", ""))
else:
segments.append(prompts.get("final_guide", ""))
segments.append(prompts.get("case_result_guide", ""))
if probe_tool_registered:
segments.append(prompts.get("probe_guide", ""))
return "\n\n".join(s for s in segments if s)
@@ -458,7 +464,11 @@ def _normalize_report(report: CheckReport, check_items: list) -> CheckReport:
evidence="no verdict produced for this item",
)
)
return CheckReport(verdicts=verdicts, unmet_subgoals=list(report.unmet_subgoals))
return CheckReport(
verdicts=verdicts,
unmet_subgoals=list(report.unmet_subgoals),
test_result=normalize_case_result(report.test_result) if report.test_result else None,
)
async def _run_check_loop(
@@ -796,6 +806,7 @@ async def run_final_check(
ledger: list[dict],
check_items,
attempt_id: str | None = None,
execution_report: dict | str | None = None,
) -> CheckReport:
"""Final review at task exit: audits the user's original goal and all
declared check items, with the final screen state available."""
@@ -828,6 +839,8 @@ async def run_final_check(
human_text = (
f"# User's Original Goal\n{goal}\n\n"
f"# User guidance received during the run\n{_format_user_guidance(ctx, steps)}\n\n"
f"# Executor's Final Report (claims to verify, not independent evidence)\n"
f"{json.dumps(execution_report, ensure_ascii=False, default=str) if execution_report is not None else '(not provided)'}\n\n"
f"# Final Task Plan\n{plan_text or '(no plan)'}\n\n"
f"# Declared Check Items\n{_format_check_items(items)}\n\n"
f"# Verdict Ledger (checkpoint results, authoritative for on_complete"
@@ -852,7 +865,15 @@ async def run_final_check(
]
with CheckerStreamCapture(ctx) as capture:
try:
return await _run_check_loop(ctx, messages, tools, items)
report = await _run_check_loop(ctx, messages, tools, items)
report.test_result = (
normalize_case_result(report.test_result)
if report.test_result
else CaseTestResult(
status="inconclusive", reason="验收未生成测试结论,不能确认用例是否通过。"
)
)
return report
finally:
_persist_stream(
ctx, capture, attempt_id=attempt_id, phase="final", checkpoint_id="final"