decompose_task
Break down complex tasks into manageable subtasks with verification steps, enabling parallel execution and structured workflow management.
Instructions
Decomposes an existing complex task into smaller, more manageable subtasks. All tasks with complexity higher than low must always be decomposed before execution. Tasks MUST be in todo status to be decomposed. Subtasks with the same sequence order may be executed in parallel. Subtasks should include a verification subtask. Created subtasks may be decomposed later if needed.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| taskID | Yes | The task to decompose | |
| decompositionReason | Yes | The reason for decomposing this task | |
| subtasks | Yes | Array of smaller, manageable subtasks to create |
Implementation Reference
- tools/decompose_task.ts:49-131 (handler)The handleDecomposeTask function is the core handler for the decompose_task tool. It creates subtasks from the provided args, organizes them into sequence orders for parallel execution where applicable, sets up dependencies between sequences, updates the task database, modifies the parent task to depend on the final subtasks, and returns structured results including notifications if further decomposition is needed.export async function handleDecomposeTask( { taskID, subtasks }: DecomposeTaskArgs, taskDB: TaskDB, singleAgent: boolean ) { const parentTask = taskDB.get(taskID) if (!parentTask) { throw new Error(`Task not found: ${taskID}`) } if (parentTask.status !== TodoStatus) { throw new Error(`Can't decompose task ${taskID} in status: ${parentTask.status}`) } const seqOrderToTasks = new Map<number, Array<Task>>() for (const subtask of subtasks) { const newTask = { taskID: newTaskID(), status: TodoStatus, dependsOnTaskIDs: [], title: subtask.title, description: subtask.description, goal: subtask.goal, definitionsOfDone: subtask.definitionsOfDone, criticalPath: !!subtask.criticalPath, uncertaintyAreas: subtask.uncertaintyAreas, estimatedComplexity: subtask.estimatedComplexity, lessonsLearned: [], verificationEvidence: [], } satisfies Task if (!seqOrderToTasks.has(subtask.sequenceOrder)) { seqOrderToTasks.set(subtask.sequenceOrder, new Array<Task>()) } seqOrderToTasks.get(subtask.sequenceOrder)!.push(newTask) } const sortedSeqOrders = Array.from(seqOrderToTasks.keys()).sort((a, b) => a - b) for (let i = 1; i < sortedSeqOrders.length; i++) { const currentSeqOrder = sortedSeqOrders[i] const prevSeqOrder = sortedSeqOrders[i - 1] const currentOrderTasks = seqOrderToTasks.get(currentSeqOrder)! const previousOrderTasks = seqOrderToTasks.get(prevSeqOrder)! for (const currentOrderTask of currentOrderTasks) { currentOrderTask.dependsOnTaskIDs = previousOrderTasks.map((task) => task.taskID) } } const createdTasks = Array.from(seqOrderToTasks.values()).flat() for (const task of createdTasks) { taskDB.set(task.taskID, task) } const highestSeqOrderTasks = seqOrderToTasks.get(sortedSeqOrders[sortedSeqOrders.length - 1])! parentTask.dependsOnTaskIDs = [...parentTask.dependsOnTaskIDs, ...highestSeqOrderTasks.map((task) => task.taskID)] const incompleteTaskIDs = taskDB.incompleteTasksInTree(taskID).map((t) => t.taskID) const res = { taskUpdated: toBasicTaskInfo(parentTask, false, false, false), tasksCreated: createdTasks.map((t) => toBasicTaskInfo(t, false, false, true)), incompleteTasksIdealOrder: singleAgent ? incompleteTaskIDs : undefined, } return { content: [ createdTasks.some((t) => mustDecompose(t)) && ({ type: 'text', text: "Some tasks must be decomposed before execution, use 'decompose_task' tool", audience: ['assistant'], } satisfies TextContent), ].filter(Boolean), structuredContent: res, } satisfies CallToolResult }
- tools/decompose_task.ts:16-31 (schema)Defines the Zod schemas for validating inputs to the decompose_task tool: SubtaskSchema (extended from SimpleTaskSchema with complexity and sequenceOrder) and DecomposeTaskArgsSchema (taskID, reason, subtasks array).const SubtaskSchema = SimpleTaskSchema.extend({ estimatedComplexity: TaskComplexitySchema, sequenceOrder: z .number() .int() .min(1) .describe( 'The sequence order of this subtask. Subtasks may use the same sequence order if they can be executed in parallel.' ), }) export const DecomposeTaskArgsSchema = z.object({ taskID: TaskIDSchema.describe('The task to decompose'), decompositionReason: z.string().min(1).describe('The reason for decomposing this task'), subtasks: SubtaskSchema.array().min(1).describe('Array of smaller, manageable subtasks to create'), })
- tools/decompose_task.ts:35-47 (registration)Defines and exports the tool constant DECOMPOSE_TASK and the decomposeTaskTool object including name, title, description, and JSON schema for MCP tool registration.export const DECOMPOSE_TASK = 'decompose_task' export const decomposeTaskTool = { name: DECOMPOSE_TASK, title: 'Decompose task', description: `Decomposes an existing complex task into smaller, more manageable subtasks. All tasks with complexity higher than low must always be decomposed before execution. Tasks MUST be in todo status to be decomposed. Subtasks with the same sequence order may be executed in parallel. Subtasks should include a verification subtask. Created subtasks may be decomposed later if needed.`, inputSchema: zodToJsonSchema(DecomposeTaskArgsSchema, { $refStrategy: 'none' }), }
- tools/index.ts:29-32 (registration)Registers the decompose_task tool by mapping the tool name to its handler function and input schema in the central toolHandlers record.[DECOMPOSE_TASK]: { handler: handleDecomposeTask, schema: DecomposeTaskArgsSchema, } satisfies ToolHandlerInfo,