fix(ai, config): Correct Anthropic API calls and improve model config UI
Resolves persistent 404 'Not Found' errors when calling Anthropic models via the Vercel AI SDK. The primary issue was likely related to incorrect or missing API headers. - Refactors Anthropic provider (src/ai-providers/anthropic.js) to use the standard 'anthropic-version' header instead of potentially outdated/incorrect beta headers when creating the client instance. - Updates the default fallback model ID in .taskmasterconfig to 'claude-3-5-sonnet-20241022'. - Fixes the interactive model setup (task-master models --setup) in scripts/modules/commands.js to correctly filter and default the main model selection. - Improves the cost display in the 'task-master models' command output to explicitly show 'Free' for models with zero cost. - Updates description for the 'id' parameter in the 'set_task_status' MCP tool definition for clarity. - Updates list of models and costs
This commit is contained in:
@@ -1659,6 +1659,18 @@ function registerCommands(programInstance) {
|
||||
|
||||
console.log(chalk.cyan.bold('\nInteractive Model Setup:'));
|
||||
|
||||
const getMainChoicesAndDefault = () => {
|
||||
const mainChoices = allModelsForSetup.filter((modelChoice) =>
|
||||
availableModelsForSetup
|
||||
.find((m) => m.modelId === modelChoice.value.id)
|
||||
?.allowedRoles?.includes('main')
|
||||
);
|
||||
const defaultIndex = mainChoices.findIndex(
|
||||
(m) => m.value.id === currentModels.main?.modelId
|
||||
);
|
||||
return { choices: mainChoices, default: defaultIndex };
|
||||
};
|
||||
|
||||
// Get all available models, including active ones
|
||||
const allModelsForSetup = availableModelsForSetup.map((model) => ({
|
||||
name: `${model.provider} / ${model.modelId}`,
|
||||
@@ -1716,6 +1728,8 @@ function registerCommands(programInstance) {
|
||||
|
||||
const researchPromptData = getResearchChoicesAndDefault();
|
||||
const fallbackPromptData = getFallbackChoicesAndDefault();
|
||||
// Call the helper function for main model choices
|
||||
const mainPromptData = getMainChoicesAndDefault();
|
||||
|
||||
// Add cancel option for all prompts
|
||||
const cancelOption = {
|
||||
@@ -1726,7 +1740,7 @@ function registerCommands(programInstance) {
|
||||
const mainModelChoices = [
|
||||
cancelOption,
|
||||
new inquirer.Separator(),
|
||||
...allModelsForSetup
|
||||
...mainPromptData.choices
|
||||
];
|
||||
|
||||
const researchModelChoices = [
|
||||
@@ -1758,7 +1772,7 @@ function registerCommands(programInstance) {
|
||||
name: 'mainModel',
|
||||
message: 'Select the main model for generation/updates:',
|
||||
choices: mainModelChoices,
|
||||
default: findDefaultIndex(currentModels.main?.modelId) + 2 // +2 for cancel option and separator
|
||||
default: mainPromptData.default + 2 // +2 for cancel option and separator
|
||||
},
|
||||
{
|
||||
type: 'list',
|
||||
@@ -2001,6 +2015,12 @@ function registerCommands(programInstance) {
|
||||
|
||||
const formatCost = (costObj) => {
|
||||
if (!costObj) return 'N/A';
|
||||
|
||||
// Check if both input and output costs are 0 and return "Free"
|
||||
if (costObj.input === 0 && costObj.output === 0) {
|
||||
return chalk.green('Free');
|
||||
}
|
||||
|
||||
const formatSingleCost = (costValue) => {
|
||||
if (costValue === null || costValue === undefined) return 'N/A';
|
||||
const isInteger = Number.isInteger(costValue);
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
{
|
||||
"anthropic": [
|
||||
{
|
||||
"id": "claude-3.5-sonnet-20240620",
|
||||
"swe_score": 0.49,
|
||||
"cost_per_1m_tokens": { "input": 3.0, "output": 15.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "claude-3-7-sonnet-20250219",
|
||||
"swe_score": 0.623,
|
||||
@@ -13,21 +7,21 @@
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "claude-3.5-haiku-20241022",
|
||||
"id": "claude-3-5-sonnet-20241022",
|
||||
"swe_score": 0.49,
|
||||
"cost_per_1m_tokens": { "input": 3.0, "output": 15.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "claude-3-5-haiku-20241022",
|
||||
"swe_score": 0.406,
|
||||
"cost_per_1m_tokens": { "input": 0.8, "output": 4.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "claude-3-haiku-20240307",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": { "input": 0.25, "output": 1.25 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "claude-3-opus-20240229",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 15, "output": 75 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
}
|
||||
],
|
||||
@@ -35,13 +29,7 @@
|
||||
{
|
||||
"id": "gpt-4o",
|
||||
"swe_score": 0.332,
|
||||
"cost_per_1m_tokens": { "input": 5.0, "output": 15.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gpt-4-turbo",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": { "input": 10.0, "output": 30.0 },
|
||||
"cost_per_1m_tokens": { "input": 2.5, "output": 10.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
@@ -50,12 +38,30 @@
|
||||
"cost_per_1m_tokens": { "input": 15.0, "output": 60.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "o3",
|
||||
"swe_score": 0.5,
|
||||
"cost_per_1m_tokens": { "input": 10.0, "output": 40.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "o3-mini",
|
||||
"swe_score": 0.493,
|
||||
"cost_per_1m_tokens": { "input": 1.1, "output": 4.4 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "o4-mini",
|
||||
"swe_score": 0.45,
|
||||
"cost_per_1m_tokens": { "input": 1.1, "output": 4.4 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "o1-mini",
|
||||
"swe_score": 0.4,
|
||||
"cost_per_1m_tokens": { "input": 1.1, "output": 4.4 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "o1-pro",
|
||||
"swe_score": 0,
|
||||
@@ -63,51 +69,63 @@
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gpt-4.1",
|
||||
"id": "gpt-4-1",
|
||||
"swe_score": 0.55,
|
||||
"cost_per_1m_tokens": { "input": 2.0, "output": 8.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gpt-4.5-preview",
|
||||
"id": "gpt-4-5-preview",
|
||||
"swe_score": 0.38,
|
||||
"cost_per_1m_tokens": { "input": 75.0, "output": 150.0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gpt-4.1-mini",
|
||||
"id": "gpt-4-1-mini",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": { "input": 0.4, "output": 1.6 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gpt-4.1-nano",
|
||||
"id": "gpt-4-1-nano",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": { "input": 0.1, "output": 0.4 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gpt-3.5-turbo",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": { "input": 0.5, "output": 1.5 },
|
||||
"id": "gpt-4o-mini",
|
||||
"swe_score": 0.3,
|
||||
"cost_per_1m_tokens": { "input": 0.15, "output": 0.6 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-search-preview",
|
||||
"swe_score": 0.33,
|
||||
"cost_per_1m_tokens": { "input": 2.5, "output": 10.0 },
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
},
|
||||
{
|
||||
"id": "gpt-4o-mini-search-preview",
|
||||
"swe_score": 0.3,
|
||||
"cost_per_1m_tokens": { "input": 0.15, "output": 0.6 },
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
}
|
||||
],
|
||||
"google": [
|
||||
{
|
||||
"id": "gemini-2.5-pro-latest",
|
||||
"id": "gemini-2.5-pro-exp-03-25",
|
||||
"swe_score": 0.638,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gemini-1.5-flash-latest",
|
||||
"id": "gemini-2.5-flash-preview-04-17",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gemini-2.0-flash-experimental",
|
||||
"id": "gemini-2.0-flash",
|
||||
"swe_score": 0.754,
|
||||
"cost_per_1m_tokens": { "input": 0.15, "output": 0.6 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
@@ -123,134 +141,146 @@
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "gemma-3-7b",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
}
|
||||
],
|
||||
"perplexity": [
|
||||
{
|
||||
"id": "sonar-pro",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
"cost_per_1m_tokens": { "input": 3, "output": 15 },
|
||||
"allowed_roles": ["research"]
|
||||
},
|
||||
{
|
||||
"id": "sonar-mini",
|
||||
"id": "sonar",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
"cost_per_1m_tokens": { "input": 1, "output": 1 },
|
||||
"allowed_roles": ["research"]
|
||||
},
|
||||
{
|
||||
"id": "deep-research",
|
||||
"swe_score": 0.211,
|
||||
"cost_per_1m_tokens": { "input": 2.0, "output": 8.0 },
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
"cost_per_1m_tokens": { "input": 2, "output": 8 },
|
||||
"allowed_roles": ["research"]
|
||||
},
|
||||
{
|
||||
"id": "sonar-reasoning-pro",
|
||||
"swe_score": 0.211,
|
||||
"cost_per_1m_tokens": { "input": 2, "output": 8 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "sonar-reasoning",
|
||||
"swe_score": 0.211,
|
||||
"cost_per_1m_tokens": { "input": 1, "output": 5 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
}
|
||||
],
|
||||
"ollama": [
|
||||
{
|
||||
"id": "llava",
|
||||
"id": "gemma3:27b",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "deepseek-coder-v2",
|
||||
"id": "gemma3:12b",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "dolphin3",
|
||||
"id": "qwq",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "olmo2-7b",
|
||||
"id": "deepseek-r1",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "olmo2-13b",
|
||||
"id": "mistral-small3.1",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "llama3.3",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "phi4",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
}
|
||||
],
|
||||
"openrouter": [
|
||||
{
|
||||
"id": "meta-llama/llama-4-scout",
|
||||
"id": "google/gemini-2.0-flash-001",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0.1, "output": 0.4 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "google/gemini-2.5-pro-exp-03-25",
|
||||
"id": "google/gemini-2.5-pro-exp-03-25:free",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "openrouter/optimus-alpha",
|
||||
"id": "deepseek/deepseek-chat-v3-0324:free",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": { "input": 30.0, "output": 60.0 },
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "openrouter/quasar-alpha",
|
||||
"id": "google/gemini-2.5-pro-preview-03-25",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 1.25, "output": 10 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "kimi-vl-a3b-thinking",
|
||||
"id": "deepseek/deepseek-chat-v3-0324",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0.27, "output": 1.1 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "qwen2.5-max",
|
||||
"id": "deepseek/deepseek-r1:free",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 0, "output": 0 },
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
}
|
||||
],
|
||||
"grok": [
|
||||
{
|
||||
"id": "grok3-beta",
|
||||
"id": "grok3",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"cost_per_1m_tokens": { "input": 3, "output": 15 },
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
},
|
||||
{
|
||||
"id": "grok-3-mini",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
"cost_per_1m_tokens": { "input": 0.3, "output": 0.5 },
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
},
|
||||
{
|
||||
"id": "grok-2",
|
||||
"id": "grok3-fast",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
"cost_per_1m_tokens": { "input": 5, "output": 25 },
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
},
|
||||
{
|
||||
"id": "grok-2-mini",
|
||||
"id": "grok-3-mini-fast",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
},
|
||||
{
|
||||
"id": "grok-1.5",
|
||||
"swe_score": 0,
|
||||
"cost_per_1m_tokens": null,
|
||||
"allowed_roles": ["main", "fallback"]
|
||||
"cost_per_1m_tokens": { "input": 0.6, "output": 4 },
|
||||
"allowed_roles": ["main", "fallback", "research"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
import chalk from 'chalk';
|
||||
import boxen from 'boxen';
|
||||
import { z } from 'zod';
|
||||
|
||||
import {
|
||||
log,
|
||||
@@ -11,10 +12,33 @@ import {
|
||||
isSilentMode
|
||||
} from '../utils.js';
|
||||
|
||||
import { callClaude } from '../ai-services.js';
|
||||
import { generateObjectService } from '../ai-services-unified.js';
|
||||
import { getDebugFlag } from '../config-manager.js';
|
||||
import generateTaskFiles from './generate-task-files.js';
|
||||
|
||||
// Define Zod schema for task validation
|
||||
const TaskSchema = z.object({
|
||||
id: z.number(),
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
status: z.string().default('pending'),
|
||||
dependencies: z.array(z.number()).default([]),
|
||||
priority: z.string().default('medium'),
|
||||
details: z.string().optional(),
|
||||
testStrategy: z.string().optional()
|
||||
});
|
||||
|
||||
// Define Zod schema for the complete tasks data
|
||||
const TasksDataSchema = z.object({
|
||||
tasks: z.array(TaskSchema),
|
||||
metadata: z.object({
|
||||
projectName: z.string(),
|
||||
totalTasks: z.number(),
|
||||
sourceFile: z.string(),
|
||||
generatedAt: z.string()
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* Parse a PRD file and generate tasks
|
||||
* @param {string} prdPath - Path to the PRD file
|
||||
@@ -24,17 +48,8 @@ import generateTaskFiles from './generate-task-files.js';
|
||||
* @param {Object} options.reportProgress - Function to report progress to MCP server (optional)
|
||||
* @param {Object} options.mcpLog - MCP logger object (optional)
|
||||
* @param {Object} options.session - Session object from MCP server (optional)
|
||||
* @param {Object} aiClient - AI client to use (optional)
|
||||
* @param {Object} modelConfig - Model configuration (optional)
|
||||
*/
|
||||
async function parsePRD(
|
||||
prdPath,
|
||||
tasksPath,
|
||||
numTasks,
|
||||
options = {},
|
||||
aiClient = null,
|
||||
modelConfig = null
|
||||
) {
|
||||
async function parsePRD(prdPath, tasksPath, numTasks, options = {}) {
|
||||
const { reportProgress, mcpLog, session } = options;
|
||||
|
||||
// Determine output format based on mcpLog presence (simplification)
|
||||
@@ -56,22 +71,79 @@ async function parsePRD(
|
||||
// Read the PRD content
|
||||
const prdContent = fs.readFileSync(prdPath, 'utf8');
|
||||
|
||||
// Call Claude to generate tasks, passing the provided AI client if available
|
||||
const tasksData = await callClaude(
|
||||
prdContent,
|
||||
prdPath,
|
||||
numTasks,
|
||||
0,
|
||||
{ reportProgress, mcpLog, session },
|
||||
aiClient,
|
||||
modelConfig
|
||||
);
|
||||
// Build system prompt for PRD parsing
|
||||
const systemPrompt = `You are an AI assistant helping to break down a Product Requirements Document (PRD) into a set of sequential development tasks.
|
||||
Your goal is to create ${numTasks} well-structured, actionable development tasks based on the PRD provided.
|
||||
|
||||
Each task should follow this JSON structure:
|
||||
{
|
||||
"id": number,
|
||||
"title": string,
|
||||
"description": string,
|
||||
"status": "pending",
|
||||
"dependencies": number[] (IDs of tasks this depends on),
|
||||
"priority": "high" | "medium" | "low",
|
||||
"details": string (implementation details),
|
||||
"testStrategy": string (validation approach)
|
||||
}
|
||||
|
||||
Guidelines:
|
||||
1. Create exactly ${numTasks} tasks, numbered from 1 to ${numTasks}
|
||||
2. Each task should be atomic and focused on a single responsibility
|
||||
3. Order tasks logically - consider dependencies and implementation sequence
|
||||
4. Early tasks should focus on setup, core functionality first, then advanced features
|
||||
5. Include clear validation/testing approach for each task
|
||||
6. Set appropriate dependency IDs (a task can only depend on tasks with lower IDs)
|
||||
7. Assign priority (high/medium/low) based on criticality and dependency order
|
||||
8. Include detailed implementation guidance in the "details" field
|
||||
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
|
||||
10. Focus on filling in any gaps left by the PRD or areas that aren't fully specified, while preserving all explicit requirements
|
||||
11. Always aim to provide the most direct path to implementation, avoiding over-engineering or roundabout approaches`;
|
||||
|
||||
// Build user prompt with PRD content
|
||||
const userPrompt = `Here's the Product Requirements Document (PRD) to break down into ${numTasks} tasks:
|
||||
|
||||
${prdContent}
|
||||
|
||||
Return your response in this format:
|
||||
{
|
||||
"tasks": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "Setup Project Repository",
|
||||
"description": "...",
|
||||
...
|
||||
},
|
||||
...
|
||||
],
|
||||
"metadata": {
|
||||
"projectName": "PRD Implementation",
|
||||
"totalTasks": ${numTasks},
|
||||
"sourceFile": "${prdPath}",
|
||||
"generatedAt": "YYYY-MM-DD"
|
||||
}
|
||||
}`;
|
||||
|
||||
// Call the unified AI service
|
||||
report('Calling AI service to generate tasks from PRD...', 'info');
|
||||
|
||||
// Call generateObjectService with proper parameters
|
||||
const tasksData = await generateObjectService({
|
||||
role: 'main', // Use 'main' role to get the model from config
|
||||
session: session, // Pass session for API key resolution
|
||||
schema: TasksDataSchema, // Pass the schema for validation
|
||||
objectName: 'tasks_data', // Name the generated object
|
||||
systemPrompt: systemPrompt, // System instructions
|
||||
prompt: userPrompt, // User prompt with PRD content
|
||||
reportProgress // Progress reporting function
|
||||
});
|
||||
|
||||
// Create the directory if it doesn't exist
|
||||
const tasksDir = path.dirname(tasksPath);
|
||||
if (!fs.existsSync(tasksDir)) {
|
||||
fs.mkdirSync(tasksDir, { recursive: true });
|
||||
}
|
||||
|
||||
// Write the tasks to the file
|
||||
writeJSON(tasksPath, tasksData);
|
||||
report(
|
||||
@@ -125,7 +197,7 @@ async function parsePRD(
|
||||
if (outputFormat === 'text') {
|
||||
console.error(chalk.red(`Error: ${error.message}`));
|
||||
|
||||
if (getDebugFlag()) {
|
||||
if (getDebugFlag(session)) {
|
||||
// Use getter
|
||||
console.error(error);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user