diff --git a/docs/contributor-docs/TaskMasterPromptChaining.ipynb b/docs/contributor-docs/TaskMasterPromptChaining.ipynb new file mode 100644 index 0000000000..6f6e4152d8 --- /dev/null +++ b/docs/contributor-docs/TaskMasterPromptChaining.ipynb @@ -0,0 +1,743 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Task Master Prompt Chaining Analysis\n", + "\n", + "This notebook analyzes how prompts are generated, chained, and processed in the Task Master system, focusing on the AI-driven task generation functionality." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 1. Overview of Task Master's AI Integration\n", + "\n", + "Task Master uses a layered architecture for AI integration that powers several key commands:\n", + "\n", + "1. `parse-prd` - Transforms text requirements into structured tasks\n", + "2. `analyze-complexity` - Assesses task complexity and recommends subtask counts\n", + "3. `expand-task` - Breaks down tasks into detailed subtasks\n", + "4. `update-task` - Updates tasks based on new context or requirements\n", + "5. `add-task` - Creates new tasks with AI assistance\n", + "\n", + "Each of these commands relies on prompt generation and AI response processing through a unified service layer." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 2. The AI Service Layer\n", + "\n", + "The central integration point for all AI operations is `ai-services-unified.js`, which provides three main functions:\n", + "\n", + "- `generateTextService` - For unstructured text responses\n", + "- `generateObjectService` - For structured JSON outputs with Zod validation\n", + "- `streamTextService` - For streaming responses\n", + "\n", + "Let's examine how this layer works:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "source": [ + "// From scripts/modules/ai-services-unified.js\n", + "\n", + "// Provider function mapping\n", + "const PROVIDER_FUNCTIONS = {\n", + " anthropic: {\n", + " generateText: anthropic.generateAnthropicText,\n", + " streamText: anthropic.streamAnthropicText,\n", + " generateObject: anthropic.generateAnthropicObject\n", + " },\n", + " perplexity: {\n", + " generateText: perplexity.generatePerplexityText,\n", + " streamText: perplexity.streamPerplexityText,\n", + " generateObject: perplexity.generatePerplexityObject\n", + " },\n", + " // Additional providers...\n", + "};\n", + "\n", + "// Main service functions\n", + "async function generateTextService(params) {\n", + " return _unifiedServiceRunner('generateText', params);\n", + "}\n", + "\n", + "async function generateObjectService(params) {\n", + " const defaults = {\n", + " objectName: 'generated_object',\n", + " maxRetries: 3\n", + " };\n", + " const combinedParams = { ...defaults, ...params };\n", + " return _unifiedServiceRunner('generateObject', combinedParams);\n", + "}\n", + "\n", + "// Core service runner with role-based fallbacks\n", + "async function _unifiedServiceRunner(serviceType, params) {\n", + " const {\n", + " role: initialRole,\n", + " session,\n", + " projectRoot,\n", + " systemPrompt,\n", + " prompt,\n", + " schema,\n", + " objectName,\n", + " ...restApiParams\n", + " } = params;\n", + " \n", + " // Determine fallback sequence based on initial role\n", + " let sequence;\n", + " if (initialRole === 'main') {\n", + " sequence = ['main', 'fallback', 'research'];\n", + " } else if (initialRole === 'research') {\n", + " sequence = ['research', 'fallback', 'main'];\n", + " } else if (initialRole === 'fallback') {\n", + " sequence = ['fallback', 'main', 'research'];\n", + " } else {\n", + " sequence = ['main', 'fallback', 'research'];\n", + " }\n", + "\n", + " // Try each role in sequence until success\n", + " for (const currentRole of sequence) {\n", + " // Get provider and model config\n", + " // Create messages array\n", + " // Attempt API call with retries\n", + " // Return on success\n", + " }\n", + " \n", + " // If loop completes, all roles failed\n", + " throw new Error('All roles in the sequence failed.');\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Key aspects of the AI service layer:\n", + "\n", + "1. **Provider Abstraction**: Maps different LLM providers (Anthropic, Perplexity, OpenAI, etc.) to consistent function signatures\n", + "2. **Role-Based Fallbacks**: Attempts calls in a sequence based on role (main → fallback → research)\n", + "3. **Structured Response Validation**: For `generateObjectService`, uses Zod schemas to validate responses\n", + "4. **Resilience**: Includes retry logic with exponential backoff for transient errors" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 3. PRD Parsing: From Text to Tasks\n", + "\n", + "The `parse-prd` command is the starting point of the task generation workflow. It takes a text requirements document and transforms it into structured tasks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "source": [ + "// From scripts/modules/task-manager/parse-prd.js\n", + "\n", + "// Zod schema for validation\n", + "const prdSingleTaskSchema = z.object({\n", + " id: z.number().int().positive(),\n", + " title: z.string().min(1),\n", + " description: z.string().min(1),\n", + " details: z.string().optional().default(''),\n", + " testStrategy: z.string().optional().default(''),\n", + " priority: z.enum(['high', 'medium', 'low']).default('medium'),\n", + " dependencies: z.array(z.number().int().positive()).optional().default([]),\n", + " status: z.string().optional().default('pending')\n", + "});\n", + "\n", + "const prdResponseSchema = z.object({\n", + " tasks: z.array(prdSingleTaskSchema),\n", + " metadata: z.object({\n", + " projectName: z.string(),\n", + " totalTasks: z.number(),\n", + " sourceFile: z.string(),\n", + " generatedAt: z.string()\n", + " })\n", + "});\n", + "\n", + "// System prompt for PRD parsing\n", + "const systemPrompt = `You are an AI assistant specialized in analyzing Product Requirements Documents (PRDs) and generating a structured, logically ordered, dependency-aware and sequenced list of development tasks in JSON format.\n", + "Analyze the provided PRD content and generate approximately ${numTasks} top-level development tasks. If the complexity or the level of detail of the PRD is high, generate more tasks relative to the complexity of the PRD\n", + "Each task should represent a logical unit of work needed to implement the requirements and focus on the most direct and effective way to implement the requirements without unnecessary complexity or overengineering. Include pseudo-code, implementation details, and test strategy for each task. Find the most up to date information to implement each task.\n", + "Assign sequential IDs starting from ${nextId}. Infer title, description, details, and test strategy for each task based *only* on the PRD content.\n", + "Set status to 'pending', dependencies to an empty array [], and priority to 'medium' initially for all tasks.\n", + "Respond ONLY with a valid JSON object containing a single key \"tasks\", where the value is an array of task objects adhering to the provided Zod schema. Do not include any explanation or markdown formatting.\n", + "\n", + "Each task should follow this JSON structure:\n", + "{\n", + " \"id\": number,\n", + " \"title\": string,\n", + " \"description\": string,\n", + " \"status\": \"pending\",\n", + " \"dependencies\": number[] (IDs of tasks this depends on),\n", + " \"priority\": \"high\" | \"medium\" | \"low\",\n", + " \"details\": string (implementation details),\n", + " \"testStrategy\": string (validation approach)\n", + "}\n", + "\n", + "Guidelines:\n", + "1. Unless complexity warrants otherwise, create exactly ${numTasks} tasks, numbered sequentially starting from ${nextId}\n", + "2. Each task should be atomic and focused on a single responsibility following the most up to date best practices and standards\n", + "3. Order tasks logically - consider dependencies and implementation sequence\n", + "4. Early tasks should focus on setup, core functionality first, then advanced features\n", + "5. Include clear validation/testing approach for each task\n", + "6. Set appropriate dependency IDs (a task can only depend on tasks with lower IDs, potentially including existing tasks with IDs less than ${nextId} if applicable)\n", + "7. Assign priority (high/medium/low) based on criticality and dependency order\n", + "8. Include detailed implementation guidance in the \"details\" field\n", + "9. If the PRD contains specific requirements for libraries, database schemas, frameworks, tech stacks, or any other implementation details, STRICTLY ADHERE to these requirements in your task breakdown and do not discard them under any circumstance\n", + "10. Focus on filling in any gaps left by the PRD or areas that aren't fully specified, while preserving all explicit requirements\n", + "11. Always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches`;\n", + "\n", + "// User prompt with PRD content\n", + "const userPrompt = `Here's the Product Requirements Document (PRD) to break down into approximately ${numTasks} tasks, starting IDs from ${nextId}:\\n\\n${prdContent}\\n\\n\n", + "\n", + "Return your response in this format:\n", + "{\n", + " \"tasks\": [\n", + " {\n", + " \"id\": 1,\n", + " \"title\": \"Setup Project Repository\",\n", + " \"description\": \"...\",\n", + " ...\n", + " },\n", + " ...\n", + " ],\n", + " \"metadata\": {\n", + " \"projectName\": \"PRD Implementation\",\n", + " \"totalTasks\": ${numTasks},\n", + " \"sourceFile\": \"${prdPath}\",\n", + " \"generatedAt\": \"YYYY-MM-DD\"\n", + " }\n", + "}`;\n", + "\n", + "// Call the unified AI service\n", + "const generatedData = await generateObjectService({\n", + " role: 'main',\n", + " session: session,\n", + " projectRoot: projectRoot,\n", + " schema: prdResponseSchema,\n", + " objectName: 'tasks_data',\n", + " systemPrompt: systemPrompt,\n", + " prompt: userPrompt,\n", + " reportProgress\n", + "});" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Key aspects of PRD parsing:\n", + "\n", + "1. **Structured Output**: Uses `generateObjectService` with a Zod schema to ensure valid task structure\n", + "2. **Detailed Instructions**: The system prompt provides comprehensive guidelines for task generation\n", + "3. **Dependency Management**: Post-processes the AI response to remap dependencies and ensure proper task sequencing\n", + "4. **Task Normalization**: Sets default values and ensures consistent task structure\n", + "\n", + "After generating tasks, the system writes them to `tasks.json` and generates individual task files." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 4. Complexity Analysis: Sizing and Prioritizing Tasks\n", + "\n", + "The `analyze-complexity` command evaluates tasks and determines how complex they are, which affects how they're broken down later." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "source": [ + "// From scripts/modules/task-manager/analyze-task-complexity.js\n", + "\n", + "/**\n", + " * Generates the prompt for complexity analysis.\n", + " */\n", + "function generateInternalComplexityAnalysisPrompt(tasksData) {\n", + " const tasksString = JSON.stringify(tasksData.tasks, null, 2);\n", + " return `Analyze the following tasks to determine their complexity (1-10 scale) and recommend the number of subtasks for expansion. Provide a brief reasoning and an initial expansion prompt for each.\n", + "\n", + "Tasks:\n", + "${tasksString}\n", + "\n", + "Respond ONLY with a valid JSON array matching the schema:\n", + "[\n", + " {\n", + " \"taskId\": ,\n", + " \"taskTitle\": \"\",\n", + " \"complexityScore\": ,\n", + " \"recommendedSubtasks\": ,\n", + " \"expansionPrompt\": \"\",\n", + " \"reasoning\": \"\"\n", + " },\n", + " ...\n", + "]\n", + "\n", + "Do not include any explanatory text, markdown formatting, or code block markers before or after the JSON array.`;\n", + "}\n", + "\n", + "// System prompt for complexity analysis\n", + "const systemPrompt =\n", + " 'You are an expert software architect and project manager analyzing task complexity. Respond only with the requested valid JSON array.';\n", + "\n", + "// AI service call\n", + "const role = useResearch ? 'research' : 'main';\n", + "fullResponse = await generateTextService({\n", + " prompt,\n", + " systemPrompt,\n", + " role,\n", + " session,\n", + " projectRoot\n", + "});\n", + "\n", + "// Then parse and process the response into a complexity report\n", + "// This includes JSON parsing with fallbacks for code blocks, error handling, etc." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Key aspects of complexity analysis:\n", + "\n", + "1. **Scoring System**: Tasks are scored on a 1-10 complexity scale\n", + "2. **Subtask Recommendations**: Each task gets a recommended number of subtasks based on complexity\n", + "3. **Custom Expansion Prompts**: Generates task-specific prompts for later expansion\n", + "4. **Reasoning**: Includes reasoning for each complexity assessment\n", + "5. **Report Generation**: Creates a report at `scripts/task-complexity-report.json` for later use\n", + "\n", + "This is a critical step in the chain as it influences how tasks are expanded and broken down in the next phase." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 5. Task Expansion: Breaking Down Tasks into Subtasks\n", + "\n", + "The `expand-task` command uses the task details and optional complexity analysis to break tasks down into actionable subtasks." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "source": [ + "// From scripts/modules/task-manager/expand-task.js\n", + "\n", + "/**\n", + " * Generates the system prompt for the main AI role.\n", + " */\n", + "function generateMainSystemPrompt(subtaskCount) {\n", + " return `You are an AI assistant helping with task breakdown for software development.\n", + "You need to break down a high-level task into ${subtaskCount} specific subtasks that can be implemented one by one.\n", + "\n", + "Subtasks should:\n", + "1. Be specific and actionable implementation steps\n", + "2. Follow a logical sequence\n", + "3. Each handle a distinct part of the parent task\n", + "4. Include clear guidance on implementation approach\n", + "5. Have appropriate dependency chains between subtasks (using the new sequential IDs)\n", + "6. Collectively cover all aspects of the parent task\n", + "\n", + "For each subtask, provide:\n", + "- id: Sequential integer starting from the provided nextSubtaskId\n", + "- title: Clear, specific title\n", + "- description: Detailed description\n", + "- dependencies: Array of prerequisite subtask IDs (use the new sequential IDs)\n", + "- details: Implementation details\n", + "- testStrategy: Optional testing approach\n", + "\n", + "\n", + "Respond ONLY with a valid JSON object containing a single key \"subtasks\" whose value is an array matching the structure described. Do not include any explanatory text, markdown formatting, or code block markers.`;\n", + "}\n", + "\n", + "/**\n", + " * Generates the user prompt for the main AI role.\n", + " */\n", + "function generateMainUserPrompt(\n", + " task,\n", + " subtaskCount,\n", + " additionalContext,\n", + " nextSubtaskId\n", + ") {\n", + " const contextPrompt = additionalContext\n", + " ? `\\n\\nAdditional context: ${additionalContext}`\n", + " : '';\n", + " const schemaDescription = `\n", + "{\n", + " \"subtasks\": [\n", + " {\n", + " \"id\": ${nextSubtaskId}, // First subtask ID\n", + " \"title\": \"Specific subtask title\",\n", + " \"description\": \"Detailed description\",\n", + " \"dependencies\": [], // e.g., [${nextSubtaskId + 1}] if it depends on the next\n", + " \"details\": \"Implementation guidance\",\n", + " \"testStrategy\": \"Optional testing approach\"\n", + " },\n", + " // ... (repeat for a total of ${subtaskCount} subtasks with sequential IDs)\n", + " ]\n", + "}`;\n", + "\n", + " return `Break down this task into exactly ${subtaskCount} specific subtasks:\n", + "\n", + "Task ID: ${task.id}\n", + "Title: ${task.title}\n", + "Description: ${task.description}\n", + "Current details: ${task.details || 'None'}\n", + "${contextPrompt}\n", + "\n", + "Return ONLY the JSON object containing the \"subtasks\" array, matching this structure:\n", + "${schemaDescription}`;\n", + "}\n", + "\n", + "// Complexity report integration\n", + "try {\n", + " if (fs.existsSync(complexityReportPath)) {\n", + " const complexityReport = readJSON(complexityReportPath);\n", + " taskAnalysis = complexityReport?.complexityAnalysis?.find(\n", + " (a) => a.taskId === task.id\n", + " );\n", + " if (taskAnalysis) {\n", + " logger.info(\n", + " `Found complexity analysis for task ${task.id}: Score ${taskAnalysis.complexityScore}`\n", + " );\n", + " if (taskAnalysis.reasoning) {\n", + " complexityReasoningContext = `\\nComplexity Analysis Reasoning: ${taskAnalysis.reasoning}`;\n", + " }\n", + " }\n", + " }\n", + "} catch (reportError) {\n", + " logger.warn(\n", + " `Could not read or parse complexity report: ${reportError.message}. Proceeding without it.`\n", + " );\n", + "}\n", + "\n", + "// Determine prompt content\n", + "if (taskAnalysis?.expansionPrompt) {\n", + " // Use prompt from complexity report\n", + " promptContent = taskAnalysis.expansionPrompt;\n", + " // Append additional context and reasoning\n", + " promptContent += `\\n\\n${additionalContext}`.trim();\n", + " promptContent += `${complexityReasoningContext}`.trim();\n", + "\n", + " // Use simplified system prompt for report prompts\n", + " systemPrompt = `You are an AI assistant helping with task breakdown. Generate exactly ${finalSubtaskCount} subtasks based on the provided prompt and context. Respond ONLY with a valid JSON object containing a single key \"subtasks\" whose value is an array of the generated subtask objects. Each subtask object in the array must have keys: \"id\", \"title\", \"description\", \"dependencies\", \"details\", \"status\". Ensure the 'id' starts from ${nextSubtaskId} and is sequential. Ensure 'dependencies' only reference valid prior subtask IDs generated in this response (starting from ${nextSubtaskId}). Ensure 'status' is 'pending'. Do not include any other text or explanation.`;\n", + "} else {\n", + " // Use standard prompt generation\n", + " const combinedAdditionalContext =\n", + " `${additionalContext}${complexityReasoningContext}`.trim();\n", + " if (useResearch) {\n", + " promptContent = generateResearchUserPrompt(\n", + " task,\n", + " finalSubtaskCount,\n", + " combinedAdditionalContext,\n", + " nextSubtaskId\n", + " );\n", + " systemPrompt = `You are an AI assistant that responds ONLY with valid JSON objects as requested. The object should contain a 'subtasks' array.`;\n", + " } else {\n", + " promptContent = generateMainUserPrompt(\n", + " task,\n", + " finalSubtaskCount,\n", + " combinedAdditionalContext,\n", + " nextSubtaskId\n", + " );\n", + " systemPrompt = generateMainSystemPrompt(finalSubtaskCount);\n", + " }\n", + "}\n", + "\n", + "// Call generateTextService with the determined prompts\n", + "responseText = await generateTextService({\n", + " prompt: promptContent,\n", + " systemPrompt: systemPrompt,\n", + " role,\n", + " session,\n", + " projectRoot\n", + "});" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Key aspects of task expansion:\n", + "\n", + "1. **Complexity Report Integration**: Uses complexity analysis if available to determine subtask count and custom prompts\n", + "2. **Two Prompt Generation Modes**:\n", + " - Standard mode with detailed structure guidance\n", + " - Research mode for more exploratory expansion\n", + "3. **Dynamic Prompt Selection**: Chooses between complexity report prompts and standard prompts based on availability\n", + "4. **Subtask Validation**: Uses Zod schemas to ensure subtasks follow the correct structure\n", + "5. **Sequential ID Management**: Ensures subtasks have proper sequential IDs\n", + "6. **Dependency Chain Support**: Facilitates dependency relationships between subtasks" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 6. Task Updates: Evolving Tasks with New Context\n", + "\n", + "The `update-task` command modifies existing tasks based on new requirements or context while preserving completed work." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "source": [ + "// From scripts/modules/task-manager/update-task-by-id.js\n", + "\n", + "// System prompt for task updates\n", + "const systemPrompt = `You are an AI assistant helping to update a software development task based on new context.\n", + "You will be given a task and a prompt describing changes or new implementation details.\n", + "Your job is to update the task to reflect these changes, while preserving its basic structure.\n", + "\n", + "Guidelines:\n", + "1. VERY IMPORTANT: NEVER change the title of the task - keep it exactly as is\n", + "2. Maintain the same ID, status, and dependencies unless specifically mentioned in the prompt\n", + "3. Update the description, details, and test strategy to reflect the new information\n", + "4. Do not change anything unnecessarily - just adapt what needs to change based on the prompt\n", + "5. Return a complete valid JSON object representing the updated task\n", + "6. VERY IMPORTANT: Preserve all subtasks marked as \"done\" or \"completed\" - do not modify their content\n", + "7. For tasks with completed subtasks, build upon what has already been done rather than rewriting everything\n", + "8. If an existing completed subtask needs to be changed/undone based on the new context, DO NOT modify it directly\n", + "9. Instead, add a new subtask that clearly indicates what needs to be changed or replaced\n", + "10. Use the existence of completed subtasks as an opportunity to make new subtasks more specific and targeted\n", + "11. Ensure any new subtasks have unique IDs that don't conflict with existing ones\n", + "\n", + "The changes described in the prompt should be thoughtfully applied to make the task more accurate and actionable.`;\n", + "\n", + "const taskDataString = JSON.stringify(taskToUpdate, null, 2);\n", + "const userPrompt = `Here is the task to update:\\n${taskDataString}\\n\\nPlease update this task based on the following new context:\\n${prompt}\\n\\nIMPORTANT: In the task JSON above, any subtasks with \"status\": \"done\" or \"status\": \"completed\" should be preserved exactly as is. Build your changes around these completed items.\\n\\nReturn only the updated task as a valid JSON object.`;\n", + "\n", + "// Call AI service\n", + "responseText = await generateTextService({\n", + " prompt: userPrompt,\n", + " systemPrompt: systemPrompt,\n", + " role,\n", + " session,\n", + " projectRoot\n", + "});\n", + "\n", + "// Parse response and perform various validations\n", + "updatedTask = parseUpdatedTaskFromText(\n", + " responseText,\n", + " taskId,\n", + " logFn,\n", + " isMCP\n", + ");\n", + "\n", + "// Preserve completed subtasks\n", + "if (taskToUpdate.subtasks?.length > 0) {\n", + " if (!updatedTask.subtasks) {\n", + " updatedTask.subtasks = taskToUpdate.subtasks;\n", + " } else {\n", + " const completedOriginal = taskToUpdate.subtasks.filter(\n", + " (st) => st.status === 'done' || st.status === 'completed'\n", + " );\n", + " completedOriginal.forEach((compSub) => {\n", + " const updatedSub = updatedTask.subtasks.find(\n", + " (st) => st.id === compSub.id\n", + " );\n", + " if (\n", + " !updatedSub ||\n", + " JSON.stringify(updatedSub) !== JSON.stringify(compSub)\n", + " ) {\n", + " // Remove potentially modified version\n", + " updatedTask.subtasks = updatedTask.subtasks.filter(\n", + " (st) => st.id !== compSub.id\n", + " );\n", + " // Add back original\n", + " updatedTask.subtasks.push(compSub);\n", + " }\n", + " });\n", + " }\n", + "}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Key aspects of task updates:\n", + "\n", + "1. **Work Preservation**: Special handling to maintain completed subtasks and prevent modifications\n", + "2. **Structural Integrity**: Guidelines to preserve core task structure while updating content\n", + "3. **Task ID Protection**: Ensures task IDs remain consistent\n", + "4. **Dependency Maintenance**: Preserved dependencies unless explicitly changed\n", + "5. **Conflict Resolution**: Logic for handling conflicts when completed subtasks need revisions" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 7. Adding Tasks: Creating New Tasks with AI\n", + "\n", + "The `add-task` command creates new tasks with appropriate integration into the existing task structure." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "source": [ + "// From mcp-server/src/core/direct-functions/add-task.js\n", + "\n", + "// Zod Schema for task validation\n", + "const AiTaskDataSchema = z.object({\n", + " title: z.string().min(1),\n", + " description: z.string().min(1),\n", + " details: z.string(),\n", + " testStrategy: z.string().optional(),\n", + " priority: z.enum(['high', 'medium', 'low']).default('medium'),\n", + " dependencies: z.array(z.number()).optional().default([])\n", + "});\n", + "\n", + "// System prompt for task creation\n", + "const systemPrompt = 'You are an AI assistant helping to create well-structured development tasks. Respond only with the requested JSON object.';\n", + "\n", + "// Assemble context information for the AI\n", + "const existingTasksInfo = getExistingTasksInfo(tasksData.tasks);\n", + "const dependenciesInfo = initialDependencies.length > 0 \n", + " ? `\\nThis task should depend on task IDs: ${initialDependencies.join(', ')}`\n", + " : '';\n", + "const priorityInfo = initialPriority \n", + " ? `\\nThis task should have priority: ${initialPriority}`\n", + " : '';\n", + "\n", + "// User prompt with context\n", + "const userPrompt = `Create a new development task based on this description: ${prompt}\\n\\n${existingTasksInfo}${dependenciesInfo}${priorityInfo}\\n\\nReturn ONLY a valid JSON object with these fields:\\n- title: A clear, specific title\\n- description: Detailed description\\n- details: Implementation guidance\\n- testStrategy: Validation approach\\n- priority: \"high\", \"medium\", or \"low\"\\n- dependencies: Array of task IDs this depends on`;\n", + "\n", + "// Generate task data\n", + "const taskData = await generateObjectService({\n", + " role: useResearch ? 'research' : 'main',\n", + " schema: AiTaskDataSchema,\n", + " objectName: 'task_data',\n", + " systemPrompt,\n", + " prompt: userPrompt,\n", + " session,\n", + " projectRoot\n", + "});\n", + "\n", + "// Verify dependencies and add the task\n", + "validateDependencies(taskData.dependencies, tasksData.tasks);\n", + "const newTask = {\n", + " id: nextId,\n", + " title: taskData.title,\n", + " description: taskData.description,\n", + " status: 'pending',\n", + " dependencies: taskData.dependencies,\n", + " priority: taskData.priority,\n", + " details: taskData.details,\n", + " testStrategy: taskData.testStrategy || '',\n", + " subtasks: []\n", + "};\n", + "\n", + "tasksData.tasks.push(newTask);" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Key aspects of adding tasks:\n", + "\n", + "1. **Context-Aware Generation**: Provides information about existing tasks to the AI\n", + "2. **Dependency Management**: Validates that dependencies refer to existing tasks\n", + "3. **Structured Output**: Uses `generateObjectService` with a schema to ensure proper structure\n", + "4. **ID Allocation**: Assigns the next available ID to the new task\n", + "5. **Priority Assignment**: Sets priority based on user input or AI recommendation" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 8. Command Chaining: How Commands Work Together\n", + "\n", + "Task Master's commands typically form chains where the output of one command serves as input to another. The most common chains are:\n", + "\n", + "### Initial Project Setup Chain\n", + "\n", + "```\n", + "parse-prd → analyze-complexity → expand-task\n", + "```\n", + "\n", + "1. `parse-prd` generates high-level tasks from requirements\n", + "2. `analyze-complexity` assesses each task's complexity and recommends subtask counts\n", + "3. `expand-task` breaks down tasks into actionable subtasks\n", + "\n", + "### Ongoing Development Chain\n", + "\n", + "```\n", + "add-task → update-task → expand-task\n", + "```\n", + "\n", + "1. `add-task` creates new tasks as requirements evolve\n", + "2. `update-task` modifies tasks based on new context or information\n", + "3. `expand-task` breaks down updated tasks into detailed subtasks\n", + "\n", + "### Integration Between Commands\n", + "\n", + "Commands integrate through:\n", + "\n", + "1. **File-based Integration**: `tasks.json` serves as the central data store\n", + "2. **Complexity Report**: `task-complexity-report.json` links analysis to expansion\n", + "3. **Task ID References**: IDs and dependencies maintain relationships\n", + "4. **Shared Service Layer**: The unified AI service provides consistent interaction\n", + "\n", + "This system allows for an iterative, flexible workflow that adapts to changing requirements while maintaining consistency." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## 9. Conclusion: Key Design Patterns in Prompt Generation\n", + "\n", + "From our analysis, we can identify several key patterns in Task Master's prompt engineering approach:\n", + "\n", + "1. **Structured Output Templates**: JSON schemas and examples guide the AI to produce consistent outputs\n", + "2. **Context Preservation**: Tasks retain completed work while evolving with new requirements\n", + "3. **Cascading Complexity**: Analysis results guide task expansion, creating a more adaptive workflow\n", + "4. **Role-Based Fallbacks**: Different AI models serve different purposes with automatic fallback mechanisms\n", + "5. **Task Dependency Management**: Complex dependency relationships are maintained through the entire workflow\n", + "6. **Robust Parsing Logic**: Sophisticated parsing handles various AI response formats and potential errors\n", + "7. **Intermediate Artifacts**: Complexity reports and other artifacts connect different commands\n", + "8. **Validation Pipelines**: Zod schemas ensure consistent, valid outputs throughout the system\n", + "\n", + "These patterns together form a robust, flexible system for transforming high-level requirements into structured, actionable development tasks." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Node.js", + "language": "javascript", + "name": "node.js" + }, + "language_info": { + "file_extension": ".js", + "mimetype": "application/javascript", + "name": "javascript", + "version": "16.x" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} \ No newline at end of file