@@ -18,10 +18,19 @@ import {
1818 MessageContentImageUrl ,
1919 MessageContentText ,
2020} from "@langchain/core/messages" ;
21- import { JSONSchema , JSONSchemaToZod } from "@dmitryrechkin/json-schema-to-zod" ;
22-
21+ import type { JSONSchema } from "@dmitryrechkin/json-schema-to-zod" ;
22+ import type { ZodSchema } from "zod" ;
2323import debug from "debug" ;
2424
25+ let JSONSchemaToZod : { convert : ( schema : JSONSchema ) => ZodSchema } | undefined ;
26+
27+ async function convertSchema ( schema : JSONSchema ) : Promise < ZodSchema > {
28+ if ( ! JSONSchemaToZod ) {
29+ ( { JSONSchemaToZod } = await import ( "@dmitryrechkin/json-schema-to-zod" ) ) ;
30+ }
31+ return JSONSchemaToZod . convert ( schema ) ;
32+ }
33+
2534// Replace direct initialization with lazy initialization
2635let debugLog : debug . Debugger ;
2736function getDebugLog ( ) {
@@ -208,36 +217,39 @@ export async function loadMcpTools(
208217 getDebugLog ( ) ( `INFO: Found ${ toolsResponse . tools ?. length || 0 } MCP tools` ) ;
209218
210219 // Filter out tools without names and convert in a single map operation
211- return ( toolsResponse . tools || [ ] )
212- . filter ( ( tool : MCPTool ) => ! ! tool . name )
213- . map ( ( tool : MCPTool ) => {
214- try {
215- const dst = new DynamicStructuredTool ( {
216- name : tool . name ,
217- description : tool . description || "" ,
218- schema : JSONSchemaToZod . convert (
219- ( tool . inputSchema ?? {
220- type : "object" ,
221- properties : { } ,
222- } ) as JSONSchema
223- ) ,
224- responseFormat : "content_and_artifact" ,
225- func : _callTool . bind (
226- null ,
227- serverName ,
228- tool . name ,
229- client
230- ) as DynamicStructuredToolInput [ "func" ] ,
231- } ) ;
232- getDebugLog ( ) ( `INFO: Successfully loaded tool: ${ dst . name } ` ) ;
233- return dst ;
234- } catch ( error ) {
235- getDebugLog ( ) ( `ERROR: Failed to load tool "${ tool . name } ":` , error ) ;
236- if ( throwOnLoadError ) {
237- throw error ;
238- }
239- return null ;
240- }
241- } )
242- . filter ( Boolean ) as StructuredToolInterface [ ] ;
220+ return (
221+ await Promise . all (
222+ ( toolsResponse . tools || [ ] )
223+ . filter ( ( tool : MCPTool ) => ! ! tool . name )
224+ . map ( async ( tool : MCPTool ) => {
225+ try {
226+ const dst = new DynamicStructuredTool ( {
227+ name : tool . name ,
228+ description : tool . description || "" ,
229+ schema : await convertSchema (
230+ ( tool . inputSchema ?? {
231+ type : "object" ,
232+ properties : { } ,
233+ } ) as JSONSchema
234+ ) ,
235+ responseFormat : "content_and_artifact" ,
236+ func : _callTool . bind (
237+ null ,
238+ serverName ,
239+ tool . name ,
240+ client
241+ ) as DynamicStructuredToolInput [ "func" ] ,
242+ } ) ;
243+ getDebugLog ( ) ( `INFO: Successfully loaded tool: ${ dst . name } ` ) ;
244+ return dst ;
245+ } catch ( error ) {
246+ getDebugLog ( ) ( `ERROR: Failed to load tool "${ tool . name } ":` , error ) ;
247+ if ( throwOnLoadError ) {
248+ throw error ;
249+ }
250+ return null ;
251+ }
252+ } )
253+ )
254+ ) . filter ( Boolean ) as StructuredToolInterface [ ] ;
243255}
0 commit comments