Updates error handling in case of incorrect tool calling. (#2304)
This commit is contained in:
parent
150df382f8
commit
db115c468a
|
@ -218,4 +218,69 @@ describe('runNonInteractive', () => {
|
||||||
'[API Error: API connection failed]',
|
'[API Error: API connection failed]',
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should not exit if a tool is not found, and should send error back to model', async () => {
|
||||||
|
const functionCall: FunctionCall = {
|
||||||
|
id: 'fcNotFound',
|
||||||
|
name: 'nonExistentTool',
|
||||||
|
args: {},
|
||||||
|
};
|
||||||
|
const errorResponsePart: Part = {
|
||||||
|
functionResponse: {
|
||||||
|
name: 'nonExistentTool',
|
||||||
|
id: 'fcNotFound',
|
||||||
|
response: { error: 'Tool "nonExistentTool" not found in registry.' },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const { executeToolCall: mockCoreExecuteToolCall } = await import(
|
||||||
|
'@google/gemini-cli-core'
|
||||||
|
);
|
||||||
|
vi.mocked(mockCoreExecuteToolCall).mockResolvedValue({
|
||||||
|
callId: 'fcNotFound',
|
||||||
|
responseParts: [errorResponsePart],
|
||||||
|
resultDisplay: 'Tool "nonExistentTool" not found in registry.',
|
||||||
|
error: new Error('Tool "nonExistentTool" not found in registry.'),
|
||||||
|
});
|
||||||
|
|
||||||
|
const stream1 = (async function* () {
|
||||||
|
yield { functionCalls: [functionCall] } as GenerateContentResponse;
|
||||||
|
})();
|
||||||
|
const stream2 = (async function* () {
|
||||||
|
yield {
|
||||||
|
candidates: [
|
||||||
|
{
|
||||||
|
content: {
|
||||||
|
parts: [{ text: 'Unfortunately the tool does not exist.' }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
} as GenerateContentResponse;
|
||||||
|
})();
|
||||||
|
mockChat.sendMessageStream
|
||||||
|
.mockResolvedValueOnce(stream1)
|
||||||
|
.mockResolvedValueOnce(stream2);
|
||||||
|
const consoleErrorSpy = vi
|
||||||
|
.spyOn(console, 'error')
|
||||||
|
.mockImplementation(() => {});
|
||||||
|
|
||||||
|
await runNonInteractive(mockConfig, 'Trigger tool not found');
|
||||||
|
|
||||||
|
expect(consoleErrorSpy).toHaveBeenCalledWith(
|
||||||
|
'Error executing tool nonExistentTool: Tool "nonExistentTool" not found in registry.',
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mockProcessExit).not.toHaveBeenCalled();
|
||||||
|
|
||||||
|
expect(mockChat.sendMessageStream).toHaveBeenCalledTimes(2);
|
||||||
|
expect(mockChat.sendMessageStream).toHaveBeenLastCalledWith(
|
||||||
|
expect.objectContaining({
|
||||||
|
message: [errorResponsePart],
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(mockProcessStdoutWrite).toHaveBeenCalledWith(
|
||||||
|
'Unfortunately the tool does not exist.',
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -110,10 +110,15 @@ export async function runNonInteractive(
|
||||||
);
|
);
|
||||||
|
|
||||||
if (toolResponse.error) {
|
if (toolResponse.error) {
|
||||||
|
const isToolNotFound = toolResponse.error.message.includes(
|
||||||
|
'not found in registry',
|
||||||
|
);
|
||||||
console.error(
|
console.error(
|
||||||
`Error executing tool ${fc.name}: ${toolResponse.resultDisplay || toolResponse.error.message}`,
|
`Error executing tool ${fc.name}: ${toolResponse.resultDisplay || toolResponse.error.message}`,
|
||||||
);
|
);
|
||||||
process.exit(1);
|
if (!isToolNotFound) {
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (toolResponse.responseParts) {
|
if (toolResponse.responseParts) {
|
||||||
|
|
Loading…
Reference in New Issue