( config: Config, toolCallRequest: ToolCallRequestInfo, toolRegistry: ToolRegistry, abortSignal?: AbortSignal, )
| 23 | * It does not handle confirmations, multiple calls, or live updates. |
| 24 | */ |
| 25 | export async function executeToolCall( |
| 26 | config: Config, |
| 27 | toolCallRequest: ToolCallRequestInfo, |
| 28 | toolRegistry: ToolRegistry, |
| 29 | abortSignal?: AbortSignal, |
| 30 | ): Promise<ToolCallResponseInfo> { |
| 31 | const tool = toolRegistry.getTool(toolCallRequest.name); |
| 32 | |
| 33 | const startTime = Date.now(); |
| 34 | if (!tool) { |
| 35 | const error = new Error( |
| 36 | `Tool "${toolCallRequest.name}" not found in registry.`, |
| 37 | ); |
| 38 | const durationMs = Date.now() - startTime; |
| 39 | logToolCall(config, { |
| 40 | 'event.name': 'tool_call', |
| 41 | 'event.timestamp': new Date().toISOString(), |
| 42 | function_name: toolCallRequest.name, |
| 43 | function_args: toolCallRequest.args, |
| 44 | duration_ms: durationMs, |
| 45 | success: false, |
| 46 | error: error.message, |
| 47 | prompt_id: toolCallRequest.prompt_id, |
| 48 | }); |
| 49 | // Ensure the response structure matches what the API expects for an error |
| 50 | return { |
| 51 | callId: toolCallRequest.callId, |
| 52 | responseParts: [ |
| 53 | { |
| 54 | functionResponse: { |
| 55 | id: toolCallRequest.callId, |
| 56 | name: toolCallRequest.name, |
| 57 | response: { error: error.message }, |
| 58 | }, |
| 59 | }, |
| 60 | ], |
| 61 | resultDisplay: error.message, |
| 62 | error, |
| 63 | errorType: ToolErrorType.TOOL_NOT_REGISTERED, |
| 64 | }; |
| 65 | } |
| 66 | |
| 67 | try { |
| 68 | // Directly execute without confirmation or live output handling |
| 69 | const effectiveAbortSignal = abortSignal ?? new AbortController().signal; |
| 70 | const toolResult: ToolResult = await tool.validateBuildAndExecute( |
| 71 | toolCallRequest.args, |
| 72 | effectiveAbortSignal, |
| 73 | // No live output callback for non-interactive mode |
| 74 | ); |
| 75 | |
| 76 | const tool_output = toolResult.llmContent; |
| 77 | |
| 78 | const tool_display = toolResult.returnDisplay; |
| 79 | |
| 80 | // eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 81 | let metadata: { [key: string]: any } = {}; |
| 82 | if ( |
no test coverage detected