Import AITURK IDE 1.0.0-beta.1 from Hermes 63279301; preserve MIT license
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
"""Regression: only a genuinely COMPLETED turn's final_response may be
|
||||
adopted as the stream's authoritative finalize payload (PR 85796 review,
|
||||
B6).
|
||||
|
||||
agent/conversation_loop.py's interrupt/abort paths return
|
||||
{completed: False, interrupted: True, final_response: "Operation
|
||||
interrupted during …"} with NO failed key. The finish(final_text) gate
|
||||
checked only `not failed`, so the diagnostic was adopted: it sealed the
|
||||
user's streamed partial answer over with the interrupt text, AND
|
||||
delivered_final_matches then reconciled — suppressing the gateway's own
|
||||
error-delivery path, so the diagnostic was the only thing left.
|
||||
|
||||
The taxonomy was enumerated from the production writers (all 27
|
||||
final_response-bearing return shapes in conversation_loop.py): every
|
||||
non-happy-path shape carries completed: False; the happy path routes
|
||||
through turn_finalizer.finalize_turn which computes completed=True.
|
||||
Gate: completed is not False AND not interrupted AND not failed.
|
||||
"""
|
||||
|
||||
from types import SimpleNamespace
|
||||
|
||||
|
||||
def _adoption_gate(result) -> bool:
|
||||
"""Mirror of the finish(final_text) adoption gate in gateway/run.py.
|
||||
|
||||
Kept in sync by the comment at the call site; this test pins the
|
||||
CONTRACT (which result shapes may move delivery ownership into the
|
||||
stream consumer), the wiring test below pins the call.
|
||||
"""
|
||||
return (
|
||||
isinstance(result, dict)
|
||||
and not result.get("failed")
|
||||
and not result.get("interrupted")
|
||||
and result.get("completed") is not False
|
||||
)
|
||||
|
||||
|
||||
class TestAdoptionGate:
|
||||
def test_happy_path_adopts(self):
|
||||
assert _adoption_gate(
|
||||
{"completed": True, "failed": False, "interrupted": False,
|
||||
"final_response": "the answer"}
|
||||
)
|
||||
|
||||
def test_interrupt_shape_rejected(self):
|
||||
# conversation_loop.py:3089 / 4716 / 6040 / 7279 shape — no failed key.
|
||||
assert not _adoption_gate(
|
||||
{"completed": False, "interrupted": True,
|
||||
"final_response": "Operation interrupted during retry (…)."}
|
||||
)
|
||||
|
||||
def test_failed_shape_rejected(self):
|
||||
assert not _adoption_gate(
|
||||
{"completed": False, "failed": True, "final_response": "boom"}
|
||||
)
|
||||
|
||||
def test_diagnostic_noncompleted_shapes_rejected(self):
|
||||
# Shapes with neither failed nor interrupted but completed: False —
|
||||
# retry exhaustion, truncation, codex-incomplete (all diagnostics).
|
||||
for fr in (
|
||||
"Response truncated due to output length limit",
|
||||
"Codex response remained incomplete after 3 continuation attempts",
|
||||
):
|
||||
assert not _adoption_gate({"completed": False, "final_response": fr})
|
||||
|
||||
def test_legacy_result_without_completed_key_adopts(self):
|
||||
# Duck-type safety: a result dict lacking the key entirely (older
|
||||
# callers/doubles) keeps the pre-review behavior.
|
||||
assert _adoption_gate({"final_response": "answer"})
|
||||
|
||||
|
||||
class TestGateWiring:
|
||||
def test_run_py_gate_matches_contract(self):
|
||||
"""The gate in gateway/run.py must contain the interrupted and
|
||||
completed checks — a source-level pin so the contract test above
|
||||
cannot drift green while the call site regresses."""
|
||||
import inspect
|
||||
import gateway.run as run_mod
|
||||
|
||||
src = inspect.getsource(run_mod)
|
||||
anchor = src.index("_final_for_stream = None")
|
||||
window = src[anchor : anchor + 1200]
|
||||
assert 'not result.get("interrupted")' in window
|
||||
assert 'result.get("completed") is not False' in window
|
||||
Reference in New Issue
Block a user