feat(sessions): Add automatic session cleanup and retention policy (#7662)

This commit is contained in:
bl-ue
2025-10-06 13:34:00 -06:00
committed by GitHub
parent abe4045c63
commit 974ab66b7a
14 changed files with 2473 additions and 46 deletions
+4
View File
@@ -207,6 +207,10 @@ export class GeminiClient {
return this.loopDetector;
}
getCurrentSequenceModel(): string | null {
return this.currentSequenceModel;
}
async addDirectoryContext(): Promise<void> {
if (!this.chat) {
return;
+28
View File
@@ -26,6 +26,7 @@ import {
} from '../config/models.js';
import { hasCycleInSchema, MUTATOR_KINDS } from '../tools/tools.js';
import type { StructuredError } from './turn.js';
import type { CompletedToolCall } from './coreToolScheduler.js';
import {
logContentRetry,
logContentRetryFailure,
@@ -584,6 +585,33 @@ export class GeminiChat {
return this.chatRecordingService;
}
/**
* Records completed tool calls with full metadata.
* This is called by external components when tool calls complete, before sending responses to Gemini.
*/
recordCompletedToolCalls(
model: string,
toolCalls: CompletedToolCall[],
): void {
const toolCallRecords = toolCalls.map((call) => {
const resultDisplayRaw = call.response?.resultDisplay;
const resultDisplay =
typeof resultDisplayRaw === 'string' ? resultDisplayRaw : undefined;
return {
id: call.request.callId,
name: call.request.name,
args: call.request.args,
result: call.response?.responseParts || null,
status: call.status as 'error' | 'success' | 'cancelled',
timestamp: new Date().toISOString(),
resultDisplay,
};
});
this.chatRecordingService.recordToolCalls(model, toolCallRecords);
}
/**
* Extracts and records thought from thought content.
*/
@@ -16,6 +16,8 @@ import type {
GenerateContentResponseUsageMetadata,
} from '@google/genai';
export const SESSION_FILE_PREFIX = 'session-';
/**
* Token usage summary for a message or conversation.
*/
@@ -149,7 +151,7 @@ export class ChatRecordingService {
.toISOString()
.slice(0, 16)
.replace(/:/g, '-');
const filename = `session-${timestamp}-${this.sessionId.slice(
const filename = `${SESSION_FILE_PREFIX}${timestamp}-${this.sessionId.slice(
0,
8,
)}.json`;
@@ -195,7 +197,7 @@ export class ChatRecordingService {
* Records a message in the conversation.
*/
recordMessage(message: {
model: string;
model: string | undefined;
type: ConversationRecordExtra['type'];
content: PartListUnion;
}): void {