From c5de4f8b68fc4d6f934bc610c59c599dedb8e510 Mon Sep 17 00:00:00 2001 From: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com> Date: Sat, 21 Jun 2025 22:50:00 +0300 Subject: [PATCH] feat: make more compatible with "o" family models (#839) --- .changeset/petite-friends-arrive.md | 10 ++++++++++ biome.json | 3 ++- scripts/modules/config-manager.js | 2 +- scripts/modules/supported-models.json | 5 +++-- scripts/modules/task-manager/add-task.js | 3 +-- scripts/modules/task-manager/expand-task.js | 3 ++- scripts/modules/task-manager/parse-prd.js | 10 +++++----- scripts/modules/task-manager/update-task-by-id.js | 15 ++++++++------- scripts/modules/task-manager/update-tasks.js | 8 ++++---- .../mcp-server/direct-functions.test.js | 2 +- tests/unit/config-manager.test.js | 2 +- tests/unit/config-manager.test.mjs | 2 +- .../modules/task-manager/update-tasks.test.js | 8 ++++++-- 13 files changed, 45 insertions(+), 28 deletions(-) create mode 100644 .changeset/petite-friends-arrive.md 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); diff --git a/tests/integration/mcp-server/direct-functions.test.js b/tests/integration/mcp-server/direct-functions.test.js index 252d9c02..8d1e60a5 100644 --- a/tests/integration/mcp-server/direct-functions.test.js +++ b/tests/integration/mcp-server/direct-functions.test.js @@ -133,7 +133,7 @@ jest.mock('../../../scripts/modules/utils.js', () => ({ readComplexityReport: mockReadComplexityReport, CONFIG: { model: 'claude-3-7-sonnet-20250219', - maxTokens: 64000, + maxTokens: 8192, temperature: 0.2, defaultSubtasks: 5 } diff --git a/tests/unit/config-manager.test.js b/tests/unit/config-manager.test.js index e32f3a37..8d4fd803 100644 --- a/tests/unit/config-manager.test.js +++ b/tests/unit/config-manager.test.js @@ -129,7 +129,7 @@ const DEFAULT_CONFIG = { fallback: { provider: 'anthropic', modelId: 'claude-3-5-sonnet', - maxTokens: 64000, + maxTokens: 8192, temperature: 0.2 } }, diff --git a/tests/unit/config-manager.test.mjs b/tests/unit/config-manager.test.mjs index 4a020614..97a944cf 100644 --- a/tests/unit/config-manager.test.mjs +++ b/tests/unit/config-manager.test.mjs @@ -75,7 +75,7 @@ const DEFAULT_CONFIG = { fallback: { provider: 'anthropic', modelId: 'claude-3-5-sonnet', - maxTokens: 64000, + maxTokens: 8192, temperature: 0.2 } }, diff --git a/tests/unit/scripts/modules/task-manager/update-tasks.test.js b/tests/unit/scripts/modules/task-manager/update-tasks.test.js index 37782bb6..3449b239 100644 --- a/tests/unit/scripts/modules/task-manager/update-tasks.test.js +++ b/tests/unit/scripts/modules/task-manager/update-tasks.test.js @@ -123,7 +123,9 @@ describe('updateTasks', () => { details: 'New details 2 based on direction', description: 'Updated description', dependencies: [], - priority: 'medium' + priority: 'medium', + testStrategy: 'Unit test the updated functionality', + subtasks: [] }, { id: 3, @@ -132,7 +134,9 @@ describe('updateTasks', () => { details: 'New details 3 based on direction', description: 'Updated description', dependencies: [], - priority: 'medium' + priority: 'medium', + testStrategy: 'Integration test the updated features', + subtasks: [] } ];