diff --git a/.changeset/petite-friends-arrive.md b/.changeset/petite-friends-arrive.md new file mode 100644 index 00000000..d1fc7012 --- /dev/null +++ b/.changeset/petite-friends-arrive.md @@ -0,0 +1,10 @@ +--- +"task-master-ai": minor +--- + +Make task-master more compatible with the "o" family models of OpenAI + +Now works well with: +- o3 +- o3-mini +- etc. diff --git a/biome.json b/biome.json index 8eda21ab..95635649 100644 --- a/biome.json +++ b/biome.json @@ -6,7 +6,8 @@ ".changeset", "tasks", "package-lock.json", - "tests/fixture/*.json" + "tests/fixture/*.json", + "dist" ] }, "formatter": { diff --git a/scripts/modules/config-manager.js b/scripts/modules/config-manager.js index c9ba8ad3..3ab36ff5 100644 --- a/scripts/modules/config-manager.js +++ b/scripts/modules/config-manager.js @@ -54,7 +54,7 @@ const DEFAULTS = { // No default fallback provider/model initially provider: 'anthropic', modelId: 'claude-3-5-sonnet', - maxTokens: 64000, // Default parameters if fallback IS configured + maxTokens: 8192, // Default parameters if fallback IS configured temperature: 0.2 } }, diff --git a/scripts/modules/supported-models.json b/scripts/modules/supported-models.json index d7a8ce7e..5144979e 100644 --- a/scripts/modules/supported-models.json +++ b/scripts/modules/supported-models.json @@ -54,7 +54,7 @@ "output": 15.0 }, "allowed_roles": ["main", "fallback"], - "max_tokens": 64000 + "max_tokens": 8192 } ], "openai": [ @@ -84,7 +84,8 @@ "input": 2.0, "output": 8.0 }, - "allowed_roles": ["main", "fallback"] + "allowed_roles": ["main", "fallback"], + "max_tokens": 100000 }, { "id": "o3-mini", diff --git a/scripts/modules/task-manager/add-task.js b/scripts/modules/task-manager/add-task.js index 61883ba3..1e94c05b 100644 --- a/scripts/modules/task-manager/add-task.js +++ b/scripts/modules/task-manager/add-task.js @@ -27,7 +27,6 @@ import { } from '../utils.js'; import { generateObjectService } from '../ai-services-unified.js'; import { getDefaultPriority } from '../config-manager.js'; -import generateTaskFiles from './generate-task-files.js'; import ContextGatherer from '../utils/contextGatherer.js'; // Define Zod schema for the expected AI output object @@ -44,7 +43,7 @@ const AiTaskDataSchema = z.object({ .describe('Detailed approach for verifying task completion'), dependencies: z .array(z.number()) - .optional() + .nullable() .describe( 'Array of task IDs that this task depends on (must be completed before this task can start)' ) diff --git a/scripts/modules/task-manager/expand-task.js b/scripts/modules/task-manager/expand-task.js index 94893e4e..eb928578 100644 --- a/scripts/modules/task-manager/expand-task.js +++ b/scripts/modules/task-manager/expand-task.js @@ -43,8 +43,9 @@ const subtaskSchema = z ), testStrategy: z .string() - .optional() + .nullable() .describe('Approach for testing this subtask') + .default('') }) .strict(); const subtaskArraySchema = z.array(subtaskSchema); diff --git a/scripts/modules/task-manager/parse-prd.js b/scripts/modules/task-manager/parse-prd.js index 5e0e2d80..da8f59ab 100644 --- a/scripts/modules/task-manager/parse-prd.js +++ b/scripts/modules/task-manager/parse-prd.js @@ -26,11 +26,11 @@ const prdSingleTaskSchema = z.object({ id: z.number().int().positive(), title: z.string().min(1), description: z.string().min(1), - details: z.string().optional().default(''), - testStrategy: z.string().optional().default(''), - priority: z.enum(['high', 'medium', 'low']).default('medium'), - dependencies: z.array(z.number().int().positive()).optional().default([]), - status: z.string().optional().default('pending') + details: z.string().nullable(), + testStrategy: z.string().nullable(), + priority: z.enum(['high', 'medium', 'low']).nullable(), + dependencies: z.array(z.number().int().positive()).nullable(), + status: z.string().nullable() }); // Define the Zod schema for the ENTIRE expected AI response object diff --git a/scripts/modules/task-manager/update-task-by-id.js b/scripts/modules/task-manager/update-task-by-id.js index fd742c98..c2f9bade 100644 --- a/scripts/modules/task-manager/update-task-by-id.js +++ b/scripts/modules/task-manager/update-task-by-id.js @@ -36,9 +36,9 @@ const updatedTaskSchema = z description: z.string(), status: z.string(), dependencies: z.array(z.union([z.number().int(), z.string()])), - priority: z.string().optional(), - details: z.string().optional(), - testStrategy: z.string().optional(), + priority: z.string().nullable().default('medium'), + details: z.string().nullable().default(''), + testStrategy: z.string().nullable().default(''), subtasks: z .array( z.object({ @@ -50,12 +50,13 @@ const updatedTaskSchema = z title: z.string(), description: z.string(), status: z.string(), - dependencies: z.array(z.number().int()).optional(), - details: z.string().optional(), - testStrategy: z.string().optional() + dependencies: z.array(z.number().int()).nullable().default([]), + details: z.string().nullable().default(''), + testStrategy: z.string().nullable().default('') }) ) - .optional() + .nullable() + .default([]) }) .strip(); // Allows parsing even if AI adds extra fields, but validation focuses on schema diff --git a/scripts/modules/task-manager/update-tasks.js b/scripts/modules/task-manager/update-tasks.js index efbae6c1..48b1d541 100644 --- a/scripts/modules/task-manager/update-tasks.js +++ b/scripts/modules/task-manager/update-tasks.js @@ -35,10 +35,10 @@ const updatedTaskSchema = z description: z.string(), status: z.string(), dependencies: z.array(z.union([z.number().int(), z.string()])), - priority: z.string().optional(), - details: z.string().optional(), - testStrategy: z.string().optional(), - subtasks: z.array(z.any()).optional() // Keep subtasks flexible for now + priority: z.string().nullable(), + details: z.string().nullable(), + testStrategy: z.string().nullable(), + subtasks: z.array(z.any()).nullable() // Keep subtasks flexible for now }) .strip(); // Allow potential extra fields during parsing if needed, then validate structure const updatedTaskArraySchema = z.array(updatedTaskSchema);