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

262 lines • 10.6 kB
/** * Intelligent Tool Selection System * Limits tools based on context to improve LLM performance (following Wordware's <15 tools rule) */ /** * Intelligent Tool Selector * Selects optimal subset of tools based on current debugging context */ export class IntelligentToolSelector { allTools = []; userHistory = new Map(); // tool usage frequency selectionStrategy; constructor(strategy) { this.selectionStrategy = { maxTools: 12, // Slightly under Wordware's 15 tool limit selectionWeights: { frameworkMatch: 0.3, trainingDataRich: 0.25, userHistoryMatch: 0.2, costEfficiency: 0.15, authorityLevel: 0.1 }, minimumScore: 0.3, ...strategy }; } /** * Register available tools */ registerTools(tools) { this.allTools = tools; } /** * Select optimal tools for current context */ selectTools(context, requestedCategories) { // Score all tools based on context const scoredTools = this.scoreTools(context, requestedCategories); // Filter by minimum score const viableTools = scoredTools.filter(scored => scored.score >= this.selectionStrategy.minimumScore); // Sort by score (highest first) viableTools.sort((a, b) => b.score - a.score); // Select top N tools const selectedTools = viableTools .slice(0, this.selectionStrategy.maxTools) .map(scored => scored.tool); const alternativeTools = viableTools .slice(this.selectionStrategy.maxTools) .map(scored => scored.tool); const selectionReasoning = this.generateSelectionReasoning(context, viableTools.slice(0, this.selectionStrategy.maxTools)); return { selectedTools, totalAvailable: this.allTools.length, selectionReasoning, alternativeTools }; } /** * Score tools based on current context */ scoreTools(context, requestedCategories) { return this.allTools.map(tool => { const scores = { frameworkMatch: this.calculateFrameworkScore(tool, context), trainingDataRich: tool.metadata.trainingDataRich ? 1.0 : 0.3, userHistoryMatch: this.calculateUserHistoryScore(tool), costEfficiency: this.calculateCostScore(tool, context), authorityLevel: this.calculateAuthorityScore(tool, context) }; // Apply category boost if requested if (requestedCategories && requestedCategories.includes(tool.metadata.category)) { scores.frameworkMatch *= 1.5; } // Calculate weighted score const totalScore = scores.frameworkMatch * this.selectionStrategy.selectionWeights.frameworkMatch + scores.trainingDataRich * this.selectionStrategy.selectionWeights.trainingDataRich + scores.userHistoryMatch * this.selectionStrategy.selectionWeights.userHistoryMatch + scores.costEfficiency * this.selectionStrategy.selectionWeights.costEfficiency + scores.authorityLevel * this.selectionStrategy.selectionWeights.authorityLevel; const reasoning = this.generateToolReasoning(tool, scores, context); return { tool, score: Math.min(1.0, totalScore), // Cap at 1.0 reasoning }; }); } /** * Calculate framework compatibility score */ calculateFrameworkScore(tool, context) { if (!context.framework) return 0.5; // Neutral if no framework specified const compatibility = tool.metadata.frameworkCompatibility.find(fc => fc.framework === context.framework || fc.framework === 'general'); if (!compatibility) return 0.1; // Low score if framework not supported switch (compatibility.compatibility) { case 'high': return 1.0; case 'medium': return 0.7; case 'low': return 0.4; default: return 0.5; } } /** * Calculate user history score based on past usage */ calculateUserHistoryScore(tool) { const usageCount = this.userHistory.get(tool.name) || 0; const maxUsage = Math.max(...Array.from(this.userHistory.values()), 1); return usageCount / maxUsage; } /** * Calculate cost efficiency score */ calculateCostScore(tool, context) { const costMultiplier = context.timeConstraint === 'urgent' ? 0.5 : 1.0; // Prefer faster tools when urgent switch (tool.metadata.costLevel) { case 'low': return 1.0 * costMultiplier; case 'medium': return 0.7 * costMultiplier; case 'high': return 0.4 * costMultiplier; default: return 0.5 * costMultiplier; } } /** * Calculate authority level appropriateness score */ calculateAuthorityScore(tool, context) { // Prefer lower authority tools for beginners const authorityPenalty = context.userExperience === 'beginner' ? 0.8 : 1.0; switch (tool.metadata.authority) { case 'read_only': return 1.0; case 'user_interaction': return 0.9 * authorityPenalty; case 'file_modification': return 0.7 * authorityPenalty; case 'system_modification': return 0.5 * authorityPenalty; case 'network_access': return 0.8 * authorityPenalty; default: return 0.5; } } /** * Generate reasoning for tool selection */ generateToolReasoning(tool, scores, context) { const reasoning = []; if (scores.frameworkMatch > 0.8) { reasoning.push(`High framework compatibility with ${context.framework}`); } if (scores.trainingDataRich > 0.8) { reasoning.push('Rich training data available for this tool'); } if (scores.userHistoryMatch > 0.5) { reasoning.push('Frequently used tool in your workflow'); } if (scores.costEfficiency > 0.8) { reasoning.push('Cost-efficient execution'); } if (context.phase === 'initial' && tool.metadata.category === 'core') { reasoning.push('Essential for initial debugging phase'); } return reasoning; } /** * Generate overall selection reasoning */ generateSelectionReasoning(context, selectedTools) { const phaseDescription = this.getPhaseDescription(context.phase); const frameworkNote = context.framework ? ` for ${context.framework}` : ''; let reasoning = `Selected ${selectedTools.length} tools optimized for ${phaseDescription}${frameworkNote}. `; const categoryCounts = this.countCategories(selectedTools.map(st => st.tool)); const categoryDescriptions = Object.entries(categoryCounts) .map(([category, count]) => `${count} ${category}`) .join(', '); reasoning += `Tool mix: ${categoryDescriptions}. `; if (context.timeConstraint === 'urgent') { reasoning += 'Prioritized fast-executing tools due to time constraints. '; } if (context.userExperience === 'beginner') { reasoning += 'Selected user-friendly tools with lower risk levels.'; } else if (context.userExperience === 'expert') { reasoning += 'Included advanced tools for comprehensive analysis.'; } return reasoning; } /** * Get human-readable phase description */ getPhaseDescription(phase) { switch (phase) { case 'initial': return 'initial exploration and setup'; case 'deep_dive': return 'detailed analysis and investigation'; case 'performance': return 'performance optimization'; case 'testing': return 'testing and validation'; case 'resolution': return 'issue resolution and verification'; default: return 'debugging'; } } /** * Count tools by category */ countCategories(tools) { const counts = {}; for (const tool of tools) { const category = tool.metadata.category; counts[category] = (counts[category] || 0) + 1; } return counts; } /** * Record tool usage for learning */ recordToolUsage(toolName) { const currentCount = this.userHistory.get(toolName) || 0; this.userHistory.set(toolName, currentCount + 1); } /** * Get tool recommendations based on current context */ getToolRecommendations(context, excludeTools = []) { const availableTools = this.allTools.filter(tool => !excludeTools.includes(tool.name)); const scoredTools = this.scoreTools(context); return scoredTools .filter(scored => !excludeTools.includes(scored.tool.name)) .sort((a, b) => b.score - a.score) .slice(0, 3) // Top 3 recommendations .map(scored => scored.tool); } /** * Explain why a tool was or wasn't selected */ explainToolSelection(toolName, context) { const tool = this.allTools.find(t => t.name === toolName); if (!tool) return `Tool '${toolName}' not found.`; const scoredTool = this.scoreTools(context).find(st => st.tool.name === toolName); if (!scoredTool) return `Unable to score tool '${toolName}'.`; let explanation = `Tool '${toolName}' scored ${(scoredTool.score * 100).toFixed(1)}%. `; if (scoredTool.score >= this.selectionStrategy.minimumScore) { explanation += 'This tool was eligible for selection. '; } else { explanation += `This tool was excluded (minimum score: ${(this.selectionStrategy.minimumScore * 100).toFixed(1)}%). `; } if (scoredTool.reasoning.length > 0) { explanation += `Reasons: ${scoredTool.reasoning.join(', ')}.`; } return explanation; } /** * Update selection strategy */ updateStrategy(updates) { this.selectionStrategy = { ...this.selectionStrategy, ...updates }; } /** * Get current selection strategy */ getStrategy() { return { ...this.selectionStrategy }; } } //# sourceMappingURL=tool-selector.js.map