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",
"tasks",
"package-lock.json",
"tests/fixture/*.json"
"tests/fixture/*.json",
"dist"
]
},
"formatter": {

View File

@@ -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
}
},

View File

@@ -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",

View File

@@ -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)'
)

View File

@@ -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);

View File

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

View File

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

View File

@@ -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);

View File

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

View File

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

View File

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

View File

@@ -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: []
}
];