fix(gateway): strip cursor from frozen message on empty fallback continuation (#7183)#12472
Merged
Conversation
…inuation (#7183) When _send_fallback_final() is called with nothing new to deliver (the visible partial already matches final_text), the last edit may still show the cursor character because fallback mode was entered after a failed edit. Before this fix the early-return path left _already_sent = True without attempting to strip the cursor, so the message stayed frozen with a visible ▉ permanently. Adds a best-effort edit inside the empty-continuation branch to clean the cursor off the last-sent text. Harmless when fallback mode wasn't actually armed or when the cursor isn't present. If the strip edit itself fails (flood still active), we return without crashing and without corrupting _last_sent_text. Adapted from PR #7429 onto current main — the surrounding fallback block grew the #10807 stale-prefix handling since #7429 was written, so the cursor strip lives in the new else-branch where we still return early. 3 unit tests covering: cursor stripped on empty continuation, no edit attempted when cursor is not configured, cursor-strip edit failure handled without crash. Originally proposed as PR #7429.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A streaming message is no longer left frozen with a visible
▉cursor when fallback mode kicks in and has nothing new to send at stream end. The cursor-stripping edit that was missing from the empty-continuation early-return path is now attempted before returning.Changes
gateway/stream_consumer.py— in_send_fallback_final(), whencontinuation.strip() == ""andfinal_textdoesn't differ meaningfully from the visible prefix, attempt a best-effort edit to strip the cursor before the early return. Harmless when fallback wasn't armed or the cursor isn't present; crash-proof if the edit itself fails.tests/gateway/test_stream_consumer.py— 3 regression tests inTestCursorStrippingOnFallback: cursor stripped on empty continuation, no edit attempted when cursor is not configured, edit-failure handled without corrupting_last_sent_text.Validation
tests/gateway/test_stream_consumer.py_send_fallback_finalempty-continuation pathLive-tested against the Phase 1 integration harness (real agent on OpenRouter → real
GatewayStreamConsumer→ mock adapter with simulated flood control): all three scenarios — no flood, flood@1, flood@2 — deliver content correctly without regressions. The remaining cursor residue visible in the live test is on a separate code path (_try_strip_cursor()inside the #8124 segment-flush helper hitting an active flood window), outside the scope of this fix.Closes
Credit
c49e848dvia--author. The cursor-strip logic was adapted onto current main because the surrounding_send_fallback_finalblock grew the [Bug]: 【高优 BUG】execute_code 超 30 秒后静默丢失,无返回、无日志、无回执 #10807 stale-prefix handling after fix(gateway): strip cursor from frozen message when fallback continuation is empty #7429 was submitted, so the strip lives in the newelse-branch where we still return early instead of the original single-exit early-return.Relationship to recent streaming fixes
This is the last defense-in-depth piece for the Discord "section-header with stuck cursor" pattern:
d7607292(Apr 11) — adaptive backoff +_try_strip_cursor()on fallback entry1d1e1277(fix(gateway): flush undelivered tail before segment reset (#8124) #12414, Apr 19) — flush undelivered tail before segment reset ([Bug]: Streaming text silently dropped when tool boundary arrives during fallback mode #8124)c49e848d(this PR) — cursor strip on empty fallback continuation ([Bug]: Telegram streaming message frozen with cursor (▉) when final cursor-removal edit fails after tool call #7183)