mirror of
https://github.com/eyaltoledano/claude-task-master.git
synced 2025-11-13 00:25:06 +00:00
* initial cutover * update log to debug * update tracker to pass units * update test to match new base tracker format * add streamTextService mocks * remove unused imports * Ensure the CLI waits for async main() completion * refactor to reduce code duplication * update comment * reuse function * ensure targetTag is defined in streaming mode * avoid throwing inside process.exit spy * check for null * remove reference to generate * fix formatting * fix textStream assignment * ensure no division by 0 * fix jest chalk mocks * refactor for maintainability * Improve bar chart calculation logic for consistent visual representation * use custom streaming error types; fix mocks * Update streamText extraction in parse-prd.js to match actual service response * remove check - doesn't belong here * update mocks * remove streaming test that wasn't really doing anything * add comment * make parsing logic more DRY * fix formatting * Fix textStream extraction to match actual service response * fix mock * Add a cleanup method to ensure proper resource disposal and prevent memory leaks * debounce progress updates to reduce UI flicker during rapid updates * Implement timeout protection for streaming operations (60-second timeout) with automatic fallback to non-streaming mode. * clear timeout properly * Add a maximum buffer size limit (1MB) to prevent unbounded memory growth with very large streaming responses. * fix formatting * remove duplicate mock * better docs * fix formatting * sanitize the dynamic property name * Fix incorrect remaining progress calculation * Use onError callback instead of console.warn * Remove unused chalk import * Add missing custom validator in fallback parsing configuration * add custom validator parameter in fallback parsing * chore: fix package-lock.json * chore: large code refactor * chore: increase timeout from 1 minute to 3 minutes * fix: refactor and fix streaming * Merge remote-tracking branch 'origin/next' into joedanz/parse-prd-progress * fix: cleanup and fix unit tests * chore: fix unit tests * chore: fix format * chore: run format * chore: fix weird CI unit test error * chore: fix format --------- Co-authored-by: Ralph Khreish <35776126+Crunchyman-ralph@users.noreply.github.com>
86 lines
2.4 KiB
JavaScript
86 lines
2.4 KiB
JavaScript
/**
|
|
* Non-streaming handler for PRD parsing
|
|
*/
|
|
|
|
import ora from 'ora';
|
|
import { generateObjectService } from '../../ai-services-unified.js';
|
|
import { LoggingConfig, prdResponseSchema } from './parse-prd-config.js';
|
|
import { estimateTokens } from './parse-prd-helpers.js';
|
|
|
|
/**
|
|
* Handle non-streaming AI service call
|
|
* @param {Object} config - Configuration object
|
|
* @param {Object} prompts - System and user prompts
|
|
* @returns {Promise<Object>} Generated tasks and telemetry
|
|
*/
|
|
export async function handleNonStreamingService(config, prompts) {
|
|
const logger = new LoggingConfig(config.mcpLog, config.reportProgress);
|
|
const { systemPrompt, userPrompt } = prompts;
|
|
const estimatedInputTokens = estimateTokens(systemPrompt + userPrompt);
|
|
|
|
// Initialize spinner for CLI
|
|
let spinner = null;
|
|
if (config.outputFormat === 'text' && !config.isMCP) {
|
|
spinner = ora('Parsing PRD and generating tasks...\n').start();
|
|
}
|
|
|
|
try {
|
|
// Call AI service
|
|
logger.report(
|
|
`Calling AI service to generate tasks from PRD${config.research ? ' with research-backed analysis' : ''}...`,
|
|
'info'
|
|
);
|
|
|
|
const aiServiceResponse = await generateObjectService({
|
|
role: config.research ? 'research' : 'main',
|
|
session: config.session,
|
|
projectRoot: config.projectRoot,
|
|
schema: prdResponseSchema,
|
|
objectName: 'tasks_data',
|
|
systemPrompt,
|
|
prompt: userPrompt,
|
|
commandName: 'parse-prd',
|
|
outputType: config.isMCP ? 'mcp' : 'cli'
|
|
});
|
|
|
|
// Extract generated data
|
|
let generatedData = null;
|
|
if (aiServiceResponse?.mainResult) {
|
|
if (
|
|
typeof aiServiceResponse.mainResult === 'object' &&
|
|
aiServiceResponse.mainResult !== null &&
|
|
'tasks' in aiServiceResponse.mainResult
|
|
) {
|
|
generatedData = aiServiceResponse.mainResult;
|
|
} else if (
|
|
typeof aiServiceResponse.mainResult.object === 'object' &&
|
|
aiServiceResponse.mainResult.object !== null &&
|
|
'tasks' in aiServiceResponse.mainResult.object
|
|
) {
|
|
generatedData = aiServiceResponse.mainResult.object;
|
|
}
|
|
}
|
|
|
|
if (!generatedData || !Array.isArray(generatedData.tasks)) {
|
|
throw new Error(
|
|
'AI service returned unexpected data structure after validation.'
|
|
);
|
|
}
|
|
|
|
if (spinner) {
|
|
spinner.succeed('Tasks generated successfully!');
|
|
}
|
|
|
|
return {
|
|
parsedTasks: generatedData.tasks,
|
|
aiServiceResponse,
|
|
estimatedInputTokens
|
|
};
|
|
} catch (error) {
|
|
if (spinner) {
|
|
spinner.fail(`Error parsing PRD: ${error.message}`);
|
|
}
|
|
throw error;
|
|
}
|
|
}
|