feat:修复多面板任务管理和历史会话加载问题
主要改进: 1. 修复面板ID唯一性问题,为每个面板生成唯一ID 2. 修改任务创建时机,改为首次发送消息时创建 3. 修复面板任务映射,同时存储taskId和projectPath 4. 修复历史会话加载后继续对话的保存问题 5. 移除ensureCurrentTask的自动创建逻辑,避免创建多余任务 技术细节: - 为面板添加__uniqueId属性,确保多窗口独立性 - 修改panelTaskMap数据结构,存储完整任务信息 - 在selectConversation中更新面板任务映射 - 优化任务创建流程,避免空任务目录
This commit is contained in:
@ -13,16 +13,16 @@ export function activate(context: vscode.ExtensionContext) {
|
||||
// 注册命令:打开助手面板
|
||||
const openPanelCommand = vscode.commands.registerCommand(
|
||||
"ic-coder.openPanel",
|
||||
() => {
|
||||
showICHelperPanel(context);
|
||||
async () => {
|
||||
await showICHelperPanel(context);
|
||||
}
|
||||
);
|
||||
|
||||
// 注册命令:打开聊天(用于侧边栏)
|
||||
const openChatCommand = vscode.commands.registerCommand(
|
||||
"ic-coder.openChat",
|
||||
() => {
|
||||
showICHelperPanel(context);
|
||||
async () => {
|
||||
await showICHelperPanel(context);
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@ import { MessageType } from "../types/chatHistory";
|
||||
/**
|
||||
* 创建并显示 IC 助手面板
|
||||
*/
|
||||
export function showICHelperPanel(
|
||||
export async function showICHelperPanel(
|
||||
context: vscode.ExtensionContext,
|
||||
viewColumn?: vscode.ViewColumn
|
||||
) {
|
||||
@ -33,6 +33,10 @@ export function showICHelperPanel(
|
||||
}
|
||||
);
|
||||
|
||||
// 为面板生成唯一ID
|
||||
const panelId = `panel_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
||||
(panel as any).__uniqueId = panelId;
|
||||
|
||||
// 设置标签页图标
|
||||
panel.iconPath = vscode.Uri.joinPath(
|
||||
context.extensionUri,
|
||||
@ -50,7 +54,27 @@ export function showICHelperPanel(
|
||||
|
||||
// 处理消息
|
||||
panel.webview.onDidReceiveMessage(
|
||||
(message) => {
|
||||
async (message) => {
|
||||
const historyManager = ChatHistoryManager.getInstance();
|
||||
const panelId = (panel as any).__uniqueId;
|
||||
|
||||
// 在处理消息前,确保面板有任务上下文
|
||||
// 如果没有,则创建新任务(仅在首次发送消息时)
|
||||
if (!historyManager.getPanelTask(panelId)) {
|
||||
const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
|
||||
if (workspacePath) {
|
||||
try {
|
||||
const taskMeta = await historyManager.createTask(workspacePath, "新对话");
|
||||
historyManager.setPanelTask(panelId, taskMeta.taskId, workspacePath);
|
||||
} catch (error) {
|
||||
console.error("创建任务失败:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 切换到当前面板的任务上下文
|
||||
historyManager.switchToPanelTask(panelId);
|
||||
|
||||
switch (message.command) {
|
||||
case "sendMessage":
|
||||
handleUserMessage(panel, message.text, context.extensionPath);
|
||||
@ -124,6 +148,17 @@ export function showICHelperPanel(
|
||||
undefined,
|
||||
context.subscriptions
|
||||
);
|
||||
|
||||
// 面板关闭时清理任务映射
|
||||
panel.onDidDispose(
|
||||
() => {
|
||||
const historyManager = ChatHistoryManager.getInstance();
|
||||
const panelId = (panel as any).__uniqueId;
|
||||
historyManager.removePanelTask(panelId);
|
||||
},
|
||||
undefined,
|
||||
context.subscriptions
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -386,6 +421,10 @@ async function selectConversation(
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新面板的任务映射,确保后续对话保存到正确的任务中
|
||||
const panelId = (panel as any).__uniqueId;
|
||||
historyManager.setPanelTask(panelId, taskId, workspacePath);
|
||||
|
||||
// 清空当前聊天界面
|
||||
panel.webview.postMessage({
|
||||
command: "clearChat"
|
||||
|
||||
@ -21,6 +21,8 @@ export class ChatHistoryManager {
|
||||
private baseDir: string; // ~/.iccoder
|
||||
private currentTaskId: string | null = null;
|
||||
private currentProjectPath: string | null = null;
|
||||
// 存储每个面板的任务信息(taskId 和 projectPath)
|
||||
private panelTaskMap: Map<string, { taskId: string; projectPath: string }> = new Map();
|
||||
|
||||
private constructor() {
|
||||
// 设置存储路径: ~/.iccoder
|
||||
@ -109,6 +111,43 @@ export class ChatHistoryManager {
|
||||
return ChatHistoryManager.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 为面板设置任务ID
|
||||
*/
|
||||
public setPanelTask(panelId: string, taskId: string, projectPath: string): void {
|
||||
this.panelTaskMap.set(panelId, { taskId, projectPath });
|
||||
this.currentTaskId = taskId;
|
||||
this.currentProjectPath = projectPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取面板的任务ID
|
||||
*/
|
||||
public getPanelTask(panelId: string): string | null {
|
||||
const taskInfo = this.panelTaskMap.get(panelId);
|
||||
return taskInfo ? taskInfo.taskId : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换到指定面板的任务上下文
|
||||
*/
|
||||
public switchToPanelTask(panelId: string): boolean {
|
||||
const taskInfo = this.panelTaskMap.get(panelId);
|
||||
if (taskInfo) {
|
||||
this.currentTaskId = taskInfo.taskId;
|
||||
this.currentProjectPath = taskInfo.projectPath;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除面板的任务映射
|
||||
*/
|
||||
public removePanelTask(panelId: string): void {
|
||||
this.panelTaskMap.delete(panelId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建新任务
|
||||
*/
|
||||
@ -266,17 +305,11 @@ export class ChatHistoryManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* 确保有当前任务,如果没有则自动创建
|
||||
* 确保有当前任务,如果没有则抛出错误
|
||||
*/
|
||||
private async ensureCurrentTask(): Promise<void> {
|
||||
if (!this.currentTaskId || !this.currentProjectPath) {
|
||||
// 获取当前工作区路径
|
||||
const workspacePath = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
|
||||
if (workspacePath) {
|
||||
await this.createTask(workspacePath, "默认任务");
|
||||
} else {
|
||||
throw new Error("没有打开的工作区,无法创建任务");
|
||||
}
|
||||
throw new Error("没有当前任务上下文,请确保已正确初始化面板任务");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user