fix(cron): preserve composed reports when verify-on-stop exhausts budget

Clear stale final_response before verify-on-stop/pre_verify loop
continues, and normalize iteration-limit exit reasons in turn_finalizer
when a composed answer survives with unknown/budget_exhausted.

Fixes #61631
This commit is contained in:
HexLab98 2026-07-10 07:10:18 +07:00 committed by kshitij
parent f82c71396d
commit 3eb937a498
2 changed files with 24 additions and 0 deletions

View file

@ -5173,6 +5173,11 @@ def run_conversation(
# terminal. Keep a debug breadcrumb in agent.log for tracing.
logger.debug("verification stop-loop nudge issued (attempt %d)",
agent._verification_stop_nudges)
# The attempted answer lives in ``final_msg`` / ``messages`` for
# the verify loop; do not keep a stale ``final_response`` that
# would skip turn_finalizer's iteration-limit normalization.
# (#61631)
final_response = None
continue
# User verification-loop gate: when the agent edited code this
@ -5224,6 +5229,7 @@ def run_conversation(
agent._session_messages = messages
logger.debug("pre_verify nudge issued (attempt %d)",
agent._pre_verify_nudges)
final_response = None
continue
messages.append(final_msg)

View file

@ -121,6 +121,24 @@ def finalize_turn(
exc_info=True,
)
elif (
final_response is not None
and (
api_call_count >= agent.max_iterations
or agent.iteration_budget.remaining <= 0
)
and not str(_turn_exit_reason).startswith("text_response(")
and not str(_turn_exit_reason).startswith("max_iterations_reached(")
):
# verify-on-stop can assign ``final_response`` then ``continue`` the
# loop until the iteration budget is gone, leaving a composed answer
# with a non-success exit reason (``unknown``, ``budget_exhausted``).
# Normalize so cron's graceful-delivery exemption can match.
# (#61631)
_turn_exit_reason = (
f"max_iterations_reached({api_call_count}/{agent.max_iterations})"
)
# Determine if conversation completed successfully
normal_text_response = str(_turn_exit_reason).startswith("text_response(")
completed = (