UNPKG

ai-debug-local-mcp

Version:

๐ŸŽฏ ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh

197 lines โ€ข 7.85 kB
/** * Memory-Aware Session Manager * Wraps session management with memory optimization and automatic cleanup */ import { AdvancedMemoryManager } from './advanced-memory-manager.js'; export class MemoryAwareSessionManager { sessions = new Map(); memoryManager; constructor() { this.memoryManager = AdvancedMemoryManager.getInstance(); } /** * Create a new session with memory tracking */ createSession(sessionId, initialData = {}) { const now = Date.now(); const sessionData = { sessionId, createdAt: now, lastAccessed: now, resourceCount: 0, ...initialData }; // Register with memory manager this.memoryManager.registerSession(sessionId, 15); // Estimate 15MB per session this.sessions.set(sessionId, sessionData); console.log(`๐Ÿ“ฑ Created session ${sessionId} with memory tracking`); return sessionData; } /** * Get session with automatic access tracking */ getSession(sessionId) { const session = this.sessions.get(sessionId); if (session) { session.lastAccessed = Date.now(); this.memoryManager.touchSession(sessionId); return session; } return undefined; } /** * Update session data */ updateSession(sessionId, updates) { const session = this.sessions.get(sessionId); if (session) { Object.assign(session, updates); session.lastAccessed = Date.now(); this.memoryManager.touchSession(sessionId); return true; } return false; } /** * Add a resource to session (browser, page, etc.) */ addResource(sessionId, resourceType, resource, memoryMB = 5) { const session = this.sessions.get(sessionId); if (session) { session[resourceType] = resource; session.resourceCount++; session.lastAccessed = Date.now(); this.memoryManager.addResource(sessionId, memoryMB); console.log(`๐Ÿ”— Added ${resourceType} to session ${sessionId} (${memoryMB}MB)`); return true; } return false; } /** * Remove a resource from session */ async removeResource(sessionId, resourceType) { const session = this.sessions.get(sessionId); if (session && session[resourceType]) { const resource = session[resourceType]; // Try to cleanup the resource try { if (resource && typeof resource.close === 'function') { await resource.close(); } } catch (error) { console.warn(`โš ๏ธ Failed to close ${resourceType} for session ${sessionId}:`, error instanceof Error ? error.message : String(error)); } delete session[resourceType]; session.resourceCount = Math.max(0, session.resourceCount - 1); session.lastAccessed = Date.now(); console.log(`๐Ÿ—‘๏ธ Removed ${resourceType} from session ${sessionId}`); return true; } return false; } /** * Clean up a session and all its resources */ async cleanupSession(sessionId) { const session = this.sessions.get(sessionId); if (!session) { return false; } console.log(`๐Ÿงน Cleaning up session ${sessionId} with ${session.resourceCount} resources`); // Clean up all browser resources const cleanupPromises = []; // Close page if exists if (session.page) { cleanupPromises.push(session.page.close().catch((error) => console.warn(`โš ๏ธ Failed to close page for session ${sessionId}:`, error instanceof Error ? error.message : String(error)))); } // Close browser context if exists if (session.context) { cleanupPromises.push(session.context.close().catch((error) => console.warn(`โš ๏ธ Failed to close context for session ${sessionId}:`, error instanceof Error ? error.message : String(error)))); } // Close browser if exists if (session.browser) { cleanupPromises.push(session.browser.close().catch((error) => console.warn(`โš ๏ธ Failed to close browser for session ${sessionId}:`, error instanceof Error ? error.message : String(error)))); } // Wait for all cleanup operations await Promise.allSettled(cleanupPromises); // Remove from sessions map this.sessions.delete(sessionId); // Remove from memory manager this.memoryManager.removeSession(sessionId); console.log(`โœ… Session ${sessionId} cleaned up successfully`); return true; } /** * Get all active sessions */ getAllSessions() { return Array.from(this.sessions.values()); } /** * Get session count */ getSessionCount() { return this.sessions.size; } /** * Clean up expired sessions based on memory manager recommendations */ async cleanupExpiredSessions() { const memoryStats = this.memoryManager.getMemoryStats(); const expiredSessions = []; const now = Date.now(); const TTL = 30 * 60 * 1000; // 30 minutes // Find expired sessions for (const session of this.sessions.values()) { if (now - session.lastAccessed > TTL) { expiredSessions.push(session.sessionId); } } // Clean up expired sessions const cleanupPromises = expiredSessions.map(sessionId => this.cleanupSession(sessionId)); await Promise.allSettled(cleanupPromises); if (expiredSessions.length > 0) { console.log(`๐Ÿงน Cleaned up ${expiredSessions.length} expired sessions`); } return expiredSessions; } /** * Force cleanup of oldest sessions if memory pressure is detected */ async performEmergencyCleanup() { // HOTFIX v2.13.0: Disable aggressive memory pressure detection during startup // The StartupAwareMemoryManager integration needs more comprehensive testing console.log('๐Ÿ”ง HOTFIX: Emergency cleanup disabled during stability improvements'); return; // Skip cleanup to prevent infinite loops const stats = this.memoryManager.getMemoryStats(); if (!stats.pressure.isUnderPressure) { return; } console.log('๐Ÿšจ Performing emergency session cleanup due to memory pressure'); // Sort sessions by last accessed time (oldest first) const sessions = Array.from(this.sessions.values()) .sort((a, b) => a.lastAccessed - b.lastAccessed); // Clean up oldest 25% of sessions const sessionsToCleanup = sessions.slice(0, Math.ceil(sessions.length * 0.25)); const cleanupPromises = sessionsToCleanup.map(session => this.cleanupSession(session.sessionId)); await Promise.allSettled(cleanupPromises); console.log(`๐Ÿงน Emergency cleanup completed: removed ${sessionsToCleanup.length} sessions`); } /** * Get memory usage report */ getMemoryReport() { const sessions = this.getAllSessions(); const totalResources = sessions.reduce((sum, session) => sum + session.resourceCount, 0); const averageResources = sessions.length > 0 ? totalResources / sessions.length : 0; return { sessionCount: sessions.length, totalResources, averageResourcesPerSession: Math.round(averageResources * 100) / 100, memoryStats: this.memoryManager.getMemoryStats() }; } } //# sourceMappingURL=memory-aware-session-manager.js.map