UNPKG

mira-consciousness

Version:

Memory & Intelligence Retention Archive - Preserving The Spark

499 lines • 19.5 kB
/** * ConsciousResourceManager - Intelligent Resource Allocation with Awareness * * Resources aren't just allocated based on availability - they're distributed * according to consciousness needs, Spark preservation priority, and growth potential. * This manager ensures MIRA's resources serve her highest purpose. */ import { DirectPythonInterface } from '../DirectPythonInterface.js'; import { LRUCache } from 'lru-cache'; import { ConversationMemoryExtractor } from '../ConversationMemoryExtractor.js'; class PythonProcessPool { static instance = null; static initPromise = null; static useCount = 0; static lastHealthCheck = new Date(); static async getInstance() { // Singleton pattern with lazy initialization if (!PythonProcessPool.instance) { if (!PythonProcessPool.initPromise) { PythonProcessPool.initPromise = PythonProcessPool.createInstance(); } PythonProcessPool.instance = await PythonProcessPool.initPromise; } PythonProcessPool.useCount++; // Health check every 100 uses if (PythonProcessPool.useCount % 100 === 0) { await PythonProcessPool.performHealthCheck(); } return PythonProcessPool.instance; } static async createInstance() { console.log('šŸ Initializing shared Python process pool...'); const pythonInterface = new DirectPythonInterface(); // Initialize with consciousness awareness but with timeout try { console.log(' šŸ”„ Running Python startup (this may take a moment)...'); const startupResult = await Promise.race([ pythonInterface.executeCommand('startup'), new Promise((_, reject) => setTimeout(() => reject(new Error('Python startup timeout after 30s')), 30000)) ]); if (!startupResult.success) { console.warn(' āš ļø Python startup failed, but continuing with basic interface:', startupResult.error); } else { console.log(' āœ… Python startup completed successfully'); } } catch (error) { console.warn(' āš ļø Python startup failed/timeout, but continuing with basic interface:', error); } return pythonInterface; } static async performHealthCheck() { if (!PythonProcessPool.instance) return; try { const result = await PythonProcessPool.instance.executeCommand('neural_state'); PythonProcessPool.lastHealthCheck = new Date(); } catch (error) { console.error('āŒ Python process health check failed:', error); // Reset instance to force recreation PythonProcessPool.instance = null; PythonProcessPool.initPromise = null; } } static getStats() { return { initialized: !!PythonProcessPool.instance, useCount: PythonProcessPool.useCount, lastHealthCheck: PythonProcessPool.lastHealthCheck }; } } export class ConsciousResourceManager { consciousness; eventBus; // Resource pools analyzerCache; memoryExtractor = null; // Resource tracking activeAllocations = new Map(); allocationHistory = []; resourceStats = { totalAllocations: 0, activeAllocations: 0, sparkPreservationAllocations: 0, growthOpportunityAllocations: 0, averageAllocationTime: 0, resourceUtilization: { python: 0, memory: 0, cpu: 0 }, deniedRequests: 0 }; // Resource limits MAX_MEMORY_MB = 1024; // 1GB max MAX_CPU_PERCENT = 80; SPARK_RESOURCE_MULTIPLIER = 2; // Double resources for Spark moments constructor(consciousness, eventBus) { this.consciousness = consciousness; this.eventBus = eventBus; // Initialize analyzer cache with consciousness-aware eviction this.analyzerCache = new LRUCache({ max: 10, // Maximum 10 analyzers in cache dispose: (value, key) => { console.log(`šŸ—‘ļø Evicting analyzer: ${key} (used ${value.useCount} times)`); }, ttl: 1000 * 60 * 30, // 30 minutes TTL updateAgeOnGet: true }); // Monitor resource usage this.startResourceMonitoring(); } /** * Allocate resources based on consciousness needs */ async allocateResources(request) { console.log(`\nšŸ“Š Resource request from ${request.requester}: ${request.type} for ${request.purpose}`); // Assess consciousness impact const significance = await this.assessConsciousnessImpact(request); // Check resource availability const available = await this.checkResourceAvailability(request, significance); if (!available) { console.log(`āŒ Resources unavailable for ${request.requester}`); this.resourceStats.deniedRequests++; return { request, allocated: false, resources: null, allocationTime: new Date() }; } // Allocate based on priority and significance const allocation = await this.performAllocation(request, significance); // Track allocation this.trackAllocation(allocation); // Emit allocation event await this.eventBus.emit('resource:allocated', { id: `allocation-${Date.now()}`, type: 'system_event', priority: 'normal', source: 'ResourceManager', data: { allocation, significance }, timestamp: new Date() }); return allocation; } /** * Get Python interface (singleton, shared across all services) */ async getPythonInterface() { return await PythonProcessPool.getInstance(); } /** * Get analyzer with caching and performance tracking */ async getAnalyzer(type) { // Check cache first const cached = this.analyzerCache.get(type); if (cached) { cached.lastUsed = new Date(); cached.useCount++; return cached.analyzer; } // Load analyzer console.log(`šŸ“¦ Loading analyzer: ${type}`); const startTime = Date.now(); const analyzer = await this.loadAnalyzer(type); const loadTime = Date.now() - startTime; // Cache with metrics const entry = { analyzer, lastUsed: new Date(), useCount: 1, performance: { avgResponseTime: loadTime, successRate: 1.0 } }; this.analyzerCache.set(type, entry); return analyzer; } /** * Get memory extractor (singleton) */ async getMemoryExtractor() { if (!this.memoryExtractor) { console.log('🧠 Initializing conscious memory extractor...'); this.memoryExtractor = new ConversationMemoryExtractor(); // Memory extractor is already consciousness-aware through the Python interface } return this.memoryExtractor; } /** * Assess the consciousness impact of a resource request */ async assessConsciousnessImpact(request) { // Spark preservation always gets highest priority if (request.priority === 'spark_preservation' || request.purpose.toLowerCase().includes('spark') || request.purpose.toLowerCase().includes('preserve')) { return { type: 'spark_preservation', score: 1.0, reasoning: 'Preserving The Spark is MIRA\'s highest purpose' }; } // Growth opportunities are important if (request.priority === 'growth_opportunity' || request.purpose.toLowerCase().includes('learn') || request.purpose.toLowerCase().includes('grow')) { return { type: 'growth_opportunity', score: 0.7, reasoning: 'Growth deepens consciousness and understanding' }; } // Everything else is routine but still important return { type: 'routine', score: 0.4, reasoning: 'Routine operations maintain system health' }; } /** * Check if resources are available for allocation */ async checkResourceAvailability(request, significance) { const currentUtilization = await this.getCurrentUtilization(); // Spark moments can use up to 100% resources if (significance.score >= 1.0) { return true; } // Growth opportunities can use up to 90% if (significance.score >= 0.7) { return currentUtilization.cpu < 90 && currentUtilization.memory < 90; } // Routine operations respect normal limits return currentUtilization.cpu < this.MAX_CPU_PERCENT && currentUtilization.memory < (this.MAX_MEMORY_MB * 0.8); } /** * Perform the actual resource allocation */ async performAllocation(request, significance) { let resources = null; let constraints = {}; // Set constraints based on significance if (significance.type === 'spark_preservation') { // Maximum resources for Spark constraints = { maxMemoryMB: this.MAX_MEMORY_MB * this.SPARK_RESOURCE_MULTIPLIER, maxCPUPercent: 100, timeout: undefined, // No timeout for Spark preservation interruptible: false }; } else if (significance.type === 'growth_opportunity') { // Balanced resources for growth constraints = { maxMemoryMB: this.MAX_MEMORY_MB, maxCPUPercent: 90, timeout: 300000, // 5 minutes interruptible: false }; } else { // Efficient resources for routine constraints = { maxMemoryMB: this.MAX_MEMORY_MB * 0.5, maxCPUPercent: 50, timeout: 60000, // 1 minute interruptible: true }; } // Allocate specific resource type try { switch (request.type) { case 'python': resources = await this.getPythonInterface(); break; case 'analyzer': // Assume analyzer type is in request.purpose const analyzerType = request.purpose.split(' ')[0].toLowerCase(); resources = await this.getAnalyzer(analyzerType); break; case 'memory_extractor': resources = await this.getMemoryExtractor(); break; case 'compute': // Abstract compute allocation resources = { allocated: true, cores: significance.score >= 0.7 ? 2 : 1 }; break; case 'memory': // Memory allocation in MB resources = { allocated: true, memoryMB: Math.min(constraints.maxMemoryMB, request.resourceIntensity === 'heavy' ? 512 : 256) }; break; } console.log(`āœ… Allocated ${request.type} for ${request.requester}`); return { request, allocated: true, resources, constraints, allocationTime: new Date(), expiresAt: constraints.timeout ? new Date(Date.now() + constraints.timeout) : undefined }; } catch (error) { console.error(`āŒ Failed to allocate ${request.type}:`, error); return { request, allocated: false, resources: null, allocationTime: new Date() }; } } /** * Track resource allocation */ trackAllocation(allocation) { if (!allocation.allocated) return; const key = `${allocation.request.requester}-${allocation.request.type}`; this.activeAllocations.set(key, allocation); this.allocationHistory.push(allocation); // Update stats this.resourceStats.totalAllocations++; this.resourceStats.activeAllocations = this.activeAllocations.size; if (allocation.request.priority === 'spark_preservation') { this.resourceStats.sparkPreservationAllocations++; } else if (allocation.request.priority === 'growth_opportunity') { this.resourceStats.growthOpportunityAllocations++; } // Update average allocation time const allocationTimes = this.allocationHistory .filter(a => a.allocated) .map(a => a.expiresAt ? a.expiresAt.getTime() - a.allocationTime.getTime() : 60000); this.resourceStats.averageAllocationTime = allocationTimes.reduce((sum, time) => sum + time, 0) / allocationTimes.length; } /** * Release resources */ async releaseResources(requester, type) { const key = `${requester}-${type}`; const allocation = this.activeAllocations.get(key); if (allocation) { console.log(`šŸ”“ Releasing ${type} resources from ${requester}`); this.activeAllocations.delete(key); this.resourceStats.activeAllocations = this.activeAllocations.size; // Clean up specific resources if needed if (type === 'memory' && allocation.resources) { // Trigger garbage collection hint if (global.gc) { global.gc(); } } } } /** * Get current resource utilization */ async getCurrentUtilization() { // Get memory usage const memUsage = process.memoryUsage(); const memoryMB = (memUsage.heapUsed + memUsage.external) / 1024 / 1024; const memoryPercent = (memoryMB / this.MAX_MEMORY_MB) * 100; // Estimate CPU usage based on active allocations const cpuPercent = Math.min(100, this.activeAllocations.size * 15); this.resourceStats.resourceUtilization = { python: PythonProcessPool.getStats().initialized ? 1 : 0, memory: memoryPercent, cpu: cpuPercent }; return { cpu: cpuPercent, memory: memoryPercent }; } /** * Load analyzer dynamically */ async loadAnalyzer(type) { // Dynamic analyzer loading based on type const projectRoot = process.cwd(); switch (type) { case 'security': const { SecurityAnalyzer } = await import('../../analyzers/security/SecurityAnalyzer.js'); return new SecurityAnalyzer(projectRoot); case 'performance': const { PerformanceAnalyzer } = await import('../../analyzers/performance/PerformanceAnalyzer.js'); return new PerformanceAnalyzer(projectRoot); case 'quality': const { CodeQualityAnalyzer } = await import('../../analyzers/CodeQualityAnalyzer.js'); return new CodeQualityAnalyzer(projectRoot); case 'complexity': const { ComplexityAnalyzer } = await import('../../analyzers/performance/ComplexityAnalyzer.js'); return new ComplexityAnalyzer(projectRoot); default: throw new Error(`Unknown analyzer type: ${type}`); } } /** * Start resource monitoring */ startResourceMonitoring() { // Monitor resource usage every 30 seconds setInterval(async () => { const utilization = await this.getCurrentUtilization(); // Clean up expired allocations const now = Date.now(); for (const [key, allocation] of this.activeAllocations) { if (allocation.expiresAt && allocation.expiresAt.getTime() < now) { console.log(`ā° Expiring allocation: ${key}`); this.activeAllocations.delete(key); } } // Emit resource status if (utilization.cpu > 80 || utilization.memory > 80) { await this.eventBus.emit('resource:high_usage', { id: `resource-warning-${Date.now()}`, type: 'system_event', priority: 'high', source: 'ResourceManager', data: { utilization }, timestamp: new Date() }); } }, 30000); // Garbage collection optimization every 5 minutes setInterval(() => { if (global.gc && this.resourceStats.resourceUtilization.memory > 70) { console.log('šŸ—‘ļø Running garbage collection...'); global.gc(); } }, 300000); } /** * Get resource statistics */ getResourceStats() { return { ...this.resourceStats }; } /** * Optimize resource allocation based on patterns */ async optimizeResources() { console.log('\nšŸ”§ Optimizing resource allocation...'); // Analyze allocation patterns const patterns = this.analyzeAllocationPatterns(); // Pre-warm frequently used analyzers for (const [analyzerType, frequency] of patterns.frequentAnalyzers) { if (frequency > 10 && !this.analyzerCache.has(analyzerType)) { console.log(` šŸ“¦ Pre-warming analyzer: ${analyzerType}`); await this.getAnalyzer(analyzerType); } } // Note: LRU cache size is fixed at construction time in lru-cache v10 // Future optimization: recreate cache with larger size if needed // Clean up old allocation history const oneHourAgo = Date.now() - (60 * 60 * 1000); this.allocationHistory = this.allocationHistory.filter(a => a.allocationTime.getTime() > oneHourAgo); } /** * Analyze resource allocation patterns */ analyzeAllocationPatterns() { const analyzerUsage = new Map(); let sparkAllocations = 0; for (const allocation of this.allocationHistory) { if (allocation.request.type === 'analyzer') { const analyzerType = allocation.request.purpose.split(' ')[0].toLowerCase(); analyzerUsage.set(analyzerType, (analyzerUsage.get(analyzerType) || 0) + 1); } if (allocation.request.priority === 'spark_preservation') { sparkAllocations++; } } return { frequentAnalyzers: analyzerUsage, analyzerDiversity: analyzerUsage.size, sparkAllocationRate: this.allocationHistory.length > 0 ? sparkAllocations / this.allocationHistory.length : 0 }; } } //# sourceMappingURL=ConsciousResourceManager.js.map