/** * SessionMemory - 会话记忆管理器(内存版) * * 功能: * - 存储用户最近3轮对话 * - 提供上下文查询 * - 自动清理过期会话(1小时) * * 设计原则: * - Node.js内存存储(MVP阶段,无需数据库) * - 单例模式(全局共享) * - 轻量级(<100行代码) */ import { logger } from '../../../common/logging/index.js'; /** * 对话消息 */ export interface ConversationMessage { role: 'user' | 'assistant'; content: string; timestamp: Date; } /** * 对话历史 */ export interface ConversationHistory { userId: string; messages: ConversationMessage[]; createdAt: Date; updatedAt: Date; } /** * 会话记忆管理器 */ export class SessionMemory { // 内存存储:{ userId: ConversationHistory } private sessions: Map = new Map(); private readonly MAX_HISTORY = 3; // 只保留最近3轮(6条消息) private readonly SESSION_TIMEOUT = 3600000; // 1小时(毫秒) /** * 添加对话记录 */ addMessage(userId: string, role: 'user' | 'assistant', content: string): void { if (!this.sessions.has(userId)) { this.sessions.set(userId, { userId, messages: [], createdAt: new Date(), updatedAt: new Date(), }); logger.debug('[SessionMemory] 创建新会话', { userId }); } const session = this.sessions.get(userId)!; session.messages.push({ role, content, timestamp: new Date(), }); // 只保留最近3轮(6条消息:3个user + 3个assistant) if (session.messages.length > this.MAX_HISTORY * 2) { const removed = session.messages.length - this.MAX_HISTORY * 2; session.messages = session.messages.slice(-this.MAX_HISTORY * 2); logger.debug('[SessionMemory] 清理历史消息', { userId, removedCount: removed }); } session.updatedAt = new Date(); logger.debug('[SessionMemory] 添加消息', { userId, role, messageLength: content.length, totalMessages: session.messages.length, }); } /** * 获取用户对话历史(最近N轮) */ getHistory(userId: string, maxTurns: number = 3): ConversationMessage[] { const session = this.sessions.get(userId); if (!session) { return []; } // 返回最近N轮(2N条消息) const maxMessages = maxTurns * 2; return session.messages.length > maxMessages ? session.messages.slice(-maxMessages) : session.messages; } /** * 获取用户上下文(格式化为字符串,用于LLM Prompt) */ getContext(userId: string): string { const history = this.getHistory(userId, 2); // 只取最近2轮 if (history.length === 0) { return ''; } return history .map((m) => `${m.role === 'user' ? 'PI' : 'Assistant'}: ${m.content}`) .join('\n'); } /** * 清除用户会话 */ clearSession(userId: string): void { const existed = this.sessions.delete(userId); if (existed) { logger.info('[SessionMemory] 清除会话', { userId }); } } /** * 清理过期会话(超过1小时未使用) */ cleanupExpiredSessions(): void { const now = Date.now(); let cleanedCount = 0; for (const [userId, session] of this.sessions.entries()) { if (now - session.updatedAt.getTime() > this.SESSION_TIMEOUT) { this.sessions.delete(userId); cleanedCount++; } } if (cleanedCount > 0) { logger.info('[SessionMemory] 清理过期会话', { cleanedCount }); } } /** * 获取统计信息(用于监控) */ getStats() { return { totalSessions: this.sessions.size, sessions: Array.from(this.sessions.entries()).map(([userId, session]) => ({ userId, messageCount: session.messages.length, createdAt: session.createdAt, updatedAt: session.updatedAt, })), }; } } // 全局单例 export const sessionMemory = new SessionMemory(); // 定时清理过期会话(每小时) setInterval(() => { sessionMemory.cleanupExpiredSessions(); }, 3600000); logger.info('[SessionMemory] 会话记忆管理器已启动', { maxHistory: 3, timeout: '1小时', });