refactor(agent): scope pending fallback to verification
Name the continuation fallback for its actual verification-only provenance so unrelated continuation paths cannot accidentally inherit its cron-delivery semantics.
This commit is contained in:
@@ -613,11 +613,11 @@ def run_conversation(
|
||||
truncated_response_parts: List[str] = []
|
||||
compression_attempts = 0
|
||||
_turn_exit_reason = "unknown" # Diagnostic: why the loop ended
|
||||
# Last composed answer intentionally held back by an internal continuation
|
||||
# gate. If the continuation consumes the remaining budget, this is the
|
||||
# best user-facing result available; it must not be confused with error or
|
||||
# Last composed answer intentionally held back by a verification gate. If
|
||||
# that continuation consumes the remaining budget, this is the best
|
||||
# user-facing result available; it must not be confused with error or
|
||||
# recovery text produced by unrelated exit paths.
|
||||
_pending_continuation_response = None
|
||||
_pending_verification_response = None
|
||||
|
||||
# Per-turn tally of consecutive successful credential-pool token refreshes,
|
||||
# keyed by (provider, pool-entry-id). A persistent upstream 401 lets
|
||||
@@ -5182,7 +5182,7 @@ def run_conversation(
|
||||
# continuation-budget exhaustion. ``final_response`` itself
|
||||
# must be cleared so the finalizer can distinguish this gate
|
||||
# from unrelated error/recovery exits. (#61631)
|
||||
_pending_continuation_response = final_response
|
||||
_pending_verification_response = final_response
|
||||
final_response = None
|
||||
continue
|
||||
|
||||
@@ -5235,7 +5235,7 @@ def run_conversation(
|
||||
agent._session_messages = messages
|
||||
logger.debug("pre_verify nudge issued (attempt %d)",
|
||||
agent._pre_verify_nudges)
|
||||
_pending_continuation_response = final_response
|
||||
_pending_verification_response = final_response
|
||||
final_response = None
|
||||
continue
|
||||
|
||||
@@ -5321,7 +5321,7 @@ def run_conversation(
|
||||
original_user_message=original_user_message,
|
||||
_should_review_memory=_should_review_memory,
|
||||
_turn_exit_reason=_turn_exit_reason,
|
||||
_pending_continuation_response=_pending_continuation_response,
|
||||
_pending_verification_response=_pending_verification_response,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -42,7 +42,7 @@ def finalize_turn(
|
||||
original_user_message,
|
||||
_should_review_memory,
|
||||
_turn_exit_reason,
|
||||
_pending_continuation_response=None,
|
||||
_pending_verification_response=None,
|
||||
):
|
||||
"""Run the post-loop finalization and return the turn ``result`` dict.
|
||||
|
||||
@@ -57,7 +57,7 @@ def finalize_turn(
|
||||
)
|
||||
continuation_budget_exhausted = (
|
||||
final_response is None
|
||||
and bool(_pending_continuation_response)
|
||||
and bool(_pending_verification_response)
|
||||
and budget_exhausted
|
||||
)
|
||||
|
||||
@@ -68,7 +68,7 @@ def finalize_turn(
|
||||
# one. Preserve that exact answer instead of replacing it with another
|
||||
# fallible model call. The explicit pending value is the provenance
|
||||
# guard: unrelated error/recovery exits can never enter this branch.
|
||||
final_response = _pending_continuation_response
|
||||
final_response = _pending_verification_response
|
||||
_turn_exit_reason = f"max_iterations_reached({api_call_count}/{agent.max_iterations})"
|
||||
iteration_limit_fallback = True
|
||||
elif final_response is None and budget_exhausted:
|
||||
|
||||
@@ -84,7 +84,7 @@ def _finalize(
|
||||
final_response,
|
||||
exit_reason,
|
||||
api_call_count=60,
|
||||
pending_continuation_response=None,
|
||||
pending_verification_response=None,
|
||||
):
|
||||
return finalize_turn(
|
||||
agent,
|
||||
@@ -100,7 +100,7 @@ def _finalize(
|
||||
original_user_message="task",
|
||||
_should_review_memory=False,
|
||||
_turn_exit_reason=exit_reason,
|
||||
_pending_continuation_response=pending_continuation_response,
|
||||
_pending_verification_response=pending_verification_response,
|
||||
)
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ def test_pending_verify_response_is_preserved_for_cron_delivery(monkeypatch):
|
||||
agent,
|
||||
final_response=None,
|
||||
exit_reason="unknown",
|
||||
pending_continuation_response=report,
|
||||
pending_verification_response=report,
|
||||
)
|
||||
|
||||
assert result["final_response"] == report
|
||||
@@ -131,7 +131,7 @@ def test_pending_pre_verify_response_is_preserved_on_budget_exhaustion(monkeypat
|
||||
agent,
|
||||
final_response=None,
|
||||
exit_reason="budget_exhausted",
|
||||
pending_continuation_response=report,
|
||||
pending_verification_response=report,
|
||||
)
|
||||
|
||||
assert result["final_response"] == report
|
||||
@@ -193,7 +193,7 @@ def test_pending_response_records_kanban_timeout(monkeypatch):
|
||||
agent,
|
||||
final_response=None,
|
||||
exit_reason="unknown",
|
||||
pending_continuation_response="composed report",
|
||||
pending_verification_response="composed report",
|
||||
)
|
||||
|
||||
assert result["turn_exit_reason"] == "max_iterations_reached(60/60)"
|
||||
|
||||
Reference in New Issue
Block a user