(config: ToolConfiguration)
| 351 | } |
| 352 | |
| 353 | export const createTaskTool: ToolFactory = (config: ToolConfiguration) => { |
| 354 | // Only advertise the `isolation` parameter on runtimes where sharing the parent checkout is |
| 355 | // supported. On local runtimes the field is omitted from the schema entirely, so it never |
| 356 | // enters LLM context. |
| 357 | const runtimeMode = resolveRuntimeMode(config); |
| 358 | const inputSchema = buildTaskToolAgentArgsSchema({ |
| 359 | includeIsolation: runtimeModeSupportsSharedTaskWorkspace(runtimeMode), |
| 360 | }); |
| 361 | const taskTool = tool({ |
| 362 | description: buildTaskDescription(config), |
| 363 | inputSchema, |
| 364 | execute: async (args, { abortSignal, toolCallId }): Promise<unknown> => { |
| 365 | // Defensive: tool() should have already validated args via inputSchema, |
| 366 | // but keep runtime validation here to preserve type-safety. |
| 367 | const parsedArgs = TOOL_DEFINITIONS.task.schema.safeParse(args); |
| 368 | if (!parsedArgs.success) { |
| 369 | const keys = |
| 370 | args && typeof args === "object" ? Object.keys(args as Record<string, unknown>) : []; |
| 371 | log.warn( |
| 372 | "[task tool] Unexpected input validation failure (should have been caught by AI SDK)", |
| 373 | { |
| 374 | issues: parsedArgs.error.issues, |
| 375 | keys, |
| 376 | } |
| 377 | ); |
| 378 | throw new Error(`task tool input validation failed: ${parsedArgs.error.message}`); |
| 379 | } |
| 380 | const validatedArgs = parsedArgs.data; |
| 381 | if (abortSignal?.aborted) { |
| 382 | throw new Error("Interrupted"); |
| 383 | } |
| 384 | |
| 385 | const { |
| 386 | kind, |
| 387 | agentId, |
| 388 | subagent_type, |
| 389 | prompt, |
| 390 | title, |
| 391 | run_in_background, |
| 392 | n, |
| 393 | variants, |
| 394 | model, |
| 395 | thinking, |
| 396 | isolation, |
| 397 | workspace, |
| 398 | } = validatedArgs; |
| 399 | |
| 400 | // Explicit per-launch model/thinking overrides. Omitted by default so delegated work |
| 401 | // inherits the parent's live settings unless the caller requests an override. |
| 402 | const aiOverrides = parseTaskAiOverrides({ model, thinking }); |
| 403 | |
| 404 | const workspaceId = requireWorkspaceId(config, "task"); |
| 405 | const taskService = requireTaskService(config, "task"); |
| 406 | |
| 407 | const parentRuntimeAiSettings = buildParentRuntimeAiSettings(config); |
| 408 | |
| 409 | if (config.planFileOnly && kind === "workspace") { |
| 410 | throw new Error(PLAN_AGENT_EXPLORE_ONLY_ERROR); |
no test coverage detected