processToolCalls executes tool calls and returns the tool result messages. Returns (messages, handoffAgentName, error).
(ctx context.Context, calls []tools.ToolCall, agentTools []tools.Tool, _ []chat.Message)
| 532 | // processToolCalls executes tool calls and returns the tool result messages. |
| 533 | // Returns (messages, handoffAgentName, error). |
| 534 | func (rt *wasmRuntime) processToolCalls(ctx context.Context, calls []tools.ToolCall, agentTools []tools.Tool, _ []chat.Message) ([]chat.Message, string, error) { |
| 535 | toolByName := make(map[string]tools.Tool, len(agentTools)) |
| 536 | for _, t := range agentTools { |
| 537 | toolByName[t.Name] = t |
| 538 | } |
| 539 | |
| 540 | var resultMessages []chat.Message |
| 541 | var handoffAgent string |
| 542 | |
| 543 | for _, tc := range calls { |
| 544 | if ctx.Err() != nil { |
| 545 | return nil, "", ctx.Err() |
| 546 | } |
| 547 | |
| 548 | // Emit tool_call event. |
| 549 | rt.emitEvent(map[string]any{ |
| 550 | "type": "tool_call", |
| 551 | "id": tc.ID, |
| 552 | "name": tc.Function.Name, |
| 553 | "args": tc.Function.Arguments, |
| 554 | }) |
| 555 | |
| 556 | // Fire pre_tool_use hook. |
| 557 | preResult := rt.fireHook(ctx, rt.currentAgent, hooks.EventPreToolUse, &hooks.Input{ |
| 558 | ToolName: tc.Function.Name, |
| 559 | ToolUseID: tc.ID, |
| 560 | ToolInput: parseToolArgs(tc.Function.Arguments), |
| 561 | }) |
| 562 | if preResult != nil && !preResult.Allowed { |
| 563 | // Hook denied the tool call. |
| 564 | rt.emitEvent(map[string]any{ |
| 565 | "type": "tool_blocked", |
| 566 | "id": tc.ID, |
| 567 | "name": tc.Function.Name, |
| 568 | "reason": preResult.Message, |
| 569 | }) |
| 570 | resultMessages = append(resultMessages, chat.Message{ |
| 571 | Role: chat.MessageRoleTool, |
| 572 | ToolCallID: tc.ID, |
| 573 | Content: fmt.Sprintf("Tool call denied by hook: %s", preResult.Message), |
| 574 | }) |
| 575 | continue |
| 576 | } |
| 577 | |
| 578 | // Handle built-in delegation tools. |
| 579 | switch tc.Function.Name { |
| 580 | case "transfer_task": |
| 581 | result, target := rt.handleTransferTask(tc) |
| 582 | resultMessages = append(resultMessages, chat.Message{ |
| 583 | Role: chat.MessageRoleTool, |
| 584 | ToolCallID: tc.ID, |
| 585 | Content: result, |
| 586 | }) |
| 587 | if target != "" { |
| 588 | handoffAgent = target |
| 589 | } |
| 590 | continue |
| 591 | case "handoff": |
no test coverage detected