fix(desktop): reduce long-history streaming work - #69151
Conversation
Reduce dominant transcript-sized conversion, repository, signature, and DOM scans while preserving authoritative fallback semantics.\n\nAdd a repeatable preloaded-history streaming benchmark and focused regression coverage for tail provenance, stale-delta fallback, repository identity, and bounded timeline geometry.
4c70a0b to
8540753
Compare
|
Superseded by #71835. Your diagnosis was right, and it's what the fix is built on — the three costs you identified (timeline geometry, discarded conversion identity, whole-repository reconcile per delta) all reproduced on Two things moved since you opened this. The timeline half was overtaken by #71789 and #71780, which idle the rail entirely on hidden panes and skip the rect walk while following the bottom. That left the repository half, and it turned out not to need the provenance-token protocol: the identity cache in You're credited as co-author on both commits. Thanks for the writeup and the profiles — the CPU attribution is what made this quick to confirm. |
What does this PR do?
Fixes #69120.
Desktop stream rendering currently repeats several dominant transcript-sized scans for every incoming delta. This PR records single-message updates at the source, forwards validated pending-tail deltas without re-exporting/re-indexing the settled repository, keeps historical runtime messages reference-stable, and limits timeline geometry work to rendered prompts. Completion, authoritative replay, deletion, branch changes, and session changes still use the complete reconcile path.
The immutable source and visible-message arrays still require shallow reference copies; this PR targets the measured conversion, repository traversal, signature, and DOM-layout costs rather than replacing the Desktop transcript data structure.
It also adds a report-only
stream-historyperformance scenario. History is mounted before recorders start; the harness verifies the source message count, waits for two paints, and applies a configurable settle period before measuring subsequent streaming.Draft #68724 is complementary: it removes
requestAnimationFramefrom production delta flushing for hidden windows. This PR does not change that production scheduler. Its synthetic perf driver also uses timer-only flushing, so it does not reintroduce a hidden-window rAF dependency.Related Issue
Fixes #69120
Type of Change
Changes Made
apps/desktop/src/app/chat/runtime-repository.tsThreadMessageobjects produced by the existing conversion cache instead of recreating the complete branch array;apps/desktop/src/app/session/hooks/use-message-stream/index.tsapps/desktop/src/lib/chat-messages.tsapps/desktop/src/lib/incremental-external-store-runtime.tsparentIdon complete reconciles, avoid duplicate full exports, and reset the head only when necessary;apps/desktop/src/components/assistant-ui/thread/timeline.tsxapps/desktop/src/components/assistant-ui/thread/list.tsxapps/desktop/scripts/perf/scenarios/stream-history.mjsheadId, and logarithmically bounded timeline geometry reads.How to Test
cd apps/desktop npm run perf -- stream-history --spawn --prod --runs 5 --historyTurns 200 npm run perf -- stream-history --spawn --prod --runs 5 --historyTurns 1000Median of five runs on the same Linux/Wayland machine:
Empty-history control remained within run-to-run noise: frame p95
22.4 msbefore and23.2 msafter, with one frame over 33 ms in each sample.The benchmark was recorded around base
a2c2ec63322b791d6d1a7a024640064d96e7f0ae. The branch was subsequently rebased onto currentmain(91546b8337068891cc0a6b834d89d0d9270fb3ec) to resolve the PR's merge conflict. The only rebase conflict was the import list inapps/desktop/src/lib/chat-messages.test.ts; it preserves both current-main'scollectUnspokenTurnSpeechimport and this PR'sgetChatMessageListUpdateimport. The published rebased head is854075304e540c0605e0b762b5d0ac4e5a4ff985.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass — N/A: this PR changes only Desktop TypeScript/React and its performance harness; the complete Desktop gate below passedDocumentation & Housekeeping
stream-historycli-config.yaml.exampleupdate is N/A — no config keys changedCONTRIBUTING.md/AGENTS.mdupdate is N/A — no contributor workflow changedScreenshots / Logs
Initial local verification on the pre-rebase base
3e953ed815ffb1e35277a77eb3e764d39dcf36f7:npm run check— PASS (typecheck, complete Desktop Vitest suite, production build, and Linux package)npm run lint— PASS with 9 existing warnings outside the changed files and 0 errorspython scripts/check-windows-footguns.py --diff origin/main— no applicable files (0scanned)git diff --check— PASS56tests)Post-rebase validation on
91546b8337068891cc0a6b834d89d0d9270fb3ec:56tests)npm --workspace apps/desktop run typecheck— PASS.ts/.tsxfile — PASSnpm --workspace apps/desktop run build— PASS (CSS and bundle-size warnings only)git diff --check— PASSNo UI screenshot is included because the change intentionally preserves rendering and interaction output; the reproducible artifact is the report-only performance scenario and its JSON metrics.