79 lines
3.0 KiB
JavaScript
79 lines
3.0 KiB
JavaScript
// ═══════════════════════════════════════
|
||
// 铸渊开发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 };
|