Repository navigation
perf(desktop): coalesce streaming events and isolate session/workspace switches - #3922
Merged
Merged
Conversation
…e switches Eliminate frame drops during long streaming replies, lag during concurrent multi-session switches, and multi-workspace switch stalls across four targeted areas: 1. Ordered batch transport & hidden-session isolation: coalesce consecutive TextChunk, ThinkingChunk, ToolEvent(ParamsPartial/Progress) runs in Desktop EventCoalescer and emit multi-event flushes via agentic://event-batch while preserving single-event compatibility; stage hidden-session streaming chunks in memory with silent store writes and materialize on session activation. 2. Zero-JSON.stringify persistence & WeakMap budget estimation: replace full-turn JSON.stringify hashing with dual-32-bit structural fingerprinting + WeakMap memoization, cache settled backend rounds, gate non-local peer checkpoints, and memoize retained-byte estimation per completed ModelRound. 3. Incremental tail Markdown & adaptive streaming reveal: fix whole-document fallback triggers in splitMarkdownSections, strip code spans/fences before math detection, make rehypeRaw conditional on raw HAST nodes, add adaptive typewriter paint cadence, and prune revealed subtrees in useStreamingTextReveal. 4. Session & workspace switch isolation: scope NavPanel session selectors by workspace, add per-session turn-prefix LRU and shallow canvas snapshot cloning, collapse workspace switching to a single WorkspaceContext wave without cross-workspace auto-select races, deduplicate macOS AppKit menubar rebuilds, and move best-effort workspace runtime ensure off the set_active_workspace IPC critical path.
… and sibling streaming paths
3 tasks done
bobleer
added a commit
that referenced
this pull request
Nov 15, 2026
revert: revert PR #3922 streaming coalescing and session switch changes
bobleer
added a commit
to bobleer/OpenBitFun
that referenced
this pull request
Nov 15, 2026
…itch changes Reverts openBitFun#3922 (commit db95809) to restore baseline FlowChat streaming cadence and session/workspace behavior.
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
Eliminates UI frame drops during long streaming replies, session-switching lag under concurrent multi-session execution, and multi-workspace switch stalls through four targeted surgeries plus sibling hot-path optimizations:
EventCoalescerto coalesce consecutiveTextChunk,ThinkingChunk, andToolEventData::{ParamsPartial, Progress}runs while preserving strict arrival order; group contiguous high-frequency streaming chunk items onto"agentic://event-batch"while emitting lifecycle/completion events directly on their dedicated channels so standalone listeners always receive them even whenAgenticEventListeneris inactive.FlowChatStoreupdates and materialize/clean them atomically on visibility, cancellation, rollback, or session removal/promotion.JSON.stringifyturn fingerprinting &WeakMapretained-byte memoization:JSON.stringifyinPersistenceModule.calculateTurnHashwith zero-allocation dual-32-bit structural fingerprinting across allmodelRounds+WeakMapmemoization on settled rounds/items, cache converted backendModelRoundpayloads, skip redundant mid-turnupdateSessionMetadataIPC writes unless UI metadata changed, and gate local checkpoints when driving a non-local Peer host.estimateRetainedBytesobject entry arrays with zero-allocation walks +WeakMap<ModelRound, number>caching on completed rounds.splitMarkdownSectionsso settled Markdown blocks stay cached and only the active streaming tail re-parses; strip code fences/spans (respecting CommonMark tab indentation and paragraph breaks) before math detection to avoid false KaTeX pipeline activation on$in code; guardrehypeRawbehind raw HAST node presence; short-circuit unused plugins/scanners forthinkingblocks.diffLinesduringParamsPartialstreaming for file edits over 80 lines (computing exact diff stats once settled) and avoid duplicateparsePartialJsoncalls.minPaintIntervalMs/maxCharsPerPaint) inuseTypewriter(both main text andModelThinkingDisplay), keep Web Worker Markdown prewarms alive across typewriter ticks, and prune already-revealed DOM subtrees inuseStreamingTextReveal.SessionsSectionselectors to the active workspace(s), defer hidden-accordion updates, stabilizeuseSessionReviewActivity/useSessionGoalModeActivesoChatInputdoes not re-render on background chunks, deduplicateSnapshotStateManager.refreshSessionStateand skip per-card file-list IPC storms on timeline file cards, and add input-equivalence guards acrossaskUserQuestionState,sessionNavStatusService,sessionNavOrdering, andsessionSceneLifecycle.cachedTurnPrefixByIdLRU inmodernFlowChatStore, raise retained timeline views to 8 with module-levelWeakSetprewarm deduplication, keep an 8-scope LRU inuseResolvedModeSkills, and replacestructuredClonecanvas tab snapshots with shallow immutable snapshot cloning.workspaceManager.setActiveWorkspace+WorkspaceProviderupdates into a single context wave, coordinate cross-workspace session activation viapendingWorkspaceSessionActivation(with fallbackinitializeif target activation aborts), keep warm Git state caches across switches, deduplicate macOS AppKitNSMenurebuilds on the main thread, and run best-effort workspace runtime directory/SSH ensure asynchronously off theset_active_workspaceIPC critical path.Type and Areas
Type: Performance / refactor
Areas: Desktop/Tauri (
src/apps/desktop), Transport adapter (src/crates/adapters/transport), Rust core workspace service (src/crates/assembly/core), Web UI (src/web-ui)Motivation / Impact
diffLineson partial JSON chunks, re-stringify full turn histories, or trigger N-session global store broadcast storms on every 16ms frame.WorkspaceContextre-renders, duplicategetSessionStats/getSessionFilesIPC bursts, redundant AppKit main-thread menu rebuilds, and cross-workspace session auto-selection races.Verification
cargo test -p openbitfun-transport --features tauri-adapter(passed)cargo check -p openbitfun-desktop(passed)cargo test -p openbitfun-desktop --lib event_coalescer&event_loop_driver_tests(24 passed)cargo test --locked -p openbitfun-core --no-default-features --features agent-runtime,git,remote-workspace --lib service::workspace::service::tests(31 passed)pnpm run fmt:rs(passed)longRoundPerfHarness.test.tsx(0.17 ms/flushavg across 300 rounds;3.14 ms/chunkfull React DOM tail streaming)pnpm --dir src/web-ui exec tsc --noEmit(0 errors in touched files)pnpm --dir src/web-ui exec eslint --max-warnings 0on all touched files (passed, 0 warnings)pnpm run i18n:audit && pnpm run check:web:appearance(passed)pnpm run check:core-boundaries && pnpm run check:repo-hygiene(passed)node scripts/check-git-object-sizes.mjs --base origin/main --head HEAD(passed)remote-workspaceworkspace activation & POSIX scene/activation invariants) and Peer Device Mode (non-local peer checkpoint gating, surface activity observation on batched events, and single-event channel fallback). Live multi-host SSH/Relay hardware was not exercised locally.Reviewer Notes
Checklist