79 lines
3.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ═══════════════════════════════════════
// 铸渊开发Agent · 任务补全引擎
// 高层面规划 → LLM补全 → 详细可执行步骤
// ═══════════════════════════════════════
const fs = require("fs");
const path = require("path");
/**
* 补全单条高级任务为详细步骤
* @param {object} task - { id, action, description, context }
* @param {function} modelCaller - LLM 调用函数 (prompt) => string
* @returns {object} 补全后的任务
*/
async function expandTask(task, modelCaller) {
const prompt = [
"你是一个开发Agent的任务补全引擎。将高级描述补全为可执行的详细步骤。",
"",
"原任务:",
" ID: " + task.id,
" 动作: " + task.action,
" 描述: " + (task.description || "无"),
" 上下文: " + (task.context || "无"),
"",
"请严格基于以上原任务拆解。不要改变原任务的action/target/content。只补充detail、depends_on等元信息。如果原任务已经足够具体直接返回",
"[{\"step\":1,\"action\":\"write_file|run_cmd|call_api|check\",\"target\":\"文件路径或命令\",\"detail\":\"具体做什么\",\"depends_on\":null}]"
].join("\n");
try {
const raw = await modelCaller(prompt);
const jsonMatch = raw.match(/\[[\s\S]*\]/);
if (jsonMatch) {
const substeps = JSON.parse(jsonMatch[0]);
return { ...task, substeps, expanded: true, expanded_at: new Date().toISOString() };
}
} catch (e) {
console.warn("[Expander] LLM补全失败退化为单步模式: " + e.message);
}
// 退化LLM不可用时原任务本身就是一个步骤
return {
...task,
substeps: [{ step: 1, action: task.action, target: task.target || "", detail: task.description || "" }],
expanded: false,
expanded_at: new Date().toISOString()
};
}
/**
* 完整规划补全
* @param {object} plan - 完整规划 { plan_id, tasks[], ... }
* @param {function} modelCaller - LLM 调用函数
* @param {string} plansDir - 规划文件存储目录
*/
async function expandPlan(plan, modelCaller, plansDir) {
console.log("[Expander] 开始补全规划: " + plan.plan_id + " · " + plan.tasks.length + "个任务");
const expandedTasks = [];
for (let i = 0; i < plan.tasks.length; i++) {
const task = plan.tasks[i];
console.log("[Expander] 补全 " + (i + 1) + "/" + plan.tasks.length + ": " + task.id);
const expanded = await expandTask(task, modelCaller);
expandedTasks.push(expanded);
}
plan.tasks = expandedTasks;
plan._status = "expanded";
plan._expanded_at = new Date().toISOString();
// 写回规划文件
const planFile = path.join(plansDir, plan.plan_id + ".json");
fs.writeFileSync(planFile, JSON.stringify(plan, null, 2), "utf-8");
console.log("[Expander] 补全完成 · 共 " + expandedTasks.reduce((s, t) => s + (t.substeps?.length || 0), 0) + " 个子步骤");
return plan;
}
module.exports = { expandPlan, expandTask };