@juspay/neurolink 7.29.2 → 7.29.3

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 (198) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/cli/commands/config.d.ts +83 -83
  3. package/dist/cli/commands/mcp.js +39 -9
  4. package/dist/cli/commands/models.js +25 -21
  5. package/dist/cli/commands/ollama.js +2 -2
  6. package/dist/cli/factories/commandFactory.d.ts +8 -0
  7. package/dist/cli/factories/commandFactory.js +65 -65
  8. package/dist/cli/factories/ollamaCommandFactory.js +3 -1
  9. package/dist/cli/factories/sagemakerCommandFactory.js +3 -2
  10. package/dist/cli/index.d.ts +1 -1
  11. package/dist/cli/index.js +11 -11
  12. package/dist/cli/utils/envManager.js +5 -5
  13. package/dist/cli/utils/ollamaUtils.d.ts +12 -0
  14. package/dist/cli/utils/ollamaUtils.js +58 -42
  15. package/dist/config/configManager.js +5 -2
  16. package/dist/core/analytics.d.ts +2 -24
  17. package/dist/core/analytics.js +12 -17
  18. package/dist/core/baseProvider.d.ts +30 -1
  19. package/dist/core/baseProvider.js +180 -198
  20. package/dist/core/dynamicModels.d.ts +4 -4
  21. package/dist/core/dynamicModels.js +7 -7
  22. package/dist/core/evaluation.d.ts +9 -9
  23. package/dist/core/evaluation.js +117 -65
  24. package/dist/core/evaluationProviders.d.ts +18 -2
  25. package/dist/core/evaluationProviders.js +15 -13
  26. package/dist/core/modelConfiguration.d.ts +63 -0
  27. package/dist/core/modelConfiguration.js +354 -290
  28. package/dist/core/streamAnalytics.d.ts +10 -5
  29. package/dist/core/streamAnalytics.js +10 -10
  30. package/dist/core/types.d.ts +19 -109
  31. package/dist/core/types.js +13 -0
  32. package/dist/factories/providerFactory.js +1 -1
  33. package/dist/index.d.ts +2 -1
  34. package/dist/lib/config/configManager.js +5 -2
  35. package/dist/lib/core/analytics.d.ts +2 -24
  36. package/dist/lib/core/analytics.js +12 -17
  37. package/dist/lib/core/baseProvider.d.ts +30 -1
  38. package/dist/lib/core/baseProvider.js +180 -198
  39. package/dist/lib/core/dynamicModels.js +7 -7
  40. package/dist/lib/core/evaluation.d.ts +9 -9
  41. package/dist/lib/core/evaluation.js +117 -65
  42. package/dist/lib/core/evaluationProviders.d.ts +18 -2
  43. package/dist/lib/core/evaluationProviders.js +15 -13
  44. package/dist/lib/core/modelConfiguration.d.ts +63 -0
  45. package/dist/lib/core/modelConfiguration.js +354 -290
  46. package/dist/lib/core/streamAnalytics.d.ts +10 -5
  47. package/dist/lib/core/streamAnalytics.js +10 -10
  48. package/dist/lib/core/types.d.ts +19 -109
  49. package/dist/lib/core/types.js +13 -0
  50. package/dist/lib/factories/providerFactory.js +1 -1
  51. package/dist/lib/index.d.ts +2 -1
  52. package/dist/lib/mcp/externalServerManager.js +15 -6
  53. package/dist/lib/mcp/factory.js +1 -1
  54. package/dist/lib/mcp/index.d.ts +1 -1
  55. package/dist/lib/mcp/index.js +1 -1
  56. package/dist/lib/mcp/mcpCircuitBreaker.js +5 -1
  57. package/dist/lib/mcp/mcpClientFactory.js +3 -0
  58. package/dist/lib/mcp/registry.d.ts +3 -3
  59. package/dist/lib/mcp/registry.js +3 -3
  60. package/dist/lib/mcp/servers/aiProviders/aiAnalysisTools.js +5 -5
  61. package/dist/lib/mcp/servers/aiProviders/aiWorkflowTools.js +6 -6
  62. package/dist/lib/mcp/servers/utilities/utilityServer.js +1 -1
  63. package/dist/lib/mcp/toolDiscoveryService.js +8 -2
  64. package/dist/lib/mcp/toolRegistry.js +4 -4
  65. package/dist/lib/middleware/builtin/analytics.js +4 -4
  66. package/dist/lib/middleware/builtin/guardrails.js +2 -2
  67. package/dist/lib/middleware/registry.js +11 -2
  68. package/dist/lib/models/modelRegistry.d.ts +1 -1
  69. package/dist/lib/models/modelRegistry.js +3 -3
  70. package/dist/lib/models/modelResolver.d.ts +1 -1
  71. package/dist/lib/models/modelResolver.js +2 -2
  72. package/dist/lib/neurolink.d.ts +116 -0
  73. package/dist/lib/neurolink.js +716 -922
  74. package/dist/lib/providers/amazonSagemaker.d.ts +1 -1
  75. package/dist/lib/providers/amazonSagemaker.js +12 -3
  76. package/dist/lib/providers/anthropic.d.ts +1 -1
  77. package/dist/lib/providers/anthropic.js +7 -6
  78. package/dist/lib/providers/anthropicBaseProvider.d.ts +1 -1
  79. package/dist/lib/providers/anthropicBaseProvider.js +4 -3
  80. package/dist/lib/providers/azureOpenai.d.ts +1 -1
  81. package/dist/lib/providers/azureOpenai.js +1 -1
  82. package/dist/lib/providers/googleAiStudio.d.ts +1 -1
  83. package/dist/lib/providers/googleAiStudio.js +2 -2
  84. package/dist/lib/providers/googleVertex.d.ts +40 -0
  85. package/dist/lib/providers/googleVertex.js +330 -274
  86. package/dist/lib/providers/huggingFace.js +1 -1
  87. package/dist/lib/providers/mistral.d.ts +1 -1
  88. package/dist/lib/providers/mistral.js +2 -2
  89. package/dist/lib/providers/ollama.d.ts +4 -0
  90. package/dist/lib/providers/ollama.js +38 -18
  91. package/dist/lib/providers/openAI.d.ts +1 -1
  92. package/dist/lib/providers/openAI.js +2 -2
  93. package/dist/lib/providers/sagemaker/adaptive-semaphore.js +7 -4
  94. package/dist/lib/providers/sagemaker/client.js +13 -3
  95. package/dist/lib/providers/sagemaker/config.js +5 -1
  96. package/dist/lib/providers/sagemaker/detection.js +19 -9
  97. package/dist/lib/providers/sagemaker/errors.d.ts +8 -1
  98. package/dist/lib/providers/sagemaker/errors.js +103 -20
  99. package/dist/lib/providers/sagemaker/language-model.d.ts +3 -3
  100. package/dist/lib/providers/sagemaker/language-model.js +4 -4
  101. package/dist/lib/providers/sagemaker/parsers.js +14 -6
  102. package/dist/lib/providers/sagemaker/streaming.js +14 -3
  103. package/dist/lib/providers/sagemaker/types.d.ts +1 -1
  104. package/dist/lib/proxy/awsProxyIntegration.js +1 -1
  105. package/dist/lib/sdk/toolRegistration.d.ts +1 -1
  106. package/dist/lib/types/cli.d.ts +80 -8
  107. package/dist/lib/types/contextTypes.js +2 -2
  108. package/dist/lib/types/generateTypes.d.ts +4 -6
  109. package/dist/lib/types/providers.d.ts +81 -19
  110. package/dist/lib/types/providers.js +6 -6
  111. package/dist/lib/types/streamTypes.d.ts +4 -6
  112. package/dist/lib/types/typeAliases.d.ts +1 -1
  113. package/dist/lib/utils/analyticsUtils.d.ts +33 -0
  114. package/dist/lib/utils/analyticsUtils.js +76 -0
  115. package/dist/lib/utils/errorHandling.js +4 -1
  116. package/dist/lib/utils/evaluationUtils.d.ts +27 -0
  117. package/dist/lib/utils/evaluationUtils.js +131 -0
  118. package/dist/lib/utils/optionsUtils.js +10 -1
  119. package/dist/lib/utils/performance.d.ts +1 -1
  120. package/dist/lib/utils/performance.js +15 -3
  121. package/dist/lib/utils/providerHealth.d.ts +48 -0
  122. package/dist/lib/utils/providerHealth.js +199 -254
  123. package/dist/lib/utils/providerUtils.js +2 -2
  124. package/dist/lib/utils/timeout.js +8 -3
  125. package/dist/mcp/externalServerManager.js +15 -6
  126. package/dist/mcp/factory.js +1 -1
  127. package/dist/mcp/index.d.ts +1 -1
  128. package/dist/mcp/index.js +1 -1
  129. package/dist/mcp/mcpCircuitBreaker.js +5 -1
  130. package/dist/mcp/mcpClientFactory.js +3 -0
  131. package/dist/mcp/registry.d.ts +3 -3
  132. package/dist/mcp/registry.js +3 -3
  133. package/dist/mcp/servers/aiProviders/aiAnalysisTools.js +5 -5
  134. package/dist/mcp/servers/aiProviders/aiWorkflowTools.js +6 -6
  135. package/dist/mcp/servers/utilities/utilityServer.js +1 -1
  136. package/dist/mcp/toolDiscoveryService.js +8 -2
  137. package/dist/mcp/toolRegistry.js +4 -4
  138. package/dist/middleware/builtin/analytics.js +4 -4
  139. package/dist/middleware/builtin/guardrails.js +2 -2
  140. package/dist/middleware/registry.js +11 -2
  141. package/dist/models/modelRegistry.d.ts +1 -1
  142. package/dist/models/modelRegistry.js +3 -3
  143. package/dist/models/modelResolver.d.ts +1 -1
  144. package/dist/models/modelResolver.js +2 -2
  145. package/dist/neurolink.d.ts +116 -0
  146. package/dist/neurolink.js +716 -922
  147. package/dist/providers/amazonSagemaker.d.ts +1 -1
  148. package/dist/providers/amazonSagemaker.js +12 -3
  149. package/dist/providers/anthropic.d.ts +1 -1
  150. package/dist/providers/anthropic.js +7 -6
  151. package/dist/providers/anthropicBaseProvider.d.ts +1 -1
  152. package/dist/providers/anthropicBaseProvider.js +4 -3
  153. package/dist/providers/azureOpenai.d.ts +1 -1
  154. package/dist/providers/azureOpenai.js +1 -1
  155. package/dist/providers/googleAiStudio.d.ts +1 -1
  156. package/dist/providers/googleAiStudio.js +2 -2
  157. package/dist/providers/googleVertex.d.ts +40 -0
  158. package/dist/providers/googleVertex.js +330 -274
  159. package/dist/providers/huggingFace.js +1 -1
  160. package/dist/providers/mistral.d.ts +1 -1
  161. package/dist/providers/mistral.js +2 -2
  162. package/dist/providers/ollama.d.ts +4 -0
  163. package/dist/providers/ollama.js +38 -18
  164. package/dist/providers/openAI.d.ts +1 -1
  165. package/dist/providers/openAI.js +2 -2
  166. package/dist/providers/sagemaker/adaptive-semaphore.js +7 -4
  167. package/dist/providers/sagemaker/client.js +13 -3
  168. package/dist/providers/sagemaker/config.js +5 -1
  169. package/dist/providers/sagemaker/detection.js +19 -9
  170. package/dist/providers/sagemaker/errors.d.ts +8 -1
  171. package/dist/providers/sagemaker/errors.js +103 -20
  172. package/dist/providers/sagemaker/language-model.d.ts +3 -3
  173. package/dist/providers/sagemaker/language-model.js +4 -4
  174. package/dist/providers/sagemaker/parsers.js +14 -6
  175. package/dist/providers/sagemaker/streaming.js +14 -3
  176. package/dist/providers/sagemaker/types.d.ts +1 -1
  177. package/dist/proxy/awsProxyIntegration.js +1 -1
  178. package/dist/sdk/toolRegistration.d.ts +1 -1
  179. package/dist/types/cli.d.ts +80 -8
  180. package/dist/types/contextTypes.js +2 -2
  181. package/dist/types/generateTypes.d.ts +4 -6
  182. package/dist/types/providers.d.ts +81 -19
  183. package/dist/types/providers.js +6 -6
  184. package/dist/types/streamTypes.d.ts +4 -6
  185. package/dist/types/typeAliases.d.ts +1 -1
  186. package/dist/utils/analyticsUtils.d.ts +33 -0
  187. package/dist/utils/analyticsUtils.js +76 -0
  188. package/dist/utils/errorHandling.js +4 -1
  189. package/dist/utils/evaluationUtils.d.ts +27 -0
  190. package/dist/utils/evaluationUtils.js +131 -0
  191. package/dist/utils/optionsUtils.js +10 -1
  192. package/dist/utils/performance.d.ts +1 -1
  193. package/dist/utils/performance.js +15 -3
  194. package/dist/utils/providerHealth.d.ts +48 -0
  195. package/dist/utils/providerHealth.js +199 -254
  196. package/dist/utils/providerUtils.js +2 -2
  197. package/dist/utils/timeout.js +8 -3
  198. package/package.json +1 -1
