Merge branch 'feat/back-to-front' into feat/plugin-front-end

This commit is contained in:
Roe-xin
2025-12-30 20:46:26 +08:00
12 changed files with 756 additions and 54 deletions

View File

@ -19,19 +19,43 @@ import { dialogManager, DialogSession } from "../services/dialogService";
import { userInteractionManager } from "../services/userInteraction";
import { healthCheck } from "../services/apiClient";
import type { RunMode } from '../types/api';
/** 是否使用后端服务(可通过配置控制) */
let useBackendService = true;
/** 当前对话会话 */
let currentSession: DialogSession | null = null;
/** 待执行的计划Plan 模式确认后自动执行) */
let pendingPlanExecution: {
panel: vscode.WebviewPanel;
planTitle: string;
extensionPath: string;
taskId: string; // 保存 taskId 以便复用
} | null = null;
/**
* 设置待执行的计划(由 ICHelperPanel 调用)
*/
export function setPendingPlanExecution(
panel: vscode.WebviewPanel,
planTitle: string,
extensionPath: string,
taskId: string
): void {
pendingPlanExecution = { panel, planTitle, extensionPath, taskId };
console.log('[MessageHandler] 设置待执行计划:', planTitle, 'taskId:', taskId);
}
/**
* 处理用户消息
*/
export async function handleUserMessage(
panel: vscode.WebviewPanel,
text: string,
extensionPath?: string
extensionPath?: string,
mode?: RunMode
) {
console.log("收到用户消息:", text);
@ -63,7 +87,7 @@ export async function handleUserMessage(
// 尝试使用后端服务
if (useBackendService && extensionPath) {
try {
await handleUserMessageWithBackend(panel, text, extensionPath);
await handleUserMessageWithBackend(panel, text, extensionPath, mode);
return;
} catch (error) {
console.error("后端服务不可用,回退到本地模式:", error);
@ -97,11 +121,16 @@ export async function handleUserMessage(
async function handleUserMessageWithBackend(
panel: vscode.WebviewPanel,
text: string,
extensionPath: string
extensionPath: string,
mode?: RunMode,
reuseTaskId?: string // 可选,复用现有 taskId用于 Plan 模式确认后继续执行)
): Promise<void> {
// 创建或复用会话
if (!currentSession || !currentSession.active) {
currentSession = dialogManager.createSession(extensionPath);
currentSession = dialogManager.createSession(extensionPath, reuseTaskId);
if (reuseTaskId) {
console.log('[MessageHandler] 复用 taskId 创建会话:', reuseTaskId);
}
}
const historyManager = ChatHistoryManager.getInstance();
@ -184,6 +213,29 @@ async function handleUserMessageWithBackend(
console.warn("保存AI响应历史失败:", error);
}
// 检查是否有待执行的计划Plan 模式确认后自动执行)
if (pendingPlanExecution) {
const { panel: execPanel, planTitle, extensionPath: execPath, taskId: reuseTaskId } = pendingPlanExecution;
pendingPlanExecution = null;
console.log('[MessageHandler] 自动执行计划:', planTitle, '复用 taskId:', reuseTaskId);
// 延迟一小段时间确保当前对话完全结束
setTimeout(async () => {
try {
// 复用 taskId 创建新会话,确保知识图谱数据不丢失
await handleUserMessageWithBackend(
execPanel,
`请按照刚才的计划执行:${planTitle}`,
execPath,
'agent',
reuseTaskId // 复用 Plan 模式的 taskId
);
} catch (err) {
console.error('[MessageHandler] 自动执行计划失败:', err);
}
}, 500);
}
resolve();
},
@ -201,7 +253,7 @@ async function handleUserMessageWithBackend(
onNotification: (message) => {
vscode.window.showInformationMessage(message);
},
});
}, mode);
});
}
@ -226,6 +278,75 @@ export function abortCurrentDialog(): void {
currentSession = null;
}
/**
* 获取当前会话的 taskId
*/
export function getCurrentTaskId(): string | null {
return currentSession?.getTaskId() || null;
}
/**
* 处理计划操作Plan 模式)
* @param panel WebView 面板
* @param action 操作类型confirm/modify/cancel
* @param planTitle 计划标题
* @param extensionPath 扩展路径
*/
export async function handlePlanAction(
panel: vscode.WebviewPanel,
action: string,
planTitle: string,
extensionPath: string
): Promise<void> {
console.log('[handlePlanAction] action:', action, 'planTitle:', planTitle);
switch (action) {
case 'confirm':
// 确认执行:切换到 Agent 模式并发送执行消息
panel.webview.postMessage({
command: 'switchMode',
mode: 'agent'
});
// 发送执行消息
await handleUserMessage(
panel,
`请按照刚才的计划执行:${planTitle}`,
extensionPath,
'agent'
);
break;
case 'modify':
// 修改计划:提示用户输入修改建议
const modification = await vscode.window.showInputBox({
prompt: '请输入您对计划的修改建议',
placeHolder: '例如第2步需要先检查文件是否存在...',
ignoreFocusOut: true
});
if (modification) {
await handleUserMessage(
panel,
`请根据以下建议修改计划:${modification}`,
extensionPath,
'plan'
);
}
break;
case 'cancel':
// 取消计划:通知用户
panel.webview.postMessage({
command: 'addMessage',
text: '计划已取消。',
sender: 'bot'
});
break;
default:
console.warn('[handlePlanAction] 未知操作:', action);
}
}
/**
* 解析文件操作命令
*/