diff --git a/src/services/apiClient.ts b/src/services/apiClient.ts index 9538b1b..bbc312d 100644 --- a/src/services/apiClient.ts +++ b/src/services/apiClient.ts @@ -155,6 +155,26 @@ export async function stopDialog(taskId: string): Promise { }); } +/** 压缩对话响应 */ +export interface CompactDialogResponse { + success: boolean; + taskId: string; + message?: string; + error?: string; +} + +/** + * 手动压缩对话历史 + * POST /api/dialog/compact + */ +export async function compactDialog(taskId: string): Promise { + console.log(`[API] 压缩对话: taskId=${taskId}`); + return request('/api/dialog/compact', { + method: 'POST', + body: { taskId } + }); +} + /** * 创建成功的工具结果 */ diff --git a/src/services/dialogService.ts b/src/services/dialogService.ts index aad42ec..3f6b6ca 100644 --- a/src/services/dialogService.ts +++ b/src/services/dialogService.ts @@ -73,6 +73,8 @@ export interface DialogCallbacks { onError?: (message: string) => void; /** 通知消息 */ onNotification?: (message: string) => void; + /** 上下文使用量更新 */ + onContextUsage?: (data: { currentTokens: number; maxTokens: number; percentage: number }) => void; } /** @@ -553,6 +555,12 @@ export class DialogSession { onComplete: (data) => { this.isActive = false; this.finalizeTextSegment(); + + // 追踪 AI 消息(用于后端重启后恢复) + if (this.accumulatedText) { + historyManager.trackAiMessage(this.accumulatedText); + } + // 发送所有段落 callbacks.onComplete?.(this.segments); }, @@ -639,6 +647,11 @@ export class DialogSession { await historyManager.saveCompactedData(data.compactedData); }, + onContextUsage: (data) => { + console.log('[DialogSession] onContextUsage:', data.currentTokens, '/', data.maxTokens); + callbacks.onContextUsage?.(data); + }, + onOpen: () => { console.log('[DialogSession] SSE 连接已建立'); }, diff --git a/src/services/sseHandler.ts b/src/services/sseHandler.ts index 081ff32..d2c94bf 100644 --- a/src/services/sseHandler.ts +++ b/src/services/sseHandler.ts @@ -27,7 +27,8 @@ import type { AgentStartEvent, AgentProgressEvent, AgentCompleteEvent, - AgentErrorEvent + AgentErrorEvent, + ContextUsageEvent } from '../types/api'; import type { MemoryCompactedEvent } from '../types/memory'; @@ -71,6 +72,8 @@ export interface SSECallbacks { onAgentError?: (data: AgentErrorEvent) => void; /** 记忆压缩完成 */ onMemoryCompacted?: (data: MemoryCompactedEvent) => void; + /** 上下文使用量更新 */ + onContextUsage?: (data: ContextUsageEvent) => void; /** 连接打开 */ onOpen?: () => void; /** 连接关闭 */ @@ -325,6 +328,9 @@ function dispatchEvent( case 'memory_compacted': callbacks.onMemoryCompacted?.(data as MemoryCompactedEvent); break; + case 'context_usage': + callbacks.onContextUsage?.(data as ContextUsageEvent); + break; default: console.log(`[SSE] 未知事件类型: ${eventType}`, data); } diff --git a/src/utils/messageHandler.ts b/src/utils/messageHandler.ts index ead218a..177b75a 100644 --- a/src/utils/messageHandler.ts +++ b/src/utils/messageHandler.ts @@ -27,6 +27,9 @@ let useBackendService = true; /** 当前对话会话 */ let currentSession: DialogSession | null = null; +/** 最后一个活跃的 taskId(用于压缩等操作) */ +let lastTaskId: string | null = null; + /** 待执行的计划(Plan 模式确认后自动执行) */ let pendingPlanExecution: { panel: vscode.WebviewPanel; @@ -128,6 +131,8 @@ async function handleUserMessageWithBackend( // 创建或复用会话 if (!currentSession || !currentSession.active) { currentSession = dialogManager.createSession(extensionPath, reuseTaskId); + // 保存 taskId 用于后续操作(如压缩) + lastTaskId = currentSession.getTaskId(); if (reuseTaskId) { console.log('[MessageHandler] 复用 taskId 创建会话:', reuseTaskId); } @@ -253,6 +258,16 @@ async function handleUserMessageWithBackend( onNotification: (message) => { vscode.window.showInformationMessage(message); }, + + onContextUsage: (data) => { + // 发送上下文使用量到 WebView + panel.webview.postMessage({ + command: 'contextUsage', + currentTokens: data.currentTokens, + maxTokens: data.maxTokens, + percentage: data.percentage + }); + }, }, mode); }); } @@ -310,7 +325,15 @@ export async function abortCurrentDialog(): Promise { * 获取当前会话的 taskId */ export function getCurrentTaskId(): string | null { - return currentSession?.getTaskId() || null; + return currentSession?.getTaskId() || lastTaskId; +} + +/** + * 设置最后的 taskId(加载历史会话时调用) + */ +export function setLastTaskId(taskId: string): void { + lastTaskId = taskId; + console.log('[MessageHandler] 设置 lastTaskId:', taskId); } /**