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

427 lines • 15.9 kB
/** * Human Escalation Framework * Implements Philip's concept of "knowing what it doesn't know" and bringing humans into the loop */ import { EventEmitter } from 'events'; /** * Human Escalation Manager * Intelligently determines when to escalate to humans and manages the escalation process */ export class HumanEscalationManager extends EventEmitter { activeEscalations = new Map(); escalationHistory = []; autoTimeouts = new Map(); // Learning system - tracks what types of escalations users typically approve/reject userPreferences = new Map(); // escalation type -> approval rate constructor() { super(); } /** * Determine if a situation requires human escalation * Core intelligence: "knowing what it doesn't know" */ shouldEscalate(context, attemptedActions = []) { // Knowledge gap detection if (this.detectKnowledgeGap(context, attemptedActions)) { return { type: 'knowledge_gap', description: 'Insufficient information or expertise to proceed safely', severity: 'medium', autoResolvable: false }; } // Permission requirements if (this.requiresPermission(context)) { return { type: 'permission_needed', description: 'Action requires explicit user authorization', severity: this.calculatePermissionSeverity(context), autoResolvable: false }; } // Ambiguous context if (this.hasAmbiguousContext(context)) { return { type: 'ambiguous_context', description: 'Multiple valid approaches exist, user preference needed', severity: 'low', autoResolvable: true }; } // Critical decisions if (this.isCriticalDecision(context)) { return { type: 'critical_decision', description: 'Decision has significant impact and requires human judgment', severity: 'high', autoResolvable: false }; } // Error recovery if (this.needsErrorRecoveryGuidance(context, attemptedActions)) { return { type: 'error_recovery', description: 'Unable to recover from errors automatically', severity: 'medium', autoResolvable: true }; } // Resource access issues if (this.lacksResourceAccess(context)) { return { type: 'resource_access', description: 'Required resources or credentials are not available', severity: 'medium', autoResolvable: false }; } return null; // No escalation needed } /** * Create an escalation request */ async createEscalation(reason, context, autoTimeoutMs) { const escalationId = `escalation-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; const suggestedActions = this.generateSuggestedActions(reason, context); const escalationRequest = { id: escalationId, timestamp: new Date(), reason, context, suggestedActions, waitingForResponse: true, autoTimeoutMs, fallbackAction: this.determineFallbackAction(reason, context) }; this.activeEscalations.set(escalationId, escalationRequest); // Set up auto-timeout if specified if (autoTimeoutMs) { const timeout = setTimeout(() => { this.handleAutoTimeout(escalationId); }, autoTimeoutMs); this.autoTimeouts.set(escalationId, timeout); } // Emit escalation event this.emit('escalation_created', escalationRequest); return escalationId; } /** * Handle escalation response from human */ async handleEscalationResponse(response) { const escalation = this.activeEscalations.get(response.escalationId); if (!escalation) { throw new Error(`Escalation ${response.escalationId} not found`); } // Clear auto-timeout const timeout = this.autoTimeouts.get(response.escalationId); if (timeout) { clearTimeout(timeout); this.autoTimeouts.delete(response.escalationId); } // Mark as resolved escalation.waitingForResponse = false; this.activeEscalations.delete(response.escalationId); this.escalationHistory.push(escalation); // Learn from user response this.learnFromResponse(escalation, response); // Emit response event this.emit('escalation_resolved', { escalation, response }); } /** * Get pending escalations */ getPendingEscalations() { return Array.from(this.activeEscalations.values()); } /** * Get escalation by ID */ getEscalation(escalationId) { return this.activeEscalations.get(escalationId); } /** * INTELLIGENCE: Detect knowledge gaps */ detectKnowledgeGap(context, attemptedActions) { // Repeated failed attempts suggest knowledge gap if (attemptedActions.length > 3 && context.errorHistory.length > 2) { return true; } // Complex projects with beginner users often need guidance if (context.projectComplexity === 'complex' && context.userExperience === 'beginner') { return true; } // Multiple similar errors suggest systematic issue const uniqueErrors = new Set(context.errorHistory); if (context.errorHistory.length > 0 && uniqueErrors.size === 1) { return true; } return false; } /** * INTELLIGENCE: Determine if permission is required */ requiresPermission(context) { // File modifications always require permission for beginners if (context.userExperience === 'beginner' && context.toolName?.includes('file')) { return true; } // System modifications require permission if (context.toolName?.includes('system') || context.toolName?.includes('install')) { return true; } // Network operations in production-like contexts if (context.sessionId?.includes('prod') || context.sessionId?.includes('deploy')) { return true; } return false; } /** * INTELLIGENCE: Detect ambiguous context */ hasAmbiguousContext(context) { // Multiple frameworks detected if (context.lastActions.some(action => action.includes('framework')) && context.lastActions.length > 1) { return true; } // Multiple possible solutions for the same problem if (context.lastActions.filter(action => action.includes('suggest')).length > 2) { return true; } return false; } /** * INTELLIGENCE: Identify critical decisions */ isCriticalDecision(context) { // Database operations if (context.toolName?.includes('database') || context.toolName?.includes('migration')) { return true; } // Production deployments if (context.sessionId?.includes('production') || context.toolName?.includes('deploy')) { return true; } // Security-related operations if (context.toolName?.includes('security') || context.toolName?.includes('auth')) { return true; } return false; } /** * INTELLIGENCE: Determine if error recovery guidance is needed */ needsErrorRecoveryGuidance(context, attemptedActions) { // Too many recovery attempts if (attemptedActions.filter(action => action.includes('retry') || action.includes('recover')).length > 3) { return true; } // Cascading errors if (context.errorHistory.length > 3 && context.errorHistory[context.errorHistory.length - 1] !== context.errorHistory[0]) { return true; } return false; } /** * INTELLIGENCE: Check for resource access issues */ lacksResourceAccess(context) { // Common access-related errors const accessErrors = ['permission denied', 'unauthorized', 'not found', 'timeout', 'connection refused']; return context.errorHistory.some(error => accessErrors.some(accessError => error.toLowerCase().includes(accessError))); } /** * Calculate permission severity based on context */ calculatePermissionSeverity(context) { if (context.toolName?.includes('delete') || context.toolName?.includes('remove')) { return 'critical'; } if (context.toolName?.includes('system') || context.toolName?.includes('install')) { return 'high'; } if (context.userExperience === 'beginner') { return 'medium'; } return 'low'; } /** * Generate suggested actions for human */ generateSuggestedActions(reason, context) { const actions = []; switch (reason.type) { case 'knowledge_gap': actions.push({ id: 'provide_context', description: 'Provide additional context about the issue', type: 'context_clarification', riskLevel: 'low', estimatedTime: '2-3 minutes' }); actions.push({ id: 'suggest_approach', description: 'Suggest a specific approach to take', type: 'user_input', riskLevel: 'low', estimatedTime: '5 minutes' }); break; case 'permission_needed': actions.push({ id: 'grant_permission', description: `Allow ${context.toolName} to proceed`, type: 'permission_grant', riskLevel: this.mapSeverityToRisk(reason.severity), estimatedTime: '30 seconds' }); actions.push({ id: 'deny_permission', description: 'Deny permission and suggest alternative', type: 'tool_selection', riskLevel: 'low', estimatedTime: '1 minute' }); break; case 'ambiguous_context': actions.push({ id: 'choose_approach', description: 'Choose preferred approach from options', type: 'user_input', riskLevel: 'low', estimatedTime: '1-2 minutes' }); break; case 'critical_decision': actions.push({ id: 'review_and_approve', description: 'Review the proposed action and approve if safe', type: 'permission_grant', riskLevel: 'high', estimatedTime: '5-10 minutes' }); actions.push({ id: 'manual_intervention', description: 'Handle this manually to ensure safety', type: 'manual_intervention', riskLevel: 'low', estimatedTime: '10-30 minutes' }); break; case 'error_recovery': actions.push({ id: 'provide_credentials', description: 'Provide missing credentials or access', type: 'user_input', riskLevel: 'medium', estimatedTime: '2-5 minutes' }); actions.push({ id: 'reset_environment', description: 'Reset debugging environment and start fresh', type: 'tool_selection', riskLevel: 'medium', estimatedTime: '5 minutes' }); break; case 'resource_access': actions.push({ id: 'provide_access', description: 'Provide required credentials or permissions', type: 'user_input', riskLevel: 'medium', estimatedTime: '3-5 minutes' }); break; } // Always provide a "continue autonomously" option for non-critical situations if (reason.severity !== 'critical') { actions.push({ id: 'continue_autonomous', description: 'Continue without human intervention (use best judgment)', type: 'permission_grant', riskLevel: 'medium', estimatedTime: 'immediate' }); } return actions; } /** * Determine fallback action for auto-timeout */ determineFallbackAction(reason, context) { if (reason.autoResolvable) { return 'proceed_with_safe_default'; } if (context.timeConstraint === 'urgent') { return 'continue_with_minimal_risk_approach'; } return 'pause_and_wait_for_human'; } /** * Handle auto-timeout */ handleAutoTimeout(escalationId) { const escalation = this.activeEscalations.get(escalationId); if (!escalation) return; // Execute fallback action const fallbackResponse = { escalationId, customAction: escalation.fallbackAction, continueAutonomously: true }; this.emit('escalation_auto_resolved', { escalation, fallbackResponse }); this.handleEscalationResponse(fallbackResponse); } /** * Learn from user responses to improve future escalation decisions */ learnFromResponse(escalation, response) { const reasonType = escalation.reason.type; const approved = response.continueAutonomously || response.selectedActionId === 'grant_permission'; const currentRate = this.userPreferences.get(reasonType) || 0.5; const learningRate = 0.1; const newRate = approved ? currentRate + (1 - currentRate) * learningRate : currentRate - currentRate * learningRate; this.userPreferences.set(reasonType, newRate); } /** * Get escalation statistics for learning insights */ getEscalationStats() { const total = this.escalationHistory.length; const byType = {}; let totalResponseTime = 0; let autoResolved = 0; for (const escalation of this.escalationHistory) { const type = escalation.reason.type; byType[type] = (byType[type] || 0) + 1; if (escalation.autoTimeoutMs) { autoResolved++; } } return { totalEscalations: total, byType, averageResponseTime: total > 0 ? totalResponseTime / total : 0, autoResolvedRate: total > 0 ? autoResolved / total : 0 }; } /** * Map severity to risk level */ mapSeverityToRisk(severity) { switch (severity) { case 'critical': case 'high': return 'high'; case 'medium': return 'medium'; default: return 'low'; } } } //# sourceMappingURL=escalation-manager.js.map