feat: add shared test acceptance and release 1.5.0
This commit is contained in:
1 parent
3fbcdfefea
commit
ec2c1265d3
35 files changed
+826
-51
No files matched your search
@@ -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"
|
||||
|
||||
Reference in new issue
Block a user