mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-06-17 14:57:01 -07:00
feat(context): persist context engine snapshots across sessions
This commit implements an opaque state export/import pattern for the ContextManager to ensure expensive LLM-derived snapshots are properly rehydrated upon session resume. The ContextManager now exposes `exportState` and `restoreState` methods, delegating structural validation to the `SnapshotStateHelper`. During active chat, the GeminiClient routinely passes the finalized context state down to the ChatRecordingService, which seamlessly embeds it into the existing JSONL metadata payload. Upon resume, the saved snapshot is re-published as a draft to the LiveInbox, allowing the synchronous pipeline to automatically and deterministically splice it back into the raw graph without an additional LLM call.
This commit is contained in:
@@ -16,6 +16,8 @@ import { HistoryObserver } from './historyObserver.js';
|
||||
import { render } from './graph/render.js';
|
||||
import { ContextWorkingBufferImpl } from './pipeline/contextWorkingBuffer.js';
|
||||
import { debugLogger } from '../utils/debugLogger.js';
|
||||
import { SnapshotStateHelper } from './utils/snapshotGenerator.js';
|
||||
import type { ContextEngineState } from '../services/chatRecordingTypes.js';
|
||||
import { hardenHistory } from '../utils/historyHardening.js';
|
||||
import { checkContextInvariants } from './utils/invariantChecker.js';
|
||||
import type { AdvancedTokenCalculator } from './utils/contextTokenCalculator.js';
|
||||
@@ -429,4 +431,29 @@ export class ContextManager {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
exportState(): ContextEngineState {
|
||||
return SnapshotStateHelper.exportState(this.buffer.nodes);
|
||||
}
|
||||
|
||||
async restoreState(state: ContextEngineState): Promise<void> {
|
||||
if (!state) return;
|
||||
SnapshotStateHelper.restoreState(state, this.env.inbox);
|
||||
|
||||
// Explicitly run the initialization trigger to eagerly splice the restored snapshot
|
||||
// into the graph *before* the first user message creates cache artifacts.
|
||||
const nodes = this.buffer.nodes;
|
||||
const hydratedNodes = await this.orchestrator.executeTriggerSync(
|
||||
'initialization',
|
||||
nodes,
|
||||
new Set(), // No trigger targets needed, it just reads the inbox
|
||||
);
|
||||
|
||||
// Create a pseudo-processor result to apply the hydration without duplicating logic
|
||||
this.buffer = this.buffer.applyProcessorResult(
|
||||
'StateSnapshotHydration',
|
||||
nodes,
|
||||
hydratedNodes,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user