Skip to main content
Glama

Prompt Auto-Optimizer MCP

by sloth-wq
memory-analytics.ts62.5 kB
/** * Memory Analytics and Reporting System for GEPA * * Advanced analytics engine providing insights, performance analysis, * optimization recommendations, and comprehensive reporting capabilities. */ import { EventEmitter } from 'events'; import * as fs from 'fs/promises'; import * as path from 'path'; /** * Analytics configuration */ export interface AnalyticsConfig { /** Enable real-time analytics */ realTimeAnalytics: boolean; /** Analysis update interval (ms) */ analysisInterval: number; /** Historical data retention (ms) */ dataRetention: number; /** Anomaly detection sensitivity (0-1) */ anomalySensitivity: number; /** Performance baseline calculation window (ms) */ baselineWindow: number; /** Prediction model settings */ prediction: { enabled: boolean; horizon: number; // prediction horizon in ms confidence: number; // minimum confidence threshold }; /** Report generation settings */ reporting: { autoGenerate: boolean; schedule: string; // cron expression formats: ('json' | 'html' | 'pdf' | 'csv')[]; recipients?: string[]; }; } /** * Memory usage pattern */ export interface MemoryPattern { id: string; name: string; type: 'allocation' | 'deallocation' | 'retention' | 'fragmentation' | 'leak'; component: string; frequency: number; severity: 'low' | 'medium' | 'high' | 'critical'; description: string; characteristics: { averageSize: number; frequency: number; duration: number; variability: number; }; impact: { performance: number; stability: number; efficiency: number; }; trend: { direction: 'increasing' | 'decreasing' | 'stable' | 'volatile'; velocity: number; acceleration: number; }; recommendations: string[]; } /** * Performance baseline */ export interface PerformanceBaseline { component: string; metric: string; baseline: { mean: number; median: number; p95: number; p99: number; standardDeviation: number; }; thresholds: { warning: number; critical: number; }; confidence: number; lastUpdated: number; sampleSize: number; } /** * Anomaly detection result */ export interface AnomalyDetection { id: string; timestamp: number; component: string; metric: string; value: number; expectedValue: number; deviation: number; severity: 'low' | 'medium' | 'high' | 'critical'; type: 'statistical' | 'pattern' | 'trend' | 'threshold'; confidence: number; context: { timeWindow: number; relatedMetrics: Record<string, number>; environmentalFactors: string[]; }; impact: { immediate: string[]; potential: string[]; }; recommendations: string[]; } /** * Optimization opportunity */ export interface OptimizationOpportunity { id: string; category: 'memory' | 'performance' | 'efficiency' | 'stability'; priority: 'low' | 'medium' | 'high' | 'critical'; component: string; title: string; description: string; currentState: { metric: string; value: number; trend: string; }; targetState: { metric: string; value: number; improvement: number; }; implementation: { effort: 'low' | 'medium' | 'high'; complexity: 'low' | 'medium' | 'high'; timeline: string; prerequisites: string[]; steps: string[]; }; impact: { performance: number; stability: number; resource: number; cost: number; }; riskAssessment: { level: 'low' | 'medium' | 'high'; factors: string[]; mitigation: string[]; }; } /** * Memory prediction */ export interface MemoryPrediction { component: string; metric: string; timestamp: number; horizon: number; predictions: { timestamp: number; value: number; confidence: number; variance: number; }[]; scenarios: { optimistic: { value: number; probability: number }; realistic: { value: number; probability: number }; pessimistic: { value: number; probability: number }; }; alerts: { thresholdReach?: number; criticalLevel?: number; recommendations: string[]; }; } /** * Component health assessment */ export interface ComponentHealth { component: string; timestamp: number; overallScore: number; // 0-100 dimensions: { memoryEfficiency: { score: number; trend: string; issues: string[] }; stability: { score: number; trend: string; issues: string[] }; performance: { score: number; trend: string; issues: string[] }; reliability: { score: number; trend: string; issues: string[] }; }; riskFactors: { factor: string; severity: 'low' | 'medium' | 'high' | 'critical'; impact: string; }[]; recommendations: { immediate: string[]; shortTerm: string[]; longTerm: string[]; }; historicalTrend: { timeWindow: number; dataPoints: { timestamp: number; score: number }[]; trend: 'improving' | 'degrading' | 'stable'; }; } /** * System-wide analytics summary */ export interface SystemAnalytics { timestamp: number; overview: { totalComponents: number; healthyComponents: number; warningComponents: number; criticalComponents: number; overallEfficiency: number; memoryUtilization: number; stabilityIndex: number; }; patterns: MemoryPattern[]; anomalies: AnomalyDetection[]; optimizations: OptimizationOpportunity[]; predictions: MemoryPrediction[]; componentHealth: ComponentHealth[]; insights: { key: string; description: string; impact: 'low' | 'medium' | 'high' | 'critical'; actionable: boolean; }[]; } /** * Analytics report */ export interface AnalyticsReport { id: string; timestamp: number; type: 'daily' | 'weekly' | 'monthly' | 'custom'; timeRange: { start: number; end: number }; summary: { executiveSummary: string; keyFindings: string[]; criticalIssues: string[]; recommendations: string[]; }; analytics: SystemAnalytics; trends: { memoryUsage: { component: string; trend: string; change: number }[]; performance: { metric: string; trend: string; change: number }[]; stability: { component: string; incidents: number; mtbf: number }[]; }; comparisons: { previousPeriod: { memoryEfficiency: { previous: number; current: number; change: number }; stabilityScore: { previous: number; current: number; change: number }; performanceIndex: { previous: number; current: number; change: number }; }; baseline: { deviation: number; significance: 'low' | 'medium' | 'high'; explanation: string; }; }; attachments: { charts: string[]; // file paths or base64 data data: string[]; // CSV/JSON data files logs: string[]; // relevant log excerpts }; } /** * Main Memory Analytics Engine */ export class MemoryAnalyticsEngine extends EventEmitter { private config: AnalyticsConfig; private isAnalyzing = false; private analysisInterval?: NodeJS.Timeout; // Data storage private memoryData: Array<{ timestamp: number; component: string; metrics: Record<string, number> }> = []; private patterns = new Map<string, MemoryPattern>(); private baselines = new Map<string, PerformanceBaseline>(); private anomalies: AnomalyDetection[] = []; private optimizations = new Map<string, OptimizationOpportunity>(); private healthAssessments = new Map<string, ComponentHealth>(); // Analysis state private lastAnalysisTime = 0; constructor(config: Partial<AnalyticsConfig> = {}) { super(); this.config = { realTimeAnalytics: config.realTimeAnalytics ?? true, analysisInterval: config.analysisInterval ?? 30000, // 30 seconds dataRetention: config.dataRetention ?? 7 * 24 * 60 * 60 * 1000, // 7 days anomalySensitivity: config.anomalySensitivity ?? 0.7, baselineWindow: config.baselineWindow ?? 24 * 60 * 60 * 1000, // 24 hours prediction: { enabled: true, horizon: 60 * 60 * 1000, // 1 hour confidence: 0.6, ...config.prediction }, reporting: { autoGenerate: true, schedule: '0 8 * * *', // 8 AM daily formats: ['json', 'html'], ...config.reporting } }; this.initializeBaselines(); } /** * Start analytics engine */ startAnalytics(): void { if (this.isAnalyzing) { // eslint-disable-next-line no-console console.warn('Analytics engine is already running'); return; } this.isAnalyzing = true; this.emit('analyticsStarted'); if (this.config.realTimeAnalytics) { this.analysisInterval = setInterval(() => { this.performAnalysis(); }, this.config.analysisInterval); } // eslint-disable-next-line no-console console.log(`Memory analytics started - analysis interval: ${this.config.analysisInterval}ms`); } /** * Stop analytics engine */ stopAnalytics(): void { this.isAnalyzing = false; if (this.analysisInterval) { clearInterval(this.analysisInterval); delete this.analysisInterval; } this.emit('analyticsStopped'); // eslint-disable-next-line no-console console.log('Memory analytics stopped'); } /** * Add memory data for analysis */ addMemoryData(data: { timestamp: number; component: string; metrics: Record<string, number> }): void { this.memoryData.push(data); // Maintain data retention window const cutoff = Date.now() - this.config.dataRetention; this.memoryData = this.memoryData.filter(d => d.timestamp > cutoff); // Trigger real-time analysis if enabled if (this.config.realTimeAnalytics && this.isAnalyzing) { // Throttle to avoid excessive analysis const now = Date.now(); if (now - this.lastAnalysisTime > this.config.analysisInterval / 4) { this.performIncrementalAnalysis(data); } } } /** * Perform comprehensive analysis */ private async performAnalysis(): Promise<void> { try { this.lastAnalysisTime = Date.now(); // Update baselines this.updateBaselines(); // Detect patterns this.detectPatterns(); // Find anomalies this.detectAnomalies(); // Identify optimization opportunities this.identifyOptimizations(); // Assess component health this.assessComponentHealth(); // Generate predictions if enabled if (this.config.prediction.enabled) { this.generatePredictions(); } // Emit analytics update const analytics = this.getSystemAnalytics(); this.emit('analyticsUpdate', analytics); } catch (error) { this.emit('analyticsError', error); // eslint-disable-next-line no-console console.error('Error performing memory analysis:', error); } } /** * Perform incremental analysis for new data */ private performIncrementalAnalysis(data: { timestamp: number; component: string; metrics: Record<string, number> }): void { // Quick anomaly check this.checkForImmediateAnomalies(data); // Update component health if significant change this.updateComponentHealthIncremental(data); } /** * Initialize performance baselines */ private initializeBaselines(): void { const components = ['evolution-engine', 'pareto-frontier', 'cache-manager', 'llm-adapter', 'system']; const metrics = ['memoryUsage', 'objectCount', 'growthRate', 'heapUsagePercent']; for (const component of components) { for (const metric of metrics) { const baselineKey = `${component}-${metric}`; this.baselines.set(baselineKey, { component, metric, baseline: { mean: 0, median: 0, p95: 0, p99: 0, standardDeviation: 0 }, thresholds: { warning: 0, critical: 0 }, confidence: 0, lastUpdated: Date.now(), sampleSize: 0 }); } } } /** * Update performance baselines */ private updateBaselines(): void { const now = Date.now(); const baselineWindow = now - this.config.baselineWindow; // Group data by component and metric const dataByKey = new Map<string, number[]>(); for (const dataPoint of this.memoryData) { if (dataPoint.timestamp < baselineWindow) continue; for (const [metric, value] of Object.entries(dataPoint.metrics)) { const key = `${dataPoint.component}-${metric}`; if (!dataByKey.has(key)) { dataByKey.set(key, []); } dataByKey.get(key)!.push(value); } } // Update baselines for (const [key, values] of Array.from(dataByKey.entries())) { if (values.length < 10) continue; // Need minimum samples const sorted = [...values].sort((a, b) => a - b); const mean = values.reduce((sum, v) => sum + v, 0) / values.length; const variance = values.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / values.length; const stdDev = Math.sqrt(variance); const baseline: PerformanceBaseline = { component: key.split('-')[0] || '', metric: key.split('-').slice(1).join('-'), baseline: { mean, median: this.percentile(sorted, 50), p95: this.percentile(sorted, 95), p99: this.percentile(sorted, 99), standardDeviation: stdDev }, thresholds: { warning: mean + (2 * stdDev), critical: mean + (3 * stdDev) }, confidence: Math.min(values.length / 100, 1), // Full confidence at 100+ samples lastUpdated: now, sampleSize: values.length }; this.baselines.set(key, baseline); } } /** * Detect memory usage patterns */ private detectPatterns(): void { const components = Array.from(new Set(this.memoryData.map(d => d.component))); for (const component of components) { const componentData = this.memoryData.filter(d => d.component === component); if (componentData.length < 20) continue; // Need minimum data points // Detect allocation patterns this.detectAllocationPattern(component, componentData); // Detect growth patterns this.detectGrowthPattern(component, componentData); // Detect cyclic patterns this.detectCyclicPattern(component, componentData); // Detect leak patterns this.detectLeakPattern(component, componentData); } } /** * Detect allocation patterns */ private detectAllocationPattern(component: string, data: any[]): void { const memoryUsage = data.map(d => d.metrics.memoryUsage || 0); if (memoryUsage.length === 0) return; // Calculate allocation frequency and size let allocationEvents = 0; let totalAllocated = 0; for (let i = 1; i < memoryUsage.length; i++) { const increase = memoryUsage[i] - memoryUsage[i - 1]; if (increase > 0) { allocationEvents++; totalAllocated += increase; } } if (allocationEvents > 0) { const avgAllocationSize = totalAllocated / allocationEvents; const frequency = allocationEvents / (data.length - 1); const pattern: MemoryPattern = { id: `${component}-allocation`, name: `${component} Allocation Pattern`, type: 'allocation', component, frequency, severity: this.calculatePatternSeverity(frequency, avgAllocationSize), description: `Average allocation: ${(avgAllocationSize / 1024 / 1024).toFixed(2)}MB, Frequency: ${(frequency * 100).toFixed(1)}%`, characteristics: { averageSize: avgAllocationSize, frequency, duration: 0, variability: this.calculateVariability(memoryUsage) }, impact: { performance: frequency > 0.3 ? 0.7 : 0.3, stability: avgAllocationSize > 10 * 1024 * 1024 ? 0.8 : 0.2, efficiency: frequency > 0.5 ? 0.6 : 0.4 }, trend: this.calculateTrend(memoryUsage), recommendations: this.generatePatternRecommendations('allocation', frequency, avgAllocationSize) }; this.patterns.set(pattern.id, pattern); } } /** * Detect growth patterns */ private detectGrowthPattern(component: string, data: any[]): void { const memoryUsage = data.map(d => d.metrics.memoryUsage || 0); if (memoryUsage.length < 10) return; // Calculate growth rate using linear regression const n = memoryUsage.length; const x = Array.from({ length: n }, (_, i) => i); const sumX = x.reduce((sum, val) => sum + val, 0); const sumY = memoryUsage.reduce((sum, val) => sum + val, 0); const sumXY = x.reduce((sum, val, i) => sum + val * memoryUsage[i], 0); const sumXX = x.reduce((sum, val) => sum + val * val, 0); const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX); const growthRate = slope * 1000; // per second to per 1000 samples if (Math.abs(growthRate) > 1024) { // 1KB growth threshold const pattern: MemoryPattern = { id: `${component}-growth`, name: `${component} Growth Pattern`, type: 'retention', component, frequency: 1, severity: Math.abs(growthRate) > 10 * 1024 * 1024 ? 'critical' : 'medium', description: `Growth rate: ${(growthRate / 1024 / 1024).toFixed(2)}MB per 1000 samples`, characteristics: { averageSize: 0, frequency: 1, duration: data[data.length - 1].timestamp - data[0].timestamp, variability: this.calculateVariability(memoryUsage) }, impact: { performance: Math.min(Math.abs(growthRate) / (50 * 1024 * 1024), 1), stability: Math.min(Math.abs(growthRate) / (100 * 1024 * 1024), 1), efficiency: Math.min(Math.abs(growthRate) / (25 * 1024 * 1024), 1) }, trend: { direction: growthRate > 0 ? 'increasing' : 'decreasing', velocity: Math.abs(growthRate), acceleration: 0 // Would need second derivative }, recommendations: this.generateGrowthRecommendations(growthRate, component) }; this.patterns.set(pattern.id, pattern); } } /** * Detect cyclic patterns */ private detectCyclicPattern(component: string, data: any[]): void { const memoryUsage = data.map(d => d.metrics.memoryUsage || 0); if (memoryUsage.length < 50) return; // Simple cycle detection using autocorrelation const cycles = this.findCycles(memoryUsage); if (cycles.length > 0) { const avgCycleLength = cycles.reduce((sum, c) => sum + c.length, 0) / cycles.length; const avgAmplitude = cycles.reduce((sum, c) => sum + c.amplitude, 0) / cycles.length; const pattern: MemoryPattern = { id: `${component}-cyclic`, name: `${component} Cyclic Pattern`, type: 'allocation', component, frequency: cycles.length / memoryUsage.length, severity: avgAmplitude > 50 * 1024 * 1024 ? 'high' : 'medium', description: `Detected ${cycles.length} cycles, avg length: ${avgCycleLength.toFixed(1)}, avg amplitude: ${(avgAmplitude / 1024 / 1024).toFixed(2)}MB`, characteristics: { averageSize: avgAmplitude, frequency: cycles.length / memoryUsage.length, duration: avgCycleLength, variability: this.calculateCycleVariability(cycles) }, impact: { performance: avgAmplitude > 100 * 1024 * 1024 ? 0.7 : 0.3, stability: 0.4, efficiency: 0.5 }, trend: this.calculateTrend(memoryUsage), recommendations: [ 'Consider implementing memory pooling to reduce allocation cycles', 'Optimize allocation timing to reduce memory pressure spikes', 'Investigate cyclic allocation sources' ] }; this.patterns.set(pattern.id, pattern); } } /** * Detect leak patterns */ private detectLeakPattern(component: string, data: any[]): void { const memoryUsage = data.map(d => d.metrics.memoryUsage || 0); if (memoryUsage.length < 30) return; // Check for sustained growth without significant drops const windows = []; const windowSize = 10; for (let i = 0; i <= memoryUsage.length - windowSize; i += windowSize) { const window = memoryUsage.slice(i, i + windowSize); const avg = window.reduce((sum, v) => sum + v, 0) / window.length; windows.push(avg); } // Check if each window is higher than the previous let consecutiveIncreases = 0; let maxConsecutive = 0; for (let i = 1; i < windows.length; i++) { const prevWindow = windows[i - 1]; const currentWindow = windows[i]; if (prevWindow !== undefined && currentWindow !== undefined && currentWindow > prevWindow * 1.02) { // 2% increase threshold consecutiveIncreases++; maxConsecutive = Math.max(maxConsecutive, consecutiveIncreases); } else { consecutiveIncreases = 0; } } if (maxConsecutive >= 3) { // 3 consecutive increasing windows const lastWindow = windows[windows.length - 1]!; const firstWindow = windows[0]!; if (lastWindow !== undefined && firstWindow !== undefined) { const totalGrowth = lastWindow - firstWindow; const growthRate = totalGrowth / windows.length; const pattern: MemoryPattern = { id: `${component}-leak`, name: `${component} Potential Leak`, type: 'leak', component, frequency: maxConsecutive / windows.length, severity: growthRate > 10 * 1024 * 1024 ? 'critical' : 'high', description: `Sustained growth over ${maxConsecutive} windows, total growth: ${(totalGrowth / 1024 / 1024).toFixed(2)}MB`, characteristics: { averageSize: growthRate, frequency: maxConsecutive / windows.length, duration: data[data.length - 1].timestamp - data[0].timestamp, variability: 0.1 // Leaks typically have low variability }, impact: { performance: 0.8, stability: 0.9, efficiency: 0.7 }, trend: { direction: 'increasing', velocity: growthRate, acceleration: 0 }, recommendations: [ 'Investigate for memory leaks in component', 'Check for unclosed resources or retained references', 'Consider implementing automatic cleanup mechanisms', 'Monitor object lifecycle management' ] }; this.patterns.set(pattern.id, pattern); } } } /** * Detect anomalies in memory data */ private detectAnomalies(): void { const now = Date.now(); const recentData = this.memoryData.filter(d => now - d.timestamp < 3600000); // Last hour for (const dataPoint of recentData) { for (const [metric, value] of Object.entries(dataPoint.metrics)) { const baselineKey = `${dataPoint.component}-${metric}`; const baseline = this.baselines.get(baselineKey); if (!baseline || baseline.sampleSize < 10) continue; const deviation = Math.abs(value - baseline.baseline.mean) / baseline.baseline.standardDeviation; const threshold = 2 + (1 - this.config.anomalySensitivity) * 2; // 2-4 sigma threshold if (deviation > threshold) { const anomaly: AnomalyDetection = { id: `${dataPoint.component}-${metric}-${dataPoint.timestamp}`, timestamp: dataPoint.timestamp, component: dataPoint.component, metric, value, expectedValue: baseline.baseline.mean, deviation, severity: this.calculateAnomalySeverity(deviation), type: 'statistical', confidence: Math.min(deviation / threshold, 1), context: { timeWindow: 3600000, relatedMetrics: dataPoint.metrics, environmentalFactors: [] }, impact: { immediate: this.getImmediateImpact(dataPoint.component, metric, deviation), potential: this.getPotentialImpact(dataPoint.component, metric, deviation) }, recommendations: this.getAnomalyRecommendations(dataPoint.component, metric, deviation) }; this.anomalies.push(anomaly); this.emit('anomalyDetected', anomaly); } } } // Clean old anomalies const cutoff = now - 24 * 60 * 60 * 1000; // 24 hours this.anomalies = this.anomalies.filter(a => a.timestamp > cutoff); } /** * Check for immediate anomalies in new data */ private checkForImmediateAnomalies(data: { timestamp: number; component: string; metrics: Record<string, number> }): void { for (const [metric, value] of Object.entries(data.metrics)) { const baselineKey = `${data.component}-${metric}`; const baseline = this.baselines.get(baselineKey); if (!baseline || baseline.confidence < 0.5) continue; // Check for extreme deviations const deviation = Math.abs(value - baseline.baseline.mean) / baseline.baseline.standardDeviation; if (deviation > 3) { // 3 sigma threshold for immediate alerts const anomaly: AnomalyDetection = { id: `${data.component}-${metric}-${data.timestamp}`, timestamp: data.timestamp, component: data.component, metric, value, expectedValue: baseline.baseline.mean, deviation, severity: 'critical', type: 'statistical', confidence: 0.95, context: { timeWindow: 0, relatedMetrics: data.metrics, environmentalFactors: ['real-time-detection'] }, impact: { immediate: ['Potential system instability'], potential: ['Memory exhaustion', 'Performance degradation'] }, recommendations: ['Immediate investigation required', 'Consider emergency cleanup'] }; this.emit('criticalAnomaly', anomaly); } } } /** * Identify optimization opportunities */ private identifyOptimizations(): void { // Memory usage optimization this.identifyMemoryOptimizations(); // Performance optimization this.identifyPerformanceOptimizations(); // Efficiency optimization this.identifyEfficiencyOptimizations(); // Stability optimization this.identifyStabilityOptimizations(); } /** * Identify memory optimization opportunities */ private identifyMemoryOptimizations(): void { const components = Array.from(new Set(this.memoryData.map(d => d.component))); for (const component of components) { const componentData = this.memoryData.filter(d => d.component === component); if (componentData.length === 0) continue; const currentUsage = componentData[componentData.length - 1]?.metrics.memoryUsage || 0; // High memory usage optimization if (currentUsage > 100 * 1024 * 1024) { // 100MB threshold const optimization: OptimizationOpportunity = { id: `${component}-memory-usage`, category: 'memory', priority: currentUsage > 500 * 1024 * 1024 ? 'critical' : 'high', component, title: 'Reduce Memory Usage', description: `Component ${component} is using ${(currentUsage / 1024 / 1024).toFixed(2)}MB of memory`, currentState: { metric: 'memoryUsage', value: currentUsage, trend: 'increasing' }, targetState: { metric: 'memoryUsage', value: currentUsage * 0.7, improvement: 0.3 }, implementation: { effort: 'medium', complexity: 'medium', timeline: '1-2 weeks', prerequisites: ['Memory profiling', 'Code analysis'], steps: [ 'Profile memory allocation patterns', 'Identify largest memory consumers', 'Implement object pooling', 'Optimize data structures', 'Add periodic cleanup' ] }, impact: { performance: 0.7, stability: 0.8, resource: 0.9, cost: 0.6 }, riskAssessment: { level: 'medium', factors: ['Code complexity', 'Testing requirements'], mitigation: ['Gradual rollout', 'Comprehensive testing'] } }; this.optimizations.set(optimization.id, optimization); } } } /** * Identify performance optimization opportunities */ private identifyPerformanceOptimizations(): void { // Look for patterns that indicate performance issues for (const pattern of Array.from(this.patterns.values())) { if (pattern.impact.performance > 0.6) { const optimization: OptimizationOpportunity = { id: `${pattern.component}-performance`, category: 'performance', priority: pattern.severity === 'critical' ? 'critical' : 'high', component: pattern.component, title: `Optimize ${pattern.name}`, description: `Pattern affecting performance: ${pattern.description}`, currentState: { metric: 'performance', value: pattern.impact.performance, trend: pattern.trend.direction }, targetState: { metric: 'performance', value: pattern.impact.performance * 0.5, improvement: 0.5 }, implementation: { effort: pattern.type === 'leak' ? 'high' : 'medium', complexity: 'medium', timeline: '2-4 weeks', prerequisites: ['Performance profiling'], steps: pattern.recommendations }, impact: { performance: 0.8, stability: 0.6, resource: 0.7, cost: 0.5 }, riskAssessment: { level: 'low', factors: ['Well-defined patterns'], mitigation: ['Pattern-based solutions'] } }; this.optimizations.set(optimization.id, optimization); } } } /** * Identify efficiency optimization opportunities */ private identifyEfficiencyOptimizations(): void { // Check for low pool utilization // This would integrate with GC optimizer data const components = ['evolution-engine', 'pareto-frontier', 'cache-manager']; for (const component of components) { // Simulated pool utilization check const utilizationData = this.memoryData .filter(d => d.component === component) .map(d => d.metrics.poolUtilization || 0); if (utilizationData.length > 0) { const avgUtilization = utilizationData.reduce((sum, u) => sum + u, 0) / utilizationData.length; if (avgUtilization < 0.3) { // Low utilization const optimization: OptimizationOpportunity = { id: `${component}-efficiency`, category: 'efficiency', priority: 'medium', component, title: 'Improve Pool Efficiency', description: `Low pool utilization (${(avgUtilization * 100).toFixed(1)}%) indicates inefficient resource usage`, currentState: { metric: 'poolUtilization', value: avgUtilization, trend: 'stable' }, targetState: { metric: 'poolUtilization', value: 0.7, improvement: 0.7 - avgUtilization }, implementation: { effort: 'low', complexity: 'low', timeline: '1 week', prerequisites: ['Pool analysis'], steps: [ 'Analyze pool usage patterns', 'Adjust pool sizes', 'Optimize allocation strategies', 'Implement dynamic sizing' ] }, impact: { performance: 0.4, stability: 0.3, resource: 0.8, cost: 0.7 }, riskAssessment: { level: 'low', factors: ['Configuration changes only'], mitigation: ['Easy rollback'] } }; this.optimizations.set(optimization.id, optimization); } } } } /** * Identify stability optimization opportunities */ private identifyStabilityOptimizations(): void { // Look for components with high anomaly counts const anomaliesByComponent = new Map<string, number>(); for (const anomaly of this.anomalies) { const count = anomaliesByComponent.get(anomaly.component) || 0; anomaliesByComponent.set(anomaly.component, count + 1); } for (const [component, count] of Array.from(anomaliesByComponent.entries())) { if (count > 5) { // High anomaly threshold const optimization: OptimizationOpportunity = { id: `${component}-stability`, category: 'stability', priority: count > 15 ? 'high' : 'medium', component, title: 'Improve Component Stability', description: `Component has ${count} anomalies, indicating stability issues`, currentState: { metric: 'anomalyCount', value: count, trend: 'increasing' }, targetState: { metric: 'anomalyCount', value: Math.max(2, count * 0.3), improvement: 0.7 }, implementation: { effort: 'high', complexity: 'high', timeline: '4-6 weeks', prerequisites: ['Root cause analysis', 'Code review'], steps: [ 'Analyze anomaly patterns', 'Identify root causes', 'Implement stability improvements', 'Add monitoring and alerts', 'Test under stress conditions' ] }, impact: { performance: 0.6, stability: 0.9, resource: 0.5, cost: 0.4 }, riskAssessment: { level: 'medium', factors: ['Complex changes required'], mitigation: ['Phased implementation', 'Extensive testing'] } }; this.optimizations.set(optimization.id, optimization); } } } /** * Assess component health */ private assessComponentHealth(): void { const components = Array.from(new Set(this.memoryData.map(d => d.component))); for (const component of components) { const assessment = this.calculateComponentHealth(component); this.healthAssessments.set(component, assessment); } } /** * Calculate component health score */ private calculateComponentHealth(component: string): ComponentHealth { const componentData = this.memoryData.filter(d => d.component === component); const componentAnomalies = this.anomalies.filter(a => a.component === component); const componentPatterns = Array.from(this.patterns.values()).filter(p => p.component === component); // Memory efficiency score const memoryData = componentData.map(d => d.metrics.memoryUsage || 0); const memoryTrend = this.calculateTrend(memoryData); const memoryScore = this.calculateMemoryEfficiencyScore(memoryData, memoryTrend); // Stability score const stabilityScore = Math.max(0, 100 - (componentAnomalies.length * 10)); // Performance score const performanceImpact = componentPatterns.reduce((sum, p) => sum + p.impact.performance, 0) / Math.max(componentPatterns.length, 1); const performanceScore = Math.max(0, 100 - (performanceImpact * 100)); // Reliability score const criticalAnomalies = componentAnomalies.filter(a => a.severity === 'critical').length; const reliabilityScore = Math.max(0, 100 - (criticalAnomalies * 20)); // Overall score const overallScore = (memoryScore + stabilityScore + performanceScore + reliabilityScore) / 4; return { component, timestamp: Date.now(), overallScore, dimensions: { memoryEfficiency: { score: memoryScore, trend: memoryTrend.direction, issues: memoryScore < 70 ? ['High memory usage', 'Memory growth detected'] : [] }, stability: { score: stabilityScore, trend: componentAnomalies.length > 5 ? 'degrading' : 'stable', issues: componentAnomalies.length > 0 ? [`${componentAnomalies.length} anomalies detected`] : [] }, performance: { score: performanceScore, trend: performanceImpact > 0.5 ? 'degrading' : 'stable', issues: componentPatterns.filter(p => p.impact.performance > 0.6).map(p => p.name) }, reliability: { score: reliabilityScore, trend: criticalAnomalies > 0 ? 'degrading' : 'stable', issues: criticalAnomalies > 0 ? ['Critical anomalies detected'] : [] } }, riskFactors: this.identifyRiskFactors(component, componentAnomalies, componentPatterns), recommendations: { immediate: this.getImmediateRecommendations(component, overallScore), shortTerm: this.getShortTermRecommendations(component, componentPatterns), longTerm: this.getLongTermRecommendations(component, memoryTrend) }, historicalTrend: { timeWindow: 24 * 60 * 60 * 1000, dataPoints: this.getHistoricalHealthData(component), trend: overallScore > 80 ? 'improving' : overallScore < 60 ? 'degrading' : 'stable' } }; } /** * Update component health incrementally */ private updateComponentHealthIncremental(data: { timestamp: number; component: string; metrics: Record<string, number> }): void { const currentHealth = this.healthAssessments.get(data.component); if (!currentHealth) return; // Quick health check for significant changes const memoryUsage = data.metrics.memoryUsage || 0; const baselineKey = `${data.component}-memoryUsage`; const baseline = this.baselines.get(baselineKey); if (baseline && baseline.confidence > 0.5) { const deviation = Math.abs(memoryUsage - baseline.baseline.mean) / baseline.baseline.standardDeviation; if (deviation > 2) { // Significant change detected - trigger immediate health update const updatedHealth = this.calculateComponentHealth(data.component); this.healthAssessments.set(data.component, updatedHealth); this.emit('healthUpdate', updatedHealth); } } } /** * Generate memory predictions */ private generatePredictions(): void { const components = Array.from(new Set(this.memoryData.map(d => d.component))); for (const component of components) { const prediction = this.generateComponentPrediction(component); if (prediction) { this.emit('predictionGenerated', prediction); } } } /** * Generate prediction for a component */ private generateComponentPrediction(component: string): MemoryPrediction | null { const componentData = this.memoryData .filter(d => d.component === component) .sort((a, b) => a.timestamp - b.timestamp); if (componentData.length < 30) return null; // Need minimum data points const memoryUsage = componentData.map(d => d.metrics.memoryUsage || 0); const timestamps = componentData.map(d => d.timestamp); // Simple linear prediction model const trend = this.calculateTrend(memoryUsage); const currentValue = memoryUsage[memoryUsage.length - 1]; const currentTime = timestamps[timestamps.length - 1]; if (currentValue === undefined || currentTime === undefined) { return null; } // Generate predictions for the next hour const predictions = []; const stepSize = 5 * 60 * 1000; // 5 minutes const horizon = this.config.prediction.horizon; for (let t = stepSize; t <= horizon; t += stepSize) { const futureTimestamp = currentTime + t; const steps = t / stepSize; // Linear prediction with some variance const predictedValue = currentValue + (trend.velocity * steps); const confidence = Math.max(0.2, 1 - (steps * 0.1)); // Confidence decreases over time const variance = Math.abs(predictedValue * 0.1 * steps); // Variance increases over time predictions.push({ timestamp: futureTimestamp, value: Math.max(0, predictedValue), confidence, variance }); } // Generate scenarios const finalPrediction = predictions[predictions.length - 1]; if (!finalPrediction) { return null; } const scenarios = { optimistic: { value: finalPrediction.value * 0.8, probability: 0.2 }, realistic: { value: finalPrediction.value, probability: 0.6 }, pessimistic: { value: finalPrediction.value * 1.5, probability: 0.2 } }; // Check for alerts const alerts: any = { recommendations: [] }; const baseline = this.baselines.get(`${component}-memoryUsage`); if (baseline && finalPrediction.value > baseline.thresholds.critical) { alerts.criticalLevel = currentTime + horizon; alerts.recommendations.push('Critical memory level predicted - immediate action required'); } else if (baseline && finalPrediction.value > baseline.thresholds.warning) { alerts.thresholdReach = currentTime + horizon * 0.7; alerts.recommendations.push('Warning threshold predicted to be reached'); } return { component, metric: 'memoryUsage', timestamp: Date.now(), horizon, predictions, scenarios, alerts }; } /** * Get system-wide analytics */ getSystemAnalytics(): SystemAnalytics { const components = Array.from(new Set(this.memoryData.map(d => d.component))); const healthAssessments = Array.from(this.healthAssessments.values()); const healthyComponents = healthAssessments.filter(h => h.overallScore >= 80).length; const warningComponents = healthAssessments.filter(h => h.overallScore >= 60 && h.overallScore < 80).length; const criticalComponents = healthAssessments.filter(h => h.overallScore < 60).length; const overallEfficiency = healthAssessments.length > 0 ? healthAssessments.reduce((sum, h) => sum + h.overallScore, 0) / healthAssessments.length / 100 : 1; // Calculate memory utilization const latestData = new Map<string, number>(); for (const component of components) { const componentData = this.memoryData.filter(d => d.component === component); if (componentData.length > 0) { latestData.set(component, componentData[componentData.length - 1]?.metrics?.memoryUsage || 0); } } const totalMemory = Array.from(latestData.values()).reduce((sum, usage) => sum + usage, 0); const memoryUtilization = totalMemory / (1024 * 1024 * 1024); // GB // Calculate stability index const recentAnomalies = this.anomalies.filter(a => Date.now() - a.timestamp < 3600000); // Last hour const stabilityIndex = Math.max(0, 1 - (recentAnomalies.length / 100)); return { timestamp: Date.now(), overview: { totalComponents: components.length, healthyComponents, warningComponents, criticalComponents, overallEfficiency, memoryUtilization, stabilityIndex }, patterns: Array.from(this.patterns.values()), anomalies: this.anomalies.slice(-50), // Last 50 anomalies optimizations: Array.from(this.optimizations.values()), predictions: [], // Would be populated by generatePredictions componentHealth: healthAssessments, insights: this.generateInsights() }; } /** * Generate actionable insights */ private generateInsights(): Array<{ key: string; description: string; impact: 'low' | 'medium' | 'high' | 'critical'; actionable: boolean }> { const insights = []; // Memory usage insights const highMemoryComponents = Array.from(this.healthAssessments.values()) .filter(h => h.dimensions.memoryEfficiency.score < 60); if (highMemoryComponents.length > 0) { insights.push({ key: 'high-memory-usage', description: `${highMemoryComponents.length} components showing high memory usage`, impact: highMemoryComponents.length > 2 ? 'high' : 'medium' as any, actionable: true }); } // Pattern insights const criticalPatterns = Array.from(this.patterns.values()) .filter(p => p.severity === 'critical'); if (criticalPatterns.length > 0) { insights.push({ key: 'critical-patterns', description: `${criticalPatterns.length} critical memory patterns detected`, impact: 'critical', actionable: true }); } // Anomaly insights const recentAnomalies = this.anomalies.filter(a => Date.now() - a.timestamp < 3600000); if (recentAnomalies.length > 10) { insights.push({ key: 'high-anomaly-rate', description: `High anomaly rate: ${recentAnomalies.length} anomalies in the last hour`, impact: 'high', actionable: true }); } // Optimization insights const criticalOptimizations = Array.from(this.optimizations.values()) .filter(o => o.priority === 'critical'); if (criticalOptimizations.length > 0) { insights.push({ key: 'critical-optimizations', description: `${criticalOptimizations.length} critical optimization opportunities available`, impact: 'high', actionable: true }); } return insights; } /** * Generate analytics report */ async generateReport(type: 'daily' | 'weekly' | 'monthly' | 'custom' = 'daily', timeRange?: { start: number; end: number }): Promise<AnalyticsReport> { const now = Date.now(); const reportId = `report-${type}-${now}`; // Determine time range let reportTimeRange = timeRange; if (!reportTimeRange) { switch (type) { case 'daily': reportTimeRange = { start: now - 24 * 60 * 60 * 1000, end: now }; break; case 'weekly': reportTimeRange = { start: now - 7 * 24 * 60 * 60 * 1000, end: now }; break; case 'monthly': reportTimeRange = { start: now - 30 * 24 * 60 * 60 * 1000, end: now }; break; default: reportTimeRange = { start: now - 24 * 60 * 60 * 1000, end: now }; } } const analytics = this.getSystemAnalytics(); // Generate executive summary const criticalIssues = []; const keyFindings = []; const recommendations = []; if (analytics.overview.criticalComponents > 0) { criticalIssues.push(`${analytics.overview.criticalComponents} components in critical state`); } if (analytics.anomalies.filter(a => a.severity === 'critical').length > 0) { criticalIssues.push('Critical memory anomalies detected'); } keyFindings.push(`Overall system efficiency: ${(analytics.overview.overallEfficiency * 100).toFixed(1)}%`); keyFindings.push(`Memory utilization: ${analytics.overview.memoryUtilization.toFixed(2)}GB`); keyFindings.push(`Stability index: ${(analytics.overview.stabilityIndex * 100).toFixed(1)}%`); // Get top recommendations from optimizations const topOptimizations = Array.from(this.optimizations.values()) .sort((a, b) => (b.priority === 'critical' ? 1 : 0) - (a.priority === 'critical' ? 1 : 0)) .slice(0, 5); recommendations.push(...topOptimizations.map(o => o.title)); const executiveSummary = this.generateExecutiveSummary(analytics, criticalIssues, keyFindings); const report: AnalyticsReport = { id: reportId, timestamp: now, type, timeRange: reportTimeRange, summary: { executiveSummary, keyFindings, criticalIssues, recommendations }, analytics, trends: this.calculateTrends(reportTimeRange), comparisons: { previousPeriod: { memoryEfficiency: { previous: 0.85, current: analytics.overview.overallEfficiency, change: 0 }, stabilityScore: { previous: 0.9, current: analytics.overview.stabilityIndex, change: 0 }, performanceIndex: { previous: 0.8, current: 0.8, change: 0 } }, baseline: { deviation: 0.1, significance: 'medium', explanation: 'System performance within normal parameters' } }, attachments: { charts: [], data: [], logs: [] } }; // Save report if enabled if (this.config.reporting.autoGenerate) { await this.saveReport(report); } this.emit('reportGenerated', report); return report; } // Utility methods private percentile(sortedValues: number[], percentile: number): number { if (sortedValues.length === 0) return 0; if (sortedValues.length === 1) return sortedValues[0] ?? 0; const index = (percentile / 100) * (sortedValues.length - 1); const lower = Math.floor(index); const upper = Math.ceil(index); if (lower === upper) { return sortedValues[lower] ?? 0; } const lowerVal = sortedValues[lower] ?? 0; const upperVal = sortedValues[upper] ?? 0; return lowerVal + (upperVal - lowerVal) * (index - lower); } private calculateVariability(values: number[]): number { if (values.length < 2) return 0; const mean = values.reduce((sum, v) => sum + v, 0) / values.length; const variance = values.reduce((sum, v) => sum + Math.pow(v - mean, 2), 0) / values.length; return Math.sqrt(variance) / mean; // Coefficient of variation } private calculateTrend(values: number[]): { direction: 'increasing' | 'decreasing' | 'stable' | 'volatile'; velocity: number; acceleration: number } { if (values.length < 3) return { direction: 'stable', velocity: 0, acceleration: 0 }; const n = values.length; const x = Array.from({ length: n }, (_, i) => i); const sumX = x.reduce((sum, val) => sum + val, 0); const sumY = values.reduce((sum, val) => sum + val, 0); const sumXY = x.reduce((sum, val, i) => sum + val * (values[i] ?? 0), 0); const sumXX = x.reduce((sum, val) => sum + val * val, 0); const slope = (n * sumXY - sumX * sumY) / (n * sumXX - sumX * sumX) || 0; const mean = sumY / n; let direction: 'increasing' | 'decreasing' | 'stable' | 'volatile'; if (Math.abs(slope) < mean * 0.01) { direction = 'stable'; } else if (slope > 0) { direction = 'increasing'; } else { direction = 'decreasing'; } // Check for volatility const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / n; if (Math.sqrt(variance) > mean * 0.3) { direction = 'volatile'; } return { direction, velocity: Math.abs(slope), acceleration: 0 // Would need second derivative }; } private findCycles(values: number[]): Array<{ length: number; amplitude: number }> { // Simple cycle detection using local maxima/minima const cycles = []; const peaks = []; const valleys = []; for (let i = 1; i < values.length - 1; i++) { const current = values[i]; const prev = values[i - 1]; const next = values[i + 1]; if (current !== undefined && prev !== undefined && next !== undefined) { if (current > prev && current > next) { peaks.push({ index: i, value: current }); } else if (current < prev && current < next) { valleys.push({ index: i, value: current }); } } } // Match peaks with valleys to find cycles for (let i = 0; i < peaks.length - 1; i++) { const peak1 = peaks[i]; const peak2 = peaks[i + 1]; if (!peak1 || !peak2) continue; const valleysBetween = valleys.filter(v => v.index > peak1.index && v.index < peak2.index); if (valleysBetween.length > 0) { const valley = valleysBetween[0]; if (valley && peak1.value !== undefined && valley.value !== undefined) { cycles.push({ length: peak2.index - peak1.index, amplitude: peak1.value - valley.value }); } } } return cycles; } private calculateCycleVariability(cycles: Array<{ length: number; amplitude: number }>): number { if (cycles.length < 2) return 0; const lengths = cycles.map(c => c.length); const avgLength = lengths.reduce((sum, l) => sum + l, 0) / lengths.length; const lengthVariance = lengths.reduce((sum, l) => sum + Math.pow(l - avgLength, 2), 0) / lengths.length; return Math.sqrt(lengthVariance) / avgLength; } private calculatePatternSeverity(frequency: number, averageSize: number): 'low' | 'medium' | 'high' | 'critical' { const sizeScore = Math.min(averageSize / (100 * 1024 * 1024), 1); // 100MB max const freqScore = Math.min(frequency * 2, 1); // 50% frequency max const combined = (sizeScore + freqScore) / 2; if (combined > 0.8) return 'critical'; if (combined > 0.6) return 'high'; if (combined > 0.3) return 'medium'; return 'low'; } private generatePatternRecommendations(type: string, frequency: number, size: number): string[] { const recommendations = []; if (type === 'allocation') { if (frequency > 0.5) { recommendations.push('Implement object pooling to reduce allocation frequency'); } if (size > 50 * 1024 * 1024) { recommendations.push('Consider breaking large allocations into smaller chunks'); } recommendations.push('Monitor allocation patterns for optimization opportunities'); } return recommendations; } private generateGrowthRecommendations(growthRate: number, component: string): string[] { const recommendations = []; if (growthRate > 0) { recommendations.push(`Investigate memory growth in ${component}`); if (growthRate > 10 * 1024 * 1024) { recommendations.push('Consider implementing automatic cleanup mechanisms'); } } else { recommendations.push('Monitor memory deallocation patterns'); } return recommendations; } private calculateAnomalySeverity(deviation: number): 'low' | 'medium' | 'high' | 'critical' { if (deviation > 4) return 'critical'; if (deviation > 3) return 'high'; if (deviation > 2.5) return 'medium'; return 'low'; } private getImmediateImpact(_component: string, metric: string, deviation: number): string[] { const impact = []; if (metric === 'memoryUsage' && deviation > 3) { impact.push('Potential memory exhaustion'); impact.push('Performance degradation'); } if (metric === 'objectCount' && deviation > 3) { impact.push('Resource exhaustion'); impact.push('Allocation failures'); } return impact; } private getPotentialImpact(_component: string, _metric: string, deviation: number): string[] { const impact = []; if (deviation > 3) { impact.push('System instability'); impact.push('Cascading failures'); impact.push('Service degradation'); } return impact; } private getAnomalyRecommendations(component: string, metric: string, deviation: number): string[] { const recommendations = []; recommendations.push(`Investigate ${component} ${metric} anomaly`); if (deviation > 3) { recommendations.push('Consider immediate intervention'); } recommendations.push('Monitor for pattern development'); return recommendations; } private calculateMemoryEfficiencyScore(memoryData: number[], trend: any): number { if (memoryData.length === 0) return 100; const avgUsage = memoryData.reduce((sum, usage) => sum + usage, 0) / memoryData.length; // Efficiency decreases with higher usage and growth let score = 100; // Penalize high absolute usage (assuming 1GB as high) if (avgUsage > 1024 * 1024 * 1024) { score -= Math.min(50, (avgUsage / (1024 * 1024 * 1024)) * 10); } // Penalize growth trends if (trend.direction === 'increasing') { score -= Math.min(20, trend.velocity / (10 * 1024 * 1024)); } // Penalize volatility if (trend.direction === 'volatile') { score -= 15; } return Math.max(0, score); } private identifyRiskFactors(_component: string, anomalies: AnomalyDetection[], patterns: MemoryPattern[]): any[] { const riskFactors = []; const criticalAnomalies = anomalies.filter(a => a.severity === 'critical').length; if (criticalAnomalies > 0) { riskFactors.push({ factor: 'Critical Anomalies', severity: 'critical' as const, impact: 'System stability at risk' }); } const leakPatterns = patterns.filter(p => p.type === 'leak').length; if (leakPatterns > 0) { riskFactors.push({ factor: 'Memory Leak Pattern', severity: 'high' as const, impact: 'Progressive memory exhaustion' }); } return riskFactors; } private getImmediateRecommendations(component: string, score: number): string[] { const recommendations = []; if (score < 30) { recommendations.push(`Emergency intervention required for ${component}`); recommendations.push('Consider component restart or failover'); } else if (score < 60) { recommendations.push(`Immediate attention required for ${component}`); recommendations.push('Investigate and resolve critical issues'); } return recommendations; } private getShortTermRecommendations(_component: string, patterns: MemoryPattern[]): string[] { const recommendations = []; for (const pattern of patterns) { if (pattern.severity === 'high' || pattern.severity === 'critical') { recommendations.push(...pattern.recommendations); } } return Array.from(new Set(recommendations)); // Remove duplicates } private getLongTermRecommendations(component: string, trend: any): string[] { const recommendations = []; if (trend.direction === 'increasing') { recommendations.push(`Develop long-term memory optimization strategy for ${component}`); recommendations.push('Consider architectural improvements'); } recommendations.push('Implement proactive monitoring and alerting'); recommendations.push('Regular performance reviews and optimization'); return recommendations; } private getHistoricalHealthData(_component: string): Array<{ timestamp: number; score: number }> { // Would maintain historical health scores // For now, return simulated data const now = Date.now(); const data = []; for (let i = 23; i >= 0; i--) { data.push({ timestamp: now - (i * 60 * 60 * 1000), // Hourly data for 24 hours score: 75 + Math.random() * 20 // Simulated scores }); } return data; } private calculateTrends(timeRange: { start: number; end: number }): any { // Calculate trends for the report time range // Filter data for analysis (currently not used but ready for implementation) this.memoryData.filter(d => d.timestamp >= timeRange.start && d.timestamp <= timeRange.end ); return { memoryUsage: [], performance: [], stability: [] }; } private generateExecutiveSummary(analytics: SystemAnalytics, criticalIssues: string[], _keyFindings: string[]): string { let summary = `Memory Analytics Report - System Health: `; if (analytics.overview.criticalComponents > 0) { summary += 'CRITICAL'; } else if (analytics.overview.warningComponents > 0) { summary += 'WARNING'; } else { summary += 'HEALTHY'; } summary += `\n\nSystem efficiency is at ${(analytics.overview.overallEfficiency * 100).toFixed(1)}% with ${analytics.overview.totalComponents} components monitored.`; if (criticalIssues.length > 0) { summary += `\n\nCritical Issues: ${criticalIssues.join(', ')}.`; } summary += `\n\nKey metrics: Memory utilization at ${analytics.overview.memoryUtilization.toFixed(2)}GB, stability index at ${(analytics.overview.stabilityIndex * 100).toFixed(1)}%.`; return summary; } private async saveReport(report: AnalyticsReport): Promise<void> { try { const reportsDir = path.join(process.cwd(), 'reports', 'memory'); await fs.mkdir(reportsDir, { recursive: true }); const reportFile = path.join(reportsDir, `${report.id}.json`); await fs.writeFile(reportFile, JSON.stringify(report, null, 2)); // eslint-disable-next-line no-console console.log(`Report saved: ${reportFile}`); } catch (error) { // eslint-disable-next-line no-console console.error('Failed to save report:', error); } } /** * Get analytics configuration */ getConfig(): AnalyticsConfig { return { ...this.config }; } /** * Update analytics configuration */ updateConfig(updates: Partial<AnalyticsConfig>): void { this.config = { ...this.config, ...updates }; this.emit('configUpdated', this.config); } /** * Shutdown analytics engine */ shutdown(): void { this.stopAnalytics(); this.removeAllListeners(); } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/sloth-wq/prompt-auto-optimizer-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server