@@ -19,9 +19,9 @@ export function createAnalytics(provider, model, result, responseTime, context)
19
19
  const analytics = {
20
20
  provider,
21
21
  model,
22
- tokens,
22
+ tokenUsage: tokens,
23
23
  cost,
24
- responseTime,
24
+ requestDuration: responseTime,
25
25
  context: context,
26
26
  timestamp: new Date().toISOString(),
27
27
  };
@@ -40,8 +40,8 @@ export function createAnalytics(provider, model, result, responseTime, context)
40
40
  return {
41
41
  provider,
42
42
  model,
43
- tokens: { input: 0, output: 0, total: 0 },
44
- responseTime,
43
+ tokenUsage: { input: 0, output: 0, total: 0 },
44
+ requestDuration: responseTime,
45
45
  context: context,
46
46
  timestamp: new Date().toISOString(),
47
47
  };
@@ -56,14 +56,11 @@ function extractTokenUsage(result) {
56
56
  typeof result.usage === "object" &&
57
57
  result.usage !== null) {
58
58
  const usage = result.usage;
59
- // Try BaseProvider normalized format first (inputTokens/outputTokens)
60
- if (typeof usage.inputTokens === "number" ||
61
- typeof usage.outputTokens === "number") {
62
- const input = typeof usage.inputTokens === "number" ? usage.inputTokens : 0;
63
- const output = typeof usage.outputTokens === "number" ? usage.outputTokens : 0;
64
- const total = typeof usage.totalTokens === "number"
65
- ? usage.totalTokens
66
- : input + output;
59
+ // Try BaseProvider normalized format first (input/output/total)
60
+ if (typeof usage.input === "number" || typeof usage.output === "number") {
61
+ const input = typeof usage.input === "number" ? usage.input : 0;
62
+ const output = typeof usage.output === "number" ? usage.output : 0;
63
+ const total = typeof usage.total === "number" ? usage.total : input + output;
67
64
  return { input, output, total };
68
65
  }
69
66
  // Try OpenAI/Mistral format (promptTokens/completionTokens)
@@ -71,14 +68,12 @@ function extractTokenUsage(result) {
71
68
  typeof usage.completionTokens === "number") {
72
69
  const input = typeof usage.promptTokens === "number" ? usage.promptTokens : 0;
73
70
  const output = typeof usage.completionTokens === "number" ? usage.completionTokens : 0;
74
- const total = typeof usage.totalTokens === "number"
75
- ? usage.totalTokens
76
- : input + output;
71
+ const total = typeof usage.total === "number" ? usage.total : input + output;
77
72
  return { input, output, total };
78
73
  }
79
74
  // Handle total-only case
80
- if (typeof usage.totalTokens === "number") {
81
- return { input: 0, output: 0, total: usage.totalTokens };
75
+ if (typeof usage.total === "number") {
76
+ return { input: 0, output: 0, total: usage.total };
82
77
  }
83
78
  }
84
79
  // Fallback for edge cases
@@ -1,6 +1,7 @@
1
1
  import type { ValidationSchema } from "../types/typeAliases.js";
2
2
  import type { Tool, LanguageModelV1 } from "ai";
3
- import type { AIProvider, TextGenerationOptions, TextGenerationResult, EnhancedGenerateResult, AnalyticsData, AIProviderName, EvaluationData } from "../core/types.js";
3
+ import type { AIProvider, TextGenerationOptions, TextGenerationResult, EnhancedGenerateResult, AnalyticsData, AIProviderName } from "../core/types.js";
4
+ import type { EvaluationData } from "../index.js";
4
5
  import type { StreamOptions, StreamResult } from "../types/streamTypes.js";
5
6
  import type { UnknownRecord } from "../types/common.js";
6
7
  import type { NeuroLink } from "../neurolink.js";
@@ -76,6 +77,34 @@ export declare abstract class BaseProvider implements AIProvider {
76
77
  * Determine if middleware should be skipped for this request
77
78
  */
78
79
  private shouldSkipMiddleware;
80
+ /**
81
+ * Check if a schema is a Zod schema
82
+ */
83
+ private isZodSchema;
84
+ /**
85
+ * Convert tool execution result from MCP format to standard format
86
+ */
87
+ private convertToolResult;
88
+ /**
89
+ * Create a custom tool from tool definition
90
+ */
91
+ private createCustomToolFromDefinition;
92
+ /**
93
+ * Process custom tools from setupToolExecutor
94
+ */
95
+ private processCustomTools;
96
+ /**
97
+ * Create an external MCP tool
98
+ */
99
+ private createExternalMCPTool;
100
+ /**
101
+ * Process external MCP tools
102
+ */
103
+ private processExternalMCPTools;
104
+ /**
105
+ * Process MCP tools integration
106
+ */
107
+ private processMCPTools;
79
108
  /**
80
109
  * Get all available tools - direct tools are ALWAYS available
81
110
  * MCP tools are added when available (without blocking)
@@ -1,4 +1,3 @@
1
- import { z } from "zod";
2
1
  import { MiddlewareFactory } from "../middleware/factory.js";
3
2
  import { logger } from "../utils/logger.js";
4
3
  import { DEFAULT_MAX_STEPS, STEP_LIMITS } from "../core/constants.js";
@@ -320,9 +319,9 @@ export class BaseProvider {
320
319
  const enhancedResult = {
321
320
  content: result.text,
322
321
  usage: {
323
- inputTokens: result.usage?.promptTokens || 0,
324
- outputTokens: result.usage?.completionTokens || 0,
325
- totalTokens: result.usage?.totalTokens || 0,
322
+ input: result.usage?.promptTokens || 0,
323
+ output: result.usage?.completionTokens || 0,
324
+ total: result.usage?.totalTokens || 0,
326
325
  },
327
326
  provider: this.providerName,
328
327
  model: this.modelName,
@@ -389,9 +388,9 @@ export class BaseProvider {
389
388
  provider: result.provider || this.providerName,
390
389
  model: result.model || this.modelName,
391
390
  usage: result.usage || {
392
- promptTokens: 0,
393
- completionTokens: 0,
394
- totalTokens: 0,
391
+ input: 0,
392
+ output: 0,
393
+ total: 0,
395
394
  },
396
395
  responseTime: 0, // BaseProvider doesn't track response time directly
397
396
  toolsUsed: result.toolsUsed || [],
@@ -483,211 +482,152 @@ export class BaseProvider {
483
482
  // TOOL MANAGEMENT
484
483
  // ===================
485
484
  /**
486
- * Get all available tools - direct tools are ALWAYS available
487
- * MCP tools are added when available (without blocking)
485
+ * Check if a schema is a Zod schema
488
486
  */
489
- async getAllTools() {
490
- const tools = {
491
- ...this.directTools, // Always include direct tools
492
- };
493
- logger.debug(`[BaseProvider] getAllTools called for ${this.providerName}`, {
494
- neurolinkAvailable: !!this.neurolink,
495
- neurolinkType: typeof this.neurolink,
496
- directToolsCount: getKeyCount(this.directTools),
497
- });
498
- logger.debug(`[BaseProvider] Direct tools: ${getKeysAsString(this.directTools)}`);
499
- // Add custom tools from setupToolExecutor if available
500
- if (this.customTools && this.customTools.size > 0) {
501
- logger.debug(`[BaseProvider] Loading ${this.customTools.size} custom tools from setupToolExecutor`);
502
- for (const [toolName, toolDef] of this.customTools.entries()) {
503
- logger.debug(`[BaseProvider] Processing custom tool: ${toolName}`, {
504
- toolDef: typeof toolDef,
505
- hasExecute: toolDef && typeof toolDef === "object" && "execute" in toolDef,
506
- hasName: toolDef && typeof toolDef === "object" && "name" in toolDef,
507
- });
508
- if (toolDef &&
509
- typeof toolDef === "object" &&
510
- "execute" in toolDef &&
511
- typeof toolDef.execute === "function") {
512
- try {
513
- const { tool: createAISDKTool } = await import("ai");
514
- const typedToolDef = toolDef;
515
- tools[toolName] = createAISDKTool({
516
- description: typedToolDef.description || `Custom tool ${toolName}`,
517
- parameters: z.object({}), // Use empty schema for custom tools
518
- execute: async (params) => {
519
- logger.debug(`[BaseProvider] Executing custom tool: ${toolName}`, { params });
520
- try {
521
- // Use the tool executor if available (from setupToolExecutor)
522
- let result;
523
- if (this.toolExecutor) {
524
- result = await this.toolExecutor(toolName, params);
525
- }
526
- else {
527
- result = await typedToolDef.execute(params);
528
- }
529
- // Log successful execution
530
- logger.debug(`[BaseProvider] Tool execution successful: ${toolName}`, {
531
- resultType: typeof result,
532
- hasResult: result !== null && result !== undefined,
533
- toolName,
534
- });
535
- return result;
536
- }
537
- catch (error) {
538
- logger.warn(`[BaseProvider] Tool execution failed: ${toolName}`, {
539
- error: error instanceof Error ? error.message : String(error),
540
- params,
541
- toolName,
542
- });
543
- // GENERIC ERROR HANDLING FOR ALL MCP TOOLS:
544
- // Return a generic error object that works with any MCP server
545
- // The AI can interpret this and try different approaches
546
- return {
547
- _neurolinkToolError: true,
548
- toolName: toolName,
549
- error: error instanceof Error ? error.message : String(error),
550
- timestamp: new Date().toISOString(),
551
- params: params,
552
- // Keep it simple - just indicate an error occurred
553
- message: `Error calling ${toolName}: ${error instanceof Error ? error.message : String(error)}`,
554
- };
555
- }
556
- },
557
- });
558
- logger.debug(`[BaseProvider] Successfully added custom tool: ${toolName}`);
559
- }
560
- catch (error) {
561
- logger.error(`[BaseProvider] Failed to add custom tool: ${toolName}`, error);
562
- }
563
- }
564
- else {
565
- logger.warn(`[BaseProvider] Invalid custom tool format: ${toolName}`, {
566
- toolDef: typeof toolDef,
567
- hasExecute: toolDef && typeof toolDef === "object" && "execute" in toolDef,
568
- executeType: toolDef && typeof toolDef === "object" && "execute" in toolDef
569
- ? typeof toolDef.execute
570
- : "N/A",
571
- });
572
- }
487
+ isZodSchema(schema) {
488
+ return (typeof schema === "object" &&
489
+ schema !== null &&
490
+ // Most Zod schemas have an internal _def and a parse method
491
+ typeof schema.parse === "function");
492
+ }
493
+ /**
494
+ * Convert tool execution result from MCP format to standard format
495
+ */
496
+ async convertToolResult(result) {
497
+ // Handle MCP-style results
498
+ if (result && typeof result === "object" && "success" in result) {
499
+ const mcpResult = result;
500
+ if (mcpResult.success) {
501
+ return mcpResult.data;
502
+ }
503
+ else {
504
+ const errorMsg = typeof mcpResult.error === "string"
505
+ ? mcpResult.error
506
+ : "Tool execution failed";
507
+ throw new Error(errorMsg);
573
508
  }
574
509
  }
575
- // Add custom tools from NeuroLink if available
576
- logger.debug(`[BaseProvider] Checking NeuroLink: ${!!this.neurolink}, has getInMemoryServers: ${this.neurolink && typeof this.neurolink.getInMemoryServers}`);
577
- if (this.neurolink &&
578
- typeof this.neurolink.getInMemoryServers === "function") {
579
- logger.debug(`[BaseProvider] NeuroLink check passed, loading custom tools`);
580
- try {
581
- const inMemoryServers = this.neurolink.getInMemoryServers();
582
- logger.debug(`[BaseProvider] Got servers:`, inMemoryServers.size);
583
- logger.debug(`[BaseProvider] Loading custom tools from SDK, found ${inMemoryServers.size} servers`);
584
- if (inMemoryServers && inMemoryServers.size > 0) {
585
- // Convert in-memory server tools to AI SDK format
586
- for (const [_serverId, serverConfig] of inMemoryServers) {
587
- if (serverConfig && serverConfig.tools) {
588
- // Handle tools array from MCPServerInfo
589
- const toolEntries = serverConfig.tools.map((tool) => [
590
- tool.name,
591
- tool,
592
- ]);
593
- for (const [toolName, toolInfo] of toolEntries) {
594
- if (toolInfo && typeof toolInfo.execute === "function") {
595
- logger.debug(`[BaseProvider] Converting custom tool: ${toolName}`);
596
- try {
597
- // Convert to AI SDK tool format
598
- const { tool: createAISDKTool } = await import("ai");
599
- // Validate optional schemas if present (accept Zod or plain JSON schema objects)
600
- const isZodSchema = (s) => typeof s === "object" &&
601
- s !== null &&
602
- // Most Zod schemas have an internal _def and a parse method
603
- typeof s.parse === "function";
604
- tools[toolName] = createAISDKTool({
605
- description: toolInfo.description || `Tool ${toolName}`,
606
- parameters: isZodSchema(toolInfo.parameters)
607
- ? toolInfo.parameters
608
- : z.object({}),
609
- execute: async (params) => {
610
- const result = await toolInfo.execute(params);
611
- // Handle MCP-style results
612
- if (result &&
613
- typeof result === "object" &&
614
- "success" in result) {
615
- if (result.success) {
616
- return result.data;
617
- }
618
- else {
619
- const errorMsg = typeof result.error === "string"
620
- ? result.error
621
- : "Tool execution failed";
622
- throw new Error(errorMsg);
623
- }
624
- }
625
- return result;
626
- },
627
- });
628
- }
629
- catch (toolCreationError) {
630
- logger.error(`Failed to create tool: ${toolName}`, toolCreationError);
631
- }
632
- }
633
- }
634
- }
635
- }
510
+ return result;
511
+ }
512
+ /**
513
+ * Create a custom tool from tool definition
514
+ */
515
+ async createCustomToolFromDefinition(toolName, toolInfo) {
516
+ try {
517
+ logger.debug(`[BaseProvider] Converting custom tool: ${toolName}`);
518
+ // Convert to AI SDK tool format
519
+ const { tool: createAISDKTool } = await import("ai");
520
+ const { z } = await import("zod");
521
+ return createAISDKTool({
522
+ description: toolInfo.description || `Tool ${toolName}`,
523
+ parameters: this.isZodSchema(toolInfo.parameters)
524
+ ? toolInfo.parameters
525
+ : z.object({}),
526
+ execute: async (params) => {
527
+ const result = await toolInfo.execute(params);
528
+ return await this.convertToolResult(result);
529
+ },
530
+ });
531
+ }
532
+ catch (toolCreationError) {
533
+ logger.error(`Failed to create tool: ${toolName}`, toolCreationError);
534
+ return null;
535
+ }
536
+ }
537
+ /**
538
+ * Process custom tools from setupToolExecutor
539
+ */
540
+ async processCustomTools(tools) {
541
+ if (!this.customTools || this.customTools.size === 0) {
542
+ return;
543
+ }
544
+ logger.debug(`[BaseProvider] Loading ${this.customTools.size} custom tools from setupToolExecutor`);
545
+ for (const [toolName, toolDef] of this.customTools.entries()) {
546
+ logger.debug(`[BaseProvider] Processing custom tool: ${toolName}`, {
547
+ toolDef: typeof toolDef,
548
+ hasExecute: toolDef && typeof toolDef === "object" && "execute" in toolDef,
549
+ hasName: toolDef && typeof toolDef === "object" && "name" in toolDef,
550
+ });
551
+ // Validate tool definition has required execute function
552
+ const toolInfo = toolDef ||
553
+ {};
554
+ if (toolInfo && typeof toolInfo.execute === "function") {
555
+ const tool = await this.createCustomToolFromDefinition(toolName, toolInfo);
556
+ if (tool) {
557
+ tools[toolName] = tool;
636
558
  }
637
559
  }
638
- catch (error) {
639
- logger.debug(`Failed to load custom tools for ${this.providerName}:`, error);
640
- // Not an error - custom tools are optional
641
- }
642
560
  }
643
- if (this.neurolink &&
644
- typeof this.neurolink.getExternalMCPTools === "function") {
645
- try {
646
- logger.debug(`[BaseProvider] Loading external MCP tools from NeuroLink via direct tool access`);
647
- const externalTools = this.neurolink.getExternalMCPTools() || [];
648
- logger.debug(`[BaseProvider] Found ${externalTools.length} external MCP tools`);
649
- for (const tool of externalTools) {
650
- logger.debug(`[BaseProvider] Converting external MCP tool: ${tool.name}`);
651
- try {
652
- // Convert to AI SDK tool format
653
- const { tool: createAISDKTool } = await import("ai");
654
- tools[tool.name] = createAISDKTool({
655
- description: tool.description || `External MCP tool ${tool.name}`,
656
- parameters: await this.convertMCPSchemaToZod(tool.inputSchema),
657
- execute: async (params) => {
658
- logger.debug(`[BaseProvider] Executing external MCP tool: ${tool.name}`, { params });
659
- // Execute via NeuroLink's direct tool execution
660
- if (this.neurolink &&
661
- typeof this.neurolink.executeExternalMCPTool === "function") {
662
- return await this.neurolink.executeExternalMCPTool(tool.serverId || "unknown", tool.name, params);
663
- }
664
- else {
665
- throw new Error(`Cannot execute external MCP tool: NeuroLink executeExternalMCPTool not available`);
666
- }
667
- },
668
- });
669
- logger.debug(`[BaseProvider] Successfully added external MCP tool: ${tool.name}`);
561
+ logger.debug(`[BaseProvider] Custom tools processing complete`, {
562
+ customToolsProcessed: this.customTools.size,
563
+ });
564
+ }
565
+ /**
566
+ * Create an external MCP tool
567
+ */
568
+ async createExternalMCPTool(tool) {
569
+ try {
570
+ logger.debug(`[BaseProvider] Converting external MCP tool: ${tool.name}`);
571
+ // Convert to AI SDK tool format
572
+ const { tool: createAISDKTool } = await import("ai");
573
+ return createAISDKTool({
574
+ description: tool.description || `External MCP tool ${tool.name}`,
575
+ parameters: await this.convertMCPSchemaToZod(tool.inputSchema),
576
+ execute: async (params) => {
577
+ logger.debug(`[BaseProvider] Executing external MCP tool: ${tool.name}`, { params });
578
+ // Execute via NeuroLink's direct tool execution
579
+ if (this.neurolink &&
580
+ typeof this.neurolink.executeExternalMCPTool === "function") {
581
+ return await this.neurolink.executeExternalMCPTool(tool.serverId || "unknown", tool.name, params);
670
582
  }
671
- catch (toolCreationError) {
672
- logger.error(`Failed to create external MCP tool: ${tool.name}`, toolCreationError);
583
+ else {
584
+ throw new Error(`Cannot execute external MCP tool: NeuroLink executeExternalMCPTool not available`);
673
585
  }
674
- }
675
- logger.debug(`[BaseProvider] External MCP tools loading complete`, {
676
- totalToolsAdded: externalTools.length,
677
- });
678
- }
679
- catch (error) {
680
- logger.error(`[BaseProvider] Failed to load external MCP tools for ${this.providerName}:`, error);
681
- // Not an error - external tools are optional
682
- }
586
+ },
587
+ });
683
588
  }
684
- else {
589
+ catch (toolCreationError) {
590
+ logger.error(`Failed to create external MCP tool: ${tool.name}`, toolCreationError);
591
+ return null;
592
+ }
593
+ }
594
+ /**
595
+ * Process external MCP tools
596
+ */
597
+ async processExternalMCPTools(tools) {
598
+ if (!this.neurolink ||
599
+ typeof this.neurolink.getExternalMCPTools !== "function") {
685
600
  logger.debug(`[BaseProvider] No external MCP tool interface available`, {
686
601
  hasNeuroLink: !!this.neurolink,
687
602
  hasGetExternalMCPTools: this.neurolink &&
688
603
  typeof this.neurolink.getExternalMCPTools === "function",
689
604
  });
605
+ return;
606
+ }
607
+ try {
608
+ logger.debug(`[BaseProvider] Loading external MCP tools for ${this.providerName}`);
609
+ const externalTools = await this.neurolink.getExternalMCPTools();
610
+ logger.debug(`[BaseProvider] Found ${externalTools.length} external MCP tools`);
611
+ for (const tool of externalTools) {
612
+ const mcpTool = await this.createExternalMCPTool(tool);
613
+ if (mcpTool) {
614
+ tools[tool.name] = mcpTool;
615
+ logger.debug(`[BaseProvider] Successfully added external MCP tool: ${tool.name}`);
616
+ }
617
+ }
618
+ logger.debug(`[BaseProvider] External MCP tools loading complete`, {
619
+ totalToolsAdded: externalTools.length,
620
+ });
690
621
  }
622
+ catch (error) {
623
+ logger.error(`[BaseProvider] Failed to load external MCP tools for ${this.providerName}:`, error);
624
+ // Not an error - external tools are optional
625
+ }
626
+ }
627
+ /**
628
+ * Process MCP tools integration
629
+ */
630
+ async processMCPTools(tools) {
691
631
  // MCP tools loading simplified - removed functionCalling dependency
692
632
  if (!this.mcpTools) {
693
633
  // Set empty tools object - MCP tools are handled at a higher level
@@ -697,6 +637,25 @@ export class BaseProvider {
697
637
  if (this.mcpTools) {
698
638
  Object.assign(tools, this.mcpTools);
699
639
  }
640
+ }
641
+ /**
642
+ * Get all available tools - direct tools are ALWAYS available
643
+ * MCP tools are added when available (without blocking)
644
+ */
645
+ async getAllTools() {
646
+ const tools = {
647
+ ...this.directTools, // Always include direct tools
648
+ };
649
+ logger.debug(`[BaseProvider] getAllTools called for ${this.providerName}`, {
650
+ neurolinkAvailable: !!this.neurolink,
651
+ neurolinkType: typeof this.neurolink,
652
+ directToolsCount: getKeyCount(this.directTools),
653
+ });
654
+ logger.debug(`[BaseProvider] Direct tools: ${getKeysAsString(this.directTools)}`);
655
+ // Process all tool types using dedicated helper methods
656
+ await this.processCustomTools(tools);
657
+ await this.processExternalMCPTools(tools);
658
+ await this.processMCPTools(tools);
700
659
  logger.debug(`[BaseProvider] getAllTools returning tools: ${getKeysAsString(tools)}`);
701
660
  return tools;
702
661
  }
@@ -992,7 +951,30 @@ export class BaseProvider {
992
951
  }
993
952
  async createEvaluation(result, options) {
994
953
  const { evaluateResponse } = await import("../core/evaluation.js");
995
- const evaluation = await evaluateResponse(result.content, options.prompt);
954
+ const context = {
955
+ userQuery: options.prompt || options.input?.text || "Generated response",
956
+ aiResponse: result.content,
957
+ context: options.context,
958
+ primaryDomain: options.evaluationDomain,
959
+ assistantRole: "AI assistant",
960
+ conversationHistory: options.conversationHistory?.map((msg) => ({
961
+ role: msg.role,
962
+ content: msg.content,
963
+ })),
964
+ toolUsage: options.toolUsageContext
965
+ ? [
966
+ {
967
+ toolName: options.toolUsageContext,
968
+ input: {},
969
+ output: {},
970
+ executionTime: 0,
971
+ },
972
+ ]
973
+ : undefined,
974
+ expectedOutcome: options.expectedOutcome,
975
+ evaluationCriteria: options.evaluationCriteria,
976
+ };
977
+ const evaluation = await evaluateResponse(context);
996
978
  return evaluation;
997
979
  }
998
980
  validateOptions(options) {
@@ -88,6 +88,8 @@ declare const ModelRegistrySchema: z.ZodObject<{
88
88
  aliases: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
89
89
  defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
90
90
  }, "strip", z.ZodTypeAny, {
91
+ version: string;
92
+ lastUpdated: string;
91
93
  models: Record<string, Record<string, {
92
94
  capabilities: string[];
93
95
  id: string;
@@ -100,11 +102,11 @@ declare const ModelRegistrySchema: z.ZodObject<{
100
102
  contextWindow: number;
101
103
  releaseDate: string;
102
104
  }>>;
103
- version: string;
104
- lastUpdated: string;
105
105
  defaults?: Record<string, string> | undefined;
106
106
  aliases?: Record<string, string> | undefined;
107
107
  }, {
108
+ version: string;
109
+ lastUpdated: string;
108
110
  models: Record<string, Record<string, {
109
111
  capabilities: string[];
110
112
  id: string;
@@ -117,8 +119,6 @@ declare const ModelRegistrySchema: z.ZodObject<{
117
119
  contextWindow: number;
118
120
  releaseDate: string;
119
121
  }>>;
120
- version: string;
121
- lastUpdated: string;
122
122
  defaults?: Record<string, string> | undefined;
123
123
  aliases?: Record<string, string> | undefined;
124
124
  }>;
@@ -100,12 +100,6 @@ export class DynamicModelProvider {
100
100
  // Setup timeout and abort controller
101
101
  const controller = new AbortController();
102
102
  const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
103
- // Load from URL
104
- const response = await fetch(source, {
105
- headers: {
106
- "User-Agent": "NeuroLink/1.0 (+https://github.com/juspay/neurolink)",
107
- },
108
- });
109
103
  try {
110
104
  // Add health check for localhost before attempting full request
111
105
  if (source.includes("localhost") || source.includes("127.0.0.1")) {
@@ -113,7 +107,7 @@ export class DynamicModelProvider {
113
107
  }
114
108
  const response = await fetch(source, {
115
109
  headers: {
116
- "User-Agent": "NeuroLink/1.0 (+https://github.com/sachinsharma92/neurolink)",
110
+ "User-Agent": "NeuroLink/1.0 (+https://github.com/juspay/neurolink)",
117
111
  Accept: "application/json",
118
112
  "Cache-Control": "no-cache",
119
113
  },
@@ -242,6 +236,9 @@ export class DynamicModelProvider {
242
236
  searchByCapability(capability, options = {}) {
243
237
  this.ensureInitialized();
244
238
  const results = [];
239
+ if (!this.modelRegistry) {
240
+ return results;
241
+ }
245
242
  for (const [providerName, models] of Object.entries(this.modelRegistry.models)) {
246
243
  if (options.provider && providerName !== options.provider) {
247
244
  continue;
@@ -301,6 +298,9 @@ export class DynamicModelProvider {
301
298
  getAllModels() {
302
299
  this.ensureInitialized();
303
300
  const results = [];
301
+ if (!this.modelRegistry) {
302
+ return results;
303
+ }
304
304
  for (const [providerName, models] of Object.entries(this.modelRegistry.models)) {
305
305
  for (const [modelName, modelConfig] of Object.entries(models)) {
306
306
  results.push({