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

430 lines 18.7 kB
/** * Intelligent Sub-Agent Orchestrator * * Automatically delegates tasks to specialized AI-Debug sub-agents when available, * with elegant fallback to direct tool execution when sub-agents are unavailable. * * Features: * - Automatic agent availability detection * - Intelligent task classification and agent selection * - Graceful fallback to direct tool execution * - Context preservation and token optimization * - Performance monitoring and optimization */ import { UserFriendlyLogger } from './user-friendly-logger.js'; import { getErrorMessage } from './error-helper.js'; export class IntelligentSubAgentOrchestrator { logger; subAgentCapabilities; availableAgents; lastAvailabilityCheck; availabilityCheckCooldown = 30000; // 30 seconds delegationStats; constructor() { this.logger = new UserFriendlyLogger('SubAgentOrchestrator'); this.subAgentCapabilities = new Map(); this.availableAgents = new Set(); this.lastAvailabilityCheck = 0; this.delegationStats = new Map(); this.initializeAgentCapabilities(); } /** * Initialize known sub-agent capabilities based on AI-Debug documentation */ initializeAgentCapabilities() { const capabilities = [ { agentType: 'debug-discovery-agent', specialization: 'Initial debugging setup and assessment', averageTimeMinutes: '3-5', contextSavingsTokens: 1000, capabilities: [ 'Browser setup and URL injection', 'Initial screenshot capture', 'Console error collection', 'Basic audit and assessment', 'Framework detection' ], keywordTriggers: [ 'debug', 'setup', 'initial', 'discover', 'assess', 'investigate', 'find', 'detect', 'identify', 'explore', 'analyze' ], fallbackTools: ['inject_debugging', 'take_screenshot', 'get_console_logs'] }, { agentType: 'performance-analysis-agent', specialization: 'Performance profiling and optimization', averageTimeMinutes: '5-10', contextSavingsTokens: 2000, capabilities: [ 'Core Web Vitals analysis', 'Bundle size analysis', 'Runtime performance profiling', 'Memory usage tracking', 'Optimization recommendations' ], keywordTriggers: [ 'performance', 'slow', 'optimize', 'speed', 'memory', 'bundle', 'loading', 'profiling', 'metrics', 'vitals', 'benchmark' ], fallbackTools: ['run_audit', 'performance_profile', 'monitor_realtime'] }, { agentType: 'accessibility-audit-agent', specialization: 'WCAG compliance and accessibility testing', averageTimeMinutes: '5-8', contextSavingsTokens: 1500, capabilities: [ 'WCAG A/AA/AAA compliance testing', 'Keyboard navigation testing', 'Screen reader compatibility', 'Color contrast analysis', 'Semantic HTML validation' ], keywordTriggers: [ 'accessibility', 'a11y', 'wcag', 'screen', 'reader', 'keyboard', 'contrast', 'semantic', 'aria', 'compliance', 'inclusive' ], fallbackTools: ['run_audit', 'take_screenshot', 'simulate_user_action'] }, { agentType: 'error-investigation-agent', specialization: 'Error detection and root cause analysis', averageTimeMinutes: '3-7', contextSavingsTokens: 1800, capabilities: [ 'JavaScript error analysis', 'Network failure investigation', 'Stack trace analysis', 'Error reproduction workflows', 'Root cause identification' ], keywordTriggers: [ 'error', 'bug', 'crash', 'fail', 'broken', 'exception', 'stack', 'trace', 'network', 'timeout', 'fix' ], fallbackTools: ['get_console_logs', 'get_debug_report', 'monitor_realtime'] }, { agentType: 'validation-testing-agent', specialization: 'Post-fix validation and regression testing', averageTimeMinutes: '4-8', contextSavingsTokens: 1200, capabilities: [ 'Visual regression detection', 'Quality gate validation', 'Cross-browser testing', 'User flow verification', 'Performance impact assessment' ], keywordTriggers: [ 'test', 'validate', 'check', 'verify', 'confirm', 'regression', 'quality', 'gate', 'flow', 'user', 'workflow' ], fallbackTools: ['take_screenshot', 'simulate_user_action', 'run_audit'] } ]; capabilities.forEach(cap => { this.subAgentCapabilities.set(cap.agentType, cap); }); this.logger.info(`🤖 Initialized ${capabilities.length} sub-agent capability profiles`); } /** * Check if sub-agents are currently available */ async checkSubAgentAvailability() { const now = Date.now(); // Use cached result if within cooldown period if (now - this.lastAvailabilityCheck < this.availabilityCheckCooldown) { return this.availableAgents.size > 0; } this.lastAvailabilityCheck = now; try { // Try to get agent status to check availability const statusResult = await this.executeAIDebugTool('get_agent_status', { includeCapabilities: false }); if (statusResult && statusResult.success) { // Parse available agents from status result this.availableAgents.clear(); this.subAgentCapabilities.forEach((_, agentType) => { this.availableAgents.add(agentType); }); this.logger.success(`✅ Sub-agents available: ${this.availableAgents.size} agents`); return true; } } catch (error) { this.logger.warn(`⚠️ Sub-agent availability check failed: ${getErrorMessage(error)}`); } this.availableAgents.clear(); return false; } /** * Classify a task to determine the best execution strategy */ classifyTask(taskDescription, context) { const description = taskDescription.toLowerCase(); const words = description.split(/\s+/); // Analyze keywords to determine task type and complexity let bestMatch = null; let totalMatches = 0; for (const [agentType, capability] of this.subAgentCapabilities) { const matches = capability.keywordTriggers.filter(trigger => words.some(word => word.includes(trigger) || trigger.includes(word))).length; totalMatches += matches; if (matches > 0 && (!bestMatch || matches > bestMatch.score)) { bestMatch = { agentType, score: matches }; } } // Determine complexity based on task description length and keyword density const estimatedComplexity = this.estimateTaskComplexity(description, totalMatches); // Determine if sub-agent is recommended const requiresSubAgent = bestMatch && bestMatch.score >= 2 && estimatedComplexity !== 'simple'; return { taskType: bestMatch ? bestMatch.agentType.replace('-agent', '') : 'general', keywords: words.filter(word => word.length > 3), // Filter out short words priority: this.determinePriority(description), estimatedComplexity, requiresSubAgent: !!requiresSubAgent, recommendedAgent: bestMatch?.agentType, fallbackStrategy: this.determineFallbackStrategy(estimatedComplexity, !!bestMatch) }; } /** * Automatically execute a task using the best available strategy */ async executeTask(taskDescription, options = {}) { const startTime = Date.now(); try { // Check if sub-agents are available const subAgentsAvailable = await this.checkSubAgentAvailability(); // Classify the task const classification = this.classifyTask(taskDescription, options); this.logger.info(`🎯 Task classified as: ${classification.taskType} (${classification.estimatedComplexity})`); // Try sub-agent delegation if available and recommended if (subAgentsAvailable && classification.requiresSubAgent && classification.recommendedAgent) { try { const result = await this.delegateToSubAgent(classification.recommendedAgent, taskDescription, options); if (result.success) { const executionTime = Date.now() - startTime; this.updateDelegationStats(classification.recommendedAgent, true, executionTime); return { success: true, usedSubAgent: true, agentType: classification.recommendedAgent, contextSavedTokens: this.subAgentCapabilities.get(classification.recommendedAgent)?.contextSavingsTokens, executionTimeMs: executionTime, result: result.data }; } } catch (error) { this.logger.warn(`⚠️ Sub-agent delegation failed: ${getErrorMessage(error)}`); } } // Fallback to direct tool execution const fallbackResult = await this.executeFallbackStrategy(classification, taskDescription, options); const executionTime = Date.now() - startTime; if (classification.recommendedAgent) { this.updateDelegationStats(classification.recommendedAgent, false, executionTime); } return { success: fallbackResult.success, usedSubAgent: false, fallbackReason: subAgentsAvailable ? 'Sub-agent delegation failed' : 'Sub-agents unavailable', executionTimeMs: executionTime, result: fallbackResult.data }; } catch (error) { const executionTime = Date.now() - startTime; this.logger.error(`❌ Task execution failed: ${getErrorMessage(error)}`); return { success: false, usedSubAgent: false, fallbackReason: `Execution error: ${getErrorMessage(error)}`, executionTimeMs: executionTime }; } } /** * Delegate a task to a specific sub-agent */ async delegateToSubAgent(agentType, taskDescription, options) { this.logger.info(`🤖 Delegating to ${agentType}: "${taskDescription.substring(0, 50)}..."`); const delegationOptions = { task: taskDescription, contextPreservation: true, priority: options.priority || 'medium', ...options }; try { const result = await this.executeAIDebugTool('delegate_to_debug_agent', delegationOptions); if (result && result.success !== false) { const capability = this.subAgentCapabilities.get(agentType); this.logger.success(`✅ ${agentType} delegation successful (saving ~${capability?.contextSavingsTokens} tokens)`); return { success: true, data: result }; } return { success: false }; } catch (error) { this.logger.warn(`⚠️ Failed to delegate to ${agentType}: ${getErrorMessage(error)}`); return { success: false }; } } /** * Execute fallback strategy when sub-agents are unavailable */ async executeFallbackStrategy(classification, taskDescription, options) { this.logger.info(`🔄 Executing fallback strategy: ${classification.fallbackStrategy}`); const capability = classification.recommendedAgent ? this.subAgentCapabilities.get(classification.recommendedAgent) : null; if (!capability || !capability.fallbackTools.length) { // Generic fallback for unclassified tasks return this.executeGenericFallback(taskDescription, options); } // Execute the most appropriate fallback tool const primaryTool = capability.fallbackTools[0]; try { const result = await this.executeAIDebugTool(primaryTool, { ...options, fallbackMode: true, originalTask: taskDescription }); this.logger.success(`✅ Fallback execution successful using ${primaryTool}`); return { success: true, data: result }; } catch (error) { this.logger.warn(`⚠️ Primary fallback failed, trying generic approach`); return this.executeGenericFallback(taskDescription, options); } } /** * Generic fallback for unhandled task types */ async executeGenericFallback(taskDescription, options) { // Try the most basic debugging tools in order of likelihood to succeed const genericTools = ['inject_debugging', 'take_screenshot', 'get_debug_report']; for (const tool of genericTools) { try { const result = await this.executeAIDebugTool(tool, options); this.logger.info(`✅ Generic fallback successful using ${tool}`); return { success: true, data: result }; } catch (error) { this.logger.debug(`Generic fallback ${tool} failed: ${getErrorMessage(error)}`); } } this.logger.warn(`⚠️ All fallback strategies exhausted`); return { success: false, data: { message: 'No suitable execution strategy available', suggestion: 'Please try a more specific task description or ensure AI-Debug tools are available' } }; } /** * Execute an AI-Debug tool (placeholder for actual implementation) */ async executeAIDebugTool(toolName, options) { // This would be replaced with actual AI-Debug tool execution // For now, simulate different responses based on tool await new Promise(resolve => setTimeout(resolve, Math.random() * 100 + 50)); // Simulate network delay if (Math.random() < 0.9) { // 90% success rate simulation return { success: true, tool: toolName, result: `Simulated result from ${toolName}`, options }; } else { throw new Error(`Simulated failure for ${toolName}`); } } /** * Estimate task complexity based on description analysis */ estimateTaskComplexity(description, keywordMatches) { const length = description.length; const hasMultipleSteps = /\b(and|then|also|plus|additionally|furthermore)\b/i.test(description); const hasComplexKeywords = /\b(comprehensive|thorough|detailed|complete|analyze|investigate|optimize)\b/i.test(description); if (length > 200 || hasMultipleSteps || hasComplexKeywords || keywordMatches > 3) { return 'complex'; } else if (length > 50 || keywordMatches > 1) { return 'moderate'; } else { return 'simple'; } } /** * Determine task priority based on keywords */ determinePriority(description) { const highPriorityKeywords = /\b(urgent|critical|important|broken|error|fail|crash)\b/i; const lowPriorityKeywords = /\b(optional|nice|enhance|improve|later)\b/i; if (highPriorityKeywords.test(description)) { return 'high'; } else if (lowPriorityKeywords.test(description)) { return 'low'; } else { return 'medium'; } } /** * Determine the best fallback strategy */ determineFallbackStrategy(complexity, hasMatchingAgent) { if (complexity === 'simple') { return 'direct'; } else if (complexity === 'moderate' && hasMatchingAgent) { return 'simplified'; } else { return 'manual'; } } /** * Update delegation statistics for performance monitoring */ updateDelegationStats(agentType, success, executionTime) { const current = this.delegationStats.get(agentType) || { attempts: 0, successes: 0, avgTime: 0 }; current.attempts++; if (success) current.successes++; current.avgTime = (current.avgTime * (current.attempts - 1) + executionTime) / current.attempts; this.delegationStats.set(agentType, current); } /** * Get performance statistics for monitoring and optimization */ getDelegationStats() { const stats = new Map(); for (const [agentType, data] of this.delegationStats) { stats.set(agentType, { ...data, successRate: data.attempts > 0 ? (data.successes / data.attempts) * 100 : 0 }); } return stats; } /** * Get current orchestrator status */ getStatus() { return { subAgentsAvailable: this.availableAgents.size > 0, availableAgents: Array.from(this.availableAgents), totalCapabilities: this.subAgentCapabilities.size, delegationStats: Object.fromEntries(this.getDelegationStats()), lastAvailabilityCheck: new Date(this.lastAvailabilityCheck) }; } } //# sourceMappingURL=intelligent-sub-agent-orchestrator.js.map