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

248 lines (232 loc) โ€ข 9.88 kB
import { BaseToolHandler } from './base-handler.js'; /** * Handler for fault injection tools */ export class FaultHandler extends BaseToolHandler { faultEngine; constructor(faultEngine) { super(); this.faultEngine = faultEngine; } tools = [ { name: 'inject_fault', description: 'Inject a fault into the debugging session to test application resilience', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'The debug session ID' }, faultType: { type: 'string', enum: [ 'network_latency', 'network_timeout', 'network_disconnection', 'packet_loss', 'memory_pressure', 'cpu_spike', 'disk_space', 'database_error', 'api_downtime', 'service_degradation' ], description: 'Type of fault to inject' }, config: { type: 'object', description: 'Fault-specific configuration', properties: { latencyMs: { type: 'number', description: 'Latency in milliseconds (for NETWORK_LATENCY)' }, timeoutMs: { type: 'number', description: 'Timeout in milliseconds (for NETWORK_TIMEOUT)' }, lossPercentage: { type: 'number', description: 'Packet loss percentage 0-100 (for PACKET_LOSS)' }, limitMB: { type: 'number', description: 'Memory limit in MB (for MEMORY_PRESSURE)' }, intensity: { type: 'number', description: 'CPU intensity 0-1 (for CPU_SPIKE)' }, durationMs: { type: 'number', description: 'Duration in milliseconds (for CPU_SPIKE)' }, availableKB: { type: 'number', description: 'Available disk space in KB (for DISK_SPACE)' }, errorRate: { type: 'number', description: 'Error rate 0-1 (for DATABASE_ERROR)' }, statusCode: { type: 'number', description: 'HTTP status code (for API_DOWNTIME)' }, degradationFactor: { type: 'number', description: 'Service degradation factor 0-1 (for SERVICE_DEGRADATION)' }, urlPattern: { type: 'string', description: 'URL pattern for network/service faults (e.g., "**/*.json", "**/api/**")' } } } }, required: ['sessionId', 'faultType', 'config'] } }, { name: 'remove_fault', description: 'Remove a specific injected fault', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'The debug session ID' }, faultId: { type: 'string', description: 'The fault ID to remove' } }, required: ['sessionId', 'faultId'] } }, { name: 'clear_all_faults', description: 'Remove all injected faults from the session', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'The debug session ID' } }, required: ['sessionId'] } }, { name: 'list_active_faults', description: 'List all currently active faults in the session', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'The debug session ID' } }, required: ['sessionId'] } }, { name: 'generate_fault_scenarios', description: 'Generate recommended fault injection test scenarios', inputSchema: { type: 'object', properties: { sessionId: { type: 'string', description: 'The debug session ID' } }, required: ['sessionId'] } } ]; async handle(toolName, args, sessions) { const session = this.getSession(args.sessionId, sessions); switch (toolName) { case 'inject_fault': return this.injectFault(args, session); case 'remove_fault': return this.removeFault(args, session); case 'clear_all_faults': return this.clearAllFaults(args, session); case 'list_active_faults': return this.listActiveFaults(args, session); case 'generate_fault_scenarios': return this.generateFaultScenarios(args, session); default: throw new Error(`Unknown tool: ${toolName}`); } } async injectFault(args, session) { const { faultType, config } = args; try { // Create fault object matching the engine's expected format const fault = { type: faultType, config: config }; const faultId = await this.faultEngine.injectFault(session.page, fault); return this.createTextResponse(`โœ… **Fault Injected Successfully** **Fault ID:** ${faultId} **Type:** ${faultType} **Status:** active **Configuration:** ${this.formatConfig(config)} The fault is now active. Monitor your application's behavior under this failure condition. ๐Ÿ’ก **Tips:** - Use \`list_active_faults\` to see all active faults - Use \`remove_fault\` with the fault ID to stop this specific fault - Use \`clear_all_faults\` to remove all faults at once`); } catch (error) { throw new Error(`Failed to inject fault: ${error instanceof Error ? error.message : error}`); } } async removeFault(args, session) { const { faultId } = args; try { await this.faultEngine.removeFault(session.page, faultId); return this.createTextResponse(`โœ… **Fault Removed Successfully** **Fault ID:** ${faultId} The fault has been deactivated and normal behavior restored.`); } catch (error) { throw new Error(`Failed to remove fault: ${error instanceof Error ? error.message : error}`); } } async clearAllFaults(args, session) { try { // Get count of active faults before clearing const activeFaults = this.faultEngine.getActiveFaults(); const count = activeFaults.length; await this.faultEngine.clearAllFaults(session.page); return this.createTextResponse(`๐Ÿงน **All Faults Cleared** **Removed:** ${count} fault${count !== 1 ? 's' : ''} All injected faults have been removed. Your application is now running normally.`); } catch (error) { throw new Error(`Failed to clear faults: ${error instanceof Error ? error.message : error}`); } } async listActiveFaults(args, session) { try { const faults = this.faultEngine.getActiveFaults(); if (faults.length === 0) { return this.createTextResponse(`๐Ÿ“‹ **No Active Faults** There are currently no injected faults in this session. Use \`inject_fault\` to add failure conditions for testing.`); } const faultList = faults.map(fault => `**${fault.id}** (${fault.fault.type}) Timestamp: ${new Date(fault.timestamp).toLocaleString()} Config: ${JSON.stringify(fault.fault.config)}`).join('\n\n'); return this.createTextResponse(`๐Ÿ“‹ **Active Faults: ${faults.length}** ${faultList} ๐Ÿ’ก **Actions:** - Use \`remove_fault\` with a fault ID to remove specific faults - Use \`clear_all_faults\` to remove all faults at once`); } catch (error) { throw new Error(`Failed to list faults: ${error instanceof Error ? error.message : error}`); } } async generateFaultScenarios(args, session) { try { const scenarios = await this.faultEngine.generateTestScenarios(); const scenarioList = scenarios.map(scenario => `### ${scenario.name} **Expected Behavior:** ${scenario.expectedBehavior} **Faults to inject:** ${scenario.faults.map(f => `- ${f.type}: ${JSON.stringify(f.config)}`).join('\n')}`).join('\n\n'); return this.createTextResponse(`๐ŸŽฏ **Recommended Fault Scenarios** Based on your application type and common failure patterns: ${scenarioList} ๐Ÿ’ก **Usage:** Copy the fault configurations above and use them with \`inject_fault\` to test these scenarios.`); } catch (error) { throw new Error(`Failed to generate scenarios: ${error instanceof Error ? error.message : error}`); } } formatConfig(config) { return Object.entries(config) .map(([key, value]) => `- **${key}:** ${value}`) .join('\n'); } } //# sourceMappingURL=fault-handler.js.map