fix: give final acceptance a shared retry budget and diagnostics
This commit is contained in:
1 parent
50638d4130
commit
32441e79c4
18 files changed
+779
-40
No files matched your search
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user