mirror of
https://github.com/TriliumNext/Notes.git
synced 2025-08-19 00:42:29 +08:00
try to fix tools again...
trying to fix tools, again...
This commit is contained in:
parent
c1ea9e376a
commit
e968e00c80
@ -4,6 +4,7 @@ import type { StreamCallback, ToolExecutionInput } from '../interfaces.js';
|
|||||||
import { BasePipelineStage } from '../pipeline_stage.js';
|
import { BasePipelineStage } from '../pipeline_stage.js';
|
||||||
import toolRegistry from '../../tools/tool_registry.js';
|
import toolRegistry from '../../tools/tool_registry.js';
|
||||||
import chatStorageService from '../../chat_storage_service.js';
|
import chatStorageService from '../../chat_storage_service.js';
|
||||||
|
import aiServiceManager from '../../ai_service_manager.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pipeline stage for handling LLM tool calling
|
* Pipeline stage for handling LLM tool calling
|
||||||
@ -16,6 +17,11 @@ import chatStorageService from '../../chat_storage_service.js';
|
|||||||
export class ToolCallingStage extends BasePipelineStage<ToolExecutionInput, { response: ChatResponse, needsFollowUp: boolean, messages: Message[] }> {
|
export class ToolCallingStage extends BasePipelineStage<ToolExecutionInput, { response: ChatResponse, needsFollowUp: boolean, messages: Message[] }> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super('ToolCalling');
|
super('ToolCalling');
|
||||||
|
|
||||||
|
// Preload the vectorSearchTool to ensure it's available when needed
|
||||||
|
this.preloadVectorSearchTool().catch(error => {
|
||||||
|
log.error(`Error preloading vector search tool: ${error.message}`);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,7 +87,50 @@ export class ToolCallingStage extends BasePipelineStage<ToolExecutionInput, { re
|
|||||||
log.info(`Executing ${response.tool_calls?.length || 0} tool calls in parallel`);
|
log.info(`Executing ${response.tool_calls?.length || 0} tool calls in parallel`);
|
||||||
|
|
||||||
const executionStartTime = Date.now();
|
const executionStartTime = Date.now();
|
||||||
const toolResults = await Promise.all((response.tool_calls || []).map(async (toolCall, index) => {
|
|
||||||
|
// First validate all tools before executing them
|
||||||
|
log.info(`Validating ${response.tool_calls?.length || 0} tools before execution`);
|
||||||
|
const validationResults = await Promise.all((response.tool_calls || []).map(async (toolCall) => {
|
||||||
|
try {
|
||||||
|
// Get the tool from registry
|
||||||
|
const tool = toolRegistry.getTool(toolCall.function.name);
|
||||||
|
|
||||||
|
if (!tool) {
|
||||||
|
log.error(`Tool not found in registry: ${toolCall.function.name}`);
|
||||||
|
return {
|
||||||
|
toolCall,
|
||||||
|
valid: false,
|
||||||
|
tool: null,
|
||||||
|
error: `Tool not found: ${toolCall.function.name}`
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the tool before execution
|
||||||
|
const isToolValid = await this.validateToolBeforeExecution(tool, toolCall.function.name);
|
||||||
|
if (!isToolValid) {
|
||||||
|
throw new Error(`Tool '${toolCall.function.name}' failed validation before execution`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
toolCall,
|
||||||
|
valid: true,
|
||||||
|
tool,
|
||||||
|
error: null
|
||||||
|
};
|
||||||
|
} catch (error: any) {
|
||||||
|
return {
|
||||||
|
toolCall,
|
||||||
|
valid: false,
|
||||||
|
tool: null,
|
||||||
|
error: error.message || String(error)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
// Execute the validated tools
|
||||||
|
const toolResults = await Promise.all(validationResults.map(async (validation, index) => {
|
||||||
|
const { toolCall, valid, tool, error } = validation;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
log.info(`========== TOOL CALL ${index + 1} OF ${response.tool_calls?.length || 0} ==========`);
|
log.info(`========== TOOL CALL ${index + 1} OF ${response.tool_calls?.length || 0} ==========`);
|
||||||
log.info(`Tool call ${index + 1} received - Name: ${toolCall.function.name}, ID: ${toolCall.id || 'unknown'}`);
|
log.info(`Tool call ${index + 1} received - Name: ${toolCall.function.name}, ID: ${toolCall.id || 'unknown'}`);
|
||||||
@ -92,16 +141,12 @@ export class ToolCallingStage extends BasePipelineStage<ToolExecutionInput, { re
|
|||||||
: JSON.stringify(toolCall.function.arguments);
|
: JSON.stringify(toolCall.function.arguments);
|
||||||
log.info(`Tool parameters: ${argsStr}`);
|
log.info(`Tool parameters: ${argsStr}`);
|
||||||
|
|
||||||
// Get the tool from registry
|
// If validation failed, throw the error
|
||||||
const tool = toolRegistry.getTool(toolCall.function.name);
|
if (!valid || !tool) {
|
||||||
|
throw new Error(error || `Unknown validation error for tool '${toolCall.function.name}'`);
|
||||||
if (!tool) {
|
|
||||||
log.error(`Tool not found in registry: ${toolCall.function.name}`);
|
|
||||||
log.info(`Available tools: ${availableTools.map(t => t.definition.function.name).join(', ')}`);
|
|
||||||
throw new Error(`Tool not found: ${toolCall.function.name}`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.info(`Tool found in registry: ${toolCall.function.name}`);
|
log.info(`Tool validated successfully: ${toolCall.function.name}`);
|
||||||
|
|
||||||
// Parse arguments (handle both string and object formats)
|
// Parse arguments (handle both string and object formats)
|
||||||
let args;
|
let args;
|
||||||
@ -366,4 +411,166 @@ export class ToolCallingStage extends BasePipelineStage<ToolExecutionInput, { re
|
|||||||
messages: updatedMessages
|
messages: updatedMessages
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create a dependency required by tools
|
||||||
|
*
|
||||||
|
* @param dependencyType The type of dependency to get or create
|
||||||
|
* @param toolName The name of the tool requiring this dependency
|
||||||
|
* @returns The requested dependency or null if it couldn't be created
|
||||||
|
*/
|
||||||
|
private async getOrCreateDependency(dependencyType: string, toolName: string): Promise<any> {
|
||||||
|
const aiServiceManager = require('../../../ai_service_manager.js').default;
|
||||||
|
|
||||||
|
try {
|
||||||
|
log.info(`Getting dependency '${dependencyType}' for tool '${toolName}'`);
|
||||||
|
|
||||||
|
// Check for specific dependency types
|
||||||
|
if (dependencyType === 'vectorSearchTool') {
|
||||||
|
// Try to get the existing vector search tool
|
||||||
|
let vectorSearchTool = aiServiceManager.getVectorSearchTool();
|
||||||
|
|
||||||
|
if (vectorSearchTool) {
|
||||||
|
log.info(`Found existing vectorSearchTool dependency`);
|
||||||
|
return vectorSearchTool;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No existing tool, try to initialize it
|
||||||
|
log.info(`Dependency '${dependencyType}' not found, attempting initialization`);
|
||||||
|
|
||||||
|
// Get agent tools manager and initialize it
|
||||||
|
const agentTools = aiServiceManager.getAgentTools();
|
||||||
|
if (agentTools && typeof agentTools.initialize === 'function') {
|
||||||
|
log.info('Initializing agent tools to create vectorSearchTool');
|
||||||
|
try {
|
||||||
|
// Force initialization to ensure it runs even if previously marked as initialized
|
||||||
|
await agentTools.initialize(true);
|
||||||
|
log.info('Agent tools initialized successfully');
|
||||||
|
} catch (initError: any) {
|
||||||
|
log.error(`Failed to initialize agent tools: ${initError.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error('Agent tools manager not available');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try getting the vector search tool again after initialization
|
||||||
|
vectorSearchTool = aiServiceManager.getVectorSearchTool();
|
||||||
|
|
||||||
|
if (vectorSearchTool) {
|
||||||
|
log.info('Successfully created vectorSearchTool dependency');
|
||||||
|
return vectorSearchTool;
|
||||||
|
} else {
|
||||||
|
log.error('Failed to create vectorSearchTool dependency after initialization');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add more dependency types as needed
|
||||||
|
|
||||||
|
// Unknown dependency type
|
||||||
|
log.error(`Unknown dependency type: ${dependencyType}`);
|
||||||
|
return null;
|
||||||
|
} catch (error: any) {
|
||||||
|
log.error(`Error getting or creating dependency '${dependencyType}': ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a tool before execution
|
||||||
|
* @param tool The tool to validate
|
||||||
|
* @param toolName The name of the tool
|
||||||
|
*/
|
||||||
|
private async validateToolBeforeExecution(tool: any, toolName: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
if (!tool) {
|
||||||
|
log.error(`Tool '${toolName}' not found or failed validation`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate execute method
|
||||||
|
if (!tool.execute || typeof tool.execute !== 'function') {
|
||||||
|
log.error(`Tool '${toolName}' is missing execute method`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For the search_notes tool specifically, check if vectorSearchTool is available
|
||||||
|
if (toolName === 'search_notes') {
|
||||||
|
try {
|
||||||
|
// Use the imported aiServiceManager instead of dynamic import
|
||||||
|
let vectorSearchTool = aiServiceManager.getVectorSearchTool();
|
||||||
|
|
||||||
|
if (!vectorSearchTool) {
|
||||||
|
log.error(`Tool '${toolName}' is missing dependency: vectorSearchTool - attempting to initialize`);
|
||||||
|
|
||||||
|
// Try to initialize the agent tools
|
||||||
|
try {
|
||||||
|
// Get agent tools manager and initialize it if needed
|
||||||
|
const agentTools = aiServiceManager.getAgentTools();
|
||||||
|
if (agentTools && typeof agentTools.initialize === 'function') {
|
||||||
|
log.info('Attempting to initialize agent tools');
|
||||||
|
// Force initialization to ensure it runs even if previously initialized
|
||||||
|
await agentTools.initialize(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try getting the vector search tool again
|
||||||
|
vectorSearchTool = aiServiceManager.getVectorSearchTool();
|
||||||
|
|
||||||
|
if (!vectorSearchTool) {
|
||||||
|
log.error('Unable to initialize vectorSearchTool after initialization attempt');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
log.info('Successfully initialized vectorSearchTool');
|
||||||
|
} catch (initError: any) {
|
||||||
|
log.error(`Failed to initialize agent tools: ${initError.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vectorSearchTool.searchNotes || typeof vectorSearchTool.searchNotes !== 'function') {
|
||||||
|
log.error(`Tool '${toolName}' dependency vectorSearchTool is missing searchNotes method`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
log.error(`Error validating dependencies for tool '${toolName}': ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add additional tool-specific validations here
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
log.error(`Error validating tool before execution: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preload the vector search tool to ensure it's available before tool execution
|
||||||
|
*/
|
||||||
|
private async preloadVectorSearchTool(): Promise<void> {
|
||||||
|
try {
|
||||||
|
log.info(`Preloading vector search tool...`);
|
||||||
|
|
||||||
|
// Get the agent tools and initialize them if needed
|
||||||
|
const agentTools = aiServiceManager.getAgentTools();
|
||||||
|
if (agentTools && typeof agentTools.initialize === 'function') {
|
||||||
|
await agentTools.initialize(true);
|
||||||
|
log.info(`Agent tools initialized during preloading`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the vector search tool is available
|
||||||
|
const vectorSearchTool = aiServiceManager.getVectorSearchTool();
|
||||||
|
if (vectorSearchTool && typeof vectorSearchTool.searchNotes === 'function') {
|
||||||
|
log.info(`Vector search tool successfully preloaded`);
|
||||||
|
} else {
|
||||||
|
log.error(`Vector search tool not available after initialization`);
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
log.error(`Failed to preload vector search tool: ${error.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,56 @@ export const searchNotesToolDefinition: Tool = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get or create the vector search tool dependency
|
||||||
|
* @returns The vector search tool or null if it couldn't be created
|
||||||
|
*/
|
||||||
|
async function getOrCreateVectorSearchTool(): Promise<any> {
|
||||||
|
try {
|
||||||
|
// Try to get the existing vector search tool
|
||||||
|
let vectorSearchTool = aiServiceManager.getVectorSearchTool();
|
||||||
|
|
||||||
|
if (vectorSearchTool) {
|
||||||
|
log.info(`Found existing vectorSearchTool`);
|
||||||
|
return vectorSearchTool;
|
||||||
|
}
|
||||||
|
|
||||||
|
// No existing tool, try to initialize it
|
||||||
|
log.info(`VectorSearchTool not found, attempting initialization`);
|
||||||
|
|
||||||
|
// Get agent tools manager and initialize it
|
||||||
|
const agentTools = aiServiceManager.getAgentTools();
|
||||||
|
if (agentTools && typeof agentTools.initialize === 'function') {
|
||||||
|
log.info('Initializing agent tools to create vectorSearchTool');
|
||||||
|
try {
|
||||||
|
// Force initialization to ensure it runs even if previously marked as initialized
|
||||||
|
await agentTools.initialize(true);
|
||||||
|
log.info('Agent tools initialized successfully');
|
||||||
|
} catch (initError: any) {
|
||||||
|
log.error(`Failed to initialize agent tools: ${initError.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log.error('Agent tools manager not available');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try getting the vector search tool again after initialization
|
||||||
|
vectorSearchTool = aiServiceManager.getVectorSearchTool();
|
||||||
|
|
||||||
|
if (vectorSearchTool) {
|
||||||
|
log.info('Successfully created vectorSearchTool');
|
||||||
|
return vectorSearchTool;
|
||||||
|
} else {
|
||||||
|
log.error('Failed to create vectorSearchTool after initialization');
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
log.error(`Error getting or creating vectorSearchTool: ${error.message}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Search notes tool implementation
|
* Search notes tool implementation
|
||||||
*/
|
*/
|
||||||
@ -53,9 +103,20 @@ export class SearchNotesTool implements ToolHandler {
|
|||||||
log.info(`Executing search_notes tool - Query: "${query}", ParentNoteId: ${parentNoteId || 'not specified'}, MaxResults: ${maxResults}`);
|
log.info(`Executing search_notes tool - Query: "${query}", ParentNoteId: ${parentNoteId || 'not specified'}, MaxResults: ${maxResults}`);
|
||||||
|
|
||||||
// Get the vector search tool from the AI service manager
|
// Get the vector search tool from the AI service manager
|
||||||
const vectorSearchTool = aiServiceManager.getVectorSearchTool();
|
const vectorSearchTool = await getOrCreateVectorSearchTool();
|
||||||
|
|
||||||
|
if (!vectorSearchTool) {
|
||||||
|
return `Error: Vector search tool is not available. The system may still be initializing or there could be a configuration issue.`;
|
||||||
|
}
|
||||||
|
|
||||||
log.info(`Retrieved vector search tool from AI service manager`);
|
log.info(`Retrieved vector search tool from AI service manager`);
|
||||||
|
|
||||||
|
// Check if searchNotes method exists
|
||||||
|
if (!vectorSearchTool.searchNotes || typeof vectorSearchTool.searchNotes !== 'function') {
|
||||||
|
log.error(`Vector search tool is missing searchNotes method`);
|
||||||
|
return `Error: Vector search tool is improperly configured (missing searchNotes method).`;
|
||||||
|
}
|
||||||
|
|
||||||
// Execute the search
|
// Execute the search
|
||||||
log.info(`Performing semantic search for: "${query}"`);
|
log.info(`Performing semantic search for: "${query}"`);
|
||||||
const searchStartTime = Date.now();
|
const searchStartTime = Date.now();
|
||||||
@ -69,7 +130,7 @@ export class SearchNotesTool implements ToolHandler {
|
|||||||
|
|
||||||
if (results.length > 0) {
|
if (results.length > 0) {
|
||||||
// Log top results
|
// Log top results
|
||||||
results.slice(0, 3).forEach((result, index) => {
|
results.slice(0, 3).forEach((result: any, index: number) => {
|
||||||
log.info(`Result ${index + 1}: "${result.title}" (similarity: ${Math.round(result.similarity * 100)}%)`);
|
log.info(`Result ${index + 1}: "${result.title}" (similarity: ${Math.round(result.similarity * 100)}%)`);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -79,7 +140,7 @@ export class SearchNotesTool implements ToolHandler {
|
|||||||
// Format the results
|
// Format the results
|
||||||
return {
|
return {
|
||||||
count: results.length,
|
count: results.length,
|
||||||
results: results.map(result => ({
|
results: results.map((result: any) => ({
|
||||||
noteId: result.noteId,
|
noteId: result.noteId,
|
||||||
title: result.title,
|
title: result.title,
|
||||||
preview: result.contentPreview,
|
preview: result.contentPreview,
|
||||||
|
@ -13,6 +13,7 @@ import log from '../../log.js';
|
|||||||
export class ToolRegistry {
|
export class ToolRegistry {
|
||||||
private static instance: ToolRegistry;
|
private static instance: ToolRegistry;
|
||||||
private tools: Map<string, ToolHandler> = new Map();
|
private tools: Map<string, ToolHandler> = new Map();
|
||||||
|
private initializationAttempted: boolean = false;
|
||||||
|
|
||||||
private constructor() {}
|
private constructor() {}
|
||||||
|
|
||||||
@ -27,10 +28,77 @@ export class ToolRegistry {
|
|||||||
return ToolRegistry.instance;
|
return ToolRegistry.instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to initialize tools if registry is empty
|
||||||
|
*/
|
||||||
|
private tryInitializeTools(): boolean {
|
||||||
|
if (this.initializationAttempted || this.tools.size > 0) {
|
||||||
|
return this.tools.size > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initializationAttempted = true;
|
||||||
|
log.info("Tool registry is empty, attempting synchronous initialization");
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Use existing tooling to initialize
|
||||||
|
// This is a light touch, not creating anything new
|
||||||
|
log.info("Tools should be initialized by AIServiceManager constructor");
|
||||||
|
return this.tools.size > 0;
|
||||||
|
} catch (error: any) {
|
||||||
|
log.error(`Error during tool initialization attempt: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validate a tool to ensure it's properly initialized
|
||||||
|
* @param handler Tool handler to validate
|
||||||
|
*/
|
||||||
|
private validateToolHandler(handler: ToolHandler): boolean {
|
||||||
|
try {
|
||||||
|
if (!handler) {
|
||||||
|
log.error(`Invalid tool handler: null or undefined`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handler.definition) {
|
||||||
|
log.error(`Tool handler is missing definition`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handler.definition.function || !handler.definition.function.name) {
|
||||||
|
log.error(`Tool definition is missing function name`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!handler.execute || typeof handler.execute !== 'function') {
|
||||||
|
log.error(`Tool '${handler.definition.function.name}' is missing execute method`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to invoke the execute method with a test parameter to verify it's bound properly
|
||||||
|
// We don't actually execute, just check that it's callable
|
||||||
|
if (handler.execute.toString().includes('[native code]')) {
|
||||||
|
log.error(`Tool '${handler.definition.function.name}' has an unbound execute method`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
log.error(`Error validating tool handler: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a tool with the registry
|
* Register a tool with the registry
|
||||||
*/
|
*/
|
||||||
public registerTool(handler: ToolHandler): void {
|
public registerTool(handler: ToolHandler): void {
|
||||||
|
if (!this.validateToolHandler(handler)) {
|
||||||
|
log.error(`Failed to register tool: validation failed`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const name = handler.definition.function.name;
|
const name = handler.definition.function.name;
|
||||||
|
|
||||||
if (this.tools.has(name)) {
|
if (this.tools.has(name)) {
|
||||||
@ -45,21 +113,47 @@ export class ToolRegistry {
|
|||||||
* Get a tool by name
|
* Get a tool by name
|
||||||
*/
|
*/
|
||||||
public getTool(name: string): ToolHandler | undefined {
|
public getTool(name: string): ToolHandler | undefined {
|
||||||
return this.tools.get(name);
|
// Try initialization if registry is empty
|
||||||
|
if (this.tools.size === 0) {
|
||||||
|
this.tryInitializeTools();
|
||||||
|
}
|
||||||
|
|
||||||
|
const tool = this.tools.get(name);
|
||||||
|
|
||||||
|
if (!tool) {
|
||||||
|
log.error(`Tool '${name}' not found in registry`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate the tool before returning it
|
||||||
|
if (!this.validateToolHandler(tool)) {
|
||||||
|
log.error(`Tool '${name}' failed validation when retrieved`);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return tool;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all registered tools
|
* Get all registered tools
|
||||||
*/
|
*/
|
||||||
public getAllTools(): ToolHandler[] {
|
public getAllTools(): ToolHandler[] {
|
||||||
return Array.from(this.tools.values());
|
// Try initialization if registry is empty
|
||||||
|
if (this.tools.size === 0) {
|
||||||
|
this.tryInitializeTools();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter out any tools that fail validation
|
||||||
|
return Array.from(this.tools.values()).filter(tool => this.validateToolHandler(tool));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all tool definitions for sending to LLM
|
* Get all tool definitions for sending to LLM
|
||||||
*/
|
*/
|
||||||
public getAllToolDefinitions(): Tool[] {
|
public getAllToolDefinitions(): Tool[] {
|
||||||
const toolDefs = Array.from(this.tools.values()).map(handler => handler.definition);
|
// Only get definitions from valid tools
|
||||||
|
const validTools = this.getAllTools();
|
||||||
|
const toolDefs = validTools.map(handler => handler.definition);
|
||||||
return toolDefs;
|
return toolDefs;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user