perf(desktop): keep transcript state incremental - #2937
Merged
Conversation
M4n5ter
force-pushed
the
perf/desktop-transcript-replica
branch
5 times, most recently
from
August 13, 2026 10:28
3c02213 to
4464f27
Compare
Make Desktop Main own a bounded sparse transcript replica and publish bounded changes to the renderer. Replace chat-path full materialization and settlement polling with range advancement, and expose paged turn summaries for history-dependent actions.
Keep turn projection chunk-aware and page it by bounded contributions rather than raw messages. Preserve transcript consumer intent across Host replacement, advance durable read markers, and make retries reopen failed generations.\n\nRelease consumed Client overlays, bound projector identities to in-flight work, and evict cold Desktop replicas under the global resident-byte budget while refreshing them on demand.
Allow a renderer transcript open to remain pending while the Runtime Host source is detached, then complete it against the replacement source. Stale source completions are closed without deleting the current registration.
Keep transcript intent pending across Host replacement, but let renderer teardown cancel the pending consumer immediately. Retry failures now remain visible instead of escaping as unhandled promises.
Keep live subscriptions available while cold transcript replicas are rebuilt, and make pending renderer opens cancellable through the Main boundary. Preserve accumulated companion history, hydrate search targets outside the tail window, bound turn-summary scans, and stream binary IPC fragments to avoid base64 amplification.
Pause the retiring event pump while a cold transcript candidate commits so old frames cannot cross into the replacement projector. Restore and drain the healthy subscription if the candidate fails.
Broadcast each encoded transcript batch to every renderer consumer. Prepare replacement reconciliation asynchronously, then activate it synchronously after ownership and failure checks so a failed candidate or concurrent recovery cannot displace a healthy replica.
Leave sessions:unobserve with the persistent Desktop owner instead of registering it again for every Runtime Host candidate. This preserves cross-candidate observation cleanup and avoids duplicate Electron handlers after the scoped IPC integration.
Route transcript reads through the active Host scope while keeping teardown persistent across candidate replacement. Bound revision settlement and message decoding independently from replica cache size so recovery cannot hang or reject otherwise supported records.
Serialize Main-to-Renderer transcript batches behind explicit acknowledgements so large records cannot build an unbounded Electron queue. Keep the established 15 MiB record path within a 16 MiB hard limit, restore the 64 MiB aggregate cache budget, and fence settlement commits against cancellation and session switches.
Keep at most one pending incremental delivery and replace additional changes with a fresh bounded replica reset after the renderer catches up. Enforce the session budget across overlay and durable records so retained presentation state cannot bypass cache accounting.
Bind transcript events and follow-up requests to the Host generation that opened them. Give each renderer consumer an independent bounded ACK window, coalesce queued changes as one bounded delta, and account retained delivery data with replica cache capacity so a slow consumer cannot block peers or escape cleanup.
Move the transcript generation scope with each accepted reset so acknowledgements and range requests follow a restored consumer onto the replacement Runtime Host without accepting stale-target frames.
Charge coalesced eviction and overlay-completion identities by their encoded wire size so delivery admission reflects every retained payload class before accepting more transcript state.
Account fragment assembly against the shared Desktop transcript budget while it is being decoded, and avoid duplicate full-record copies. Keep renderer delivery flowing with a true sliding acknowledgement window so one completed batch immediately admits the next.
Keep preparing replicas inside the global memory ledger until activation, and bound turn diagnostics before publishing them over the Runtime Host protocol.\n\nReplace manual history paging with bounded multi-page prefetch on upward scroll. Preserve the reader's message anchor while older turns mount incrementally, and expose the complete prompt index so the existing rail can navigate outside the resident tail.
When a range contains only part of the transcript, resolve scroll-spy endpoints from mounted turns instead of the complete navigation index. This preserves the tick selected for an unloaded turn after its range arrives.
Bound the prompt rail and turn-summary wire projection while preserving navigable history. Keep transcript ownership, sparse sends, cross-session scroll restoration, and return-to-latest positioning correct across asynchronous replacement and progressive mounting.
Give the active overlay and sparse durable window separate bounded residency so a valid overlay cannot make a successfully loaded history page immediately unreachable. Global eviction continues to account for their combined bytes.
Apply external preparation accounting before mutating replica-local balances so a rejected global allocation cannot be released again during teardown.
When subscription recovery overlaps the initial reset acknowledgement, wait for the owner to stabilize and deliver the replacement generation before completing the renderer open. Any post-registration failure now tears down the consumer.
Load a larger history range in one renderer commit, keep progressive anchor lookup incremental, and account reset encoding work without double-charging the resident replica. Keep transcript acknowledgements available while a Runtime Host candidate reconnects.
Replace full turn enumeration with bounded storage landmarks so session opening remains tail-first. Treat detached transcript acknowledgements as stale, and skip message descendants during incremental scroll-anchor lookup.
Use the existing ordered root-turn authority to discover prompt landmarks without scanning tool-heavy transcript gaps. Keep the sampled index as the rail's ordering authority so sparse loaded ranges cannot reorder navigation.
M4n5ter
force-pushed
the
perf/desktop-transcript-replica
branch
from
August 13, 2026 13:22
0f1de89 to
9998a4c
Compare
Retain the landmark watermark through Desktop so newly durable prompts refresh the bounded rail index without reopening the session. Keep mixed legacy and indexed prompts navigable while using endpoint lookups instead of scanning the transcript for bounds.
A durable steering row can arrive before its live event on the independent transcript stream. Hold that trailing row behind the current live content until the event projection catches up, preserving the answer DOM and smooth redaction rewrite across remounts.
M4n5ter
marked this pull request as ready for review
August 13, 2026 14:02
Member
Author
|
I’ve completed multiple rounds of review, including re-reviewing the follow-up fixes and validating the Desktop behavior end to end. The current revision meets the merge bar from my side. ✅ |
sunheyi6
added a commit
to sunheyi6/maka-agent
that referenced
this pull request
Aug 14, 2026
Resolve conflicts from the transcript range-store refactor (apache#2937 and related) that removed the readMessages bridge and refreshMessagesUntilTurn polling: - runtime-host-session-execution-ipc-main.ts: keep both isClosedSteeringAdmission (mid-turn steer) and normalizeTranscriptRangeRequest (transcript range) helpers. - bridge-contract.d.ts: keep steer(messageId?) and drop the removed readMessages method. - app-shell-chat-actions.ts: drop the removed refreshMessagesUntilTurn settle poll (readMessages is gone); the transcript range controller now owns refresh. - app-shell-first-send-cleanup.test.ts: keep both imports, adapt send mocks to the disposition/turnId contract, and track transcript refresh through the range controller instead of readMessages.
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.
English
Summary
Desktop previously opened a session by materializing its complete durable transcript, so startup time and memory grew with the full conversation even when the user only needed the latest turns.
This PR moves Desktop onto the bounded transcript data plane from #2922:
The primary gain here is bounded session opening and history residency. The larger rendering-speed improvement comes from the follow-up that virtualizes the mounted conversation; Host-side search is also kept separate.
中文
概述
Desktop 以前会在打开会话时完整物化全部 durable transcript,因此启动耗时和内存会随完整对话增长,即使用户只需要查看最新几轮。
本 PR 让 Desktop 使用 #2922 提供的有界 transcript 数据平面:
本 PR 的主要收益是让会话打开和历史常驻内存有界。更显著的渲染提速来自后续的会话 DOM 虚拟化;Host-side search 也保持为独立后续工作。
Refs #2913
Checklist
Does this PR entail a change in behavior?