( step: ToolCallBatchContext, call: PreflightedToolCall, )
| 226 | } |
| 227 | |
| 228 | async function prepareToolCall( |
| 229 | step: ToolCallBatchContext, |
| 230 | call: PreflightedToolCall, |
| 231 | ): Promise<PreparedToolCallTask> { |
| 232 | const settleError = async ( |
| 233 | args: unknown, |
| 234 | output: string, |
| 235 | displayFields?: ToolCallDisplayFields, |
| 236 | ): Promise<PreparedToolCallTask> => { |
| 237 | await dispatchToolCall(step, call, args, displayFields); |
| 238 | return { task: makeResolvedToolCallTask(makeErrorToolResult(call, args, output)) }; |
| 239 | }; |
| 240 | |
| 241 | const settleSynthetic = async ( |
| 242 | args: unknown, |
| 243 | result: ExecutableToolResult, |
| 244 | displayFields?: ToolCallDisplayFields, |
| 245 | ): Promise<PreparedToolCallTask> => { |
| 246 | const coerced = coerceToolResult(result, call.toolName); |
| 247 | await dispatchToolCall(step, call, args, displayFields); |
| 248 | return { |
| 249 | task: makeResolvedToolCallTask(makeToolResult(call, args, coerced)), |
| 250 | stopBatchAfterThis: toolResultStopsTurn(coerced), |
| 251 | }; |
| 252 | }; |
| 253 | |
| 254 | if (call.kind === 'rejected') return settleError(call.args, call.output); |
| 255 | |
| 256 | const decision = await runPrepareToolExecutionHook(step, call); |
| 257 | if (decision.kind === 'blocked' || decision.kind === 'hookFailed') { |
| 258 | return settleError(decision.args, decision.output); |
| 259 | } |
| 260 | if (decision.kind === 'synthetic') { |
| 261 | return settleSynthetic(decision.args, decision.result); |
| 262 | } |
| 263 | |
| 264 | const validationError = validateExecutableToolArgs(call.tool, decision.args); |
| 265 | if (validationError !== null) { |
| 266 | return settleError( |
| 267 | decision.args, |
| 268 | `Invalid args for tool "${call.toolName}" after prepareToolExecution hook: ${validationError}`, |
| 269 | ); |
| 270 | } |
| 271 | |
| 272 | const effectiveArgs = decision.args; |
| 273 | let execution: ToolExecution; |
| 274 | try { |
| 275 | execution = await call.tool.resolveExecution(effectiveArgs); |
| 276 | } catch (error) { |
| 277 | if (!(error instanceof PathSecurityError)) { |
| 278 | step.log?.warn('tool execution setup failed', { |
| 279 | toolName: call.toolName, |
| 280 | toolCallId: call.toolCall.id, |
| 281 | error, |
| 282 | }); |
| 283 | } |
| 284 | const output = |
| 285 | error instanceof PathSecurityError |
no test coverage detected