fix(agent): restore legacy session tool recording and error routing

This commit is contained in:
Adam Weidman
2026-03-17 14:16:56 -04:00
parent ea19aeb14b
commit 1f727251eb
4 changed files with 47 additions and 6 deletions
+10 -1
View File
@@ -21,6 +21,7 @@ import {
FatalInputError,
CoreEvent,
CoreToolCallStatus,
debugLogger,
} from '@google/gemini-cli-core';
import type { Part } from '@google/genai';
import { runNonInteractive } from './nonInteractiveCli.js';
@@ -1703,6 +1704,9 @@ describe('runNonInteractive', () => {
);
it('should log error when tool recording fails', async () => {
const errorSpy = vi
.spyOn(debugLogger, 'error')
.mockImplementation(() => {});
const toolCallEvent: ServerGeminiStreamEvent = {
type: GeminiEventType.ToolCallRequest,
value: {
@@ -1769,7 +1773,12 @@ describe('runNonInteractive', () => {
// The LegacyAgentSession silently catches recording failures
// (they shouldn't break the loop). Verify the loop continued
// and produced output.
// and logged the error.
expect(errorSpy).toHaveBeenCalledWith(
expect.stringContaining(
'Error recording completed tool call information',
),
);
expect(getWrittenOutput()).toContain('Done');
});
+17 -2
View File
@@ -27,6 +27,7 @@ import {
Scheduler,
ROOT_SCHEDULER_ID,
LegacyAgentSession,
ToolErrorType,
} from '@google/gemini-cli-core';
import type { Part } from '@google/genai';
@@ -381,7 +382,10 @@ export async function runNonInteractive({
output: displayText,
error: event.isError
? {
type: 'TOOL_EXECUTION_ERROR',
type:
typeof event.data?.['errorType'] === 'string'
? event.data['errorType']
: 'TOOL_EXECUTION_ERROR',
message: errorMsg,
}
: undefined,
@@ -400,10 +404,21 @@ export async function runNonInteractive({
event.name,
new Error(errorMsg),
config,
undefined,
typeof event.data?.['errorType'] === 'string'
? event.data['errorType']
: undefined,
displayText,
);
}
if (
event.isError &&
event.data?.['errorType'] === ToolErrorType.STOP_EXECUTION
) {
const stopMessage = `Agent execution stopped: ${errorMsg}`;
if (config.getOutputFormat() === OutputFormat.TEXT) {
process.stderr.write(`${stopMessage}\n`);
}
}
break;
}
case 'error': {
@@ -16,6 +16,8 @@ import type { Scheduler } from '../scheduler/scheduler.js';
import type { Config } from '../config/config.js';
import type { ToolCallRequestInfo } from '../scheduler/types.js';
import { ToolErrorType } from '../tools/tool-error.js';
import { recordToolCallInteractions } from '../code_assist/telemetry.js';
import { debugLogger } from '../utils/debugLogger.js';
import {
translateEvent,
createTranslationState,
@@ -261,7 +263,16 @@ export class LegacyAgentSession implements AgentSession {
],
}
: {}),
...(response.data ? { data: response.data } : {}),
...(response.data || response.errorType
? {
data: {
...(response.data || {}),
...(response.errorType
? { errorType: response.errorType }
: {}),
},
}
: {}),
}),
]);
@@ -277,8 +288,12 @@ export class LegacyAgentSession implements AgentSession {
this._client
.getChat()
.recordCompletedToolCalls(currentModel, completedToolCalls);
} catch {
// Recording failures shouldn't break the loop
await recordToolCallInteractions(this._config, completedToolCalls);
} catch (error) {
debugLogger.error(
`Error recording completed tool call information: ${error}`,
);
}
// Check if a tool requested stop execution
+2
View File
@@ -74,6 +74,7 @@ export class MockAgentSession implements AgentSession {
const now = new Date().toISOString();
for (const eventData of events) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const event: AgentEvent = {
...eventData,
id: eventData.id ?? `e-${this._nextEventId++}`,
@@ -172,6 +173,7 @@ export class MockAgentSession implements AgentSession {
const normalizedResponse: AgentEvent[] = [];
for (const eventData of response) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
const event: AgentEvent = {
...eventData,
id: eventData.id ?? `e-${this._nextEventId++}`,