* Processes a list of function calls, executing each one and collecting their responses. * This method iterates through the provided function calls, executes them using the * `executeToolCall` function (or handles `self.emitvalue` internally), and aggregates * their results. It also manages
(
functionCalls: FunctionCall[],
toolRegistry: ToolRegistry,
abortController: AbortController,
promptId: string,
)
| 480 | * which are then used to update the chat history. |
| 481 | */ |
| 482 | private async processFunctionCalls( |
| 483 | functionCalls: FunctionCall[], |
| 484 | toolRegistry: ToolRegistry, |
| 485 | abortController: AbortController, |
| 486 | promptId: string, |
| 487 | ): Promise<Content[]> { |
| 488 | const toolResponseParts: Part[] = []; |
| 489 | |
| 490 | for (const functionCall of functionCalls) { |
| 491 | const callId = functionCall.id ?? `${functionCall.name}-${Date.now()}`; |
| 492 | const requestInfo: ToolCallRequestInfo = { |
| 493 | callId, |
| 494 | name: functionCall.name as string, |
| 495 | args: (functionCall.args ?? {}) as Record<string, unknown>, |
| 496 | isClientInitiated: true, |
| 497 | prompt_id: promptId, |
| 498 | }; |
| 499 | |
| 500 | let toolResponse; |
| 501 | |
| 502 | // Handle scope-local tools first. |
| 503 | if (functionCall.name === 'self.emitvalue') { |
| 504 | const valName = String(requestInfo.args['emit_variable_name']); |
| 505 | const valVal = String(requestInfo.args['emit_variable_value']); |
| 506 | this.output.emitted_vars[valName] = valVal; |
| 507 | |
| 508 | toolResponse = { |
| 509 | callId, |
| 510 | responseParts: `Emitted variable ${valName} successfully`, |
| 511 | resultDisplay: `Emitted variable ${valName} successfully`, |
| 512 | error: undefined, |
| 513 | }; |
| 514 | } else { |
| 515 | toolResponse = await executeToolCall( |
| 516 | this.runtimeContext, |
| 517 | requestInfo, |
| 518 | toolRegistry, |
| 519 | abortController.signal, |
| 520 | ); |
| 521 | } |
| 522 | |
| 523 | if (toolResponse.error) { |
| 524 | console.error( |
| 525 | `Error executing tool ${functionCall.name}: ${toolResponse.resultDisplay || toolResponse.error.message}`, |
| 526 | ); |
| 527 | } |
| 528 | |
| 529 | if (toolResponse.responseParts) { |
| 530 | const parts = Array.isArray(toolResponse.responseParts) |
| 531 | ? toolResponse.responseParts |
| 532 | : [toolResponse.responseParts]; |
| 533 | for (const part of parts) { |
| 534 | if (typeof part === 'string') { |
| 535 | toolResponseParts.push({ text: part }); |
| 536 | } else if (part) { |
| 537 | toolResponseParts.push(part); |
| 538 | } |
| 539 | } |
no test coverage detected