Compare commits

...

2 Commits

Author SHA1 Message Date
Ralph Khreish
8c91520356 fix CI 2025-06-21 22:34:47 +03:00
Ralph Khreish
54f50a4dc8 feat: make more compatible with "o" family models 2025-06-21 22:16:51 +03:00
13 changed files with 45 additions and 28 deletions

View File

@@ -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.

View File

@@ -6,7 +6,8 @@
".changeset", ".changeset",
"tasks", "tasks",
"package-lock.json", "package-lock.json",
"tests/fixture/*.json" "tests/fixture/*.json",
"dist"
] ]
}, },
"formatter": { "formatter": {

View File

@@ -54,7 +54,7 @@ const DEFAULTS = {
// No default fallback provider/model initially // No default fallback provider/model initially
provider: 'anthropic', provider: 'anthropic',
modelId: 'claude-3-5-sonnet', modelId: 'claude-3-5-sonnet',
maxTokens: 64000, // Default parameters if fallback IS configured maxTokens: 8192, // Default parameters if fallback IS configured
temperature: 0.2 temperature: 0.2
} }
}, },

View File

@@ -54,7 +54,7 @@
"output": 15.0 "output": 15.0
}, },
"allowed_roles": ["main", "fallback"], "allowed_roles": ["main", "fallback"],
"max_tokens": 64000 "max_tokens": 8192
} }
], ],
"openai": [ "openai": [
@@ -84,7 +84,8 @@
"input": 2.0, "input": 2.0,
"output": 8.0 "output": 8.0
}, },
"allowed_roles": ["main", "fallback"] "allowed_roles": ["main", "fallback"],
"max_tokens": 100000
}, },
{ {
"id": "o3-mini", "id": "o3-mini",

View File

@@ -27,7 +27,6 @@ import {
} from '../utils.js'; } from '../utils.js';
import { generateObjectService } from '../ai-services-unified.js'; import { generateObjectService } from '../ai-services-unified.js';
import { getDefaultPriority } from '../config-manager.js'; import { getDefaultPriority } from '../config-manager.js';
import generateTaskFiles from './generate-task-files.js';
import ContextGatherer from '../utils/contextGatherer.js'; import ContextGatherer from '../utils/contextGatherer.js';
// Define Zod schema for the expected AI output object // Define Zod schema for the expected AI output object
@@ -44,7 +43,7 @@ const AiTaskDataSchema = z.object({
.describe('Detailed approach for verifying task completion'), .describe('Detailed approach for verifying task completion'),
dependencies: z dependencies: z
.array(z.number()) .array(z.number())
.optional() .nullable()
.describe( .describe(
'Array of task IDs that this task depends on (must be completed before this task can start)' 'Array of task IDs that this task depends on (must be completed before this task can start)'
) )

View File

@@ -43,8 +43,9 @@ const subtaskSchema = z
), ),
testStrategy: z testStrategy: z
.string() .string()
.optional() .nullable()
.describe('Approach for testing this subtask') .describe('Approach for testing this subtask')
.default('')
}) })
.strict(); .strict();
const subtaskArraySchema = z.array(subtaskSchema); const subtaskArraySchema = z.array(subtaskSchema);

View File

@@ -26,11 +26,11 @@ const prdSingleTaskSchema = z.object({
id: z.number().int().positive(), id: z.number().int().positive(),
title: z.string().min(1), title: z.string().min(1),
description: z.string().min(1), description: z.string().min(1),
details: z.string().optional().default(''), details: z.string().nullable(),
testStrategy: z.string().optional().default(''), testStrategy: z.string().nullable(),
priority: z.enum(['high', 'medium', 'low']).default('medium'), priority: z.enum(['high', 'medium', 'low']).nullable(),
dependencies: z.array(z.number().int().positive()).optional().default([]), dependencies: z.array(z.number().int().positive()).nullable(),
status: z.string().optional().default('pending') status: z.string().nullable()
}); });
// Define the Zod schema for the ENTIRE expected AI response object // Define the Zod schema for the ENTIRE expected AI response object

View File

