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

497 lines 20.4 kB
/** * Performance Orchestrator - Real Implementation * Coordinates performance analysis and optimization across multiple sub-agents */ import { SubAgentExecutor } from '../sub-agents/sub-agent-executor.js'; export class PerformanceOrchestrator { name = 'performance_orchestrator'; description = `PERFORMANCE OPTIMIZATION COORDINATOR. Analyzes and optimizes application performance through specialized sub-agents.`; subAgentExecutor; subAgents = { baseline: 'performance_analysis_agent', profiling: 'performance_profiling_agent', bundle: 'bundle_analysis_agent', optimization: 'optimization_suggestion_agent', monitoring: 'performance_monitoring_agent' }; async orchestrate(task) { const startTime = Date.now(); console.log('⚡ Performance Orchestrator: Starting analysis...'); try { // Initialize sub-agent executor if handler provided if (!this.subAgentExecutor && task.handler) { this.subAgentExecutor = new SubAgentExecutor(task.handler); console.error(' ✅ Sub-agent executor initialized'); } // 1. Analyze performance requirements const analysis = this.analyzeTask(task); console.error(` 📊 Analysis: Focus on ${analysis.primaryFocus}`); // 2. Create execution plan const plan = this.createExecutionPlan(analysis, task); console.error(` 📋 Execution plan: ${plan.steps.length} performance tasks`); // 3. Execute plan with sub-agents const results = await this.executePlan(plan); // 4. Synthesize results and generate optimization plan const synthesis = this.synthesizeResults(results, task); console.error(` ✅ Performance analysis complete in ${Date.now() - startTime}ms`); return synthesis; } catch (error) { console.error(' ❌ Performance orchestration failed:', error); return { success: false, summary: `Performance orchestration failed: ${error instanceof Error ? error.message : String(error)}`, metadata: { duration: Date.now() - startTime, error: error instanceof Error ? error.message : String(error), agentsUsed: [], confidence: 0 } }; } } analyzeTask(task) { const text = [ task.task, task.description, task.url ].filter(Boolean).join(' ').toLowerCase(); const analysis = { primaryFocus: task.focus || 'general', hasTargets: !!task.targetMetrics, currentIssues: [], suggestedAgents: [this.subAgents.baseline] }; // Detect performance issues from description if (text.includes('slow') || text.includes('lag')) { analysis.currentIssues.push('slow_performance'); analysis.suggestedAgents.push(this.subAgents.profiling); } if (text.includes('bundle') || text.includes('size') || text.includes('large')) { analysis.currentIssues.push('large_bundle'); analysis.suggestedAgents.push(this.subAgents.bundle); if (!task.focus) analysis.primaryFocus = 'bundle'; } if (text.includes('memory') || text.includes('leak')) { analysis.currentIssues.push('memory_issues'); analysis.suggestedAgents.push(this.subAgents.profiling); if (!task.focus) analysis.primaryFocus = 'memory'; } // Always include optimization agent analysis.suggestedAgents.push(this.subAgents.optimization); return analysis; } createExecutionPlan(analysis, task) { const steps = []; // Step 1: Always collect baseline metrics steps.push({ agent: this.subAgents.baseline, action: 'collect_baseline', context: { ...task, metrics: ['LCP', 'FCP', 'TTI', 'CLS', 'bundleSize', 'memoryUsage'] }, priority: 'critical', tools: ['inject_debugging', 'run_audit', 'performance_profile'] }); // Step 2: Focus-specific analysis switch (analysis.primaryFocus) { case 'speed': steps.push({ agent: this.subAgents.profiling, action: 'profile_runtime', context: { ...task, duration: 10000, captureCallStacks: true, identifyBottlenecks: true }, priority: 'high', tools: ['performance_profile', 'monitor_realtime'] }); break; case 'bundle': steps.push({ agent: this.subAgents.bundle, action: 'analyze_bundles', context: { ...task, showDuplicates: true, analyzeTreeShaking: true, identifyLargeModules: true }, priority: 'high', tools: ['analyze_bundle_size', 'dependency_analysis'] }); break; case 'memory': steps.push({ agent: this.subAgents.profiling, action: 'profile_memory', context: { ...task, captureSnapshots: true, detectLeaks: true, monitorGrowth: true }, priority: 'high', tools: ['memory_profiler', 'detect_memory_leaks'] }); break; case 'general': // Add both runtime and bundle analysis for general performance steps.push({ agent: this.subAgents.profiling, action: 'comprehensive_profile', context: task, priority: 'high', tools: ['performance_profile', 'run_audit'] }); steps.push({ agent: this.subAgents.bundle, action: 'quick_bundle_check', context: task, priority: 'medium', tools: ['analyze_bundle_size'] }); break; } // Step 3: Generate optimization suggestions based on findings steps.push({ agent: this.subAgents.optimization, action: 'generate_suggestions', context: { ...task, targetMetrics: analysis.hasTargets, prioritizeByImpact: true, previousFindings: 'will be populated from results' }, priority: 'medium', tools: ['analyze_with_ai', 'suggest_optimizations'] }); // Step 4: Set up monitoring if targets specified if (analysis.hasTargets) { steps.push({ agent: this.subAgents.monitoring, action: 'setup_monitoring', context: { ...task, targets: task.targetMetrics, alertThresholds: true }, priority: 'low', tools: ['monitor_realtime', 'setup_performance_alerts'] }); } return { steps, parallel: false, estimatedDuration: steps.length * 8 // 8 seconds per step }; } async executePlan(plan) { if (!this.subAgentExecutor) { console.warn(' ⚠️ No sub-agent executor available, using fallback'); return this.executePlanFallback(plan); } try { // Execute all tasks through the sub-agent executor const results = await this.subAgentExecutor.executeTasks(plan.steps); // Update context for optimization step with previous findings const optimizationStep = plan.steps.find(s => s.action === 'generate_suggestions'); if (optimizationStep && results.length > 0) { optimizationStep.context.previousFindings = results .filter(r => r.success) .map(r => r.data); } // Log results results.forEach(result => { const icon = result.success ? '✅' : '❌'; console.log(` ${icon} ${result.agent}: ${result.summary}`); // Log key metrics if (result.data.metrics) { const metrics = result.data.metrics; if (metrics.LCP) console.log(` - LCP: ${metrics.LCP}ms`); if (metrics.bundleSize) console.log(` - Bundle: ${(metrics.bundleSize / 1024).toFixed(2)}MB`); if (metrics.memoryUsage) console.error(` - Memory: ${metrics.memoryUsage}MB`); } }); return results; } catch (error) { console.error(' ❌ Sub-agent execution failed:', error); return this.executePlanFallback(plan); } } async executePlanFallback(plan) { console.error(' ⚠️ Using fallback execution (no real tools available)'); const results = []; for (const step of plan.steps) { results.push({ agent: step.agent, action: step.action, success: true, summary: `[Simulated] Completed ${step.action}`, data: { findings: [{ type: 'info', severity: 'info', message: 'Using fallback execution - initialize sub-agent executor for real results' }], metrics: this.getSimulatedMetrics(step.action), suggestions: ['Enable real tool execution for accurate performance analysis'] }, duration: 1000 }); } return results; } getSimulatedMetrics(action) { switch (action) { case 'collect_baseline': return { LCP: 2500, FCP: 1800, TTI: 3500, CLS: 0.1, bundleSize: 2048, memoryUsage: 45 }; case 'profile_runtime': return { topBottlenecks: ['renderLargeList', 'calculateLayout'], totalBlockingTime: 1200 }; case 'analyze_bundles': return { totalSize: 2048, largestModules: ['vendor.js', 'main.js'], duplicateModules: 2 }; default: return {}; } } synthesizeResults(results, task) { const allFindings = results.flatMap(r => r.data.findings || []); const allSuggestions = results.flatMap(r => r.data.suggestions || []); const allMetrics = results.reduce((acc, r) => ({ ...acc, ...r.data.metrics }), {}); // Calculate performance score const score = this.calculatePerformanceScore(allMetrics, task.targetMetrics); // Group findings by severity const findings = { critical: allFindings.filter(f => f.severity === 'critical'), warnings: allFindings.filter(f => f.severity === 'warning'), info: allFindings.filter(f => f.severity === 'info') }; // Create performance summary const summary = this.createPerformanceSummary(results, allMetrics, score); // Generate optimization roadmap const nextSteps = this.generateOptimizationRoadmap(findings, allMetrics, task); return { success: results.every(r => r.success), summary, findings, suggestions: this.prioritizeOptimizations(allSuggestions, allMetrics), nextSteps, metadata: { duration: results.reduce((sum, r) => sum + r.duration, 0), agentsUsed: results.map(r => r.agent), toolsUsed: results.flatMap(r => r.toolsUsed || []), performanceScore: score, metrics: allMetrics, targetsMet: this.checkTargetsMet(allMetrics, task.targetMetrics), confidence: this.calculateConfidence(results) } }; } calculatePerformanceScore(metrics, targets) { let score = 100; // Core Web Vitals impact if (metrics.LCP) { if (metrics.LCP > 4000) score -= 30; else if (metrics.LCP > 2500) score -= 15; } if (metrics.FCP) { if (metrics.FCP > 3000) score -= 20; else if (metrics.FCP > 1800) score -= 10; } if (metrics.CLS) { if (metrics.CLS > 0.25) score -= 20; else if (metrics.CLS > 0.1) score -= 10; } // Bundle size impact if (metrics.bundleSize) { const sizeMB = metrics.bundleSize / 1024; if (sizeMB > 5) score -= 20; else if (sizeMB > 2) score -= 10; } // Memory impact if (metrics.memoryUsage) { if (metrics.memoryUsage > 100) score -= 15; else if (metrics.memoryUsage > 50) score -= 5; } return Math.max(0, Math.min(100, score)); } createPerformanceSummary(results, metrics, score) { const parts = []; // Overall score const scoreEmoji = score >= 90 ? '🟢' : score >= 70 ? '🟡' : score >= 50 ? '🟠' : '🔴'; parts.push(`${scoreEmoji} Performance Score: ${score}/100`); // Key metrics summary if (metrics.LCP && metrics.FCP) { parts.push(`⏱️ Load Performance: LCP ${metrics.LCP}ms, FCP ${metrics.FCP}ms`); } if (metrics.bundleSize) { const sizeMB = (metrics.bundleSize / 1024).toFixed(2); parts.push(`📦 Bundle Size: ${sizeMB}MB`); } if (metrics.memoryUsage) { parts.push(`💾 Memory Usage: ${metrics.memoryUsage}MB`); } // Add critical findings const criticalFindings = results .flatMap(r => r.data.findings || []) .filter(f => f.severity === 'critical'); if (criticalFindings.length > 0) { parts.push(`🚨 ${criticalFindings.length} critical performance issues found`); } return parts.join(' | '); } generateOptimizationRoadmap(findings, metrics, task) { const steps = []; // Critical issues first if (findings.critical.length > 0) { steps.push('🚨 Address critical performance bottlenecks immediately'); steps.push('💡 Run fix_orchestrator to apply automated performance fixes'); } // Metric-based recommendations if (metrics.LCP > 2500) { steps.push('⚡ Optimize Largest Contentful Paint (target: <2.5s)'); steps.push(' - Implement lazy loading for images'); steps.push(' - Optimize server response time'); } if (metrics.bundleSize > 2048) { steps.push('📦 Reduce bundle size (current: ' + (metrics.bundleSize / 1024).toFixed(2) + 'MB)'); steps.push(' - Enable code splitting'); steps.push(' - Remove unused dependencies'); } if (metrics.memoryUsage > 50) { steps.push('💾 Optimize memory usage'); steps.push(' - Fix memory leaks'); steps.push(' - Implement virtual scrolling for large lists'); } // Monitoring setup if (task.targetMetrics) { steps.push('📊 Set up continuous performance monitoring'); steps.push('🎯 Configure alerts for target metrics'); } return steps; } prioritizeOptimizations(suggestions, metrics) { // Group and prioritize suggestions by impact const prioritized = suggestions.map((suggestion, index) => ({ id: `optimization-${index}`, title: suggestion, priority: this.getOptimizationPriority(suggestion, metrics), impact: this.estimateImpact(suggestion, metrics), effort: this.estimateEffort(suggestion) })); // Sort by priority and impact return prioritized.sort((a, b) => { const priorityOrder = { critical: 0, high: 1, medium: 2, low: 3 }; const priorityDiff = priorityOrder[a.priority] - priorityOrder[b.priority]; if (priorityDiff !== 0) return priorityDiff; const impactOrder = { high: 0, medium: 1, low: 2 }; return impactOrder[a.impact] - impactOrder[b.impact]; }); } getOptimizationPriority(suggestion, metrics) { const lower = suggestion.toLowerCase(); // Critical if addressing major performance issues if (metrics.LCP > 4000 && lower.includes('lcp')) return 'critical'; if (metrics.bundleSize > 5120 && lower.includes('bundle')) return 'critical'; if (lower.includes('memory leak')) return 'critical'; // High priority optimizations if (lower.includes('lazy') || lower.includes('split')) return 'high'; if (lower.includes('cache') || lower.includes('cdn')) return 'high'; // Medium priority if (lower.includes('optimize') || lower.includes('reduce')) return 'medium'; return 'low'; } estimateImpact(suggestion, metrics) { const lower = suggestion.toLowerCase(); // High impact optimizations if (lower.includes('code splitting') && metrics.bundleSize > 2048) return 'high'; if (lower.includes('lazy loading') && metrics.LCP > 2500) return 'high'; if (lower.includes('memory leak') && metrics.memoryUsage > 50) return 'high'; // Medium impact if (lower.includes('optimize') || lower.includes('cache')) return 'medium'; return 'low'; } estimateEffort(suggestion) { const lower = suggestion.toLowerCase(); // Low effort if (lower.includes('enable') || lower.includes('configure')) return 'low'; // High effort if (lower.includes('refactor') || lower.includes('migrate')) return 'high'; if (lower.includes('implement') && lower.includes('virtual')) return 'high'; return 'medium'; } checkTargetsMet(metrics, targets) { if (!targets) return true; if (targets.lcp && metrics.LCP > targets.lcp) return false; if (targets.fcp && metrics.FCP > targets.fcp) return false; if (targets.tti && metrics.TTI > targets.tti) return false; if (targets.cls && metrics.CLS > targets.cls) return false; return true; } calculateConfidence(results) { // Calculate confidence based on the completeness and consistency of results let confidence = 0.8; // Base confidence // Adjust based on available metrics if (results.metrics && Object.keys(results.metrics).length > 3) { confidence += 0.1; } // Adjust based on sub-agent consistency if (results.subAgentResults && results.subAgentResults.length > 0) { confidence += 0.1; } return Math.min(1.0, confidence); } } //# sourceMappingURL=performance-orchestrator-real.js.map