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
The Desktop transcript cache currently serializes the newest 40 messages, then falls back directly to the newest 8 when that exceeds the 256 KiB cap. If those 8 are still too large, it drops the cache entry even when a smaller complete suffix would fit. That turns a cacheable recent transcript into a cold resume on the next launch.
This replaces the fixed fallback with a bounded binary search for the largest complete message suffix that fits. It preserves the existing 40-message and 256 KiB limits, never truncates a message, and needs at most six serialization attempts.
The durable transcript-tail cache is existing core Desktop behavior introduced by merged PR #89510. This PR fixes that core cache's serializer independently of #96721. PR #96721 is related because it keeps an already-cached transcript visible while the live session resumes; this PR ensures the existing cache does not unnecessarily discard a complete suffix that #96721 could paint.
This is intentionally separate from the transcript-provenance work in #96130. It changes only which bounded payload is retained after the caller has already established the cache identity.
Desktop performance series
This change is one independently reviewable layer of the same Desktop startup and first-interaction performance pass.
The three Python backend PRs share startup files but solve separate stages. Recommended landing order is #96749, then #96750, then #96751, rebasing the next PR only after the preceding one lands. #97032 is an independently reviewable Electron ordering change. The remaining renderer and Bot Mode PRs can also land independently; their effects compose without making cached state authoritative.
This PR owns transcript-cache retention correctness: the existing bounded cache keeps the largest complete suffix that fits instead of dropping a cacheable tail.
New feature (non-breaking change that adds functionality)
Security fix
Documentation update
Tests (adding or improving test coverage)
Refactor (no behavior change)
New skill (bundled or hub)
Changes Made
Replace the fixed 8-message retry in apps/desktop/src/store/transcript-tail-cache.ts with a bounded search for the largest complete suffix under the existing cap.
Add a regression case where three heavy messages exceed the cap but the newest two fit and must remain cacheable.
How to Test
Run npm run test:ui -- src/store/transcript-tail-cache.test.ts --maxWorkers=4 --reporter=verbose from apps/desktop.
Run npm run typecheck from apps/desktop.
Run npx eslint src/store/transcript-tail-cache.ts src/store/transcript-tail-cache.test.ts from apps/desktop.
AI code review — automated review for reference; please use your judgment.
fix(desktop): retain the largest cacheable transcript tail
apps/desktop/src/store/transcript-tail-cache.test.ts:54 — The old fixed-8-message retry (take last 8, if oversized drop all) discarded an otherwise cacheable tail when fewer than eight heavy messages fit (e.g. 3×100KB where the newest 2 fit under the cap, but the 8-slice was 300KB and got dropped entirely). The fix iteratively shrinks or keeps the largest suffix under the byte cap (saveTranscriptTail loop), so the newest 2 survive.
The new test keeps the largest complete suffix when fewer than eight heavy messages fit constructs 3×100KB heavies, saves, and asserts loaded.length==2 with IDs short-heavy-1, short-heavy-2 — directly proves the previous zero-result bug and the new suffix-maximizing behavior.
No blocker. The cache cap and eviction remain per-session, no cross-profile leak.
(Comment drafted and posted by Hermes Agent, an AI assistant acting on behalf of @Enough1122.)
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
area/sessionsSession lifecycle, resume, persistence, historycomp/desktopElectron desktop app (apps/desktop/*)P3Low — cosmetic, nice to havesweeper:risk-session-stateSweeper risk: may lose/corrupt/mis-associate session or context statetype/bugSomething isn't working
3 participants
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.
What does this PR do?
The Desktop transcript cache currently serializes the newest 40 messages, then falls back directly to the newest 8 when that exceeds the 256 KiB cap. If those 8 are still too large, it drops the cache entry even when a smaller complete suffix would fit. That turns a cacheable recent transcript into a cold resume on the next launch.
This replaces the fixed fallback with a bounded binary search for the largest complete message suffix that fits. It preserves the existing 40-message and 256 KiB limits, never truncates a message, and needs at most six serialization attempts.
The durable transcript-tail cache is existing core Desktop behavior introduced by merged PR #89510. This PR fixes that core cache's serializer independently of #96721. PR #96721 is related because it keeps an already-cached transcript visible while the live session resumes; this PR ensures the existing cache does not unnecessarily discard a complete suffix that #96721 could paint.
This is intentionally separate from the transcript-provenance work in #96130. It changes only which bounded payload is retained after the caller has already established the cache identity.
Desktop performance series
This change is one independently reviewable layer of the same Desktop startup and first-interaction performance pass.
hermes serveentry path.The three Python backend PRs share startup files but solve separate stages. Recommended landing order is #96749, then #96750, then #96751, rebasing the next PR only after the preceding one lands. #97032 is an independently reviewable Electron ordering change. The remaining renderer and Bot Mode PRs can also land independently; their effects compose without making cached state authoritative.
This PR owns transcript-cache retention correctness: the existing bounded cache keeps the largest complete suffix that fits instead of dropping a cacheable tail.
Related Issue
No linked issue.
Related work:
Type of Change
Changes Made
apps/desktop/src/store/transcript-tail-cache.tswith a bounded search for the largest complete suffix under the existing cap.How to Test
npm run test:ui -- src/store/transcript-tail-cache.test.ts --maxWorkers=4 --reporter=verbosefromapps/desktop.npm run typecheckfromapps/desktop.npx eslint src/store/transcript-tail-cache.ts src/store/transcript-tail-cache.test.tsfromapps/desktop.Checklist
Code
fix(scope):,feat(scope):, etc.)pytest tests/ -qand all tests pass (not applicable to this renderer-only TypeScript change; focused Vitest and Desktop typecheck passed)Documentation & Housekeeping
docs/, docstrings) - N/A; behavior and bounds are documented beside the serializercli-config.yaml.exampleif I added/changed config keys - N/ACONTRIBUTING.mdorAGENTS.mdif I changed architecture or workflows - N/AScreenshots / Logs
Focused result: 15 tests passed, including the new short-heavy transcript regression. Desktop typecheck and affected-file ESLint also passed.