79 lines
3.0 KiB
JavaScript
Raw Normal View History

// ═══════════════════════════════════════
// 铸渊开发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 };