Merge branch 'feat/back-to-front' into feat/plugin-front-end
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析文件操作命令
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user