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

239 lines 10.6 kB
/** * Hybrid Orchestrator - Gives main agent strategic control with selective tool access */ export class HybridOrchestrator { name = 'hybrid_orchestrator'; description = `STRATEGIC CONTROL MODE. Provides direct access to key verification tools while delegating complex workflows to sub-agents.`; toolExecutor; // Will be injected by UniversalRealHandler // Verification tools that the main agent can use directly VERIFICATION_SUITE = { visual: ['take_screenshot', 'capture_full_page', 'visual_diff'], console: ['get_console_logs', 'get_console_errors', 'get_console_warnings'], dom: ['get_dom_snapshot', 'check_element_exists', 'get_element_state'], network: ['get_network_requests', 'get_failed_requests', 'get_api_responses'], performance: ['get_performance_metrics', 'get_memory_usage', 'get_cpu_usage'], state: ['get_application_state', 'get_local_storage', 'get_session_storage'] }; async orchestrate(task) { const startTime = Date.now(); const taskDescription = task.description || task.task || ''; try { const approach = this.determineApproach(taskDescription); if (approach.useDirectVerification) { const verificationResults = await this.performDirectVerification(approach); let subAgentResults = null; if (approach.needsSubAgent) { subAgentResults = await this.delegateToSubAgent(approach.subAgent, taskDescription); } const discrepancies = this.analyzeDiscrepancies(verificationResults, subAgentResults); return { success: true, summary: this.generateSummary(verificationResults, subAgentResults, discrepancies), findings: { critical: discrepancies.filter(d => d.severity === 'critical'), warnings: discrepancies.filter(d => d.severity === 'warning'), info: this.extractInfoFindings(verificationResults) }, suggestions: this.generateSuggestions(discrepancies), nextSteps: this.determineNextSteps(verificationResults, subAgentResults), metadata: { duration: Date.now() - startTime, agentsUsed: approach.needsSubAgent ? [approach.subAgent] : [], confidence: this.calculateConfidence(discrepancies), verificationTools: approach.verificationTools, directEvidence: verificationResults } }; } else { // Pure delegation mode const result = await this.delegateToSubAgent(approach.subAgent, taskDescription); return { ...result, metadata: { ...(result.metadata || {}), mode: 'pure_delegation', duration: result.metadata?.duration || 0, agentsUsed: result.metadata?.agentsUsed || [], confidence: result.metadata?.confidence || 0 } }; } } catch (error) { return { success: false, summary: `Hybrid orchestration failed: ${error instanceof Error ? error.message : String(error)}`, metadata: { duration: Date.now() - startTime, agentsUsed: [], confidence: 0 } }; } } determineApproach(taskDescription) { const lowerTask = taskDescription.toLowerCase(); const verificationKeywords = ['verify', 'check', 'confirm', 'validate', 'ensure', 'actually', 'really']; const needsVerification = verificationKeywords.some(kw => lowerTask.includes(kw)); const verificationTools = []; if (needsVerification || lowerTask.includes('false positive')) { verificationTools.push(...this.VERIFICATION_SUITE.visual); verificationTools.push(...this.VERIFICATION_SUITE.console); } if (lowerTask.includes('error') || lowerTask.includes('bug')) { verificationTools.push(...this.VERIFICATION_SUITE.console); verificationTools.push(...this.VERIFICATION_SUITE.network); } if (lowerTask.includes('performance') || lowerTask.includes('slow')) { verificationTools.push(...this.VERIFICATION_SUITE.performance); } const subAgent = this.selectSubAgent(lowerTask); return { useDirectVerification: verificationTools.length > 0, verificationTools: [...new Set(verificationTools)], needsSubAgent: !needsVerification || lowerTask.length > 50, subAgent }; } selectSubAgent(task) { if (task.includes('performance')) return 'performance_agent'; if (task.includes('test')) return 'test_agent'; if (task.includes('error')) return 'error_investigation_agent'; return 'debug_agent'; } async performDirectVerification(approach) { const results = {}; for (const tool of approach.verificationTools) { try { // Use appropriate parameters based on the tool const toolParams = this.getToolParams(tool, approach); results[tool] = await this.executeTool(tool, toolParams); } catch (error) { results[tool] = { error: error instanceof Error ? error.message : String(error) }; } } return results; } async delegateToSubAgent(agent, task) { // Mock sub-agent delegation return { success: true, summary: `${agent} completed analysis`, findings: { critical: [], warnings: [], info: [] } }; } analyzeDiscrepancies(directResults, subAgentResults) { const discrepancies = []; if (!subAgentResults) return []; // Check for console errors that sub-agent might have missed const consoleErrors = directResults.get_console_errors?.errors || []; if (consoleErrors.length > 0 && !subAgentResults.summary?.includes('error')) { discrepancies.push({ id: 'missed-console-errors', type: 'verification_mismatch', severity: 'critical', title: 'Console errors not reported by sub-agent', description: `Found ${consoleErrors.length} console errors that were not mentioned in sub-agent report`, evidence: consoleErrors }); } return discrepancies; } generateSummary(verificationResults, subAgentResults, discrepancies) { if (discrepancies.length > 0) { return `Verification found discrepancies. Direct evidence shows issues that sub-agent may have missed. ${discrepancies.length} discrepancies found.`; } if (subAgentResults) { return `Verification confirms sub-agent findings. Both direct tools and sub-agent analysis agree on the current state.`; } return `Direct verification completed. Used ${Object.keys(verificationResults).length} verification tools.`; } extractInfoFindings(verificationResults) { const findings = []; if (verificationResults.take_screenshot?.url) { findings.push({ id: 'screenshot-captured', type: 'evidence', severity: 'info', title: 'Visual state captured', description: 'Screenshot available for visual verification' }); } return findings; } generateSuggestions(discrepancies) { return discrepancies.map((d, i) => ({ id: `fix-${i}`, title: `Address ${d.title}`, description: d.description, priority: d.severity === 'critical' ? 'high' : 'medium', effort: 'medium' })); } determineNextSteps(verificationResults, subAgentResults) { const steps = []; if (verificationResults.get_console_errors?.errors?.length > 0) { steps.push('Fix console errors before proceeding'); } if (subAgentResults && this.analyzeDiscrepancies(verificationResults, subAgentResults).length > 0) { steps.push('Use verification-first orchestrator for more thorough analysis'); } return steps; } calculateConfidence(discrepancies) { if (discrepancies.length === 0) return 0.9; if (discrepancies.some(d => d.severity === 'critical')) return 0.3; return 0.6; } async executeTool(tool, params = {}) { // Use the real tool executor if available if (this.toolExecutor) { return await this.toolExecutor.execute(tool, params, {}); } // Fallback if no executor is set console.warn(`⚠️ No tool executor available for ${tool}`); return { error: 'Tool executor not initialized' }; } // Method to inject the tool executor setToolExecutor(executor) { this.toolExecutor = executor; } getToolParams(tool, approach) { // Return appropriate parameters based on the tool const baseParams = {}; // Add sessionId if available from approach context if (approach.sessionId) { baseParams.sessionId = approach.sessionId; } // Tool-specific parameters switch (tool) { case 'take_screenshot': return { ...baseParams, fullPage: false }; case 'get_console_logs': case 'get_console_errors': case 'get_console_warnings': return { ...baseParams, includeTimestamps: true }; case 'get_dom_snapshot': return { ...baseParams, selector: 'body' }; case 'check_element_exists': return { ...baseParams, selector: approach.selector || 'body' }; case 'get_performance_metrics': return { ...baseParams, detailed: true }; default: return baseParams; } } } //# sourceMappingURL=hybrid-orchestrator.js.map