mirror of
https://github.com/cjo4m06/mcp-shrimp-task-manager.git
synced 2025-07-27 00:12:26 +08:00
更新功能清單,調整任務更新模式參數為可選,新增三種更新模式:追加、覆蓋及選擇性更新,並在相關工具中更新描述與邏輯,提升任務管理的靈活性與準確性。
This commit is contained in:
parent
ef092eb45e
commit
1637573662
@ -129,7 +129,10 @@
|
|||||||
|
|
||||||
**參數**:
|
**參數**:
|
||||||
|
|
||||||
- `isOverwrite: boolean` (必填) - 任務覆蓋模式選擇(true:清除並覆蓋所有現有任務;false:保留現有任務並新增)
|
- `updateMode?: "append" | "overwrite" | "selective"` (選填) - 任務更新模式選擇:
|
||||||
|
- `append`(預設):保留所有現有任務並添加新任務
|
||||||
|
- `overwrite`:清除所有未完成任務並完全替換
|
||||||
|
- `selective`:根據任務名稱匹配更新現有任務,保留不在列表中的任務
|
||||||
- `tasks: Array<object>` (必填) - 結構化的任務清單,每個任務應保持原子性且有明確的完成標準
|
- `tasks: Array<object>` (必填) - 結構化的任務清單,每個任務應保持原子性且有明確的完成標準
|
||||||
- `name: string` (必填) - 簡潔明確的任務名稱,應能清晰表達任務目的
|
- `name: string` (必填) - 簡潔明確的任務名稱,應能清晰表達任務目的
|
||||||
- 不超過 100 個字符
|
- 不超過 100 個字符
|
||||||
|
16
src/index.ts
16
src/index.ts
@ -51,7 +51,7 @@ async function main() {
|
|||||||
// 註冊工具 - 使用已定義的schema物件,並添加內嵌錯誤處理
|
// 註冊工具 - 使用已定義的schema物件,並添加內嵌錯誤處理
|
||||||
server.tool(
|
server.tool(
|
||||||
"plan_task",
|
"plan_task",
|
||||||
"初始化並詳細規劃任務流程,建立明確的目標與成功標準",
|
"初始化並詳細規劃任務流程,建立明確的目標與成功標準,可選擇參考現有任務進行延續規劃",
|
||||||
{
|
{
|
||||||
description: z
|
description: z
|
||||||
.string()
|
.string()
|
||||||
@ -64,6 +64,11 @@ async function main() {
|
|||||||
.string()
|
.string()
|
||||||
.optional()
|
.optional()
|
||||||
.describe("任務的特定技術要求、業務約束條件或品質標準(選填)"),
|
.describe("任務的特定技術要求、業務約束條件或品質標準(選填)"),
|
||||||
|
existingTasksReference: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
|
.describe("是否參考現有任務作為規劃基礎,用於任務調整和延續性規劃"),
|
||||||
},
|
},
|
||||||
async (args) => {
|
async (args) => {
|
||||||
return await planTask(args);
|
return await planTask(args);
|
||||||
@ -128,12 +133,13 @@ async function main() {
|
|||||||
|
|
||||||
server.tool(
|
server.tool(
|
||||||
"split_tasks",
|
"split_tasks",
|
||||||
"將複雜任務分解為獨立且可追蹤的子任務,建立明確的依賴關係和優先順序,dependencies 是一個字串陣列,支援任務名稱或任務ID(UUID)",
|
"將複雜任務分解為獨立且可追蹤的子任務,建立明確的依賴關係和優先順序。支援三種任務更新模式:追加(append)、覆蓋(overwrite)和選擇性更新(selective),其中覆蓋模式只會刪除未完成的任務並保留已完成任務,選擇性更新模式可根據任務名稱智能匹配更新現有任務,同時保留其他任務。",
|
||||||
{
|
{
|
||||||
isOverwrite: z
|
updateMode: z
|
||||||
.boolean()
|
.enum(["append", "overwrite", "selective"])
|
||||||
|
.optional()
|
||||||
.describe(
|
.describe(
|
||||||
"任務覆蓋模式選擇(true:清除並覆蓋所有現有任務;false:保留現有任務並新增)"
|
"任務更新模式選擇:'append'(保留所有現有任務並添加新任務)、'overwrite'(清除所有未完成任務並完全替換,保留已完成任務)、'selective'(智能更新:根據任務名稱匹配更新現有任務,保留不在列表中的任務,推薦用於任務微調)"
|
||||||
),
|
),
|
||||||
tasks: z
|
tasks: z
|
||||||
.array(
|
.array(
|
||||||
|
@ -263,37 +263,94 @@ export async function batchCreateOrUpdateTasks(
|
|||||||
dependencies?: string[];
|
dependencies?: string[];
|
||||||
relatedFiles?: RelatedFile[];
|
relatedFiles?: RelatedFile[];
|
||||||
}>,
|
}>,
|
||||||
isOverwrite: boolean
|
updateMode: "append" | "overwrite" | "selective"
|
||||||
): Promise<Task[]> {
|
): Promise<Task[]> {
|
||||||
// 獲取現有任務,建立名稱到ID的映射
|
// 獲取現有任務
|
||||||
const existingTasks = isOverwrite ? [] : await readTasks();
|
const existingTasks = await readTasks();
|
||||||
const nameToIdMap = new Map<string, string>();
|
const nameToIdMap = new Map<string, string>();
|
||||||
|
const idToTaskMap = new Map<string, Task>();
|
||||||
|
|
||||||
// 添加現有任務到映射表
|
// 添加現有任務到映射表
|
||||||
existingTasks.forEach((task) => {
|
existingTasks.forEach((task) => {
|
||||||
nameToIdMap.set(task.name, task.id);
|
nameToIdMap.set(task.name, task.id);
|
||||||
|
idToTaskMap.set(task.id, task);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (isOverwrite) {
|
// 處理不同的更新模式
|
||||||
// 覆蓋模式:刪除所有現有任務
|
if (updateMode === "overwrite") {
|
||||||
await writeTasks([]);
|
// 覆蓋模式:只刪除未完成的任務,保留已完成的任務
|
||||||
|
const completedTasks = existingTasks.filter(
|
||||||
|
(task) => task.status === TaskStatus.COMPLETED
|
||||||
|
);
|
||||||
|
await writeTasks(completedTasks);
|
||||||
|
|
||||||
|
// 更新映射表,只保留已完成的任務
|
||||||
|
nameToIdMap.clear();
|
||||||
|
idToTaskMap.clear();
|
||||||
|
completedTasks.forEach((task) => {
|
||||||
|
nameToIdMap.set(task.name, task.id);
|
||||||
|
idToTaskMap.set(task.id, task);
|
||||||
|
});
|
||||||
|
} else if (updateMode === "selective") {
|
||||||
|
// selective 模式:保留未在清單中的現有任務,更新名稱匹配的任務
|
||||||
|
// 不做任何預處理,保留所有現有任務,在處理每個新任務時進行選擇性更新
|
||||||
|
} else {
|
||||||
|
// append 模式:保留所有現有任務,不需要特殊處理
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第一階段:創建所有任務,但不設置依賴
|
// 創建任務名稱集合,用於選擇性更新模式
|
||||||
|
const taskNameSet = new Set(taskDataList.map((task) => task.name));
|
||||||
|
|
||||||
|
// 準備最終的任務清單,如果是 selective 模式,先保留不在新清單中的任務
|
||||||
|
let finalTaskList: Task[] = [];
|
||||||
|
if (updateMode === "selective") {
|
||||||
|
finalTaskList = existingTasks.filter((task) => !taskNameSet.has(task.name));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 第一階段:創建或更新任務,但不設置依賴
|
||||||
const firstPassTasks: Array<{ task: Task; originalDeps: string[] }> = [];
|
const firstPassTasks: Array<{ task: Task; originalDeps: string[] }> = [];
|
||||||
|
|
||||||
for (const taskData of taskDataList) {
|
for (const taskData of taskDataList) {
|
||||||
// 創建任務,暫時不設置依賴
|
let newTask: Task;
|
||||||
const newTask = await createTask(
|
|
||||||
taskData.name,
|
// 查找是否存在同名任務
|
||||||
taskData.description,
|
const existingTaskId = nameToIdMap.get(taskData.name);
|
||||||
taskData.notes,
|
const isExistingTask = existingTaskId !== undefined;
|
||||||
[], // 空依賴列表
|
|
||||||
taskData.relatedFiles // 添加關聯檔案
|
if (isExistingTask && updateMode === "selective") {
|
||||||
);
|
// 選擇性更新模式:更新現有任務
|
||||||
|
const existingTask = idToTaskMap.get(existingTaskId)!;
|
||||||
|
|
||||||
|
// 更新任務內容但保留原始ID和創建時間
|
||||||
|
newTask = (await updateTask(existingTaskId, {
|
||||||
|
name: taskData.name,
|
||||||
|
description: taskData.description,
|
||||||
|
notes: taskData.notes,
|
||||||
|
// 暫時不更新依賴,在第二階段處理
|
||||||
|
relatedFiles: taskData.relatedFiles,
|
||||||
|
})) as Task;
|
||||||
|
|
||||||
|
// 如果更新失敗,使用現有任務作為後備
|
||||||
|
if (!newTask) {
|
||||||
|
console.warn(
|
||||||
|
`警告:更新任務 "${taskData.name}" 失敗,使用現有任務作為後備`
|
||||||
|
);
|
||||||
|
newTask = existingTask;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 創建新任務
|
||||||
|
newTask = await createTask(
|
||||||
|
taskData.name,
|
||||||
|
taskData.description,
|
||||||
|
taskData.notes,
|
||||||
|
[], // 空依賴列表,在第二階段設置
|
||||||
|
taskData.relatedFiles
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// 將新任務添加到映射表
|
// 將新任務添加到映射表
|
||||||
nameToIdMap.set(newTask.name, newTask.id);
|
nameToIdMap.set(newTask.name, newTask.id);
|
||||||
|
idToTaskMap.set(newTask.id, newTask);
|
||||||
|
|
||||||
// 保存原始依賴信息
|
// 保存原始依賴信息
|
||||||
firstPassTasks.push({
|
firstPassTasks.push({
|
||||||
@ -302,8 +359,8 @@ export async function batchCreateOrUpdateTasks(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 第二階段:更新所有任務的依賴關係
|
// 第二階段:更新所有新增或修改任務的依賴關係
|
||||||
const finalTasks: Task[] = [];
|
const processedTasks: Task[] = [];
|
||||||
|
|
||||||
for (const { task, originalDeps } of firstPassTasks) {
|
for (const { task, originalDeps } of firstPassTasks) {
|
||||||
// 解析依賴關係
|
// 解析依賴關係
|
||||||
@ -337,13 +394,18 @@ export async function batchCreateOrUpdateTasks(
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (updatedTask) {
|
if (updatedTask) {
|
||||||
finalTasks.push(updatedTask);
|
processedTasks.push(updatedTask);
|
||||||
} else {
|
} else {
|
||||||
finalTasks.push(task); // 回退到原始任務
|
processedTasks.push(task); // 回退到原始任務
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return finalTasks;
|
// 如果是選擇性更新模式,合併保留的任務和新建/更新的任務
|
||||||
|
if (updateMode === "selective") {
|
||||||
|
return [...finalTaskList, ...processedTasks];
|
||||||
|
}
|
||||||
|
|
||||||
|
return processedTasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 檢查任務是否可以執行(所有依賴都已完成)
|
// 檢查任務是否可以執行(所有依賴都已完成)
|
||||||
|
@ -31,6 +31,35 @@ import {
|
|||||||
} from "../utils/summaryExtractor.js";
|
} from "../utils/summaryExtractor.js";
|
||||||
import { loadTaskRelatedFiles } from "../utils/fileLoader.js";
|
import { loadTaskRelatedFiles } from "../utils/fileLoader.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 將任務狀態轉換為更友好的顯示文字
|
||||||
|
*/
|
||||||
|
function getTaskStatusDisplay(status: TaskStatus): string {
|
||||||
|
switch (status) {
|
||||||
|
case TaskStatus.PENDING:
|
||||||
|
return "待處理";
|
||||||
|
case TaskStatus.IN_PROGRESS:
|
||||||
|
return "進行中";
|
||||||
|
case TaskStatus.COMPLETED:
|
||||||
|
return "已完成";
|
||||||
|
default:
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化日期為更友好的顯示格式
|
||||||
|
*/
|
||||||
|
function formatDate(date: Date): string {
|
||||||
|
return date.toLocaleString("zh-TW", {
|
||||||
|
year: "numeric",
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 開始規劃工具
|
// 開始規劃工具
|
||||||
export const planTaskSchema = z.object({
|
export const planTaskSchema = z.object({
|
||||||
description: z
|
description: z
|
||||||
@ -43,11 +72,17 @@ export const planTaskSchema = z.object({
|
|||||||
.string()
|
.string()
|
||||||
.optional()
|
.optional()
|
||||||
.describe("任務的特定技術要求、業務約束條件或品質標準(選填)"),
|
.describe("任務的特定技術要求、業務約束條件或品質標準(選填)"),
|
||||||
|
existingTasksReference: z
|
||||||
|
.boolean()
|
||||||
|
.optional()
|
||||||
|
.default(false)
|
||||||
|
.describe("是否參考現有任務作為規劃基礎,用於任務調整和延續性規劃"),
|
||||||
});
|
});
|
||||||
|
|
||||||
export async function planTask({
|
export async function planTask({
|
||||||
description,
|
description,
|
||||||
requirements,
|
requirements,
|
||||||
|
existingTasksReference = false,
|
||||||
}: z.infer<typeof planTaskSchema>) {
|
}: z.infer<typeof planTaskSchema>) {
|
||||||
// 記錄任務規劃開始
|
// 記錄任務規劃開始
|
||||||
try {
|
try {
|
||||||
@ -69,6 +104,132 @@ export async function planTask({
|
|||||||
prompt += `## 附加要求與限制條件\n\n請確保方案完全符合以下要求:\n\n\`\`\`\n${requirements}\n\`\`\`\n\n`;
|
prompt += `## 附加要求與限制條件\n\n請確保方案完全符合以下要求:\n\n\`\`\`\n${requirements}\n\`\`\`\n\n`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 當 existingTasksReference 為 true 時,從數據庫中載入所有任務作為參考
|
||||||
|
if (existingTasksReference) {
|
||||||
|
try {
|
||||||
|
const allTasks = await getAllTasks();
|
||||||
|
|
||||||
|
// 將任務分為已完成和未完成兩類
|
||||||
|
const completedTasks = allTasks.filter(
|
||||||
|
(task) => task.status === TaskStatus.COMPLETED
|
||||||
|
);
|
||||||
|
const pendingTasks = allTasks.filter(
|
||||||
|
(task) => task.status !== TaskStatus.COMPLETED
|
||||||
|
);
|
||||||
|
|
||||||
|
// 如果存在任務,則添加到提示詞中
|
||||||
|
if (allTasks.length > 0) {
|
||||||
|
prompt += `## 現有任務參考\n\n您正在對現有任務進行調整或延續規劃。以下任務資訊將作為您分析和規劃的基礎:\n\n`;
|
||||||
|
|
||||||
|
// 添加已完成任務的參考
|
||||||
|
if (completedTasks.length > 0) {
|
||||||
|
prompt += `### 已完成的任務(僅供參考,不可修改)\n\n`;
|
||||||
|
prompt += `以下任務已標記為完成,作為系統穩定功能的基石和固定參考點:\n\n`;
|
||||||
|
|
||||||
|
// 最多顯示10個已完成任務,避免提示詞過長
|
||||||
|
const tasksToShow =
|
||||||
|
completedTasks.length > 10
|
||||||
|
? completedTasks.slice(0, 10)
|
||||||
|
: completedTasks;
|
||||||
|
|
||||||
|
tasksToShow.forEach((task, index) => {
|
||||||
|
// 使用摘要提取工具處理較長的描述
|
||||||
|
const taskDescriptionSummary = extractSummary(
|
||||||
|
task.description,
|
||||||
|
100
|
||||||
|
);
|
||||||
|
prompt += `${index + 1}. **${task.name}** (ID: \`${task.id}\`)\n`;
|
||||||
|
prompt += ` - 描述:${taskDescriptionSummary}\n`;
|
||||||
|
if (task.completedAt) {
|
||||||
|
prompt += ` - 完成時間:${formatDate(task.completedAt)}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < tasksToShow.length - 1) {
|
||||||
|
prompt += `\n`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (completedTasks.length > 10) {
|
||||||
|
prompt += `\n*(僅顯示前10個已完成任務,實際共有 ${completedTasks.length} 個已完成任務)*\n`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加未完成任務的參考
|
||||||
|
if (pendingTasks.length > 0) {
|
||||||
|
prompt += `\n### 未完成的任務(可根據需要調整)\n\n`;
|
||||||
|
prompt += `以下任務尚未完成,您可以根據新需求對其進行調整或重新規劃:\n\n`;
|
||||||
|
|
||||||
|
pendingTasks.forEach((task, index) => {
|
||||||
|
// 使用摘要提取工具處理較長的描述
|
||||||
|
const taskDescriptionSummary = extractSummary(
|
||||||
|
task.description,
|
||||||
|
150
|
||||||
|
);
|
||||||
|
prompt += `${index + 1}. **${task.name}** (ID: \`${task.id}\`)\n`;
|
||||||
|
prompt += ` - 描述:${taskDescriptionSummary}\n`;
|
||||||
|
prompt += ` - 狀態:${getTaskStatusDisplay(task.status)}\n`;
|
||||||
|
|
||||||
|
// 如果有依賴關係,也顯示出來
|
||||||
|
if (task.dependencies && task.dependencies.length > 0) {
|
||||||
|
prompt += ` - 依賴:${task.dependencies
|
||||||
|
.map((dep) => `\`${dep.taskId}\``)
|
||||||
|
.join(", ")}\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index < pendingTasks.length - 1) {
|
||||||
|
prompt += `\n`;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
prompt += `\n## 任務調整指南\n\n`;
|
||||||
|
prompt += `規劃新任務或調整現有任務時,請嚴格遵循以下五項原則:\n\n`;
|
||||||
|
prompt += `1. **已完成任務保護原則** - 已完成的任務是系統穩定功能的基石,絕對不可修改或刪除。\n`;
|
||||||
|
prompt += `2. **未完成任務可調整原則** - 未完成的任務可以根據新需求進行調整,包括修改描述、依賴關係等,或建議移除。\n`;
|
||||||
|
prompt += `3. **任務ID一致性原則** - 引用現有任務時必須使用其原始ID,以確保系統跟踪的準確性。\n`;
|
||||||
|
prompt += `4. **依賴關係完整性原則** - 調整任務計劃時必須維護依賴關係的完整性:\n`;
|
||||||
|
prompt += ` - 不創建循環依賴\n`;
|
||||||
|
prompt += ` - 不依賴已標記為移除的任務\n`;
|
||||||
|
prompt += ` - 確保新增依賴關係合理且必要\n`;
|
||||||
|
prompt += `5. **任務延續性原則** - 新任務應與現有任務構成連貫整體,維持整體計劃的邏輯性和可行性。\n\n`;
|
||||||
|
prompt += `**重要提醒:** 系統強制執行已完成任務保護機制,無法修改已完成的任務。請在規劃階段充分考慮這一限制。\n\n`;
|
||||||
|
|
||||||
|
// 添加選擇性任務更新模式指導
|
||||||
|
prompt += `## 選擇性任務更新指南\n\n`;
|
||||||
|
prompt += `任務更新時,您可以選擇以下三種更新模式,每種模式適用於不同的場景:\n\n`;
|
||||||
|
prompt += `### 1. **追加模式(append)**\n`;
|
||||||
|
prompt += `- **說明**:保留所有現有任務,僅添加新任務\n`;
|
||||||
|
prompt += `- **適用場景**:逐步擴展功能,添加獨立的新特性,現有任務計劃仍然有效\n`;
|
||||||
|
prompt += `- **使用方式**:split_tasks 工具中設置 \`updateMode="append"\`\n`;
|
||||||
|
prompt += `- **潛在問題**:長期使用可能導致積累過多已不再相關但未完成的任務\n\n`;
|
||||||
|
|
||||||
|
prompt += `### 2. **覆蓋模式(overwrite)**\n`;
|
||||||
|
prompt += `- **說明**:清除所有現有未完成任務,完全使用新任務列表替換\n`;
|
||||||
|
prompt += `- **適用場景**:徹底變更方向,現有未完成任務已完全不相關\n`;
|
||||||
|
prompt += `- **使用方式**:split_tasks 工具中設置 \`updateMode="overwrite"\`\n`;
|
||||||
|
prompt += `- **潛在問題**:可能會丟失有價值的未完成任務,需要確保所有重要任務都在新列表中\n\n`;
|
||||||
|
|
||||||
|
prompt += `### 3. **選擇性更新模式(selective)**\n`;
|
||||||
|
prompt += `- **說明**:根據任務名稱匹配選擇性地更新任務,保留不在列表中的現有任務\n`;
|
||||||
|
prompt += `- **適用場景**:部分調整任務計劃,保留部分未完成任務,更新或添加其他任務\n`;
|
||||||
|
prompt += `- **使用方式**:split_tasks 工具中設置 \`updateMode="selective"\`\n`;
|
||||||
|
prompt += `- **工作原理**:\n`;
|
||||||
|
prompt += ` 1. 對於名稱相同的任務,更新其內容(描述、注釋等),保留原ID和創建時間\n`;
|
||||||
|
prompt += ` 2. 新任務名稱的條目將被創建為新任務\n`;
|
||||||
|
prompt += ` 3. 不在提交列表中的現有任務將被保留不變\n`;
|
||||||
|
prompt += `- **最佳實踐**:在需要微調部分任務時優先選擇此模式,既避免重建所有任務,又能保持計劃的連續性\n\n`;
|
||||||
|
|
||||||
|
prompt += `### 實際應用建議\n`;
|
||||||
|
prompt += `- 對於小範圍調整,優先使用 **selective** 模式,精確更新目標任務\n`;
|
||||||
|
prompt += `- 需要添加新功能時,可使用 **append** 模式保留現有工作\n`;
|
||||||
|
prompt += `- 僅在徹底重構計劃時使用 **overwrite** 模式,謹慎權衡是否真正需要刪除所有未完成任務\n`;
|
||||||
|
prompt += `- 無論使用哪種模式,始終需要**維護依賴關係的完整性和正確性**\n\n`;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("載入現有任務時發生錯誤:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
prompt += `## 分析指引\n\n1. 首先確定任務的確切目標和預期成果
|
prompt += `## 分析指引\n\n1. 首先確定任務的確切目標和預期成果
|
||||||
2. 識別任務中可能的技術挑戰和關鍵決策點
|
2. 識別任務中可能的技術挑戰和關鍵決策點
|
||||||
3. 考慮潛在的解決方案和替代方案
|
3. 考慮潛在的解決方案和替代方案
|
||||||
@ -290,6 +451,11 @@ export async function reflectTask({
|
|||||||
- 建立明確的依賴關係和執行順序
|
- 建立明確的依賴關係和執行順序
|
||||||
- 為每個子任務設定明確的完成標準和驗收條件
|
- 為每個子任務設定明確的完成標準和驗收條件
|
||||||
|
|
||||||
|
## split_tasks 的 updateMode 選擇建議
|
||||||
|
- 若希望**保留所有現有任務並添加新任務**,使用 updateMode="append"
|
||||||
|
- 若希望**清除所有未完成任務**,但保留已完成任務,使用 updateMode="overwrite"
|
||||||
|
- 若希望**選擇性更新特定任務**,同時保留其他未完成任務,使用 updateMode="selective"
|
||||||
|
|
||||||
您的批判性評估將決定最終方案的質量,請務必嚴格審查,不放過任何潛在問題。`;
|
您的批判性評估將決定最終方案的質量,請務必嚴格審查,不放過任何潛在問題。`;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -305,10 +471,11 @@ export async function reflectTask({
|
|||||||
// 拆分任務工具
|
// 拆分任務工具
|
||||||
export const splitTasksSchema = z
|
export const splitTasksSchema = z
|
||||||
.object({
|
.object({
|
||||||
isOverwrite: z
|
updateMode: z
|
||||||
.boolean()
|
.enum(["append", "overwrite", "selective"])
|
||||||
|
.optional()
|
||||||
.describe(
|
.describe(
|
||||||
"任務覆蓋模式選擇(true:清除並覆蓋所有現有任務;false:保留現有任務並新增)"
|
"任務更新模式:'append'(保留現有任務並新增)、'overwrite'(清除所有未完成任務並重建)、'selective'(根據名稱匹配更新現有任務,保留其餘任務)"
|
||||||
),
|
),
|
||||||
tasks: z
|
tasks: z
|
||||||
.array(
|
.array(
|
||||||
@ -378,16 +545,28 @@ export const splitTasksSchema = z
|
|||||||
);
|
);
|
||||||
|
|
||||||
export async function splitTasks({
|
export async function splitTasks({
|
||||||
isOverwrite,
|
updateMode,
|
||||||
tasks,
|
tasks,
|
||||||
}: z.infer<typeof splitTasksSchema>) {
|
}: z.infer<typeof splitTasksSchema>) {
|
||||||
|
// 如果未指定更新模式,預設為 "append" 模式
|
||||||
|
const effectiveUpdateMode = updateMode || "append";
|
||||||
|
|
||||||
|
// 根據不同更新模式生成日誌訊息
|
||||||
|
let updateModeMessage = "";
|
||||||
|
if (effectiveUpdateMode === "append") {
|
||||||
|
updateModeMessage = "追加模式:保留現有任務並新增";
|
||||||
|
} else if (effectiveUpdateMode === "overwrite") {
|
||||||
|
updateModeMessage = "覆蓋模式:清除所有未完成任務並重建";
|
||||||
|
} else if (effectiveUpdateMode === "selective") {
|
||||||
|
updateModeMessage =
|
||||||
|
"選擇性更新模式:根據任務名稱更新現有任務、新增缺少任務,保留其餘任務";
|
||||||
|
}
|
||||||
|
|
||||||
// 記錄任務拆分
|
// 記錄任務拆分
|
||||||
try {
|
try {
|
||||||
await addConversationEntry(
|
await addConversationEntry(
|
||||||
ConversationParticipant.MCP,
|
ConversationParticipant.MCP,
|
||||||
`拆分任務:${isOverwrite ? "覆蓋模式" : "新增模式"},任務數量:${
|
`拆分任務:${updateModeMessage},任務數量:${tasks.length}`,
|
||||||
tasks.length
|
|
||||||
}`,
|
|
||||||
undefined,
|
undefined,
|
||||||
"任務拆分"
|
"任務拆分"
|
||||||
);
|
);
|
||||||
@ -395,8 +574,11 @@ export async function splitTasks({
|
|||||||
console.error("記錄對話日誌時發生錯誤:", error);
|
console.error("記錄對話日誌時發生錯誤:", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 批量創建任務
|
// 批量創建任務 - 將 updateMode 傳遞給 batchCreateOrUpdateTasks
|
||||||
const createdTasks = await batchCreateOrUpdateTasks(tasks, isOverwrite);
|
const createdTasks = await batchCreateOrUpdateTasks(
|
||||||
|
tasks,
|
||||||
|
effectiveUpdateMode
|
||||||
|
);
|
||||||
|
|
||||||
// 記錄任務創建成功
|
// 記錄任務創建成功
|
||||||
try {
|
try {
|
||||||
@ -414,11 +596,15 @@ export async function splitTasks({
|
|||||||
// 獲取所有任務,用於顯示完整的依賴關係
|
// 獲取所有任務,用於顯示完整的依賴關係
|
||||||
const allTasks = await getAllTasks();
|
const allTasks = await getAllTasks();
|
||||||
|
|
||||||
const prompt = `## 任務拆分結果 - ${
|
let prompt = `## 任務拆分結果 - ${effectiveUpdateMode} 模式\n\n### 系統確認\n任務已成功${
|
||||||
isOverwrite ? "覆蓋模式" : "新增模式"
|
effectiveUpdateMode === "overwrite"
|
||||||
}\n\n### 系統確認\n任務已成功${
|
? "覆蓋未完成的任務清單(已完成任務已保留)"
|
||||||
isOverwrite ? "覆蓋現有任務清單" : "新增至現有任務清單"
|
: effectiveUpdateMode === "selective"
|
||||||
}。\n\n## 任務拆分指南\n\n### 有效的任務拆分策略\n\n1. **按功能分解** - 將大功能拆分為獨立可測試的子功能
|
? "選擇性更新任務清單"
|
||||||
|
: "新增至現有任務清單"
|
||||||
|
}。\n\n`;
|
||||||
|
|
||||||
|
prompt += `## 任務拆分指南\n\n### 有效的任務拆分策略\n\n1. **按功能分解** - 將大功能拆分為獨立可測試的子功能
|
||||||
- 每個子功能應有清晰的輸入、輸出和功能邊界
|
- 每個子功能應有清晰的輸入、輸出和功能邊界
|
||||||
- 確保子功能間邏輯關係明確且最小化耦合
|
- 確保子功能間邏輯關係明確且最小化耦合
|
||||||
- 避免功能過度細分導致管理複雜度增加
|
- 避免功能過度細分導致管理複雜度增加
|
||||||
|
@ -65,7 +65,13 @@ export interface ReflectTaskArgs {
|
|||||||
|
|
||||||
// 拆分任務的參數:用於將大型任務分解為可管理的小型任務
|
// 拆分任務的參數:用於將大型任務分解為可管理的小型任務
|
||||||
export interface SplitTasksArgs {
|
export interface SplitTasksArgs {
|
||||||
isOverwrite: boolean; // 任務覆蓋模式選擇(true:清除並覆蓋所有現有任務;false:保留現有任務並新增)
|
/**
|
||||||
|
* 任務更新模式(可選):
|
||||||
|
* - "append":保留所有現有任務,新增提供的任務(預設值)
|
||||||
|
* - "overwrite":保留已完成的任務,但刪除所有未完成的任務,然後新增提供的任務
|
||||||
|
* - "selective":保留所有未提供名稱的現有任務,更新名稱匹配的任務
|
||||||
|
*/
|
||||||
|
updateMode?: "append" | "overwrite" | "selective";
|
||||||
tasks: Array<{
|
tasks: Array<{
|
||||||
name: string; // 簡潔明確的任務名稱,應能清晰表達任務目的
|
name: string; // 簡潔明確的任務名稱,應能清晰表達任務目的
|
||||||
description: string; // 詳細的任務描述,包含實施要點、技術細節和驗收標準
|
description: string; // 詳細的任務描述,包含實施要點、技術細節和驗收標準
|
||||||
|
Loading…
x
Reference in New Issue
Block a user