Files
gemini-cli/packages/core/src/context/historyObserver.ts
T

49 lines
1.6 KiB
TypeScript
Raw Normal View History

2026-04-06 18:46:21 +00:00
/**
* @license
* Copyright 2026 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import type { AgentChatHistory, HistoryEvent } from '../core/agentChatHistory.js';
import { IrMapper } from './ir/mapper.js';
2026-04-06 19:54:09 +00:00
import type { ContextTokenCalculator } from './utils/contextTokenCalculator.js';
2026-04-06 18:46:21 +00:00
import type { ContextEventBus } from './eventBus.js';
import type { ContextTracer } from './tracer.js';
/**
* Connects the raw AgentChatHistory to the ContextManager.
* It maps raw messages into Episodic Intermediate Representation (IR)
* and evaluates background triggers whenever history changes.
*/
export class HistoryObserver {
private unsubscribeHistory?: () => void;
constructor(
private readonly chatHistory: AgentChatHistory,
private readonly eventBus: ContextEventBus,
private readonly tracer: ContextTracer,
2026-04-06 19:54:09 +00:00
private readonly tokenCalculator: ContextTokenCalculator,
2026-04-06 18:46:21 +00:00
) {}
start() {
if (this.unsubscribeHistory) {
this.unsubscribeHistory();
}
this.unsubscribeHistory = this.chatHistory.subscribe((_event: HistoryEvent) => {
// Rebuild the pristine IR graph from the full source history on every change.
2026-04-06 19:54:09 +00:00
const pristineEpisodes = IrMapper.toIr(this.chatHistory.get(), this.tokenCalculator);
2026-04-06 18:46:21 +00:00
this.tracer.logEvent('HistoryObserver', 'Rebuilt pristine graph from chat history update', { episodeCount: pristineEpisodes.length });
2026-04-06 19:54:09 +00:00
this.eventBus.emitPristineHistoryUpdated({ episodes: pristineEpisodes });
2026-04-06 18:46:21 +00:00
});
}
stop() {
if (this.unsubscribeHistory) {
this.unsubscribeHistory();
this.unsubscribeHistory = undefined;
}
}
}