@@ -36,9 +36,9 @@ const updatedTaskSchema = z
description: z.string(), description: z.string(),
status: z.string(), status: z.string(),
dependencies: z.array(z.union([z.number().int(), z.string()])), dependencies: z.array(z.union([z.number().int(), z.string()])),
priority: z.string().optional(), priority: z.string().nullable().default('medium'),
details: z.string().optional(), details: z.string().nullable().default(''),
testStrategy: z.string().optional(), testStrategy: z.string().nullable().default(''),
subtasks: z subtasks: z
.array( .array(
z.object({ z.object({
@@ -50,12 +50,13 @@ const updatedTaskSchema = z
title: z.string(), title: z.string(),
description: z.string(), description: z.string(),
status: z.string(), status: z.string(),
dependencies: z.array(z.number().int()).optional(), dependencies: z.array(z.number().int()).nullable().default([]),
details: z.string().optional(), details: z.string().nullable().default(''),
testStrategy: z.string().optional() testStrategy: z.string().nullable().default('')
}) })
) )
.optional() .nullable()
.default([])
}) })
.strip(); // Allows parsing even if AI adds extra fields, but validation focuses on schema .strip(); // Allows parsing even if AI adds extra fields, but validation focuses on schema

View File

@@ -35,10 +35,10 @@ const updatedTaskSchema = z
description: z.string(), description: z.string(),
status: z.string(), status: z.string(),
dependencies: z.array(z.union([z.number().int(), z.string()])), dependencies: z.array(z.union([z.number().int(), z.string()])),
priority: z.string().optional(), priority: z.string().nullable(),
details: z.string().optional(), details: z.string().nullable(),
testStrategy: z.string().optional(), testStrategy: z.string().nullable(),
subtasks: z.array(z.any()).optional() // Keep subtasks flexible for now subtasks: z.array(z.any()).nullable() // Keep subtasks flexible for now
}) })
.strip(); // Allow potential extra fields during parsing if needed, then validate structure .strip(); // Allow potential extra fields during parsing if needed, then validate structure
const updatedTaskArraySchema = z.array(updatedTaskSchema); const updatedTaskArraySchema = z.array(updatedTaskSchema);

View File

@@ -133,7 +133,7 @@ jest.mock('../../../scripts/modules/utils.js', () => ({
readComplexityReport: mockReadComplexityReport, readComplexityReport: mockReadComplexityReport,
CONFIG: { CONFIG: {
model: 'claude-3-7-sonnet-20250219', model: 'claude-3-7-sonnet-20250219',
maxTokens: 64000, maxTokens: 8192,
temperature: 0.2, temperature: 0.2,
defaultSubtasks: 5 defaultSubtasks: 5
} }

View File

@@ -129,7 +129,7 @@ const DEFAULT_CONFIG = {
fallback: { fallback: {
provider: 'anthropic', provider: 'anthropic',
modelId: 'claude-3-5-sonnet', modelId: 'claude-3-5-sonnet',
maxTokens: 64000, maxTokens: 8192,
temperature: 0.2 temperature: 0.2
} }
}, },

View File

@@ -75,7 +75,7 @@ const DEFAULT_CONFIG = {
fallback: { fallback: {
provider: 'anthropic', provider: 'anthropic',
modelId: 'claude-3-5-sonnet', modelId: 'claude-3-5-sonnet',
maxTokens: 64000, maxTokens: 8192,
temperature: 0.2 temperature: 0.2
} }
}, },

View File

@@ -123,7 +123,9 @@ describe('updateTasks', () => {
details: 'New details 2 based on direction', details: 'New details 2 based on direction',
description: 'Updated description', description: 'Updated description',
dependencies: [], dependencies: [],
priority: 'medium' priority: 'medium',
testStrategy: 'Unit test the updated functionality',
subtasks: []
}, },
{ {
id: 3, id: 3,
@@ -132,7 +134,9 @@ describe('updateTasks', () => {
details: 'New details 3 based on direction', details: 'New details 3 based on direction',
description: 'Updated description', description: 'Updated description',
dependencies: [], dependencies: [],
priority: 'medium' priority: 'medium',
testStrategy: 'Integration test the updated features',
subtasks: []
} }
]; ];