fix(core): ensure chat compression summary persists across session resumes

- Modified ChatRecordingService.initialize to accept an optional initialHistory parameter.
- When initialHistory is provided during session resumption (e.g., after chat compression), it now overwrites the messages in the session file on disk.
- Updated GeminiChat constructor to pass the history to ChatRecordingService.initialize.
- Implemented apiContentToMessageRecords helper to convert API Content objects to storage-compatible MessageRecord objects.
- This ensures that the compressed chat history (the summary) is immediately synced to disk, preventing it from being lost when the session is closed and resumed.
- Added a unit test in chatRecordingService.test.ts to verify the new overwrite behavior.

Fixes #21335
This commit is contained in:
Abhijit Balaji
2026-03-05 15:54:37 -08:00
parent e8bc7bea44
commit 389ed663ac
3 changed files with 72 additions and 2 deletions
@@ -122,6 +122,50 @@ describe('ChatRecordingService', () => {
const conversation = JSON.parse(fs.readFileSync(sessionFile, 'utf8'));
expect(conversation.sessionId).toBe('old-session-id');
});
it('should overwrite existing messages if initialHistory is provided', () => {
const chatsDir = path.join(testTempDir, 'chats');
fs.mkdirSync(chatsDir, { recursive: true });
const sessionFile = path.join(chatsDir, 'session-overwrite.json');
const initialData = {
sessionId: 'test-session-id',
projectHash: 'test-project-hash',
messages: [
{
id: 'msg-1',
type: 'user',
content: 'Old Message',
timestamp: new Date().toISOString(),
},
],
};
fs.writeFileSync(sessionFile, JSON.stringify(initialData));
const newHistory: Content[] = [
{
role: 'user',
parts: [{ text: 'Compressed Summary' }],
},
];
chatRecordingService.initialize(
{
filePath: sessionFile,
conversation: initialData as ConversationRecord,
},
'main',
newHistory,
);
const conversation = JSON.parse(
fs.readFileSync(sessionFile, 'utf8'),
) as ConversationRecord;
expect(conversation.messages).toHaveLength(1);
expect(conversation.messages[0].content).toEqual([
{ text: 'Compressed Summary' },
]);
expect(conversation.messages[0].type).toBe('user');
});
});
describe('recordMessage', () => {