From f46e7647eb72664c74829fe31550a2b74fe19314 Mon Sep 17 00:00:00 2001 From: kshitijk4poor <82637225+kshitijk4poor@users.noreply.github.com> Date: Fri, 10 Jul 2026 11:31:42 +0530 Subject: [PATCH] fix(agent): clear stale intermediate acknowledgments Treat intent-ack continuation text as non-final so last-turn exhaustion requests a real summary instead of surfacing a premature promise. Keep iteration-limit fallback text free of the abnormal-fragment explainer. --- agent/conversation_loop.py | 4 ++++ agent/turn_finalizer.py | 2 +- .../test_verification_continuation_budget.py | 19 +++++++++++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/agent/conversation_loop.py b/agent/conversation_loop.py index c0af0e865fe..ce62ffcde1a 100644 --- a/agent/conversation_loop.py +++ b/agent/conversation_loop.py @@ -5104,6 +5104,10 @@ def run_conversation( } messages.append(continue_msg) agent._session_messages = messages + # An acknowledgment is explicitly non-final. Do not let its + # text suppress iteration-limit summarization if this + # continuation consumes the remaining budget. + final_response = None continue codex_ack_continuations = 0 diff --git a/agent/turn_finalizer.py b/agent/turn_finalizer.py index 17961eda222..c7779bd6b9a 100644 --- a/agent/turn_finalizer.py +++ b/agent/turn_finalizer.py @@ -320,7 +320,7 @@ def finalize_turn( # truncated partial (the "The" case from #34452). _is_partial_fragment = ( not _is_empty_terminal - and not continuation_budget_exhausted + and not iteration_limit_fallback and not str(_turn_exit_reason).startswith("text_response") and len(_stripped) <= 24 and _stripped[-1:] not in {".", "!", "?", "。", "!", "?", "`", ")"} diff --git a/tests/run_agent/test_verification_continuation_budget.py b/tests/run_agent/test_verification_continuation_budget.py index e55ce65a42a..a71b995a5aa 100644 --- a/tests/run_agent/test_verification_continuation_budget.py +++ b/tests/run_agent/test_verification_continuation_budget.py @@ -102,3 +102,22 @@ def test_pre_verify_preserves_composed_report_at_budget_limit(agent, monkeypatch _assert_pending_response_survives(agent, result) assert result["messages"][1]["_pre_verify_synthetic"] is True assert result["messages"][2]["_pre_verify_synthetic"] is True + + +def test_intermediate_ack_uses_summary_instead_of_premature_text(agent, monkeypatch): + agent.valid_tool_names = ["web_search"] + agent._intent_ack_continuation = True + agent._looks_like_codex_intermediate_ack = MagicMock(return_value=True) + agent._interruptible_api_call = lambda _kwargs: _response("I'll inspect the files now") + agent._handle_max_iterations = MagicMock(return_value="verified summary") + monkeypatch.setenv("HERMES_VERIFY_ON_STOP", "0") + + with ( + patch("hermes_cli.plugins.has_hook", return_value=False), + patch("hermes_cli.plugins.invoke_hook", return_value=[]), + ): + result = agent.run_conversation("inspect /tmp/project") + + assert result["final_response"] == "verified summary" + assert result["turn_exit_reason"] == "max_iterations_reached(1/1)" + agent._handle_max_iterations.assert_called_once()