fix: give final acceptance a shared retry budget and diagnostics

This commit is contained in:
chenmingxuan committed 2026-10-18 20:51:19 +08:00
1 parent 50638d4130
commit 32441e79c4
18 files changed
+779 -40

No files matched your search

+66
View File
@@ -125,6 +125,46 @@ async def test_review_stops_capture_before_waiting_and_seals_exploration(explora
ctx.on_execution_resume.assert_not_called()
@pytest.mark.asyncio
async def test_exploration_guidance_can_interrupt_shared_final_review_budget(exploration_exit):
from types import SimpleNamespace
ctx, _, _, _ = exploration_exit
started = asyncio.Event()
closed = asyncio.Event()
async def review(*args, **kwargs):
started.set()
try:
await asyncio.Event().wait()
finally:
closed.set()
async def interrupt(operation, **kwargs):
task = asyncio.create_task(operation)
await started.wait()
task.cancel()
with pytest.raises(asyncio.CancelledError):
await task
return True, None
ctx.task_control = SimpleNamespace(
run_interruptibly=interrupt, directory=ctx.data_engine.base_dir / "control"
)
with patch("artemis.graph.graph.run_final_check", new=review):
result = await exit_settlement_node(_make_state(execution_report="调查报告"), ctx)
assert result == {"exit_settlement_route": "continue"}
assert closed.is_set()
assert ctx.final_check_attempts == 0
assert not (ctx.data_engine.base_dir / "run_outcome.json").exists()
diagnostics = [
call.kwargs["payload"]
for call in ctx.data_engine.record_trace.call_args_list
if call.kwargs.get("type") == "final_review_diagnostic"
]
assert diagnostics[-1]["status"] == "cancelled"
@pytest.mark.asyncio
async def test_completed_exploration_waits_for_report_before_review(exploration_exit):
ctx, repo, session, run = exploration_exit
@@ -237,6 +277,32 @@ def _make_state(**overrides):
return state
@pytest.mark.asyncio
async def test_pro_final_review_has_its_own_budget_and_reports_exhaustion(tmp_path, monkeypatch):
from artemis.llm import final_review
from artemis.runtime.case_result import CaseTestResult
_write_plan(tmp_path, DONE_PLAN_NO_CHECKS)
ctx = _make_ctx(tmp_path, checkpoint_timeout=0.001)
async def slow_review(*args, **kwargs):
await asyncio.sleep(0.02)
return CheckReport(
test_result=CaseTestResult(status="passed", reason="证据齐全", evidence=["步骤 1 截图"])
)
with patch("artemis.graph.graph.run_final_check", new=slow_review):
result = await exit_settlement_node(_make_state(), ctx)
assert result["run_outcome"]["test_result"]["status"] == "passed"
monkeypatch.setattr(final_review, "MAX_FINAL_REVIEW_SECONDS", 0.001)
with patch("artemis.graph.graph.run_final_check", new=slow_review):
result = await exit_settlement_node(_make_state(), ctx)
assert result["exit_settlement_route"] == "end"
assert result["run_outcome"]["test_result"]["status"] == "inconclusive"
assert "总预算已用尽" in result["run_outcome"]["test_result"]["reason"]
def _write_plan(tmp_path, content):
notes = tmp_path / "notes"
notes.mkdir(parents=True, exist_ok=True)