UNPKG

dynamic-interaction

Version:

Dynamic interaction 动态交互mcp,用于cursor、windsurf、trae 等 AI 智能编辑器 Agent 运行时交互使用

186 lines (185 loc) 6.8 kB
"use strict"; /** * 会话管理器 * 重构和改进的会话管理功能 */ Object.defineProperty(exports, "__esModule", { value: true }); exports.sessionManager = exports.SessionManager = void 0; const logger_1 = require("../../logger"); const context_1 = require("./context"); const queue_1 = require("./queue"); const transport_1 = require("../websocket/transport"); const config_1 = require("../../config"); const errors_1 = require("../utils/errors"); class SessionManager { static instance; activeSessions = new Map(); sessionById = new Map(); constructor() { } static getInstance() { if (!SessionManager.instance) { SessionManager.instance = new SessionManager(); } return SessionManager.instance; } createSession(ws, request) { if (this.activeSessions.has(ws)) { const existing = this.activeSessions.get(ws); logger_1.logger.warn(`WebSocket连接已存在会话,ID: ${existing.id}`); return existing; } const timeout = parseInt(process.env.SESSION_TIMEOUT || '300', 10); const session = new context_1.SessionContextBuilder() .setId(request.id) .setWebSocket(ws) .setRequest(request) .setStartTime(request.createdAt) .setTimeout(timeout) .setMode(request.mode) .build(); // 设置超时处理 session.timeoutId = setTimeout(() => { this.handleTimeout(session); }, config_1.SESSION_TIMEOUT * 1000); // 存储会话 this.activeSessions.set(ws, session); this.sessionById.set(session.id, session); logger_1.logger.info(`会话已创建,ID: ${session.id},模式: ${session.mode},活跃会话数: ${this.activeSessions.size}`); // 发送会话初始化信息 this.initializeSession(session); return session; } initializeSession(session) { // 发送摘要信息 transport_1.transport.send(session.ws, { type: 'summary', data: session.request.summary }); // 发送系统信息 transport_1.transport.sendSystemInfo(session.ws, session.id, session.request.projectDirectory || process.cwd(), session.startTime, session.timeout, session.mode); } endSession(ws) { const session = this.activeSessions.get(ws); if (!session) { logger_1.logger.warn('尝试结束不存在的会话'); return; } this.cleanup(session); logger_1.logger.info(`会话已结束,ID: ${session.id},剩余活跃会话: ${this.activeSessions.size}`); } endSessionById(sessionId) { const session = this.sessionById.get(sessionId); if (!session) { logger_1.logger.warn(`尝试结束不存在的会话,ID: ${sessionId}`); return; } this.cleanup(session); } cleanup(session) { // 清理超时定时器 if (session.timeoutId) { clearTimeout(session.timeoutId); session.timeoutId = null; } // 从映射中移除 this.activeSessions.delete(session.ws); this.sessionById.delete(session.id); } handleTimeout(session) { logger_1.logger.warn(`会话超时,ID: ${session.id}`); // 发送超时通知 transport_1.transport.send(session.ws, { type: 'timeout', data: { message: '会话因长时间未活动已超时' } }); transport_1.transport.send(session.ws, { type: 'stop_timer' }); // 解析会话Promise,返回超时标识 session.request.resolve({ text: '__SESSION_TIMEOUT__', imageData: [] }); // 确认队列中的请求 queue_1.sessionQueue.acknowledge(session.request.id); // 清理会话 this.cleanup(session); } handleDisconnection(ws) { const session = this.activeSessions.get(ws); if (!session) { return; } logger_1.logger.info(`客户端断开连接,会话ID: ${session.id}`); // 将请求重新入队 queue_1.sessionQueue.requeue(session.request.id, new Error('WebSocket连接在反馈完成前关闭')); // 清理会话 this.cleanup(session); // 通知生命周期管理器检查空闲状态 const { lifecycleManager } = require('../core/lifecycle'); lifecycleManager.checkAndStopIfIdle(); } getSessionByWs(ws) { return this.activeSessions.get(ws); } getSessionById(sessionId) { return this.sessionById.get(sessionId); } hasSession(ws) { return this.activeSessions.has(ws); } getSessionCount() { return this.activeSessions.size; } getSessionStats(sessionId) { const session = this.sessionById.get(sessionId); if (!session) { return null; } const now = Date.now(); const elapsedTime = now - session.startTime; const remainingTime = Math.max(0, (session.timeout * 1000) - elapsedTime); return { id: session.id, startTime: session.startTime, elapsedTime, remainingTime: Math.floor(remainingTime / 1000), mode: session.mode, projectDirectory: session.request.projectDirectory }; } getAllSessions() { return Array.from(this.activeSessions.values()); } clearAll() { logger_1.logger.info(`清理所有会话 (${this.activeSessions.size}个)`); for (const session of this.activeSessions.values()) { // 清理超时定时器 if (session.timeoutId) { clearTimeout(session.timeoutId); } // 拒绝未完成的请求 session.request.reject(new errors_1.SessionError('服务器正在关闭', errors_1.ErrorCodes.SERVER_STOP_ERROR)); } this.activeSessions.clear(); this.sessionById.clear(); } extendSession(sessionId, additionalTime) { const session = this.sessionById.get(sessionId); if (!session) { return false; } // 清除当前超时定时器 if (session.timeoutId) { clearTimeout(session.timeoutId); } // 设置新的超时定时器 session.timeoutId = setTimeout(() => { this.handleTimeout(session); }, additionalTime * 1000); logger_1.logger.info(`会话时间已延长,ID: ${sessionId},延长时间: ${additionalTime}秒`); return true; } } exports.SessionManager = SessionManager; exports.sessionManager = SessionManager.getInstance();