import { z } from 'zod'; import type { ToolDef, ToolContext } from './types.js'; import { getInferenceContext } from './inference_context.js'; const NewTaskInput = z.object({ input: z.string().min(1).describe('Task description for the child subtask'), agent: z.string().optional().describe('Optional: dispatch to a specific agent'), model: z.string().optional().describe('Optional: model override for the subtask'), }); type NewTaskInputT = z.infer; export const newTaskTool: ToolDef = { name: 'new_task', description: 'Spawn a subtask that runs in isolation. The subtask gets its own session and ' + 'worktree. Use check_task_status to monitor progress. Only the output_summary is ' + 'accessible to the parent — full isolation (Boomerang pattern).', inputSchema: NewTaskInput, jsonSchema: { type: 'function', function: { name: 'new_task', description: 'Spawn a subtask that runs in isolation. The subtask gets its own session and ' + 'worktree. Use check_task_status to monitor progress.', parameters: { type: 'object', properties: { input: { type: 'string', description: 'Task description for the child subtask' }, agent: { type: 'string', description: 'Optional: dispatch to a specific agent' }, model: { type: 'string', description: 'Optional: model override for the subtask' }, }, required: ['input'], }, }, }, async execute(input: NewTaskInputT, _projectRoot: string, context: ToolContext): Promise { const { sql } = context; // Get the current task's project_id from the inference context const ctx = getInferenceContext(); const currentTaskId = ctx.taskId; // Look up the project_id from the current session const [session] = await sql<{ project_id: string }[]>` SELECT project_id FROM sessions WHERE id = ${ctx.sessionId} `; if (!session) { return { error: 'Cannot determine project_id from current session' }; } const [task] = await sql<{ id: string; state: string }[]>` INSERT INTO tasks (project_id, parent_task_id, input, agent, model) VALUES (${session.project_id}, ${currentTaskId}, ${input.input}, ${input.agent ?? null}, ${input.model ?? null}) RETURNING id, state `; return { message: `Subtask created (id: ${task!.id}). It will run in isolation. Use check_task_status to monitor.`, task_id: task!.id, state: task!.state, }; }, };