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

204 lines 8.88 kB
/** * Project-Aware Lazy Handler Wrapper * Extends the existing LazyHandlerWrapper with project-aware loading intelligence * Integrates with FrameworkDetector to optimize loading based on detected project stack */ import { LazyHandlerWrapper } from '../handlers/lazy-handler-wrapper.js'; import { AdaptiveProjectAwareStrategy } from './project-aware-loading-strategy.js'; export class ProjectAwareLazyHandlerWrapper extends LazyHandlerWrapper { projectStrategy; frameworkDetected = false; pendingTools = new Set(); constructor(handler) { super(handler); this.projectStrategy = new AdaptiveProjectAwareStrategy(); } /** * Initialize project-aware loading based on framework detection * Called when inject_debugging detects the framework */ async initializeProjectAwareLoading(frameworkResult) { if (this.frameworkDetected) return; // Already initialized console.log(`🎯 Framework detected: ${frameworkResult.framework}`); // Determine optimal loading strategy for this project const strategy = this.projectStrategy.determineStrategy(frameworkResult); console.log(`📊 Project-aware loading strategy:`); console.log(` Framework: ${strategy.framework}`); console.log(` Immediate tools: ${strategy.immediateTools.length}`); console.log(` Lazy tools: ${strategy.lazyTools.length}`); console.log(` Est. memory savings: ${strategy.estimatedMemorySavingsMB}MB`); console.log(` Reasoning: ${strategy.reasoning}`); this.frameworkDetected = true; // Preload tools that should be immediate for this project await this.preloadProjectTools(strategy.immediateTools); } /** * Preload tools that should be immediately available for the detected project */ async preloadProjectTools(immediateTools) { const toolsToPreload = immediateTools.filter(toolName => this.wrappedHandler.tools.some(tool => tool.name === toolName)); if (toolsToPreload.length === 0) return; console.log(`⚡ Preloading ${toolsToPreload.length} project-relevant tools...`); const preloadPromises = toolsToPreload.map(async (toolName) => { try { // Trigger dependency loading for this tool without actually calling it await this.preloadToolDependencies(toolName); } catch (error) { console.warn(`⚠️ Failed to preload dependencies for ${toolName}:`, error); } }); await Promise.all(preloadPromises); console.log(`✅ Project tools preloaded successfully`); } /** * Preload dependencies for a specific tool without executing it */ async preloadToolDependencies(toolName) { // Use the parent class's dependency loading logic const { requiresExternalDependencies } = await import('./comprehensive-tool-dependencies.js'); if (requiresExternalDependencies(toolName)) { // Check if already loading or loaded if (this.isLoadingDeps.has(toolName) || this.loadedDependencies.has(toolName)) { return; } // Start loading dependencies (same as parent class) const loadPromise = this.loadDependencies(toolName); this.isLoadingDeps.set(toolName, loadPromise); try { await loadPromise; } finally { this.isLoadingDeps.delete(toolName); } } } /** * Enhanced handle method with project-aware prioritization */ async handle(toolName, args, sessions) { // Track tool usage for adaptive learning this.projectStrategy.trackToolUsage(toolName); // If framework not detected yet, check if this is inject_debugging if (!this.frameworkDetected && toolName === 'inject_debugging') { // Let inject_debugging complete first, then it will call our framework detection const result = await super.handle(toolName, args, sessions); // Framework detection happens inside inject_debugging // The CoreHandler will call our initializeProjectAwareLoading method return result; } // Check if this tool should be prioritized for the current project if (this.frameworkDetected && this.projectStrategy.shouldLoadImmediately(toolName)) { // This tool should already be preloaded, so it should be fast console.log(`⚡ Using preloaded project tool: ${toolName}`); } else if (this.frameworkDetected && this.projectStrategy.shouldStayLazy(toolName)) { // This tool is intentionally lazy for this project type console.log(`📦 Loading on-demand tool: ${toolName} (not relevant for ${this.projectStrategy.getCurrentStrategy()?.framework})`); } // Use parent class handling with all our optimizations return super.handle(toolName, args, sessions); } /** * Get project-aware loading statistics */ getProjectAwareStats() { const loadingStats = this.projectStrategy.getLoadingStats(); const memoryStats = this.getMemoryStats(); return { frameworkDetected: this.frameworkDetected, framework: loadingStats.framework, immediateToolCount: loadingStats.immediateToolCount, lazyToolCount: loadingStats.lazyToolCount, memorySavingsMB: loadingStats.memorySavingsMB, reasoning: loadingStats.reasoning, loadedTools: memoryStats.loadedTools, pendingTools: Array.from(this.pendingTools) }; } /** * Adapt strategy based on usage patterns * Called periodically to optimize loading based on actual usage */ adaptToUsagePatterns() { if (!this.frameworkDetected) return; this.projectStrategy.adaptStrategy(); // Log adapted strategy const stats = this.getProjectAwareStats(); console.log(`🧠 Adapted loading strategy for ${stats.framework}:`); console.log(` Immediate tools: ${stats.immediateToolCount}`); console.log(` Memory savings: ${stats.memorySavingsMB}MB`); } /** * Manual framework override for testing or special cases */ overrideFramework(framework) { const mockFrameworkResult = { framework, engines: {} }; this.frameworkDetected = false; this.initializeProjectAwareLoading(mockFrameworkResult); } } /** * Create a project-aware lazy-loaded version of a handler */ export function createProjectAwareLazyHandler(handler) { return new ProjectAwareLazyHandlerWrapper(handler); } /** * Helper to integrate framework detection with project-aware loading * Used by CoreHandler when inject_debugging detects framework */ export class ProjectAwareLoadingCoordinator { static wrappers = new Map(); /** * Register a project-aware wrapper for coordination */ static registerWrapper(handlerName, wrapper) { this.wrappers.set(handlerName, wrapper); } /** * Notify all wrappers about framework detection * Called by CoreHandler after framework is detected */ static async notifyFrameworkDetected(frameworkResult) { console.log(`🌍 Broadcasting framework detection: ${frameworkResult.framework}`); const notifications = Array.from(this.wrappers.values()).map(wrapper => wrapper.initializeProjectAwareLoading(frameworkResult)); await Promise.all(notifications); console.log(`📡 Framework detection broadcast complete`); } /** * Get aggregated project-aware statistics from all wrappers */ static getAggregatedStats() { const wrappers = Array.from(this.wrappers.values()); if (wrappers.length === 0) { return { totalWrappers: 0, frameworkDetected: false, totalMemorySavingsMB: 0, totalLoadedTools: 0 }; } const firstWrapper = wrappers[0]; const stats = firstWrapper.getProjectAwareStats(); return { totalWrappers: wrappers.length, frameworkDetected: stats.frameworkDetected, framework: stats.framework, totalMemorySavingsMB: stats.memorySavingsMB, totalLoadedTools: wrappers.reduce((total, wrapper) => total + wrapper.getMemoryStats().loadedTools.length, 0) }; } /** * Trigger adaptation for all wrappers */ static adaptAllToUsagePatterns() { for (const wrapper of this.wrappers.values()) { wrapper.adaptToUsagePatterns(); } } } //# sourceMappingURL=project-aware-lazy-handler-wrapper.js.map