mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-03-13 23:51:16 -07:00
perf: optimize chat recording and add universal tool output truncation
This commit is contained in:
@@ -17,7 +17,6 @@ import {
|
||||
logToolOutputTruncated,
|
||||
runInDevTraceSpan,
|
||||
} from '../index.js';
|
||||
import { SHELL_TOOL_NAME } from '../tools/tool-names.js';
|
||||
import { ShellToolInvocation } from '../tools/shell.js';
|
||||
import { executeToolWithHooks } from '../core/coreToolHookTriggers.js';
|
||||
import {
|
||||
@@ -204,7 +203,7 @@ export class ToolExecutor {
|
||||
const toolName = call.request.name;
|
||||
const callId = call.request.callId;
|
||||
|
||||
if (typeof content === 'string' && toolName === SHELL_TOOL_NAME) {
|
||||
if (typeof content === 'string') {
|
||||
const threshold = this.config.getTruncateToolOutputThreshold();
|
||||
|
||||
if (threshold > 0 && content.length > threshold) {
|
||||
|
||||
@@ -125,6 +125,7 @@ export interface ResumedSessionData {
|
||||
*/
|
||||
export class ChatRecordingService {
|
||||
private conversationFile: string | null = null;
|
||||
private conversation: ConversationRecord | null = null;
|
||||
private cachedLastConvData: string | null = null;
|
||||
private sessionId: string;
|
||||
private projectHash: string;
|
||||
@@ -148,6 +149,7 @@ export class ChatRecordingService {
|
||||
// Resume from existing session
|
||||
this.conversationFile = resumedSessionData.filePath;
|
||||
this.sessionId = resumedSessionData.conversation.sessionId;
|
||||
this.conversation = resumedSessionData.conversation;
|
||||
|
||||
// Update the session ID in the existing file
|
||||
this.updateConversation((conversation) => {
|
||||
@@ -174,13 +176,15 @@ export class ChatRecordingService {
|
||||
)}.json`;
|
||||
this.conversationFile = path.join(chatsDir, filename);
|
||||
|
||||
this.writeConversation({
|
||||
const initialConversation: ConversationRecord = {
|
||||
sessionId: this.sessionId,
|
||||
projectHash: this.projectHash,
|
||||
startTime: new Date().toISOString(),
|
||||
lastUpdated: new Date().toISOString(),
|
||||
messages: [],
|
||||
});
|
||||
};
|
||||
this.conversation = initialConversation;
|
||||
this.writeConversation(initialConversation, { allowEmpty: true });
|
||||
}
|
||||
|
||||
// Clear any queued data since this is a fresh start
|
||||
@@ -416,9 +420,12 @@ export class ChatRecordingService {
|
||||
* Loads up the conversation record from disk.
|
||||
*/
|
||||
private readConversation(): ConversationRecord {
|
||||
if (this.conversation) return this.conversation;
|
||||
|
||||
try {
|
||||
this.cachedLastConvData = fs.readFileSync(this.conversationFile!, 'utf8');
|
||||
return JSON.parse(this.cachedLastConvData);
|
||||
this.conversation = JSON.parse(this.cachedLastConvData);
|
||||
return this.conversation!;
|
||||
} catch (error) {
|
||||
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') {
|
||||
debugLogger.error('Error reading conversation file.', error);
|
||||
@@ -426,13 +433,14 @@ export class ChatRecordingService {
|
||||
}
|
||||
|
||||
// Placeholder empty conversation if file doesn't exist.
|
||||
return {
|
||||
this.conversation = {
|
||||
sessionId: this.sessionId,
|
||||
projectHash: this.projectHash,
|
||||
startTime: new Date().toISOString(),
|
||||
lastUpdated: new Date().toISOString(),
|
||||
messages: [],
|
||||
};
|
||||
return this.conversation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -446,14 +454,18 @@ export class ChatRecordingService {
|
||||
try {
|
||||
if (!this.conversationFile) return;
|
||||
// Don't write the file yet until there's at least one message.
|
||||
if (conversation.messages.length === 0 && !allowEmpty) return;
|
||||
if ((conversation.messages?.length ?? 0) === 0 && !allowEmpty) return;
|
||||
|
||||
// Only write the file if this change would change the file.
|
||||
if (this.cachedLastConvData !== JSON.stringify(conversation, null, 2)) {
|
||||
// Avoid redundant stringification by checking if the content changed first.
|
||||
// We use the cached string for comparison to avoid a new stringification
|
||||
// when nothing has changed.
|
||||
const currentContent = JSON.stringify(conversation, null, 2);
|
||||
if (this.cachedLastConvData !== currentContent) {
|
||||
// Only update the timestamp and re-stringify if something actually changed.
|
||||
conversation.lastUpdated = new Date().toISOString();
|
||||
const newContent = JSON.stringify(conversation, null, 2);
|
||||
this.cachedLastConvData = newContent;
|
||||
fs.writeFileSync(this.conversationFile, newContent);
|
||||
const finalContent = JSON.stringify(conversation, null, 2);
|
||||
this.cachedLastConvData = finalContent;
|
||||
fs.writeFileSync(this.conversationFile, finalContent);
|
||||
}
|
||||
} catch (error) {
|
||||
// Handle disk full (ENOSPC) gracefully - disable recording but allow conversation to continue
|
||||
|
||||
Reference in New Issue
Block a user