From 80c29e2a01752060fc549146a0d22ceec1f9049a Mon Sep 17 00:00:00 2001 From: perf3ct Date: Fri, 11 Apr 2025 22:52:09 +0000 Subject: [PATCH] Do a better job of handling tools --- src/services/llm/ai_service_manager.ts | 62 ++++++++++++------- .../llm/context/services/context_service.ts | 10 +-- src/services/llm/pipeline/chat_pipeline.ts | 3 +- .../pipeline/stages/model_selection_stage.ts | 4 +- .../llm/pipeline/stages/tool_calling_stage.ts | 4 +- src/services/llm/providers/ollama_service.ts | 4 +- src/services/llm/rest_chat_service.ts | 21 ++++--- 7 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/services/llm/ai_service_manager.ts b/src/services/llm/ai_service_manager.ts index 12639baa9..771723e47 100644 --- a/src/services/llm/ai_service_manager.ts +++ b/src/services/llm/ai_service_manager.ts @@ -29,8 +29,34 @@ export class AIServiceManager implements IAIServiceManager { private initialized = false; constructor() { - // Don't call updateProviderOrder here - // Wait until a method is called to initialize + // Initialize provider order immediately + this.updateProviderOrder(); + + // Initialize tools immediately + this.initializeTools().catch(error => { + log.error(`Error initializing LLM tools during AIServiceManager construction: ${error.message || String(error)}`); + }); + } + + /** + * Initialize all LLM tools in one place + */ + private async initializeTools(): Promise { + try { + log.info('Initializing LLM tools during AIServiceManager construction...'); + + // Initialize agent tools + await agentTools.initialize(true); + log.info("Agent tools initialized successfully"); + + // Initialize LLM tools + const toolInitializer = await import('./tools/tool_initializer.js'); + await toolInitializer.default.initializeTools(); + log.info("LLM tools initialized successfully"); + } catch (error: any) { + log.error(`Error initializing tools: ${error.message || String(error)}`); + // Don't throw, just log the error to prevent breaking construction + } } /** @@ -282,15 +308,13 @@ export class AIServiceManager implements IAIServiceManager { } /** - * Initialize agent tools for enhanced LLM features + * Ensure agent tools are initialized (no-op as they're initialized in constructor) + * Kept for backward compatibility with existing API */ async initializeAgentTools(): Promise { - try { - await agentTools.initialize(true); - log.info("Agent tools initialized successfully"); - } catch (error: any) { - log.error(`Error initializing agent tools: ${error.message}`); - } + // Agent tools are already initialized in the constructor + // This method is kept for backward compatibility + log.debug("initializeAgentTools called, but tools are already initialized in constructor"); } /** @@ -403,13 +427,8 @@ export class AIServiceManager implements IAIServiceManager { // Initialize index service await this.getIndexService().initialize(); - // Initialize agent tools with this service manager instance - await agentTools.initialize(true); - - // Initialize LLM tools - this is the single place where tools are initialized - const toolInitializer = await import('./tools/tool_initializer.js'); - await toolInitializer.default.initializeTools(); - log.info("LLM tools initialized successfully"); + // Tools are already initialized in the constructor + // No need to initialize them again this.initialized = true; log.info("AI service initialized successfully"); @@ -462,9 +481,9 @@ export class AIServiceManager implements IAIServiceManager { try { // Create agent tools message const toolsMessage = await this.getAgentToolsDescription(); - - // Initialize and use the agent tools - await this.initializeAgentTools(); + + // Agent tools are already initialized in the constructor + // No need to initialize them again // If we have notes that were already found to be relevant, use them directly let contextNotes = relevantNotes; @@ -623,10 +642,7 @@ export default { return getInstance().getIndexService(); }, // Agent tools related methods - async initializeAgentTools(): Promise { - const manager = getInstance(); - return manager.initializeAgentTools(); - }, + // Tools are now initialized in the constructor getAgentTools() { return getInstance().getAgentTools(); }, diff --git a/src/services/llm/context/services/context_service.ts b/src/services/llm/context/services/context_service.ts index 1530ec402..604cd1d3c 100644 --- a/src/services/llm/context/services/context_service.ts +++ b/src/services/llm/context/services/context_service.ts @@ -63,14 +63,8 @@ export class ContextService { throw new Error(`No embedding provider available. Could not initialize context service.`); } - // Initialize agent tools to ensure they're ready - try { - await aiServiceManager.getInstance().initializeAgentTools(); - log.info("Agent tools initialized for use with ContextService"); - } catch (toolError) { - log.error(`Error initializing agent tools: ${toolError}`); - // Continue even if agent tools fail to initialize - } + // Agent tools are already initialized in the AIServiceManager constructor + // No need to initialize them again this.initialized = true; log.info(`Context service initialized with provider: ${provider.name}`); diff --git a/src/services/llm/pipeline/chat_pipeline.ts b/src/services/llm/pipeline/chat_pipeline.ts index c3051030e..0128b380c 100644 --- a/src/services/llm/pipeline/chat_pipeline.ts +++ b/src/services/llm/pipeline/chat_pipeline.ts @@ -104,7 +104,8 @@ export class ChatPipeline { // If there are no tools registered, initialize them if (toolCount === 0) { log.info('No tools found in registry, initializing tools...'); - await toolInitializer.initializeTools(); + // Tools are already initialized in the AIServiceManager constructor + // No need to initialize them again log.info(`Tools initialized, now have ${toolRegistry.getAllTools().length} tools`); } else { log.info(`Found ${toolCount} tools already registered`); diff --git a/src/services/llm/pipeline/stages/model_selection_stage.ts b/src/services/llm/pipeline/stages/model_selection_stage.ts index 9f93df657..5245e3a4c 100644 --- a/src/services/llm/pipeline/stages/model_selection_stage.ts +++ b/src/services/llm/pipeline/stages/model_selection_stage.ts @@ -69,8 +69,8 @@ export class ModelSelectionStage extends BasePipelineStage t.definition.function.name).join(', ')}`); } catch (error: unknown) { @@ -1427,20 +1427,25 @@ class RestChatService { */ private async ensureToolsInitialized() { try { - log.info("Initializing LLM tools..."); + log.info("Checking LLM tool initialization..."); - // Import tool initializer and registry - const toolInitializer = (await import('./tools/tool_initializer.js')).default; + // Import tool registry const toolRegistry = (await import('./tools/tool_registry.js')).default; // Check if tools are already initialized const registeredTools = toolRegistry.getAllTools(); if (registeredTools.length === 0) { - // Initialize tools if none are registered - await toolInitializer.initializeTools(); + log.info("No tools found in registry."); + log.info("Note: Tools should be initialized in the AIServiceManager constructor."); + + // Create AI service manager instance to trigger tool initialization + const aiServiceManager = (await import('./ai_service_manager.js')).default; + aiServiceManager.getInstance(); + + // Check again after AIServiceManager instantiation const tools = toolRegistry.getAllTools(); - log.info(`Successfully registered ${tools.length} LLM tools: ${tools.map(t => t.definition.function.name).join(', ')}`); + log.info(`After AIServiceManager instantiation: ${tools.length} tools available`); } else { log.info(`LLM tools already initialized: ${registeredTools.length} tools available`); }