fix(session): stop retaining full file-diff patch text in summaries#32410
Open
OddballGreg wants to merge 2 commits into
Open
fix(session): stop retaining full file-diff patch text in summaries#32410OddballGreg wants to merge 2 commits into
OddballGreg wants to merge 2 commits into
Conversation
added 2 commits
June 14, 2026 12:41
SessionSummary.summarize() stored the full per-file unified-diff text (FileDiff.patch) on each user message's in-memory info.summary.diffs every turn. On a long session repeatedly editing the same large file this retained one full-file-content copy per turn in the hydrated message list and the synced session_diff state, driving multi-GB heap growth (~460 MiB/hr observed; heap snapshot showed 8x identical 2.68MB copies of one file's diff). - summarize(): store only lightweight diff metadata (file/status/additions/ deletions), stripping the heavy patch text. Aggregate counts preserved. - diff(): recompute full diffs (with patch text) on demand via computeDiff so the diff viewer still gets full content when actually requested, falling back to stored diffs for legacy sessions whose snapshots are gone. The full patch is reconstructable from the git-backed snapshots, so retaining it was redundant.
…still returns it Regression test for the summary-diff memory fix. Verifies summarize() stores only lightweight diff metadata (no FileDiff.patch text) while diff() still reconstructs full patches on demand. Run in a git-backed tmpdir editing a large file across a turn.
Contributor
|
The following comment was made by an LLM, it may be inaccurate: Based on my search, I found one potentially related PR: Related PR:
This could be related as it also addresses diff handling performance, though it focuses on rendering rather than storage. However, they may be complementary fixes addressing different aspects of diff performance. The current PR (32410) is specifically about reducing memory retention by stripping the |
This was referenced Jun 15, 2026
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.
Issue for this PR
Closes #17622
Type of change
What does this PR do?
SessionSummary.summarize()stored the full per-file diff produced bySnapshot.diffFull()— including the completepatchtext — ontotarget.info.summary.diffs, which is persisted intomessage.dataand kept in the hydrated in-memory message list. On a session that repeatedly edits the same large file, each turn appends another full-file-content copy, so memory (andmessage.data) grows roughly linearly with edits, and reopening rehydrates all of it (#17622, and the symptoms in #24445 / #20695).This changes
summarize()to store only lightweight diff metadata (file,status,additions,deletions) and strip the heavypatchtext. The aggregateadditions/deletions/filescounts are still computed.diff()now recomputes the full diff (with patch text) on demand via the existingcomputeDiff()path, so the diff viewer still gets full content when a client actually requests it — it just isn't retained for the session's lifetime. The full patch is always reconstructable from the git-backed snapshots, so storing it was redundant.There's a fallback in
diff()to the stored diffs when recomputation yields nothing, so legacy/imported sessions whose snapshots are gone still return whatever metadata they have.How did you verify your code works?
test/session/summary-memory.test.ts: edits a 4000-line file across a turn, then asserts the storedsummary.diffscarries nopatchtext (with correct file count) whilediff()still returns full patch text on demand. It passes with the change and fails without it.test/session/{revert-compact,session}.test.tsandtest/snapshot/snapshot.test.tsstill pass (66 tests).Screenshots / recordings
N/A (no UI change; diff viewer output is unchanged).
Checklist