fix(core): persist compression state in session file for correct resume#21334
fix(core): persist compression state in session file for correct resume#21334amircodota wants to merge 20 commits intogoogle-gemini:mainfrom
Conversation
When context compression occurs, the compressed history replaces the in-memory API history but the session file on disk retains all original messages. On --resume, convertSessionToClientHistory replays every message from the file, restoring the full uncompressed history and potentially overflowing the context window. Record a compression_marker message in the session file when compression succeeds. The marker stores the compressed API history (Content[]). On resume, convertSessionToClientHistory finds the last marker and uses its compressedHistory as the base, converting only post-marker messages. Fixes google-gemini#20803
Verifies that a session compressed via /compress can be correctly resumed with --resume latest. The test checks that: - A compression_marker is written to the session file on disk - The resumed session completes without context overflow errors Golden responses recorded from gemini-2.5-pro.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request resolves a critical bug where resuming a chat session after compression would incorrectly restore the full, uncompressed conversation history, leading to context overflow and degraded performance. The solution introduces a mechanism to explicitly record the compressed state within the session file using a new 'compression_marker' message type. This ensures that when a session is resumed, the system accurately reconstructs the chat history from the last known compressed point, thereby maintaining performance and context integrity. Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request correctly addresses the issue of session resume ignoring compression history by introducing a compression_marker in the session file. The implementation is robust, with changes to persist the marker upon compression and correctly reconstruct the history from it upon resume. The code is well-tested with new unit and integration tests. I have one suggestion to improve the assertion in the new integration test to make it more robust.
| expect(result).toBeDefined(); | ||
| expect(result.length).toBeGreaterThan(0); |
There was a problem hiding this comment.
The current assertions only verify that the resumed command produces some output, not that the context was correctly restored from the compressed state. To make this test more robust and directly validate the fix, you should assert that the model's response contains content from the original conversation, which would only be possible if the compressed history was used.
Based on the mocked responses, the model should reply with a summary of the robot story. You can assert that the output includes keywords like 'robot' or 'Unit 734'.
| expect(result).toBeDefined(); | |
| expect(result.length).toBeGreaterThan(0); | |
| expect(result).toContain('robot'); | |
| expect(result).toContain('Unit 734'); |
There was a problem hiding this comment.
Good catch — updated the assertions to verify the resumed session actually recalls content from the compressed history (robot and Unit 734). Fixed in fbedf72.
Assert that the resumed session output contains 'robot' and 'Unit 734' from the compressed history, not just that it produced any output.
…-resume test - Use GEMINI_DIR instead of hardcoded '.gemini' for the session tmp path, avoiding conflicts in downstream forks. - Remove 'robot' assertion: the fake response story text never contains the word 'robot'. The 'Unit 734' check suffices.
|
Hi there! Thank you for your interest in contributing to Gemini CLI. To ensure we maintain high code quality and focus on our prioritized roadmap, we have updated our contribution policy (see Discussion #17383). We only guarantee review and consideration of pull requests for issues that are explicitly labeled as 'help wanted'. All other community pull requests are subject to closure after 14 days if they do not align with our current focus areas. For this reason, we strongly recommend that contributors only submit pull requests against issues explicitly labeled as 'help-wanted'. This pull request is being closed as it has been open for 14 days without a 'help wanted' designation. We encourage you to find and contribute to existing 'help wanted' issues in our backlog! Thank you for your understanding and for being part of our community! |
Summary
Session resume (
--resume) ignored compression history, restoring the full uncompressed conversation. This caused context overflow and degraded performance on resumed sessions that had been compressed via/compress.Details
The root cause:
tryCompressChatreplaced the in-memory history but never updated the on-disk session file. On--resume,convertSessionToClientHistoryread all historical messages from the file, effectively re-inflating the context.Fix: Introduce a
compression_markermessage type inConversationRecord:chatRecordingService.ts— Addedcompression_markertype withcompressedHistory: Content[]payload, and arecordCompressionMarker()method to append it to the session file.client.ts— After successful compression, callrecordCompressionMarker(newHistory)before re-initializing the chat.sessionUtils.ts(core) —convertSessionToClientHistorynow finds the latestcompression_markerand uses itscompressedHistoryas the base, processing only subsequent messages.sessionUtils.ts(cli) —convertSessionToHistoryFormatsrenderscompression_markeras an INFO message in the UI.Related Issues
Fixes #20803
How to Validate
gemini/compress— should compress successfully/quitgemini --resume latestAlternatively, run the new integration test:
And the unit tests:
Pre-Merge Checklist