openai-compatible-task-master
Version:
使用MCP解析PRD文档并生成任务列表
129 lines (121 loc) • 5.83 kB
JavaScript
import { callOpenAIAPI, processDependencies, cleanJsonContent } from './llm_utils.js';
import chalk from 'chalk';
// 解析任务更新的JSON响应
export function parseTaskUpdateResponse(jsonContent) {
const cleanedContent = cleanJsonContent(jsonContent);
try {
// 尝试将内容解析为JSON
const tasks = JSON.parse(cleanedContent);
if (!Array.isArray(tasks)) {
throw new Error('JSON响应格式不正确,预期是任务数组');
}
// 验证和处理任务数据
return tasks.map((task, index) => {
if (!task || typeof task !== 'object') {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务不是对象`);
}
// 验证必要字段
if (!task.id && task.id !== 0) {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务缺少id`);
}
if (!task.title || typeof task.title !== 'string') {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务缺少title字符串`);
}
if (!task.description || typeof task.description !== 'string') {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务缺少description字符串`);
}
if (!task.details || typeof task.details !== 'string') {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务缺少details字符串`);
}
if (!task.testStrategy || typeof task.testStrategy !== 'string') {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务缺少testStrategy字符串`);
}
// 处理可选默认字段
const status = task.status || 'pending';
if (typeof status !== 'string') {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务的status不是字符串`);
}
// 验证状态值是否有效
if (!['pending', 'in-progress', 'done'].includes(String(status).toLowerCase())) {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务的status无效,必须是 'pending', 'in-progress', 'done' 之一`);
}
// 处理优先级字段
if (!task.priority || typeof task.priority !== 'string' ||
!['high', 'medium', 'low'].includes(String(task.priority).toLowerCase())) {
throw new Error(`任务更新响应格式不正确: 第${index + 1}个任务的priority无效,必须是 'high', 'medium', 'low' 之一`);
}
// 返回验证和规范化后的任务数据
return {
id: String(task.id), // 确保 id 始终是 string 类型
title: String(task.title),
description: String(task.description),
status: String(status).toLowerCase(),
dependencies: processDependencies(task.dependencies),
priority: String(task.priority).toLowerCase(),
details: String(task.details),
testStrategy: String(task.testStrategy),
};
});
}
catch (error) {
const err = error;
console.debug(chalk.blue("原始JSON内容:"), cleanedContent); // 记录清理后的JSON以供调试
throw new Error(`LLM返回的任务更新内容无法解析: ${err.message}`);
}
}
// 调用OpenAI Compatible API更新任务
export async function updateTasksWithLLM(tasks, prompt, metadata, openaiUrl, apiKey, model, streamMode) {
if (!apiKey) {
throw new Error('API密钥未提供,请使用 --api-key 参数提供有效的API密钥');
}
// 构建系统提示
const systemPrompt = `你是一个AI助手,负责根据新的上下文更新软件开发任务。
你将收到一组任务和描述更改或新实现细节的提示。
你的工作是更新任务以反映这些变化,同时保持任务的基本结构。
指南:
1. 除非提示中特别提及,否则保持相同的ID、状态和依赖关系
2. 更新标题、描述、实现细节和测试策略以反映新信息
3. 不要进行不必要的更改 - 只根据提示调整需要更改的内容
4. 你应该按顺序返回所有任务,而不仅仅是修改过的任务
5. 返回包含更新任务数组的完整有效JSON对象
提示中描述的更改应应用于列表中的所有任务。
任务格式要求:
{
"id": "字符串形式的ID(如 '1' 或 '1.2')",
"title": "标题",
"description": "描述",
"status": "pending|in-progress|done",
"dependencies": [依赖任务ID数组,如 ["1", "2"],若无依赖则为空数组 []],
"priority": "high|medium|low",
"details": "实现细节",
"testStrategy": "验证方法"
}
重要: 你的回复必须仅包含有效的JSON数组,不要添加任何额外的解释、评论或代码块标记。必须使用简体中文回复。`;
// 构建请求体
const messages = [
{
role: 'system',
content: systemPrompt,
},
{
role: 'user',
content: `这是需要更新的任务列表和更新提示:
任务列表:
${JSON.stringify(tasks, null, 2)}
项目信息:
${JSON.stringify(metadata, null, 2)}
更新提示:
${prompt}
请根据上述提示更新任务信息。`,
},
];
try {
const jsonContent = await callOpenAIAPI(messages, openaiUrl, apiKey, model, streamMode);
return parseTaskUpdateResponse(jsonContent);
}
catch (error) {
const err = error;
throw new Error(`更新任务失败: ${err.message}`);
}
}
//# sourceMappingURL=llm_update_tasks.js.map