You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
fix(session-ui): grow markdown live tail in place - #48432
Closes#36043 — jointly with the tui-delta-coalesce PR. Each applies
independently (different layer, no shared code, merge in either order);
only together do they remove O(n²) from both client-side stages of the
stream path and fully close the freeze. Builds on the freeze diagnosis in #41472.
Type of change
Bug fix
New feature
Refactor / code improvement
Documentation
What does this PR do?
While streaming, the markdown projection re-parsed the entire accumulated text
on every delta, even when the previous text was unchanged and the new suffix
was small. Each re-lex is O(length), so a stream of n small deltas costs
O(n²) — the dominant cost in the TUI freeze once deltas are batched.
project() in markdown-stream.ts now grows the open live tail in place
instead of re-lexing, and only re-lexes when the new suffix contains a
blank-line block boundary or the raw text exceeds a 2048-char cap. A single
giant boundary-less paragraph/list/table therefore never re-parses per delta.
Because the projection lives in the shared session-ui package, web and
desktop also inherit the cheaper project() as a free performance win, even
though their per-token rendering is not the freeze described in #36043.
Counterpart on the store side: the tui-delta-coalesce PR (coalesces message.part.delta events per part in a delta buffer, flushing to the store
on a 32 ms timer instead of once per event). Together they remove O(n²) from
both halves of the TUI stream path — the markdown projection here, the store
writes there.
How did you verify your code works?
bun test: 26 markdown-stream tests (incl. a new test growing a
boundary-less oversized tail in place without splitting) — 86 tests, 0
failures.
bun typecheck clean in packages/session-ui.
oxlint: 0 errors.
Micro-benchmark streaming 6–15 KB through project() in small deltas
(Bun): paragraphs 1399 ms → 20 ms, single 15 KB paragraph 32345 ms → 161 ms,
growing list 4467 ms → 60 ms.
Screenshots / recordings
N/A — no visual change; it's a rendering-perf fix (benchmark above).
This branch has been upgraded to V2. We're no longer taking PRs for V1. If you think this is still relevant, please port it over and open it for V2.
— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊
This is the dev branch which is still producing V1 binaries. V2 binary is still identified as beta. V1 is in LTS production environments and will be for many years. V1 requires maintenance PRs exactly like this one.
Per the request to port this to V2, #55857 re-implements the live-tail optimization against the current packages/session-ui/src/components/markdown-stream.ts. project() grows the open mode: "live" tail in place and re-lexes only the tail past the 2048-char cap on a blank-line boundary, preserving frozen blocks. The V2 port adds the edges V1 did not need: late reference definitions, frozen display math, fence-open detection, and rebuilding the tail raw from source text. Micro-benchmark: 12.6 KB boundary-less paragraph 10.8 s → 91 ms (~119×).
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
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.
Issue for this PR
Closes #36043 — jointly with the tui-delta-coalesce PR. Each applies
independently (different layer, no shared code, merge in either order);
only together do they remove O(n²) from both client-side stages of the
stream path and fully close the freeze. Builds on the freeze diagnosis in
#41472.
Type of change
What does this PR do?
While streaming, the markdown projection re-parsed the entire accumulated text
on every delta, even when the previous text was unchanged and the new suffix
was small. Each re-lex is O(length), so a stream of n small deltas costs
O(n²) — the dominant cost in the TUI freeze once deltas are batched.
project()inmarkdown-stream.tsnow grows the openlivetail in placeinstead of re-lexing, and only re-lexes when the new suffix contains a
blank-line block boundary or the raw text exceeds a 2048-char cap. A single
giant boundary-less paragraph/list/table therefore never re-parses per delta.
Because the projection lives in the shared
session-uipackage, web anddesktop also inherit the cheaper
project()as a free performance win, eventhough their per-token rendering is not the freeze described in #36043.
Counterpart on the store side: the tui-delta-coalesce PR (coalesces
message.part.deltaevents per part in a delta buffer, flushing to the storeon a 32 ms timer instead of once per event). Together they remove O(n²) from
both halves of the TUI stream path — the markdown projection here, the store
writes there.
How did you verify your code works?
bun test: 26markdown-streamtests (incl. a new test growing aboundary-less oversized tail in place without splitting) — 86 tests, 0
failures.
bun typecheckclean inpackages/session-ui.oxlint: 0 errors.project()in small deltas(Bun): paragraphs 1399 ms → 20 ms, single 15 KB paragraph 32345 ms → 161 ms,
growing list 4467 ms → 60 ms.
Screenshots / recordings
N/A — no visual change; it's a rendering-perf fix (benchmark above).
Checklist
Tracking: #48430