Skip to content

fix(interrupt): keep partial streamed reply when stopped mid-response - #52854

Merged
OutThisLife merged 1 commit into
mainfrom
bb/fix-interrupt-partial-reply
Jun 26, 2026
Merged

fix(interrupt): keep partial streamed reply when stopped mid-response#52854
OutThisLife merged 1 commit into
mainfrom
bb/fix-interrupt-partial-reply

Conversation

@OutThisLife

@OutThisLife OutThisLife commented Jun 26, 2026

Copy link
Copy Markdown
Collaborator

Summary

Pressing stop/esc to redirect mid-response made the agent "forget" what it
was saying. When a turn is interrupted while the model is streaming,
InterruptedError was caught, final_response was set to the throwaway
"Operation interrupted: waiting for model response (Xs elapsed)." sentinel, and
messages were persisted without the assistant text already streamed to the
screen. The next turn had no record of the half-finished reply, so the model
restarted blind — reported as "if I stop a message it forgets about it."

The fix recovers the on-screen text from agent._current_streamed_assistant_text
in the InterruptedError branch (agent/conversation_loop.py) and appends it as
the assistant turn, also surfacing it as final_response. The metadata sentinel
is kept only when nothing was streamed yet, so the ACP/client suppression
behavior (INTERRUPT_WAITING_FOR_MODEL_PREFIX startswith check) is unchanged.

Root cause / history

  • Lossy from day one — the streaming except InterruptedError handler was
    introduced in c98ee9852
    ("feat: implement interactive prompts for sudo password and command approval",
    Feb 21 2026) with final_response = "Operation interrupted." and no capture of
    the streamed text.
  • The fix that missed this path397eae5d9
    ("fix: recover partial streamed content on connection failure", Apr 13 2026)
    added the _current_streamed_assistant_text salvage, but only for the
    stream-failure twin — the user-interrupt branch right above it was never
    wired up. This PR completes that work.
  • No-op for this bug2394e1872
    (sentinel wording) and the refactors 053025238
    / f5bd09af4
    only moved/renamed the handler.

Test plan

  • test_interrupt_during_stream_preserves_partial_assistant_text — partial
    reply is appended to history + returned as final_response.
  • test_interrupt_before_any_stream_keeps_sentinel — no streamed text falls
    back to the metadata sentinel, tail stays the user turn.
  • Existing interrupt/streaming/alternation suites green (streaming,
    partial_stream_finish_reason, turn_finalizer_interrupt_alternation,
    interrupt_propagation, concurrent_interrupt — 60 passed).

Stopping a turn while the model is streaming (stop/esc to redirect) raised
InterruptedError, set final_response to the throwaway "waiting for model
response" sentinel, and persisted messages WITHOUT the assistant text that
was already streamed to the screen. The next turn then had no record of the
half-finished reply, so the model appeared to "forget" what it just said.

Recover the on-screen text from _current_streamed_assistant_text in the
InterruptedError branch and append it as the assistant turn (and surface it
as final_response). The metadata sentinel is kept only when nothing was
streamed yet, preserving the ACP/client suppression behavior.

Completes the partial-stream recovery from 397eae5 (which wired the same
_current_streamed_assistant_text salvage into the connection-failure twin
but missed the user-interrupt path). The lossy handler dates to c98ee98.
@github-actions

Copy link
Copy Markdown
Contributor

🔎 Lint report: bb/fix-interrupt-partial-reply vs origin/main

ruff

Total: 0 on HEAD, 0 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 0 pre-existing issues carried over.

ty (type checker)

Total: 11396 on HEAD, 11396 on base (➖ 0)

🆕 New issues: none

✅ Fixed issues: none

Unchanged: 6001 pre-existing issues carried over.

Diagnostics are surfaced as warnings — this check never fails the build.

@OutThisLife
OutThisLife enabled auto-merge June 26, 2026 04:56
@alt-glitch alt-glitch added type/bug Something isn't working comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jun 26, 2026
@OutThisLife
OutThisLife disabled auto-merge June 26, 2026 05:04
@OutThisLife
OutThisLife merged commit f4c656b into main Jun 26, 2026
46 of 48 checks passed
@OutThisLife
OutThisLife deleted the bb/fix-interrupt-partial-reply branch June 26, 2026 05:04
T02200059 pushed a commit to T02200059/hermes-agent that referenced this pull request Jun 29, 2026
…ch#52854 from NousResearch/bb/fix 4d04c65 fix(curator): make external-skill write guard actu  [analysis]
waefrebeorn pushed a commit to waefrebeorn/slermes that referenced this pull request Jul 2, 2026
…upt-partial-reply

fix(interrupt): keep partial streamed reply when stopped mid-response
habarmc1223-sudo pushed a commit to habarmc1223-sudo/hermes-agent-fluxmem that referenced this pull request Jul 8, 2026
…upt-partial-reply

fix(interrupt): keep partial streamed reply when stopped mid-response
santhreal pushed a commit to santhreal/hermes-agent that referenced this pull request Jul 13, 2026
…upt-partial-reply

fix(interrupt): keep partial streamed reply when stopped mid-response
Gravezzz pushed a commit to Gravezzz/hermes-agent that referenced this pull request Jul 21, 2026
…upt-partial-reply

fix(interrupt): keep partial streamed reply when stopped mid-response
leewenjie pushed a commit to leewenjie/hermes-agent that referenced this pull request Aug 7, 2026
…upt-partial-reply

fix(interrupt): keep partial streamed reply when stopped mid-response
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/agent Core agent runtime: loop, agent_init, prompt builder, context-compression, responses endpoint P2 Medium — degraded but workaround exists sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants