fix: 修复 Plan 模式转 Agent 模式的递归执行问题

- 删除 pendingPlanExecution 自动执行机制,避免任务重复执行
- planAction confirm 只做 UI 切换,后端 LLM 在同一对话中执行
- planAction modify/cancel 调用 handlePlanAction 处理
- submitAnswer 改为 void 明确不等待
This commit is contained in:
XiaoFeng
2026-01-12 16:01:21 +08:00
parent a1e88d473b
commit 1231ef0892
2 changed files with 11 additions and 79 deletions

View File

@ -10,7 +10,6 @@ import {
handleUserAnswer, handleUserAnswer,
abortCurrentDialog, abortCurrentDialog,
handlePlanAction, handlePlanAction,
setPendingPlanExecution,
getCurrentTaskId, getCurrentTaskId,
setLastTaskId, setLastTaskId,
} from "../utils/messageHandler"; } from "../utils/messageHandler";
@ -282,7 +281,7 @@ export async function showICHelperPanel(
break; break;
// 新增:处理用户回答 // 新增:处理用户回答
case "submitAnswer": case "submitAnswer":
handleUserAnswer( void handleUserAnswer(
message.askId, message.askId,
message.selected, message.selected,
message.customInput message.customInput
@ -328,27 +327,20 @@ export async function showICHelperPanel(
// 处理计划操作(只做模式切换,响应已通过 submitAnswer 发送) // 处理计划操作(只做模式切换,响应已通过 submitAnswer 发送)
case "planAction": case "planAction":
if (message.action === "confirm") { if (message.action === "confirm") {
// 确认执行:切换到 Agent 模式 // 确认执行:切换到 Agent 模式UI 切换)
panel.webview.postMessage({ panel.webview.postMessage({
command: "switchMode", command: "switchMode",
mode: "agent", mode: "agent",
}); });
// 获取当前会话的 taskId用于复用知识图谱数据 // 注意:不再设置待执行计划;后端 LLM 会在同一对话中自动执行计划
const taskId = getCurrentTaskId(); } else if (message.action === "modify" || message.action === "cancel") {
if (taskId) { void handlePlanAction(
// 设置待执行的计划,对话结束后自动执行(复用 taskId
setPendingPlanExecution(
panel, panel,
message.planTitle || "计划", message.action,
message.planTitle || "",
context.extensionPath, context.extensionPath,
taskId, message.model
message.model // 传递服务等级
); );
} else {
console.warn(
"[ICHelperPanel] 无法获取当前 taskId知识图谱数据可能丢失"
);
}
} }
break; break;
// 添加文件上下文 - 显示工作区文件列表 // 添加文件上下文 - 显示工作区文件列表

View File

@ -31,29 +31,6 @@ let currentSession: DialogSession | null = null;
/** 最后一个活跃的 taskId用于压缩等操作 */ /** 最后一个活跃的 taskId用于压缩等操作 */
let lastTaskId: string | null = null; let lastTaskId: string | null = null;
/** 待执行的计划Plan 模式确认后自动执行) */
let pendingPlanExecution: {
panel: vscode.WebviewPanel;
planTitle: string;
extensionPath: string;
taskId: string; // 保存 taskId 以便复用
serviceTier?: ServiceTier; // 保存服务等级
} | null = null;
/**
* 设置待执行的计划(由 ICHelperPanel 调用)
*/
export function setPendingPlanExecution(
panel: vscode.WebviewPanel,
planTitle: string,
extensionPath: string,
taskId: string,
serviceTier?: ServiceTier
): void {
pendingPlanExecution = { panel, planTitle, extensionPath, taskId, serviceTier };
console.log("[MessageHandler] 设置待执行计划:", planTitle, "taskId:", taskId, "serviceTier:", serviceTier);
}
/** /**
* 处理用户消息 * 处理用户消息
*/ */
@ -244,43 +221,6 @@ async function handleUserMessageWithBackend(
console.warn("保存AI响应历史失败:", error); console.warn("保存AI响应历史失败:", error);
} }
// 检查是否有待执行的计划Plan 模式确认后自动执行)
if (pendingPlanExecution) {
const {
panel: execPanel,
planTitle,
extensionPath: execPath,
taskId: reuseTaskId,
serviceTier: savedServiceTier,
} = pendingPlanExecution;
pendingPlanExecution = null;
console.log(
"[MessageHandler] 自动执行计划:",
planTitle,
"复用 taskId:",
reuseTaskId,
"serviceTier:",
savedServiceTier
);
// 延迟一小段时间确保当前对话完全结束
setTimeout(async () => {
try {
// 复用 taskId 创建新会话,确保知识图谱数据不丢失
await handleUserMessageWithBackend(
execPanel,
`请按照刚才的计划执行:${planTitle}`,
execPath,
"agent",
reuseTaskId, // 复用 Plan 模式的 taskId
savedServiceTier // 传递保存的服务等级
);
} catch (err) {
console.error("[MessageHandler] 自动执行计划失败:", err);
}
}, 500);
}
resolve(); resolve();
}, },