feat: 实现会话记忆同步和知识图谱恢复机制
- 添加 memory_compacted SSE 事件处理 - 添加 CompactedMemory/CompactedMessage 类型定义 - 添加 COMPACTION_SUMMARY 消息类型 - 实现压缩数据存储到 conversation.json - 实现从 conversation.json 构建恢复数据 - 发送请求时附带 knowledgeData 用于恢复知识图谱
This commit is contained in:
@ -3,12 +3,15 @@
|
|||||||
* 整合 SSE 通信、工具执行、用户交互
|
* 整合 SSE 通信、工具执行、用户交互
|
||||||
*/
|
*/
|
||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
import { startStreamDialog, generateTaskId, SSEController, SSECallbacks } from './sseHandler';
|
import { startStreamDialog, generateTaskId, SSEController, SSECallbacks } from './sseHandler';
|
||||||
import { executeToolCall, createToolExecutorContext, ToolExecutorContext } from './toolExecutor';
|
import { executeToolCall, createToolExecutorContext, ToolExecutorContext } from './toolExecutor';
|
||||||
import { userInteractionManager } from './userInteraction';
|
import { userInteractionManager } from './userInteraction';
|
||||||
import { getConfig } from '../config/settings';
|
import { getConfig } from '../config/settings';
|
||||||
import type { DialogRequest, ToolCallRequest, AskUserEvent, RunMode, ToolConfirmEvent, PlanConfirmEvent } from '../types/api';
|
import type { DialogRequest, ToolCallRequest, AskUserEvent, RunMode, ToolConfirmEvent, PlanConfirmEvent } from '../types/api';
|
||||||
import { submitToolConfirm, submitAnswer } from './apiClient';
|
import { submitToolConfirm, submitAnswer } from './apiClient';
|
||||||
|
import { ChatHistoryManager } from '../utils/chatHistoryManager';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 消息段落类型
|
* 消息段落类型
|
||||||
@ -152,6 +155,39 @@ export class DialogSession {
|
|||||||
return this.isActive;
|
return this.isActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载知识图谱数据
|
||||||
|
* 从 .iccoder/knowledge.json 读取
|
||||||
|
*/
|
||||||
|
private loadKnowledgeData(): string | null {
|
||||||
|
console.log('[DialogSession] loadKnowledgeData 开始执行');
|
||||||
|
|
||||||
|
const workspaceFolders = vscode.workspace.workspaceFolders;
|
||||||
|
if (!workspaceFolders || workspaceFolders.length === 0) {
|
||||||
|
console.log('[DialogSession] 没有工作区文件夹');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const workspacePath = workspaceFolders[0].uri.fsPath;
|
||||||
|
const knowledgePath = path.join(workspacePath, '.iccoder', 'knowledge.json');
|
||||||
|
console.log('[DialogSession] 知识图谱路径:', knowledgePath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const exists = fs.existsSync(knowledgePath);
|
||||||
|
console.log('[DialogSession] 文件存在:', exists);
|
||||||
|
|
||||||
|
if (exists) {
|
||||||
|
const content = fs.readFileSync(knowledgePath, 'utf-8');
|
||||||
|
console.log('[DialogSession] 加载知识图谱成功, 长度:', content.length);
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.warn('[DialogSession] 加载知识图谱失败:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取工具操作描述(用于确认对话框)
|
* 获取工具操作描述(用于确认对话框)
|
||||||
*/
|
*/
|
||||||
@ -210,13 +246,29 @@ export class DialogSession {
|
|||||||
this.currentTextSegment = null;
|
this.currentTextSegment = null;
|
||||||
|
|
||||||
const config = getConfig();
|
const config = getConfig();
|
||||||
|
|
||||||
|
// 获取压缩数据和新消息(用于后端重启后恢复)
|
||||||
|
const historyManager = ChatHistoryManager.getInstance();
|
||||||
|
const compactedData = await historyManager.loadCompactedData(this.taskId);
|
||||||
|
const newMessages = historyManager.getNewMessagesSinceCompaction();
|
||||||
|
|
||||||
|
// 加载知识图谱数据
|
||||||
|
const knowledgeData = this.loadKnowledgeData();
|
||||||
|
console.log('[DialogSession] knowledgeData 加载结果:', knowledgeData ? `${knowledgeData.length} 字符` : 'null');
|
||||||
|
|
||||||
const request: DialogRequest = {
|
const request: DialogRequest = {
|
||||||
taskId: this.taskId,
|
taskId: this.taskId,
|
||||||
message,
|
message,
|
||||||
userId: config.userId,
|
userId: config.userId,
|
||||||
mode: mode || 'agent'
|
mode: mode || 'agent',
|
||||||
|
compactedData: compactedData || undefined,
|
||||||
|
newMessages: newMessages.length > 0 ? newMessages : undefined,
|
||||||
|
knowledgeData: knowledgeData || undefined
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 追踪用户消息
|
||||||
|
historyManager.trackUserMessage(message);
|
||||||
|
|
||||||
const sseCallbacks: SSECallbacks = {
|
const sseCallbacks: SSECallbacks = {
|
||||||
onTextDelta: (data) => {
|
onTextDelta: (data) => {
|
||||||
this.accumulatedText += data.text;
|
this.accumulatedText += data.text;
|
||||||
@ -466,6 +518,12 @@ export class DialogSession {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onMemoryCompacted: async (data) => {
|
||||||
|
console.log('[DialogSession] onMemoryCompacted:', data.taskId);
|
||||||
|
// 保存压缩数据到本地
|
||||||
|
await historyManager.saveCompactedData(data.compactedData);
|
||||||
|
},
|
||||||
|
|
||||||
onOpen: () => {
|
onOpen: () => {
|
||||||
console.log('[DialogSession] SSE 连接已建立');
|
console.log('[DialogSession] SSE 连接已建立');
|
||||||
},
|
},
|
||||||
|
|||||||
@ -29,6 +29,7 @@ import type {
|
|||||||
AgentCompleteEvent,
|
AgentCompleteEvent,
|
||||||
AgentErrorEvent
|
AgentErrorEvent
|
||||||
} from '../types/api';
|
} from '../types/api';
|
||||||
|
import type { MemoryCompactedEvent } from '../types/memory';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SSE 事件回调接口
|
* SSE 事件回调接口
|
||||||
@ -68,6 +69,8 @@ export interface SSECallbacks {
|
|||||||
onAgentComplete?: (data: AgentCompleteEvent) => void;
|
onAgentComplete?: (data: AgentCompleteEvent) => void;
|
||||||
/** 子智能体错误 */
|
/** 子智能体错误 */
|
||||||
onAgentError?: (data: AgentErrorEvent) => void;
|
onAgentError?: (data: AgentErrorEvent) => void;
|
||||||
|
/** 记忆压缩完成 */
|
||||||
|
onMemoryCompacted?: (data: MemoryCompactedEvent) => void;
|
||||||
/** 连接打开 */
|
/** 连接打开 */
|
||||||
onOpen?: () => void;
|
onOpen?: () => void;
|
||||||
/** 连接关闭 */
|
/** 连接关闭 */
|
||||||
@ -319,6 +322,9 @@ function dispatchEvent(
|
|||||||
case 'agent_error':
|
case 'agent_error':
|
||||||
callbacks.onAgentError?.(data as AgentErrorEvent);
|
callbacks.onAgentError?.(data as AgentErrorEvent);
|
||||||
break;
|
break;
|
||||||
|
case 'memory_compacted':
|
||||||
|
callbacks.onMemoryCompacted?.(data as MemoryCompactedEvent);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
console.log(`[SSE] 未知事件类型: ${eventType}`, data);
|
console.log(`[SSE] 未知事件类型: ${eventType}`, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,6 +3,8 @@
|
|||||||
* 对应后端 IC Coder Backend 的接口格式
|
* 对应后端 IC Coder Backend 的接口格式
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { CompactedMemory, CompactedMessage } from './memory';
|
||||||
|
|
||||||
// ============== 对话请求/响应 ==============
|
// ============== 对话请求/响应 ==============
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,6 +29,12 @@ export interface DialogRequest {
|
|||||||
userId: string;
|
userId: string;
|
||||||
/** 运行模式 */
|
/** 运行模式 */
|
||||||
mode: RunMode;
|
mode: RunMode;
|
||||||
|
/** 压缩后的记忆数据(用于后端重启后恢复) */
|
||||||
|
compactedData?: CompactedMemory;
|
||||||
|
/** 压缩后产生的新消息 */
|
||||||
|
newMessages?: CompactedMessage[];
|
||||||
|
/** 知识图谱数据(JSON 字符串,用于恢复知识图谱) */
|
||||||
|
knowledgeData?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============== SSE 事件类型 ==============
|
// ============== SSE 事件类型 ==============
|
||||||
@ -45,6 +53,7 @@ export type SSEEventType =
|
|||||||
| 'agent_progress' // 子智能体进度
|
| 'agent_progress' // 子智能体进度
|
||||||
| 'agent_complete' // 子智能体完成
|
| 'agent_complete' // 子智能体完成
|
||||||
| 'agent_error' // 子智能体错误
|
| 'agent_error' // 子智能体错误
|
||||||
|
| 'memory_compacted' // 记忆压缩完成
|
||||||
| 'complete' // 对话完成
|
| 'complete' // 对话完成
|
||||||
| 'error' // 错误
|
| 'error' // 错误
|
||||||
| 'warning' // 警告
|
| 'warning' // 警告
|
||||||
|
|||||||
@ -5,7 +5,8 @@ export enum MessageType {
|
|||||||
SYSTEM = "SYSTEM",
|
SYSTEM = "SYSTEM",
|
||||||
USER = "USER",
|
USER = "USER",
|
||||||
AI = "AI",
|
AI = "AI",
|
||||||
TOOL_EXECUTION_RESULT = "TOOL_EXECUTION_RESULT"
|
TOOL_EXECUTION_RESULT = "TOOL_EXECUTION_RESULT",
|
||||||
|
COMPACTION_SUMMARY = "COMPACTION_SUMMARY" // 压缩摘要
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -69,10 +70,22 @@ export interface ToolExecutionResultMessage extends BaseMessage {
|
|||||||
text: string; // JSON字符串
|
text: string; // JSON字符串
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩摘要消息
|
||||||
|
*/
|
||||||
|
export interface CompactionSummaryMessage extends BaseMessage {
|
||||||
|
type: MessageType.COMPACTION_SUMMARY;
|
||||||
|
summary: string;
|
||||||
|
version: number;
|
||||||
|
compactedAt: string;
|
||||||
|
originalMessageCount: number;
|
||||||
|
compactedMessageCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 联合消息类型
|
* 联合消息类型
|
||||||
*/
|
*/
|
||||||
export type ChatMessage = SystemMessage | UserMessage | AiMessage | ToolExecutionResultMessage;
|
export type ChatMessage = SystemMessage | UserMessage | AiMessage | ToolExecutionResultMessage | CompactionSummaryMessage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 对话轮次元数据
|
* 对话轮次元数据
|
||||||
|
|||||||
42
src/types/memory.ts
Normal file
42
src/types/memory.ts
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* 压缩记忆相关类型定义
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩后的记忆数据
|
||||||
|
*/
|
||||||
|
export interface CompactedMemory {
|
||||||
|
taskId: string;
|
||||||
|
version: number;
|
||||||
|
compactedAt: string;
|
||||||
|
summary: string;
|
||||||
|
recentMessages: CompactedMessage[];
|
||||||
|
originalMessageCount: number;
|
||||||
|
compactedMessageCount: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 压缩消息格式
|
||||||
|
*/
|
||||||
|
export interface CompactedMessage {
|
||||||
|
type: 'USER' | 'AI' | 'SYSTEM' | 'TOOL_RESULT';
|
||||||
|
content: string;
|
||||||
|
toolCall?: ToolCallInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 工具调用信息
|
||||||
|
*/
|
||||||
|
export interface ToolCallInfo {
|
||||||
|
toolName: string;
|
||||||
|
toolInput: string;
|
||||||
|
toolOutput?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 记忆压缩 SSE 事件
|
||||||
|
*/
|
||||||
|
export interface MemoryCompactedEvent {
|
||||||
|
taskId: string;
|
||||||
|
compactedData: CompactedMemory;
|
||||||
|
}
|
||||||
@ -9,8 +9,10 @@ import {
|
|||||||
UserMessage,
|
UserMessage,
|
||||||
AiMessage,
|
AiMessage,
|
||||||
SystemMessage,
|
SystemMessage,
|
||||||
ToolExecutionResultMessage
|
ToolExecutionResultMessage,
|
||||||
|
CompactionSummaryMessage
|
||||||
} from '../types/chatHistory';
|
} from '../types/chatHistory';
|
||||||
|
import { CompactedMemory, CompactedMessage } from '../types/memory';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 会话历史管理器
|
* 会话历史管理器
|
||||||
@ -23,6 +25,8 @@ export class ChatHistoryManager {
|
|||||||
private currentProjectPath: string | null = null;
|
private currentProjectPath: string | null = null;
|
||||||
// 存储每个面板的任务信息(taskId 和 projectPath)
|
// 存储每个面板的任务信息(taskId 和 projectPath)
|
||||||
private panelTaskMap: Map<string, { taskId: string; projectPath: string }> = new Map();
|
private panelTaskMap: Map<string, { taskId: string; projectPath: string }> = new Map();
|
||||||
|
// 追踪压缩后产生的新消息
|
||||||
|
private newMessagesSinceCompaction: CompactedMessage[] = [];
|
||||||
|
|
||||||
private constructor() {
|
private constructor() {
|
||||||
// 设置存储路径: ~/.iccoder
|
// 设置存储路径: ~/.iccoder
|
||||||
@ -690,4 +694,203 @@ export class ChatHistoryManager {
|
|||||||
hasMore: end < total
|
hasMore: end < total
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ========== 压缩数据相关方法 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存压缩数据(存入 conversation.json 作为压缩摘要消息)
|
||||||
|
*/
|
||||||
|
public async saveCompactedData(compacted: CompactedMemory): Promise<void> {
|
||||||
|
// 尝试从多个来源获取 projectPath
|
||||||
|
let projectPath = this.currentProjectPath;
|
||||||
|
|
||||||
|
if (!projectPath) {
|
||||||
|
for (const [, taskInfo] of this.panelTaskMap) {
|
||||||
|
if (taskInfo.taskId === compacted.taskId) {
|
||||||
|
projectPath = taskInfo.projectPath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!projectPath) {
|
||||||
|
console.error('[ChatHistoryManager] 无法保存压缩数据:projectPath 为空');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取现有对话历史
|
||||||
|
const taskDir = this.getTaskDir(projectPath, compacted.taskId);
|
||||||
|
const conversationPath = path.join(taskDir, 'conversation.json');
|
||||||
|
let messages: ChatMessage[] = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
const uri = vscode.Uri.file(conversationPath);
|
||||||
|
const content = await vscode.workspace.fs.readFile(uri);
|
||||||
|
messages = JSON.parse(Buffer.from(content).toString('utf-8'));
|
||||||
|
} catch {
|
||||||
|
// 文件不存在,使用空数组
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建压缩摘要消息
|
||||||
|
const summaryMessage: CompactionSummaryMessage = {
|
||||||
|
type: MessageType.COMPACTION_SUMMARY,
|
||||||
|
summary: compacted.summary,
|
||||||
|
version: compacted.version,
|
||||||
|
compactedAt: compacted.compactedAt,
|
||||||
|
originalMessageCount: compacted.originalMessageCount,
|
||||||
|
compactedMessageCount: compacted.compactedMessageCount
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加到对话历史
|
||||||
|
messages.push(summaryMessage);
|
||||||
|
|
||||||
|
// 保存
|
||||||
|
const uri = vscode.Uri.file(conversationPath);
|
||||||
|
const content = Buffer.from(JSON.stringify(messages, null, 2), 'utf-8');
|
||||||
|
await vscode.workspace.fs.writeFile(uri, content);
|
||||||
|
|
||||||
|
// 重置新消息追踪
|
||||||
|
this.newMessagesSinceCompaction = [];
|
||||||
|
|
||||||
|
console.log(`[ChatHistoryManager] 压缩摘要已保存到 conversation.json: taskId=${compacted.taskId}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载压缩数据(从 conversation.json 构建)
|
||||||
|
*/
|
||||||
|
public async loadCompactedData(taskId: string): Promise<CompactedMemory | null> {
|
||||||
|
// 尝试从多个来源获取 projectPath
|
||||||
|
let projectPath = this.currentProjectPath;
|
||||||
|
|
||||||
|
if (!projectPath) {
|
||||||
|
for (const [, taskInfo] of this.panelTaskMap) {
|
||||||
|
if (taskInfo.taskId === taskId) {
|
||||||
|
projectPath = taskInfo.projectPath;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!projectPath) {
|
||||||
|
console.log('[ChatHistoryManager] loadCompactedData: projectPath 为空');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 读取 conversation.json
|
||||||
|
const taskDir = this.getTaskDir(projectPath, taskId);
|
||||||
|
const conversationPath = path.join(taskDir, 'conversation.json');
|
||||||
|
|
||||||
|
try {
|
||||||
|
const uri = vscode.Uri.file(conversationPath);
|
||||||
|
const content = await vscode.workspace.fs.readFile(uri);
|
||||||
|
const messages: ChatMessage[] = JSON.parse(Buffer.from(content).toString('utf-8'));
|
||||||
|
|
||||||
|
if (messages.length === 0) {
|
||||||
|
console.log('[ChatHistoryManager] conversation.json 为空');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 从 conversation.json 构建 CompactedMemory
|
||||||
|
return this.buildCompactedMemoryFromConversation(taskId, messages);
|
||||||
|
} catch {
|
||||||
|
console.log('[ChatHistoryManager] conversation.json 不存在:', conversationPath);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 conversation.json 构建 CompactedMemory
|
||||||
|
*/
|
||||||
|
private buildCompactedMemoryFromConversation(taskId: string, messages: ChatMessage[]): CompactedMemory {
|
||||||
|
// 查找最后一个压缩摘要消息
|
||||||
|
let lastSummary: CompactionSummaryMessage | null = null;
|
||||||
|
let summaryIndex = -1;
|
||||||
|
|
||||||
|
for (let i = messages.length - 1; i >= 0; i--) {
|
||||||
|
if (messages[i].type === MessageType.COMPACTION_SUMMARY) {
|
||||||
|
lastSummary = messages[i] as CompactionSummaryMessage;
|
||||||
|
summaryIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取摘要后的消息(或全部消息)
|
||||||
|
const recentMessages = summaryIndex >= 0
|
||||||
|
? messages.slice(summaryIndex + 1)
|
||||||
|
: messages;
|
||||||
|
|
||||||
|
// 转换为 CompactedMessage 格式
|
||||||
|
const compactedMessages: CompactedMessage[] = recentMessages.map(msg => ({
|
||||||
|
type: this.mapMessageType(msg.type),
|
||||||
|
content: this.extractMessageContent(msg)
|
||||||
|
}));
|
||||||
|
|
||||||
|
return {
|
||||||
|
taskId,
|
||||||
|
version: lastSummary?.version || Date.now(),
|
||||||
|
compactedAt: lastSummary?.compactedAt || new Date().toISOString(),
|
||||||
|
summary: lastSummary?.summary || '',
|
||||||
|
recentMessages: compactedMessages,
|
||||||
|
originalMessageCount: messages.length,
|
||||||
|
compactedMessageCount: compactedMessages.length
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 映射消息类型
|
||||||
|
*/
|
||||||
|
private mapMessageType(type: MessageType): 'USER' | 'AI' | 'SYSTEM' | 'TOOL_RESULT' {
|
||||||
|
switch (type) {
|
||||||
|
case MessageType.USER: return 'USER';
|
||||||
|
case MessageType.AI: return 'AI';
|
||||||
|
case MessageType.SYSTEM: return 'SYSTEM';
|
||||||
|
case MessageType.TOOL_EXECUTION_RESULT: return 'TOOL_RESULT';
|
||||||
|
default: return 'USER';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 提取消息内容
|
||||||
|
*/
|
||||||
|
private extractMessageContent(msg: ChatMessage): string {
|
||||||
|
switch (msg.type) {
|
||||||
|
case MessageType.USER:
|
||||||
|
return (msg as UserMessage).contents?.[0]?.text || '';
|
||||||
|
case MessageType.AI:
|
||||||
|
return (msg as AiMessage).text || '';
|
||||||
|
case MessageType.SYSTEM:
|
||||||
|
return (msg as SystemMessage).text || '';
|
||||||
|
case MessageType.TOOL_EXECUTION_RESULT:
|
||||||
|
return (msg as ToolExecutionResultMessage).text || '';
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取压缩后产生的新消息
|
||||||
|
*/
|
||||||
|
public getNewMessagesSinceCompaction(): CompactedMessage[] {
|
||||||
|
return this.newMessagesSinceCompaction;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追踪新消息(用户消息)
|
||||||
|
*/
|
||||||
|
public trackUserMessage(text: string): void {
|
||||||
|
this.newMessagesSinceCompaction.push({
|
||||||
|
type: 'USER',
|
||||||
|
content: text
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 追踪新消息(AI消息)
|
||||||
|
*/
|
||||||
|
public trackAiMessage(text: string): void {
|
||||||
|
this.newMessagesSinceCompaction.push({
|
||||||
|
type: 'AI',
|
||||||
|
content: text
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user