({
workspaceDir,
assistantContent,
confirmShellCommand,
printLog,
})
| 118 | ] |
| 119 | |
| 120 | export async function executeToolCalls({ |
| 121 | workspaceDir, |
| 122 | assistantContent, |
| 123 | confirmShellCommand, |
| 124 | printLog, |
| 125 | }) { |
| 126 | const toolCalls = assistantContent.filter(block => block?.type === 'tool_use') |
| 127 | const results = [] |
| 128 | |
| 129 | for (const toolCall of toolCalls) { |
| 130 | const input = isObject(toolCall.input) ? toolCall.input : {} |
| 131 | const summary = `${toolCall.name} ${JSON.stringify(input)}` |
| 132 | printLog(`[tool] ${summary}`) |
| 133 | |
| 134 | let payload |
| 135 | let isError = false |
| 136 | |
| 137 | try { |
| 138 | payload = await dispatchTool({ |
| 139 | workspaceDir, |
| 140 | name: toolCall.name, |
| 141 | input, |
| 142 | confirmShellCommand, |
| 143 | }) |
| 144 | } catch (error) { |
| 145 | isError = true |
| 146 | payload = { |
| 147 | ok: false, |
| 148 | error: error instanceof Error ? error.message : String(error), |
| 149 | } |
| 150 | } |
| 151 | |
| 152 | const text = |
| 153 | typeof payload === 'string' |
| 154 | ? payload |
| 155 | : JSON.stringify(payload, null, 2).slice(0, MAX_TOOL_OUTPUT) |
| 156 | |
| 157 | results.push({ |
| 158 | type: 'tool_result', |
| 159 | tool_use_id: toolCall.id, |
| 160 | content: text, |
| 161 | ...(isError ? { is_error: true } : {}), |
| 162 | }) |
| 163 | } |
| 164 | |
| 165 | return results |
| 166 | } |
| 167 | |
| 168 | async function dispatchTool({ workspaceDir, name, input, confirmShellCommand }) { |
| 169 | switch (name) { |
no test coverage detected