Skip to content

💬 fix: Show a Thought on the Live Header Only as Finished Sentences - #16392

Merged
danny-avila merged 1 commit into
devfrom
danny-avila/live-reasoning-complete-sentence
Sep 27, 2026
Merged

danny-avila merged 1 commit into
devfrom
danny-avila/live-reasoning-complete-sentence

Conversation

@danny-avila

@danny-avila danny-avila commented Sep 26, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

While a span is only reasoning, the live header previews the thought one sentence at a time, and it previewed the sentence the model was still writing, word by word. On screen that is a run of fragments ("This is a simple greeting, not", "I should respond in a friendly,") that change before they can be read and are replaced mid-thought by the next fragment, which reads as disjointed.

The header now shows the last sentence that ended, never the one in progress. A finished sentence holds the line for at least a second before the next finished one may replace it, and until the first sentence ends the header keeps its generic line ("Thinking…" or the reasoning label). A Latin sentence mark closes a sentence only before whitespace or the end of the text, so "3.5" and "v2.1" stay inside one sentence; CJK marks need no space, as before.

The measurement that let short sentences stream unthrottled until they filled the row (a ResizeObserver plus a scroll-width read per paint) is removed with it: the line no longer changes per word, so there is nothing to meter.

Stacked on #16391 and targets its branch.

How it works

// live.ts
const boundary = /[.!?](?:\s+|$)|[。!?]\s*/g;
// walk every boundary in the bounded tail; `complete` is the text from the
// previous boundary to the newest mark; the remainder after it is ignored.

LivePhaseHeader throttles a think: line at LIVE_REASONING_HOLD_MS (1000ms) and everything else at LIVE_ACTIVITY_THROTTLE_MS (500ms). The throttle is leading-edge, so a sentence that ends a second or more after the last paint shows at once; only sentences that end faster than that wait.

Type of change

  • Bug fix

Testing

Automated tests:

  • LiveParity.test.tsx: new "shows a thought only as finished sentences, each held for a second" and "keeps decimals and versions inside one sentence"; the CJK preview case and the bounded-window case updated to the finished sentence; the two fill-measurement cases removed with the mechanism
  • ContentParts.integration.test.tsx: the one-sentence-at-a-time case now waits for the second sentence to end
  • cd client && npx jest LiveParity ActivityPhaseGroup ContentParts — 180 tests
  • npx tsc --noEmit in client: no errors in touched files

Before / after screenshot

Captured while the first reasoning sentence is still streaming. Before, the header exposes the in-progress fragment “First I”; after, it keeps “Thinking...” until a sentence ends.

Before and after the live reasoning sentence policy

349e01f3a3cd (before) → 118bbcf2e37c (after).

@danny-avila
danny-avila force-pushed the danny-avila/live-reasoning-complete-sentence branch from b24d23a to 118bbcf Compare September 26, 2026 12:51
@danny-avila
danny-avila added this pull request to stack #16396 September 26, 2026 14:10
@danny-avila
danny-avila force-pushed the danny-avila/live-reasoning-complete-sentence branch 2 times, most recently from f8b78e5 to d00f62c Compare September 27, 2026 01:25
Base automatically changed from danny-avila/reasoning-header-row-size to dev September 27, 2026 01:46
The live header previewed the sentence the model was still writing, word
by word, so it read as fragments ("This is a simple greeting, not") that
changed before they made sense and were replaced by the next fragment. It
now shows the last sentence that ENDED, holds it for at least a second, and
keeps its generic line until the first sentence finishes. A Latin mark
closes a sentence only before whitespace or the end of the text, so
decimals and version numbers stay whole; CJK marks need no space.

The measurement that let short sentences stream freely until they filled
the row (a ResizeObserver and a per-paint scroll-width read) goes with it:
the line no longer changes per word, so there is nothing to meter.
@danny-avila
danny-avila marked this pull request as ready for review September 27, 2026 01:46
@danny-avila
danny-avila force-pushed the danny-avila/live-reasoning-complete-sentence branch from d00f62c to 69bf1be Compare September 27, 2026 01:46
@danny-avila
danny-avila merged commit 269e6b3 into dev Sep 27, 2026
27 checks passed
@danny-avila
danny-avila deleted the danny-avila/live-reasoning-complete-sentence branch September 27, 2026 01:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant