@juspay/neurolink 7.13.0 → 7.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +89 -25
  3. package/dist/agent/directTools.d.ts +3 -3
  4. package/dist/agent/directTools.js +1 -1
  5. package/dist/cli/commands/mcp.js +67 -207
  6. package/dist/cli/factories/commandFactory.js +7 -1
  7. package/dist/cli/utils/interactiveSetup.js +1 -1
  8. package/dist/config/conversationMemoryConfig.js +2 -1
  9. package/dist/context/ContextManager.js +15 -4
  10. package/dist/context/config.js +5 -1
  11. package/dist/context/utils.js +1 -1
  12. package/dist/core/baseProvider.d.ts +11 -30
  13. package/dist/core/baseProvider.js +268 -42
  14. package/dist/core/conversationMemoryManager.js +3 -2
  15. package/dist/core/dynamicModels.d.ts +14 -14
  16. package/dist/core/dynamicModels.js +1 -1
  17. package/dist/core/evaluation.js +1 -1
  18. package/dist/core/factory.js +1 -1
  19. package/dist/factories/providerFactory.js +5 -11
  20. package/dist/factories/providerRegistry.js +2 -2
  21. package/dist/index.d.ts +5 -4
  22. package/dist/index.js +1 -1
  23. package/dist/lib/agent/directTools.js +1 -1
  24. package/dist/lib/config/conversationMemoryConfig.js +2 -1
  25. package/dist/lib/context/ContextManager.js +15 -4
  26. package/dist/lib/context/config.js +5 -1
  27. package/dist/lib/context/utils.js +1 -1
  28. package/dist/lib/core/baseProvider.d.ts +11 -30
  29. package/dist/lib/core/baseProvider.js +268 -42
  30. package/dist/lib/core/conversationMemoryManager.js +3 -2
  31. package/dist/lib/core/dynamicModels.js +1 -1
  32. package/dist/lib/core/evaluation.js +1 -1
  33. package/dist/lib/core/factory.js +1 -1
  34. package/dist/lib/factories/providerFactory.js +5 -11
  35. package/dist/lib/factories/providerRegistry.js +2 -2
  36. package/dist/lib/index.d.ts +5 -4
  37. package/dist/lib/index.js +1 -1
  38. package/dist/lib/mcp/externalServerManager.d.ts +148 -0
  39. package/dist/lib/mcp/externalServerManager.js +1038 -0
  40. package/dist/lib/mcp/mcpCircuitBreaker.d.ts +184 -0
  41. package/dist/lib/mcp/mcpCircuitBreaker.js +338 -0
  42. package/dist/lib/mcp/mcpClientFactory.d.ts +105 -0
  43. package/dist/lib/mcp/mcpClientFactory.js +421 -0
  44. package/dist/lib/mcp/toolDiscoveryService.d.ts +193 -0
  45. package/dist/lib/mcp/toolDiscoveryService.js +646 -0
  46. package/dist/lib/mcp/toolRegistry.d.ts +15 -11
  47. package/dist/lib/mcp/toolRegistry.js +118 -55
  48. package/dist/lib/models/modelResolver.js +1 -1
  49. package/dist/lib/neurolink.d.ts +139 -43
  50. package/dist/lib/neurolink.js +604 -174
  51. package/dist/lib/providers/googleVertex.d.ts +7 -1
  52. package/dist/lib/providers/googleVertex.js +34 -7
  53. package/dist/lib/providers/huggingFace.js +1 -1
  54. package/dist/lib/providers/mistral.js +3 -3
  55. package/dist/lib/providers/ollama.js +1 -1
  56. package/dist/lib/providers/openAI.d.ts +3 -2
  57. package/dist/lib/providers/openAI.js +2 -2
  58. package/dist/lib/providers/openaiCompatible.d.ts +1 -1
  59. package/dist/lib/providers/openaiCompatible.js +2 -2
  60. package/dist/lib/providers/sagemaker/config.js +1 -1
  61. package/dist/lib/sdk/toolRegistration.d.ts +4 -13
  62. package/dist/lib/sdk/toolRegistration.js +19 -66
  63. package/dist/lib/types/cli.d.ts +0 -1
  64. package/dist/lib/types/cli.js +0 -1
  65. package/dist/lib/types/common.d.ts +1 -2
  66. package/dist/lib/types/common.js +0 -1
  67. package/dist/lib/types/contextTypes.d.ts +1 -1
  68. package/dist/lib/types/contextTypes.js +3 -3
  69. package/dist/lib/types/externalMcp.d.ts +288 -0
  70. package/dist/lib/types/externalMcp.js +7 -0
  71. package/dist/lib/types/generateTypes.d.ts +0 -1
  72. package/dist/lib/types/index.d.ts +2 -2
  73. package/dist/lib/types/index.js +0 -1
  74. package/dist/lib/types/mcpTypes.d.ts +53 -99
  75. package/dist/lib/types/providers.d.ts +0 -1
  76. package/dist/lib/types/providers.js +0 -1
  77. package/dist/lib/types/tools.d.ts +2 -2
  78. package/dist/lib/types/tools.js +2 -2
  79. package/dist/lib/utils/factoryProcessing.js +1 -1
  80. package/dist/lib/utils/mcpDefaults.d.ts +54 -0
  81. package/dist/lib/utils/mcpDefaults.js +125 -0
  82. package/dist/lib/utils/providerConfig.d.ts +1 -1
  83. package/dist/lib/utils/providerConfig.js +2 -2
  84. package/dist/lib/utils/providerHealth.js +6 -6
  85. package/dist/mcp/externalServerManager.d.ts +148 -0
  86. package/dist/mcp/externalServerManager.js +1038 -0
  87. package/dist/mcp/mcpCircuitBreaker.d.ts +184 -0
  88. package/dist/mcp/mcpCircuitBreaker.js +338 -0
  89. package/dist/mcp/mcpClientFactory.d.ts +105 -0
  90. package/dist/mcp/mcpClientFactory.js +421 -0
  91. package/dist/mcp/toolDiscoveryService.d.ts +193 -0
  92. package/dist/mcp/toolDiscoveryService.js +646 -0
  93. package/dist/mcp/toolRegistry.d.ts +15 -11
  94. package/dist/mcp/toolRegistry.js +118 -55
  95. package/dist/models/modelResolver.js +1 -1
  96. package/dist/neurolink.d.ts +139 -43
  97. package/dist/neurolink.js +604 -174
  98. package/dist/providers/googleVertex.d.ts +7 -1
  99. package/dist/providers/googleVertex.js +34 -7
  100. package/dist/providers/huggingFace.js +1 -1
  101. package/dist/providers/mistral.js +3 -3
  102. package/dist/providers/ollama.js +1 -1
  103. package/dist/providers/openAI.d.ts +3 -2
  104. package/dist/providers/openAI.js +2 -2
  105. package/dist/providers/openaiCompatible.d.ts +1 -1
  106. package/dist/providers/openaiCompatible.js +2 -2
  107. package/dist/providers/sagemaker/config.js +1 -1
  108. package/dist/sdk/toolRegistration.d.ts +4 -13
  109. package/dist/sdk/toolRegistration.js +19 -66
  110. package/dist/types/cli.d.ts +0 -1
  111. package/dist/types/cli.js +0 -1
  112. package/dist/types/common.d.ts +1 -2
  113. package/dist/types/common.js +0 -1
  114. package/dist/types/contextTypes.d.ts +1 -1
  115. package/dist/types/contextTypes.js +3 -3
  116. package/dist/types/externalMcp.d.ts +288 -0
  117. package/dist/types/externalMcp.js +7 -0
  118. package/dist/types/generateTypes.d.ts +0 -1
  119. package/dist/types/index.d.ts +2 -2
  120. package/dist/types/index.js +0 -1
  121. package/dist/types/mcpTypes.d.ts +53 -99
  122. package/dist/types/providers.d.ts +0 -1
  123. package/dist/types/providers.js +0 -1
  124. package/dist/types/tools.d.ts +2 -2
  125. package/dist/types/tools.js +2 -2
  126. package/dist/utils/factoryProcessing.js +1 -1
  127. package/dist/utils/mcpDefaults.d.ts +54 -0
  128. package/dist/utils/mcpDefaults.js +125 -0
  129. package/dist/utils/providerConfig.d.ts +1 -1
  130. package/dist/utils/providerConfig.js +2 -2
  131. package/dist/utils/providerHealth.js +6 -6
  132. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import { z } from "zod";
1
2
  import { logger } from "../utils/logger.js";
2
3
  import { SYSTEM_LIMITS, DEFAULT_MAX_STEPS } from "../core/constants.js";
3
4
  import { directAgentTools } from "../agent/directTools.js";
@@ -5,19 +6,6 @@ import { getSafeMaxTokens } from "../utils/tokenLimits.js";
5
6
  import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
6
7
  import { shouldDisableBuiltinTools } from "../utils/toolUtils.js";
7
8
  import { buildMessagesArray } from "../utils/messageBuilder.js";
8
- /**
9
- * Validates if a result contains a valid toolsObject structure
10
- * @param result - The result object to validate
11
- * @returns true if the result contains a valid toolsObject, false otherwise
12
- */
13
- function isValidToolsObject(result) {
14
- return (result !== null &&
15
- typeof result === "object" &&
16
- "toolsObject" in result &&
17
- result.toolsObject !== null &&
18
- typeof result.toolsObject === "object" &&
19
- Object.keys(result.toolsObject).length > 0);
20
- }
21
9
  /**
22
10
  * Abstract base class for all AI providers
23
11
  * Tools are integrated as first-class citizens - always available by default
@@ -31,13 +19,15 @@ export class BaseProvider {
31
19
  ? {}
32
20
  : directAgentTools;
33
21
  mcpTools; // MCP tools loaded dynamically when available
22
+ customTools; // Custom tools from registerTool()
23
+ toolExecutor; // Tool executor from setupToolExecutor
34
24
  sessionId;
35
25
  userId;
36
- sdk; // Reference to NeuroLink SDK instance for custom tools
37
- constructor(modelName, providerName, sdk) {
26
+ neurolink; // Reference to actual NeuroLink instance for MCP tools
27
+ constructor(modelName, providerName, neurolink) {
38
28
  this.modelName = modelName || this.getDefaultModel();
39
29
  this.providerName = providerName || this.getProviderName();
40
- this.sdk = sdk;
30
+ this.neurolink = neurolink;
41
31
  }
42
32
  /**
43
33
  * Check if this provider supports tool/function calling
@@ -106,7 +96,7 @@ export class BaseProvider {
106
96
  await new Promise((resolve) => setTimeout(resolve, Math.random() * 9 + 1));
107
97
  }
108
98
  }
109
- // Yield any remaining content
99
+ // Yield all remaining content
110
100
  if (buffer.trim()) {
111
101
  yield { content: buffer };
112
102
  }
@@ -157,10 +147,20 @@ export class BaseProvider {
157
147
  try {
158
148
  // Import generateText dynamically to avoid circular dependencies
159
149
  const { generateText } = await import("ai");
160
- // Get ALL available tools (direct + MCP when available)
150
+ // Get ALL available tools (direct + MCP + external from options)
161
151
  const shouldUseTools = !options.disableTools && this.supportsTools();
162
- const tools = shouldUseTools ? await this.getAllTools() : {};
163
- logger.debug(`[BaseProvider.generate] Tools for ${this.providerName}: ${Object.keys(tools).join(", ")}`);
152
+ const baseTools = shouldUseTools ? await this.getAllTools() : {};
153
+ const tools = shouldUseTools
154
+ ? {
155
+ ...baseTools,
156
+ ...(options.tools || {}), // Include external tools passed from NeuroLink
157
+ }
158
+ : {};
159
+ logger.debug(`[BaseProvider.generate] Tools for ${this.providerName}:`, {
160
+ directTools: Object.keys(baseTools),
161
+ externalTools: Object.keys(options.tools || {}),
162
+ totalTools: Object.keys(tools),
163
+ });
164
164
  // EVERY provider uses Vercel AI SDK - no exceptions
165
165
  const model = await this.getAISDKModel(); // This method is now REQUIRED
166
166
  // Build proper message array with conversation history
@@ -201,22 +201,66 @@ export class BaseProvider {
201
201
  const uniqueToolsUsed = [...new Set(toolsUsed)];
202
202
  // ✅ Extract tool executions from AI SDK result
203
203
  const toolExecutions = [];
204
+ // Create a map of tool calls to their arguments for matching with results
205
+ const toolCallArgsMap = new Map();
204
206
  // Extract tool executions from AI SDK result steps
205
- // Extract tool executions from steps (where tool results are stored)
206
207
  if (result.steps &&
207
208
  Array.isArray(result.steps)) {
208
209
  for (const step of result.steps ||
209
210
  []) {
210
- // Focus only on tool results (which have complete execution data)
211
- // Tool calls are just the requests, tool results contain the actual execution data
211
+ // First, collect tool calls and their arguments
212
+ if (step?.toolCalls && Array.isArray(step.toolCalls)) {
213
+ for (const toolCall of step.toolCalls) {
214
+ const tcRecord = toolCall;
215
+ const toolName = tcRecord.toolName ||
216
+ tcRecord.name ||
217
+ "unknown";
218
+ const toolId = tcRecord.toolCallId ||
219
+ tcRecord.id ||
220
+ toolName;
221
+ // Extract arguments from tool call
222
+ let callArgs = {};
223
+ if (tcRecord.args) {
224
+ callArgs = tcRecord.args;
225
+ }
226
+ else if (tcRecord.arguments) {
227
+ callArgs = tcRecord.arguments;
228
+ }
229
+ else if (tcRecord.parameters) {
230
+ callArgs = tcRecord.parameters;
231
+ }
232
+ toolCallArgsMap.set(toolId, callArgs);
233
+ toolCallArgsMap.set(toolName, callArgs); // Also map by name as fallback
234
+ }
235
+ }
236
+ // Then, process tool results and match with call arguments
212
237
  if (step?.toolResults && Array.isArray(step.toolResults)) {
213
238
  for (const toolResult of step.toolResults) {
214
239
  const trRecord = toolResult;
240
+ const toolName = trRecord.toolName || "unknown";
241
+ const toolId = trRecord.toolCallId || trRecord.id;
242
+ // Try to get arguments from the tool result first
243
+ let toolArgs = {};
244
+ if (trRecord.args) {
245
+ toolArgs = trRecord.args;
246
+ }
247
+ else if (trRecord.arguments) {
248
+ toolArgs = trRecord.arguments;
249
+ }
250
+ else if (trRecord.parameters) {
251
+ toolArgs = trRecord.parameters;
252
+ }
253
+ else if (trRecord.input) {
254
+ toolArgs = trRecord.input;
255
+ }
256
+ else {
257
+ // Fallback: get arguments from the corresponding tool call
258
+ toolArgs = toolCallArgsMap.get(toolId || toolName) || {};
259
+ }
215
260
  toolExecutions.push({
216
- name: trRecord.toolName || "unknown",
217
- input: trRecord.args || {},
261
+ name: toolName,
262
+ input: toolArgs,
218
263
  output: trRecord.result || "success",
219
- duration: 0, // AI SDK doesn't track duration
220
264
  });
221
265
  }
222
266
  }
@@ -248,6 +292,12 @@ export class BaseProvider {
248
292
  toolResults: result.toolResults,
249
293
  toolsUsed: uniqueToolsUsed,
250
294
  toolExecutions, // ✅ Add extracted tool executions
295
+ availableTools: Object.keys(tools).map((name) => ({
296
+ name,
297
+ description: tools[name].description || "No description available",
298
+ parameters: tools[name].parameters || {},
299
+ server: tools[name].serverId || "direct",
300
+ })),
251
301
  };
252
302
  // Enhanced result with analytics and evaluation
253
303
  return await this.enhanceResult(enhancedResult, options, startTime);
@@ -274,37 +324,88 @@ export class BaseProvider {
274
324
  const tools = {
275
325
  ...this.directTools, // Always include direct tools
276
326
  };
277
- logger.debug(`[BaseProvider] getAllTools called, SDK available: ${!!this.sdk}, type: ${typeof this.sdk}`);
327
+ logger.debug(`[BaseProvider] getAllTools called for ${this.providerName}`, {
328
+ neurolinkAvailable: !!this.neurolink,
329
+ neurolinkType: typeof this.neurolink,
330
+ directToolsCount: Object.keys(this.directTools).length,
331
+ });
278
332
  logger.debug(`[BaseProvider] Direct tools: ${Object.keys(this.directTools).join(", ")}`);
279
- // Add custom tools from SDK if available
280
- logger.debug(`[BaseProvider] Checking SDK: ${!!this.sdk}, has getInMemoryServers: ${this.sdk && typeof this.sdk.getInMemoryServers}`);
281
- if (this.sdk && typeof this.sdk.getInMemoryServers === "function") {
282
- logger.debug(`[BaseProvider] SDK check passed, loading custom tools`);
333
+ // Add custom tools from setupToolExecutor if available
334
+ if (this.customTools && this.customTools.size > 0) {
335
+ logger.debug(`[BaseProvider] Loading ${this.customTools.size} custom tools from setupToolExecutor`);
336
+ for (const [toolName, toolDef] of this.customTools.entries()) {
337
+ logger.debug(`[BaseProvider] Processing custom tool: ${toolName}`, {
338
+ toolDef: typeof toolDef,
339
+ hasExecute: toolDef && typeof toolDef === "object" && "execute" in toolDef,
340
+ hasName: toolDef && typeof toolDef === "object" && "name" in toolDef,
341
+ });
342
+ if (toolDef &&
343
+ typeof toolDef === "object" &&
344
+ "execute" in toolDef &&
345
+ typeof toolDef.execute === "function") {
346
+ try {
347
+ const { tool: createAISDKTool } = await import("ai");
348
+ const typedToolDef = toolDef;
349
+ tools[toolName] = createAISDKTool({
350
+ description: typedToolDef.description || `Custom tool ${toolName}`,
351
+ parameters: z.object({}), // Use empty schema for custom tools
352
+ execute: async (args) => {
353
+ logger.debug(`[BaseProvider] Executing custom tool: ${toolName}`, { args });
354
+ // Use the tool executor if available (from setupToolExecutor)
355
+ if (this.toolExecutor) {
356
+ return await this.toolExecutor(toolName, args);
357
+ }
358
+ else {
359
+ return await typedToolDef.execute(args);
360
+ }
361
+ },
362
+ });
363
+ logger.debug(`[BaseProvider] Successfully added custom tool: ${toolName}`);
364
+ }
365
+ catch (error) {
366
+ logger.error(`[BaseProvider] Failed to add custom tool: ${toolName}`, error);
367
+ }
368
+ }
369
+ else {
370
+ logger.warn(`[BaseProvider] Invalid custom tool format: ${toolName}`, {
371
+ toolDef: typeof toolDef,
372
+ hasExecute: toolDef && typeof toolDef === "object" && "execute" in toolDef,
373
+ executeType: toolDef && typeof toolDef === "object" && "execute" in toolDef
374
+ ? typeof toolDef.execute
375
+ : "N/A",
376
+ });
377
+ }
378
+ }
379
+ }
380
+ // Add custom tools from NeuroLink if available
381
+ logger.debug(`[BaseProvider] Checking NeuroLink: ${!!this.neurolink}, has getInMemoryServers: ${this.neurolink && typeof this.neurolink.getInMemoryServers}`);
382
+ if (this.neurolink &&
383
+ typeof this.neurolink.getInMemoryServers === "function") {
384
+ logger.debug(`[BaseProvider] NeuroLink check passed, loading custom tools`);
283
385
  try {
284
- const inMemoryServers = this.sdk.getInMemoryServers();
386
+ const inMemoryServers = this.neurolink.getInMemoryServers();
285
387
  logger.debug(`[BaseProvider] Got servers:`, inMemoryServers.size);
286
388
  logger.debug(`[BaseProvider] Loading custom tools from SDK, found ${inMemoryServers.size} servers`);
287
389
  if (inMemoryServers && inMemoryServers.size > 0) {
288
390
  // Convert in-memory server tools to AI SDK format
289
391
  for (const [serverId, serverConfig] of inMemoryServers) {
290
- const server = serverConfig.server;
291
- if (server && server.tools) {
292
- // Handle both Map and object formats
293
- const toolEntries = server.tools instanceof Map
294
- ? Array.from(server.tools.entries())
295
- : Object.entries(server.tools || {});
392
+ if (serverConfig && serverConfig.tools) {
393
+ // Handle tools array from MCPServerInfo
394
+ const toolEntries = serverConfig.tools.map((tool) => [
395
+ tool.name,
396
+ tool,
397
+ ]);
296
398
  for (const [toolName, toolInfo] of toolEntries) {
297
399
  if (toolInfo && typeof toolInfo.execute === "function") {
298
400
  logger.debug(`[BaseProvider] Converting custom tool: ${toolName}`);
299
401
  try {
300
402
  // Convert to AI SDK tool format
301
403
  const { tool: createAISDKTool } = await import("ai");
302
- const { z } = await import("zod");
303
404
  tools[toolName] = createAISDKTool({
304
405
  description: toolInfo.description || `Tool ${toolName}`,
305
- parameters: toolInfo.inputSchema ||
306
- toolInfo.parameters ||
307
- z.object({}),
406
+ parameters: toolInfo.parameters instanceof z.ZodType
407
+ ? toolInfo.parameters
408
+ : z.object({}),
308
409
  execute: async (args) => {
309
410
  const result = await toolInfo.execute(args);
310
411
  // Handle MCP-style results
@@ -339,6 +440,54 @@ export class BaseProvider {
339
440
  // Not an error - custom tools are optional
340
441
  }
341
442
  }
443
+ if (this.neurolink &&
444
+ typeof this.neurolink.getExternalMCPTools === "function") {
445
+ try {
446
+ logger.debug(`[BaseProvider] Loading external MCP tools from NeuroLink via direct tool access`);
447
+ const externalTools = this.neurolink.getExternalMCPTools() || [];
448
+ logger.debug(`[BaseProvider] Found ${externalTools.length} external MCP tools`);
449
+ for (const tool of externalTools) {
450
+ logger.debug(`[BaseProvider] Converting external MCP tool: ${tool.name}`);
451
+ try {
452
+ // Convert to AI SDK tool format
453
+ const { tool: createAISDKTool } = await import("ai");
454
+ tools[tool.name] = createAISDKTool({
455
+ description: tool.description || `External MCP tool ${tool.name}`,
456
+ parameters: await this.convertMCPSchemaToZod(tool.inputSchema),
457
+ execute: async (args) => {
458
+ logger.debug(`[BaseProvider] Executing external MCP tool: ${tool.name}`, { args });
459
+ // Execute via NeuroLink's direct tool execution
460
+ if (this.neurolink &&
461
+ typeof this.neurolink.executeExternalMCPTool === "function") {
462
+ return await this.neurolink.executeExternalMCPTool(tool.serverId || "unknown", tool.name, args);
463
+ }
464
+ else {
465
+ throw new Error(`Cannot execute external MCP tool: NeuroLink executeExternalMCPTool not available`);
466
+ }
467
+ },
468
+ });
469
+ logger.debug(`[BaseProvider] Successfully added external MCP tool: ${tool.name}`);
470
+ }
471
+ catch (toolCreationError) {
472
+ logger.error(`Failed to create external MCP tool: ${tool.name}`, toolCreationError);
473
+ }
474
+ }
475
+ logger.debug(`[BaseProvider] External MCP tools loading complete`, {
476
+ totalToolsAdded: externalTools.length,
477
+ });
478
+ }
479
+ catch (error) {
480
+ logger.error(`[BaseProvider] Failed to load external MCP tools for ${this.providerName}:`, error);
481
+ // Not an error - external tools are optional
482
+ }
483
+ }
484
+ else {
485
+ logger.debug(`[BaseProvider] No external MCP tool interface available`, {
486
+ hasNeuroLink: !!this.neurolink,
487
+ hasGetExternalMCPTools: this.neurolink &&
488
+ typeof this.neurolink.getExternalMCPTools === "function",
489
+ });
490
+ }
342
491
  // MCP tools loading simplified - removed functionCalling dependency
343
492
  if (!this.mcpTools) {
344
493
  // Set empty tools object - MCP tools are handled at a higher level
@@ -351,6 +500,80 @@ export class BaseProvider {
351
500
  logger.debug(`[BaseProvider] getAllTools returning tools: ${Object.keys(tools).join(", ")}`);
352
501
  return tools;
353
502
  }
503
+ /**
504
+ * Convert MCP JSON Schema to Zod schema for AI SDK tools
505
+ * Handles common MCP schema patterns safely
506
+ */
507
+ async convertMCPSchemaToZod(inputSchema) {
508
+ const { z } = await import("zod");
509
+ if (!inputSchema || typeof inputSchema !== "object") {
510
+ return z.object({});
511
+ }
512
+ try {
513
+ const schema = inputSchema;
514
+ const zodFields = {};
515
+ // Handle JSON Schema properties
516
+ if (schema.properties && typeof schema.properties === "object") {
517
+ const required = new Set(Array.isArray(schema.required) ? schema.required : []);
518
+ for (const [propName, propDef] of Object.entries(schema.properties)) {
519
+ const prop = propDef;
520
+ let zodType;
521
+ // Convert based on JSON Schema type
522
+ switch (prop.type) {
523
+ case "string":
524
+ zodType = z.string();
525
+ if (prop.description) {
526
+ zodType = zodType.describe(prop.description);
527
+ }
528
+ break;
529
+ case "number":
530
+ case "integer":
531
+ zodType = z.number();
532
+ if (prop.description) {
533
+ zodType = zodType.describe(prop.description);
534
+ }
535
+ break;
536
+ case "boolean":
537
+ zodType = z.boolean();
538
+ if (prop.description) {
539
+ zodType = zodType.describe(prop.description);
540
+ }
541
+ break;
542
+ case "array":
543
+ zodType = z.array(z.unknown());
544
+ if (prop.description) {
545
+ zodType = zodType.describe(prop.description);
546
+ }
547
+ break;
548
+ case "object":
549
+ zodType = z.object({});
550
+ if (prop.description) {
551
+ zodType = zodType.describe(prop.description);
552
+ }
553
+ break;
554
+ default:
555
+ // Unknown type, use string as fallback
556
+ zodType = z.string();
557
+ if (prop.description) {
558
+ zodType = zodType.describe(prop.description);
559
+ }
560
+ }
561
+ // Make optional if not required
562
+ if (!required.has(propName)) {
563
+ zodType = zodType.optional();
564
+ }
565
+ zodFields[propName] = zodType;
566
+ }
567
+ }
568
+ return Object.keys(zodFields).length > 0
569
+ ? z.object(zodFields)
570
+ : z.object({});
571
+ }
572
+ catch (error) {
573
+ logger.warn(`Failed to convert MCP schema to Zod, using empty schema:`, error);
574
+ return z.object({});
575
+ }
576
+ }
354
577
  /**
355
578
  * Set session context for MCP tools
356
579
  */
@@ -490,6 +713,9 @@ export class BaseProvider {
490
713
  });
491
714
  return;
492
715
  }
716
+ // Store custom tools for use in getAllTools()
717
+ this.customTools = sdk.customTools;
718
+ this.toolExecutor = sdk.executeTool;
493
719
  logger.debug(`[${functionTag}] Setting up tool executor for provider`, {
494
720
  providerType: this.constructor.name,
495
721
  availableCustomTools: sdk.customTools.size,
@@ -3,7 +3,7 @@
3
3
  * Handles in-memory conversation storage, session management, and context injection
4
4
  */
5
5
  import { ConversationMemoryError } from "../types/conversationTypes.js";
6
- import { DEFAULT_MAX_TURNS_PER_SESSION, DEFAULT_MAX_SESSIONS, MESSAGES_PER_TURN } from "../config/conversationMemoryConfig.js";
6
+ import { DEFAULT_MAX_TURNS_PER_SESSION, DEFAULT_MAX_SESSIONS, MESSAGES_PER_TURN, } from "../config/conversationMemoryConfig.js";
7
7
  import { logger } from "../utils/logger.js";
8
8
  export class ConversationMemoryManager {
9
9
  sessions = new Map();
@@ -49,7 +49,8 @@ export class ConversationMemoryManager {
49
49
  session.messages.push({ role: "user", content: userMessage }, { role: "assistant", content: aiResponse });
50
50
  session.lastActivity = Date.now();
51
51
  // Enforce per-session turn limit (each turn = MESSAGES_PER_TURN messages: user + assistant)
52
- const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) * MESSAGES_PER_TURN;
52
+ const maxMessages = (this.config.maxTurnsPerSession || DEFAULT_MAX_TURNS_PER_SESSION) *
53
+ MESSAGES_PER_TURN;
53
54
  if (session.messages.length > maxMessages) {
54
55
  session.messages = session.messages.slice(-maxMessages);
55
56
  }
@@ -89,7 +89,7 @@ export class DynamicModelProvider {
89
89
  }
90
90
  // Log all failures for debugging
91
91
  logger.warn(`[DynamicModelProvider] All model configuration sources failed`, { errors });
92
- throw new Error(`Failed to load model configuration from any source. Attempted: ${errors.map((e) => e.source).join(", ")}`);
92
+ throw new Error(`Failed to load model configuration from all source. Attempted: ${errors.map((e) => e.source).join(", ")}`);
93
93
  }
94
94
  /**
95
95
  * Load configuration from a source with timeout handling
@@ -181,7 +181,7 @@ Relevance: [score]
181
181
  Accuracy: [score]
182
182
  Completeness: [score]
183
183
  Overall: [score]
184
- Reasoning: [Provide a detailed explanation of your evaluation, explaining why you gave these scores. Include specific observations about the response's strengths and any areas for improvement.]
184
+ Reasoning: [Provide a detailed explanation of your evaluation, explaining why you gave these scores. Include specific observations about the response's strengths and all possible areas for improvement.]
185
185
  `;
186
186
  // Generate evaluation
187
187
  const result = await provider.generate(prompt);
@@ -109,13 +109,13 @@ export class AIProviderFactory {
109
109
  const finalModelName = resolvedModelName === "default" || resolvedModelName === null
110
110
  ? undefined
111
111
  : resolvedModelName;
112
+ // Create provider with enhanced SDK
112
113
  const provider = await ProviderFactory.createProvider(normalizedName, finalModelName, sdk);
113
114
  logger.debug(componentIdentifier, "Pure factory pattern provider created", {
114
115
  providerName: normalizedName,
115
116
  modelName: finalModelName,
116
117
  factoryUsed: true,
117
118
  });
118
- // PURE FACTORY PATTERN: All providers handled by ProviderFactory - no switch statements needed
119
119
  // Wrap with MCP if enabled
120
120
  if (enableMCP) {
121
121
  try {
@@ -46,22 +46,16 @@ export class ProviderFactory {
46
46
  model = model || registration.defaultModel;
47
47
  }
48
48
  try {
49
- // Try calling as factory function first, then fallback to constructor
50
49
  let result;
51
50
  try {
52
- // Try as factory function
53
- result = registration.constructor(model, providerName, sdk);
51
+ // Try as async factory function first (most providers are async functions)
52
+ result = await registration.constructor(model, providerName, sdk);
54
53
  }
55
- catch (factoryError) {
56
- // Fallback to constructor
54
+ catch (functionError) {
55
+ // Fallback to constructor - ensure parameters are maintained
57
56
  result = new registration.constructor(model, providerName, sdk);
58
57
  }
59
- // Only await if result is actually a Promise
60
- if (result &&
61
- typeof result === "object" &&
62
- typeof result.then === "function") {
63
- result = await result;
64
- }
58
+ // Return result (no need to await again if already awaited in try block)
65
59
  return result;
66
60
  }
67
61
  catch (error) {
@@ -52,9 +52,9 @@ export class ProviderRegistry {
52
52
  process.env.AZURE_OPENAI_DEPLOYMENT_ID ||
53
53
  "gpt-4o-mini", ["azure", "azureOpenai"]);
54
54
  // Register Google Vertex AI provider
55
- ProviderFactory.registerProvider(AIProviderName.VERTEX, async (modelName) => {
55
+ ProviderFactory.registerProvider(AIProviderName.VERTEX, async (modelName, providerName, sdk) => {
56
56
  const { GoogleVertexProvider } = await import("../providers/googleVertex.js");
57
- return new GoogleVertexProvider(modelName);
57
+ return new GoogleVertexProvider(modelName, providerName, sdk);
58
58
  }, "claude-sonnet-4@20250514", ["vertex", "googleVertex"]);
59
59
  // Register Hugging Face provider (Unified Router implementation)
60
60
  ProviderFactory.registerProvider(AIProviderName.HUGGINGFACE, async (modelName) => {
@@ -10,13 +10,14 @@ import { AIProviderFactory } from "./core/factory.js";
10
10
  export { AIProviderFactory };
11
11
  export type { AIProvider, AIProviderName, ProviderConfig, StreamingOptions, ProviderAttempt, SupportedModelName, } from "./core/types.js";
12
12
  export type { GenerateOptions, GenerateResult, EnhancedProvider, } from "./types/generateTypes.js";
13
- export type { SimpleTool, ToolContext } from "./sdk/toolRegistration.js";
14
- export { createTool, createTypedTool, validateTool, } from "./sdk/toolRegistration.js";
15
- export type { InMemoryMCPServerConfig, InMemoryToolInfo, InMemoryToolResult, } from "./types/mcpTypes.js";
13
+ export type { ToolContext } from "./sdk/toolRegistration.js";
14
+ export { validateTool } from "./sdk/toolRegistration.js";
15
+ export type { ToolResult, ToolDefinition } from "./types/tools.js";
16
16
  export { BedrockModels, OpenAIModels, VertexModels, DEFAULT_PROVIDER_CONFIGS, } from "./core/types.js";
17
17
  export { getBestProvider, getAvailableProviders, isValidProvider, } from "./utils/providerUtils.js";
18
18
  export { NeuroLink } from "./neurolink.js";
19
- export type { ProviderStatus, MCPStatus, MCPServerInfo } from "./neurolink.js";
19
+ export type { ProviderStatus, MCPStatus } from "./neurolink.js";
20
+ export type { MCPServerInfo } from "./types/mcpTypes.js";
20
21
  export declare const VERSION = "1.0.0";
21
22
  /**
22
23
  * Quick start factory function
package/dist/lib/index.js CHANGED
@@ -9,7 +9,7 @@
9
9
  // Core exports
10
10
  import { AIProviderFactory } from "./core/factory.js";
11
11
  export { AIProviderFactory };
12
- export { createTool, createTypedTool, validateTool, } from "./sdk/toolRegistration.js";
12
+ export { validateTool } from "./sdk/toolRegistration.js";
13
13
  // Model enums
14
14
  export { BedrockModels, OpenAIModels, VertexModels, DEFAULT_PROVIDER_CONFIGS, } from "./core/types.js";
15
15
  // Utility exports