@juspay/neurolink 5.1.0 → 5.3.0

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 (190) hide show
  1. package/CHANGELOG.md +21 -9
  2. package/README.md +123 -126
  3. package/dist/agent/direct-tools.d.ts +6 -6
  4. package/dist/cli/commands/config.d.ts +3 -3
  5. package/dist/cli/commands/mcp.js +8 -7
  6. package/dist/cli/factories/command-factory.d.ts +4 -0
  7. package/dist/cli/factories/command-factory.js +63 -8
  8. package/dist/cli/index.js +87 -140
  9. package/dist/core/base-provider.d.ts +423 -0
  10. package/dist/core/base-provider.js +376 -0
  11. package/dist/core/constants.d.ts +2 -1
  12. package/dist/core/constants.js +2 -1
  13. package/dist/core/dynamic-models.d.ts +6 -6
  14. package/dist/core/evaluation.d.ts +19 -80
  15. package/dist/core/evaluation.js +185 -484
  16. package/dist/core/factory.d.ts +3 -3
  17. package/dist/core/factory.js +31 -91
  18. package/dist/core/service-registry.d.ts +47 -0
  19. package/dist/core/service-registry.js +112 -0
  20. package/dist/core/types.d.ts +8 -1
  21. package/dist/factories/compatibility-factory.js +1 -1
  22. package/dist/factories/provider-factory.d.ts +72 -0
  23. package/dist/factories/provider-factory.js +144 -0
  24. package/dist/factories/provider-registry.d.ts +38 -0
  25. package/dist/factories/provider-registry.js +107 -0
  26. package/dist/index.d.ts +4 -3
  27. package/dist/index.js +2 -4
  28. package/dist/lib/agent/direct-tools.d.ts +6 -6
  29. package/dist/lib/core/base-provider.d.ts +423 -0
  30. package/dist/lib/core/base-provider.js +376 -0
  31. package/dist/lib/core/constants.d.ts +2 -1
  32. package/dist/lib/core/constants.js +2 -1
  33. package/dist/lib/core/dynamic-models.d.ts +6 -6
  34. package/dist/lib/core/evaluation.d.ts +19 -80
  35. package/dist/lib/core/evaluation.js +185 -484
  36. package/dist/lib/core/factory.d.ts +3 -3
  37. package/dist/lib/core/factory.js +30 -91
  38. package/dist/lib/core/service-registry.d.ts +47 -0
  39. package/dist/lib/core/service-registry.js +112 -0
  40. package/dist/lib/core/types.d.ts +8 -1
  41. package/dist/lib/factories/compatibility-factory.js +1 -1
  42. package/dist/lib/factories/provider-factory.d.ts +72 -0
  43. package/dist/lib/factories/provider-factory.js +144 -0
  44. package/dist/lib/factories/provider-registry.d.ts +38 -0
  45. package/dist/lib/factories/provider-registry.js +107 -0
  46. package/dist/lib/index.d.ts +4 -3
  47. package/dist/lib/index.js +2 -4
  48. package/dist/lib/mcp/client.d.ts +1 -0
  49. package/dist/lib/mcp/client.js +1 -0
  50. package/dist/lib/mcp/config.js +28 -3
  51. package/dist/lib/mcp/context-manager.d.ts +1 -0
  52. package/dist/lib/mcp/context-manager.js +8 -4
  53. package/dist/lib/mcp/function-calling.d.ts +13 -0
  54. package/dist/lib/mcp/function-calling.js +134 -35
  55. package/dist/lib/mcp/initialize-tools.d.ts +1 -1
  56. package/dist/lib/mcp/initialize-tools.js +45 -1
  57. package/dist/lib/mcp/initialize.js +16 -6
  58. package/dist/lib/mcp/neurolink-mcp-client.d.ts +1 -0
  59. package/dist/lib/mcp/neurolink-mcp-client.js +21 -5
  60. package/dist/lib/mcp/servers/agent/direct-tools-server.d.ts +8 -0
  61. package/dist/lib/mcp/servers/agent/direct-tools-server.js +109 -0
  62. package/dist/lib/mcp/servers/ai-providers/ai-core-server.js +3 -1
  63. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
  64. package/dist/lib/mcp/unified-registry.d.ts +4 -0
  65. package/dist/lib/mcp/unified-registry.js +42 -9
  66. package/dist/lib/neurolink.d.ts +156 -117
  67. package/dist/lib/neurolink.js +619 -404
  68. package/dist/lib/providers/amazon-bedrock.d.ts +32 -0
  69. package/dist/lib/providers/amazon-bedrock.js +143 -0
  70. package/dist/lib/providers/analytics-helper.js +7 -4
  71. package/dist/lib/providers/anthropic-baseprovider.d.ts +23 -0
  72. package/dist/lib/providers/anthropic-baseprovider.js +114 -0
  73. package/dist/lib/providers/anthropic.d.ts +19 -43
  74. package/dist/lib/providers/anthropic.js +82 -306
  75. package/dist/lib/providers/azure-openai.d.ts +20 -0
  76. package/dist/lib/providers/azure-openai.js +89 -0
  77. package/dist/lib/providers/function-calling-provider.d.ts +64 -2
  78. package/dist/lib/providers/function-calling-provider.js +208 -9
  79. package/dist/lib/providers/google-ai-studio.d.ts +23 -0
  80. package/dist/lib/providers/google-ai-studio.js +107 -0
  81. package/dist/lib/providers/google-vertex.d.ts +47 -0
  82. package/dist/lib/providers/google-vertex.js +205 -0
  83. package/dist/lib/providers/huggingFace.d.ts +32 -25
  84. package/dist/lib/providers/huggingFace.js +97 -431
  85. package/dist/lib/providers/index.d.ts +9 -9
  86. package/dist/lib/providers/index.js +9 -9
  87. package/dist/lib/providers/mcp-provider.js +24 -5
  88. package/dist/lib/providers/mistral.d.ts +42 -0
  89. package/dist/lib/providers/mistral.js +160 -0
  90. package/dist/lib/providers/ollama.d.ts +52 -36
  91. package/dist/lib/providers/ollama.js +297 -520
  92. package/dist/lib/providers/openAI.d.ts +19 -18
  93. package/dist/lib/providers/openAI.js +76 -275
  94. package/dist/lib/sdk/tool-extension.d.ts +181 -0
  95. package/dist/lib/sdk/tool-extension.js +283 -0
  96. package/dist/lib/sdk/tool-registration.d.ts +95 -0
  97. package/dist/lib/sdk/tool-registration.js +167 -0
  98. package/dist/lib/services/streaming/streaming-manager.js +11 -10
  99. package/dist/lib/services/websocket/websocket-server.js +12 -11
  100. package/dist/lib/telemetry/telemetry-service.js +8 -7
  101. package/dist/lib/types/generate-types.d.ts +1 -0
  102. package/dist/lib/types/mcp-types.d.ts +116 -0
  103. package/dist/lib/types/mcp-types.js +5 -0
  104. package/dist/lib/types/stream-types.d.ts +30 -18
  105. package/dist/lib/types/universal-provider-options.d.ts +87 -0
  106. package/dist/lib/types/universal-provider-options.js +53 -0
  107. package/dist/mcp/client.d.ts +1 -0
  108. package/dist/mcp/client.js +1 -0
  109. package/dist/mcp/config.js +28 -3
  110. package/dist/mcp/context-manager.d.ts +1 -0
  111. package/dist/mcp/context-manager.js +8 -4
  112. package/dist/mcp/function-calling.d.ts +13 -0
  113. package/dist/mcp/function-calling.js +134 -35
  114. package/dist/mcp/initialize-tools.d.ts +1 -1
  115. package/dist/mcp/initialize-tools.js +45 -1
  116. package/dist/mcp/initialize.js +16 -6
  117. package/dist/mcp/neurolink-mcp-client.d.ts +1 -0
  118. package/dist/mcp/neurolink-mcp-client.js +21 -5
  119. package/dist/mcp/servers/agent/direct-tools-server.d.ts +8 -0
  120. package/dist/mcp/servers/agent/direct-tools-server.js +109 -0
  121. package/dist/mcp/servers/ai-providers/ai-core-server.js +3 -1
  122. package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
  123. package/dist/mcp/unified-registry.d.ts +4 -0
  124. package/dist/mcp/unified-registry.js +42 -9
  125. package/dist/neurolink.d.ts +156 -117
  126. package/dist/neurolink.js +619 -404
  127. package/dist/providers/amazon-bedrock.d.ts +32 -0
  128. package/dist/providers/amazon-bedrock.js +143 -0
  129. package/dist/providers/analytics-helper.js +7 -4
  130. package/dist/providers/anthropic-baseprovider.d.ts +23 -0
  131. package/dist/providers/anthropic-baseprovider.js +114 -0
  132. package/dist/providers/anthropic.d.ts +19 -43
  133. package/dist/providers/anthropic.js +81 -305
  134. package/dist/providers/azure-openai.d.ts +20 -0
  135. package/dist/providers/azure-openai.js +89 -0
  136. package/dist/providers/function-calling-provider.d.ts +64 -2
  137. package/dist/providers/function-calling-provider.js +208 -9
  138. package/dist/providers/google-ai-studio.d.ts +23 -0
  139. package/dist/providers/google-ai-studio.js +108 -0
  140. package/dist/providers/google-vertex.d.ts +47 -0
  141. package/dist/providers/google-vertex.js +205 -0
  142. package/dist/providers/huggingFace.d.ts +32 -25
  143. package/dist/providers/huggingFace.js +96 -430
  144. package/dist/providers/index.d.ts +9 -9
  145. package/dist/providers/index.js +9 -9
  146. package/dist/providers/mcp-provider.js +24 -5
  147. package/dist/providers/mistral.d.ts +42 -0
  148. package/dist/providers/mistral.js +160 -0
  149. package/dist/providers/ollama.d.ts +52 -36
  150. package/dist/providers/ollama.js +297 -519
  151. package/dist/providers/openAI.d.ts +19 -18
  152. package/dist/providers/openAI.js +76 -276
  153. package/dist/sdk/tool-extension.d.ts +181 -0
  154. package/dist/sdk/tool-extension.js +283 -0
  155. package/dist/sdk/tool-registration.d.ts +95 -0
  156. package/dist/sdk/tool-registration.js +168 -0
  157. package/dist/services/streaming/streaming-manager.js +11 -10
  158. package/dist/services/websocket/websocket-server.js +12 -11
  159. package/dist/telemetry/telemetry-service.js +8 -7
  160. package/dist/types/generate-types.d.ts +1 -0
  161. package/dist/types/mcp-types.d.ts +116 -0
  162. package/dist/types/mcp-types.js +5 -0
  163. package/dist/types/stream-types.d.ts +30 -18
  164. package/dist/types/universal-provider-options.d.ts +87 -0
  165. package/dist/types/universal-provider-options.js +53 -0
  166. package/package.json +12 -5
  167. package/dist/lib/providers/agent-enhanced-provider.d.ts +0 -93
  168. package/dist/lib/providers/agent-enhanced-provider.js +0 -605
  169. package/dist/lib/providers/amazonBedrock.d.ts +0 -28
  170. package/dist/lib/providers/amazonBedrock.js +0 -364
  171. package/dist/lib/providers/azureOpenAI.d.ts +0 -42
  172. package/dist/lib/providers/azureOpenAI.js +0 -347
  173. package/dist/lib/providers/googleAIStudio.d.ts +0 -42
  174. package/dist/lib/providers/googleAIStudio.js +0 -364
  175. package/dist/lib/providers/googleVertexAI.d.ts +0 -34
  176. package/dist/lib/providers/googleVertexAI.js +0 -547
  177. package/dist/lib/providers/mistralAI.d.ts +0 -37
  178. package/dist/lib/providers/mistralAI.js +0 -325
  179. package/dist/providers/agent-enhanced-provider.d.ts +0 -93
  180. package/dist/providers/agent-enhanced-provider.js +0 -606
  181. package/dist/providers/amazonBedrock.d.ts +0 -28
  182. package/dist/providers/amazonBedrock.js +0 -364
  183. package/dist/providers/azureOpenAI.d.ts +0 -42
  184. package/dist/providers/azureOpenAI.js +0 -348
  185. package/dist/providers/googleAIStudio.d.ts +0 -42
  186. package/dist/providers/googleAIStudio.js +0 -364
  187. package/dist/providers/googleVertexAI.d.ts +0 -34
  188. package/dist/providers/googleVertexAI.js +0 -547
  189. package/dist/providers/mistralAI.d.ts +0 -37
  190. package/dist/providers/mistralAI.js +0 -325
@@ -0,0 +1,107 @@
1
+ import { ProviderFactory } from "./provider-factory.js";
2
+ // ✅ FINAL CIRCULAR DEPENDENCY FIX: Lazy loading all providers
3
+ // Removed all static imports - providers loaded dynamically when needed
4
+ // This breaks the circular dependency chain completely
5
+ import { AIProviderName, GoogleAIModels, OpenAIModels } from "../core/types.js";
6
+ import { logger } from "../utils/logger.js";
7
+ /**
8
+ * Provider Registry - registers all providers with the factory
9
+ * This is where we migrate providers one by one to the new pattern
10
+ */
11
+ export class ProviderRegistry {
12
+ static registered = false;
13
+ static options = {
14
+ enableManualMCP: false, // Default to disabled for safety
15
+ };
16
+ /**
17
+ * Register all providers with the factory
18
+ */
19
+ static async registerAllProviders() {
20
+ if (this.registered) {
21
+ return;
22
+ }
23
+ try {
24
+ // ✅ LAZY LOADING: Register providers with dynamic import factory functions
25
+ const { ProviderFactory } = await import("./provider-factory.js");
26
+ // Register Google AI Studio Provider (our validated baseline)
27
+ ProviderFactory.registerProvider(AIProviderName.GOOGLE_AI, async (modelName, providerName, sdk) => {
28
+ const { GoogleAIStudioProvider } = await import("../providers/google-ai-studio.js");
29
+ return new GoogleAIStudioProvider(modelName, sdk);
30
+ }, GoogleAIModels.GEMINI_2_5_FLASH, ["google-ai-studio", "google", "gemini", "google-ai"]);
31
+ // Register OpenAI provider
32
+ ProviderFactory.registerProvider(AIProviderName.OPENAI, async (modelName, providerName, sdk) => {
33
+ const { OpenAIProvider } = await import("../providers/openAI.js");
34
+ return new OpenAIProvider(modelName);
35
+ }, OpenAIModels.GPT_4O_MINI, ["gpt", "chatgpt"]);
36
+ // Register Anthropic provider
37
+ ProviderFactory.registerProvider(AIProviderName.ANTHROPIC, async (modelName, providerName, sdk) => {
38
+ const { AnthropicProvider } = await import("../providers/anthropic.js");
39
+ return new AnthropicProvider(modelName, sdk);
40
+ }, "claude-3-5-sonnet-20241022", ["claude", "anthropic"]);
41
+ // Register Amazon Bedrock provider
42
+ ProviderFactory.registerProvider(AIProviderName.BEDROCK, async (modelName) => {
43
+ const { AmazonBedrockProvider } = await import("../providers/amazon-bedrock.js");
44
+ return new AmazonBedrockProvider(modelName);
45
+ }, undefined, // Let provider read BEDROCK_MODEL from .env
46
+ ["bedrock", "aws"]);
47
+ // Register Azure OpenAI provider
48
+ ProviderFactory.registerProvider(AIProviderName.AZURE, async (modelName) => {
49
+ const { AzureOpenAIProvider } = await import("../providers/azure-openai.js");
50
+ return new AzureOpenAIProvider(modelName);
51
+ }, "gpt-4o-mini", ["azure", "azure-openai"]);
52
+ // Register Google Vertex AI provider
53
+ ProviderFactory.registerProvider(AIProviderName.VERTEX, async (modelName) => {
54
+ const { GoogleVertexProvider } = await import("../providers/google-vertex.js");
55
+ return new GoogleVertexProvider(modelName);
56
+ }, "gemini-2.5-pro", ["vertex", "google-vertex"]);
57
+ // Register Hugging Face provider (Unified Router implementation)
58
+ ProviderFactory.registerProvider(AIProviderName.HUGGINGFACE, async (modelName) => {
59
+ const { HuggingFaceProvider } = await import("../providers/huggingFace.js");
60
+ return new HuggingFaceProvider(modelName);
61
+ }, process.env.HUGGINGFACE_MODEL || "microsoft/DialoGPT-medium", ["huggingface", "hf"]);
62
+ // Register Mistral AI provider
63
+ ProviderFactory.registerProvider(AIProviderName.MISTRAL, async (modelName, providerName, sdk) => {
64
+ const { MistralProvider } = await import("../providers/mistral.js");
65
+ return new MistralProvider(modelName, sdk);
66
+ }, "mistral-large-latest", ["mistral"]);
67
+ // Register Ollama provider
68
+ ProviderFactory.registerProvider(AIProviderName.OLLAMA, async (modelName) => {
69
+ const { OllamaProvider } = await import("../providers/ollama.js");
70
+ return new OllamaProvider(modelName);
71
+ }, process.env.OLLAMA_MODEL || "llama3.1:8b", ["ollama", "local"]);
72
+ logger.debug("All providers registered successfully");
73
+ this.registered = true;
74
+ }
75
+ catch (error) {
76
+ logger.error("Failed to register providers:", error);
77
+ throw error;
78
+ }
79
+ }
80
+ /**
81
+ * Check if providers are registered
82
+ */
83
+ static isRegistered() {
84
+ return this.registered;
85
+ }
86
+ /**
87
+ * Clear registrations (for testing)
88
+ */
89
+ static clearRegistrations() {
90
+ ProviderFactory.clearRegistrations();
91
+ this.registered = false;
92
+ }
93
+ /**
94
+ * Set registry options (should be called before initialization)
95
+ */
96
+ static setOptions(options) {
97
+ this.options = { ...this.options, ...options };
98
+ logger.debug("Provider registry options updated:", this.options);
99
+ }
100
+ /**
101
+ * Get current registry options
102
+ */
103
+ static getOptions() {
104
+ return { ...this.options };
105
+ }
106
+ }
107
+ // Note: Providers are registered explicitly when needed to avoid circular dependencies
@@ -12,12 +12,13 @@ export type { AIProvider, AIProviderName, ProviderConfig, StreamingOptions, Prov
12
12
  export type { GenerateOptions, GenerateResult, EnhancedProvider, } from "./types/generate-types.js";
13
13
  export { CompatibilityConversionFactory } from "./factories/compatibility-factory.js";
14
14
  export { ProviderGenerateFactory } from "./factories/provider-generate-factory.js";
15
+ export type { SimpleTool, ToolContext } from "./sdk/tool-registration.js";
16
+ export { createTool, createTypedTool, validateTool, } from "./sdk/tool-registration.js";
17
+ export type { InMemoryMCPServerConfig, InMemoryToolInfo, InMemoryToolResult, } from "./types/mcp-types.js";
15
18
  export { BedrockModels, OpenAIModels, VertexModels, DEFAULT_PROVIDER_CONFIGS, } from "./core/types.js";
16
- export { GoogleVertexAI, AmazonBedrock, OpenAI, AnthropicProvider, AzureOpenAIProvider, } from "./providers/index.js";
17
- export type { ProviderName } from "./providers/index.js";
18
- export { PROVIDERS, AVAILABLE_PROVIDERS } from "./providers/index.js";
19
19
  export { getBestProvider, getAvailableProviders, isValidProvider, } from "./utils/providerUtils.js";
20
20
  export { NeuroLink } from "./neurolink.js";
21
+ export type { ProviderStatus, MCPStatus, MCPServerInfo } from "./neurolink.js";
21
22
  export declare const VERSION = "1.0.0";
22
23
  /**
23
24
  * Quick start factory function
package/dist/lib/index.js CHANGED
@@ -11,14 +11,12 @@ import { AIProviderFactory } from "./core/factory.js";
11
11
  export { AIProviderFactory };
12
12
  export { CompatibilityConversionFactory } from "./factories/compatibility-factory.js";
13
13
  export { ProviderGenerateFactory } from "./factories/provider-generate-factory.js";
14
+ export { createTool, createTypedTool, validateTool, } from "./sdk/tool-registration.js";
14
15
  // Model enums
15
16
  export { BedrockModels, OpenAIModels, VertexModels, DEFAULT_PROVIDER_CONFIGS, } from "./core/types.js";
16
- // Provider exports
17
- export { GoogleVertexAI, AmazonBedrock, OpenAI, AnthropicProvider, AzureOpenAIProvider, } from "./providers/index.js";
18
- export { PROVIDERS, AVAILABLE_PROVIDERS } from "./providers/index.js";
19
17
  // Utility exports
20
18
  export { getBestProvider, getAvailableProviders, isValidProvider, } from "./utils/providerUtils.js";
21
- // Main NeuroLink wrapper class
19
+ // Main NeuroLink wrapper class and diagnostic types
22
20
  export { NeuroLink } from "./neurolink.js";
23
21
  // Version
24
22
  export const VERSION = "1.0.0";
@@ -33,6 +33,7 @@ export declare class NeuroLinkMCPClient extends EventEmitter {
33
33
  * Get all registered tools
34
34
  */
35
35
  getTools(): Record<string, {
36
+ name: string;
36
37
  description?: string;
37
38
  inputSchema?: unknown;
38
39
  }>;
@@ -130,6 +130,7 @@ export class NeuroLinkMCPClient extends EventEmitter {
130
130
  const tools = {};
131
131
  for (const [name, tool] of this.tools) {
132
132
  tools[name] = {
133
+ name: name, // Include the tool name as a property
133
134
  description: tool.description,
134
135
  inputSchema: tool.inputSchema,
135
136
  };
@@ -3,15 +3,36 @@
3
3
  * Central registry for all MCP servers following Lighthouse patterns
4
4
  * Handles built-in servers only - auto-discovery handled by unified registry
5
5
  */
6
- import { aiCoreServer } from "./servers/ai-providers/ai-core-server.js";
7
6
  import { utilityServer } from "./servers/utilities/utility-server.js";
8
7
  import { logger } from "../utils/logger.js";
8
+ /**
9
+ * Lazy-loaded AI Core Server to avoid circular dependencies
10
+ */
11
+ let aiCoreServerCache = null;
12
+ async function getAICoreServer() {
13
+ if (!aiCoreServerCache) {
14
+ const { aiCoreServer } = await import("./servers/ai-providers/ai-core-server.js");
15
+ aiCoreServerCache = aiCoreServer;
16
+ }
17
+ return aiCoreServerCache;
18
+ }
19
+ /**
20
+ * Lazy-loaded Direct Tools Server to avoid circular dependencies
21
+ */
22
+ let directToolsServerCache = null;
23
+ async function getDirectToolsServer() {
24
+ if (!directToolsServerCache) {
25
+ const { directToolsServer } = await import("./servers/agent/direct-tools-server.js");
26
+ directToolsServerCache = directToolsServer;
27
+ }
28
+ return directToolsServerCache;
29
+ }
9
30
  /**
10
31
  * Built-in MCP servers (kept for backward compatibility)
11
32
  * Add new servers here as they are created
12
33
  */
13
34
  export const allServers = [
14
- aiCoreServer,
35
+ // aiCoreServer will be added dynamically in getServers()
15
36
  utilityServer,
16
37
  // Add more servers as they are created
17
38
  ];
@@ -25,8 +46,12 @@ export const mcpConfig = {
25
46
  */
26
47
  getServers: async () => {
27
48
  const activeServers = [];
49
+ // Get all servers including dynamically loaded ones
50
+ const aiCoreServer = await getAICoreServer();
51
+ const directToolsServer = await getDirectToolsServer();
52
+ const servers = [aiCoreServer, directToolsServer, ...allServers];
28
53
  // Include built-in servers with filtering
29
- for (const server of allServers) {
54
+ for (const server of servers) {
30
55
  const implementedTools = {};
31
56
  let hasImplementedTools = false;
32
57
  for (const toolName in server.tools) {
@@ -29,6 +29,7 @@ export interface ContextRequest {
29
29
  export declare class ContextManager {
30
30
  private sessionCounter;
31
31
  private activeContexts;
32
+ private static cachedLogger;
32
33
  /**
33
34
  * Create a new execution context with rich information
34
35
  *
@@ -10,6 +10,7 @@
10
10
  export class ContextManager {
11
11
  sessionCounter = 0;
12
12
  activeContexts = new Map();
13
+ static cachedLogger = null;
13
14
  /**
14
15
  * Create a new execution context with rich information
15
16
  *
@@ -64,6 +65,7 @@ export class ContextManager {
64
65
  },
65
66
  path: {
66
67
  join: (...paths) => {
68
+ // Use dynamic require for synchronous path operations
67
69
  const path = require("path");
68
70
  return path.join(...paths);
69
71
  },
@@ -85,11 +87,13 @@ export class ContextManager {
85
87
  },
86
88
  },
87
89
  grantedPermissions: request.permissions || [],
88
- log: (level, message, data) => {
89
- // Use logger if available, otherwise console
90
+ log: async (level, message, data) => {
91
+ // Use cached logger if available, otherwise import and cache
90
92
  try {
91
- const { logger } = require("../utils/logger.js");
92
- logger[level](message, data);
93
+ if (!ContextManager.cachedLogger) {
94
+ ContextManager.cachedLogger = await import("../utils/logger.js").then(({ logger }) => logger);
95
+ }
96
+ ContextManager.cachedLogger[level](message, data);
93
97
  }
94
98
  catch {
95
99
  console[level === "debug" ? "log" : level](message, data);
@@ -14,6 +14,7 @@ export declare function mcpToolToAISDKTool(tool: NeuroLinkMCPTool, serverId: str
14
14
  */
15
15
  export declare function getAvailableFunctionTools(): Promise<{
16
16
  tools: Tool[];
17
+ toolsObject: Record<string, Tool>;
17
18
  toolMap: Map<string, {
18
19
  serverId: string;
19
20
  toolName: string;
@@ -49,3 +50,15 @@ export declare function getFunctionToolsForCategory(category?: string, maxTools?
49
50
  * Check if function calling is available
50
51
  */
51
52
  export declare function isFunctionCallingAvailable(): Promise<boolean>;
53
+ /**
54
+ * Utility function to create a named tool object for debugging
55
+ */
56
+ export declare function createNamedTool(name: string, toolDef: any): any & {
57
+ name: string;
58
+ };
59
+ /**
60
+ * Get tools with proper name properties for debugging
61
+ */
62
+ export declare function getToolsWithNames(): Promise<Record<string, any & {
63
+ name: string;
64
+ }>>;
@@ -8,6 +8,100 @@ import { z } from "zod";
8
8
  import { unifiedRegistry } from "./unified-registry.js";
9
9
  import { createExecutionContext } from "./context-manager.js";
10
10
  import { mcpLogger } from "./logging.js";
11
+ /**
12
+ * Parses neurolink-specific function name patterns to extract the server ID and tool name.
13
+ *
14
+ * @param {string[]} parts - An array of strings representing parts of a function name,
15
+ * typically obtained by splitting the function name on underscores.
16
+ * @returns {{ serverId: string; toolName: string } | null} An object containing the `serverId`
17
+ * and `toolName` if the input matches a neurolink-specific pattern, or `null` if no match is found.
18
+ *
19
+ * @example
20
+ * // Returns { serverId: "neurolink_ai_core", toolName: "generate" }
21
+ * parseNeuroLinkPattern(["neurolink", "ai", "core", "generate"]);
22
+ *
23
+ * @example
24
+ * // Returns { serverId: "neurolink_utility", toolName: "format_number" }
25
+ * parseNeuroLinkPattern(["neurolink", "utility", "format_number"]);
26
+ *
27
+ * @example
28
+ * // Returns null
29
+ * parseNeuroLinkPattern(["other", "pattern"]);
30
+ */
31
+ function parseNeuroLinkPattern(parts) {
32
+ if (parts.length >= 3 &&
33
+ parts[0] === "neurolink" &&
34
+ (parts[1] === "ai" || parts[1] === "utility")) {
35
+ // neurolink_ai_core_generate -> serverId: "neurolink_ai_core", toolName: "generate"
36
+ // neurolink_utility_format_number -> serverId: "neurolink_utility", toolName: "format_number"
37
+ if (parts[1] === "ai" && parts[2] === "core") {
38
+ return {
39
+ serverId: "neurolink_ai_core",
40
+ toolName: parts.slice(3).join("_"),
41
+ };
42
+ }
43
+ else if (parts[1] === "utility") {
44
+ return {
45
+ serverId: "neurolink_utility",
46
+ toolName: parts.slice(2).join("_"),
47
+ };
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+ /**
53
+ * Parse underscore-separated function name format
54
+ */
55
+ function parseUnderscoreFormat(functionName) {
56
+ const parts = functionName.split("_");
57
+ if (parts.length >= 2) {
58
+ // Try neurolink-specific patterns first
59
+ const neurolinkResult = parseNeuroLinkPattern(parts);
60
+ if (neurolinkResult) {
61
+ return neurolinkResult;
62
+ }
63
+ // Default underscore parsing
64
+ return {
65
+ serverId: parts[0],
66
+ toolName: parts.slice(1).join("_"),
67
+ };
68
+ }
69
+ return null;
70
+ }
71
+ /**
72
+ * Parse dot-separated function name format (legacy support)
73
+ */
74
+ function parseDotFormat(functionName) {
75
+ const parts = functionName.split(".");
76
+ if (parts.length >= 2) {
77
+ return {
78
+ serverId: parts[0],
79
+ toolName: parts.slice(1).join("."),
80
+ };
81
+ }
82
+ return null;
83
+ }
84
+ /**
85
+ * Parse function name to extract server ID and tool name
86
+ * Handles various naming patterns including neurolink server patterns
87
+ */
88
+ function parseFunctionName(functionName) {
89
+ // Try underscore format first (most common)
90
+ const underscoreResult = parseUnderscoreFormat(functionName);
91
+ if (underscoreResult) {
92
+ return underscoreResult;
93
+ }
94
+ // Fallback to dot format for backward compatibility
95
+ const dotResult = parseDotFormat(functionName);
96
+ if (dotResult) {
97
+ return dotResult;
98
+ }
99
+ // Final fallback - return as-is with unknown server
100
+ return {
101
+ serverId: "unknown",
102
+ toolName: functionName,
103
+ };
104
+ }
11
105
  /**
12
106
  * Convert MCP tool to AI SDK function definition
13
107
  */
@@ -55,10 +149,11 @@ export function mcpToolToAISDKTool(tool, serverId) {
55
149
  export async function getAvailableFunctionTools() {
56
150
  const functionTag = "getAvailableFunctionTools";
57
151
  const tools = [];
152
+ const toolsObject = {};
58
153
  const toolMap = new Map();
59
154
  try {
60
155
  // Add overall timeout for the entire function
61
- const overallTimeoutMs = 5000; // 5 seconds max for everything
156
+ const overallTimeoutMs = process.env.NODE_ENV === "test" ? 30000 : 15000; // 30s for tests, 15s for production
62
157
  let overallTimeoutId;
63
158
  const overallTimeoutPromise = new Promise((_, reject) => {
64
159
  overallTimeoutId = setTimeout(() => {
@@ -281,6 +376,8 @@ export async function getAvailableFunctionTools() {
281
376
  },
282
377
  });
283
378
  tools.push(aiTool);
379
+ // Store tool with proper name association
380
+ toolsObject[functionName] = aiTool;
284
381
  // Store mapping for execution - CRITICAL: Use sanitized functionName as key
285
382
  toolMap.set(functionName, {
286
383
  serverId: typeof toolInfo.serverId === "string"
@@ -302,7 +399,7 @@ export async function getAvailableFunctionTools() {
302
399
  if (overallTimeoutId) {
303
400
  clearTimeout(overallTimeoutId);
304
401
  }
305
- return { tools, toolMap };
402
+ return { tools, toolsObject, toolMap };
306
403
  }
307
404
  catch (error) {
308
405
  if (overallTimeoutId) {
@@ -315,7 +412,7 @@ export async function getAvailableFunctionTools() {
315
412
  }
316
413
  catch (error) {
317
414
  mcpLogger.error(`[${functionTag}] Error getting function tools:`, error);
318
- return { tools: [], toolMap: new Map() };
415
+ return { tools: [], toolsObject: {}, toolMap: new Map() };
319
416
  }
320
417
  }
321
418
  /**
@@ -345,38 +442,12 @@ export async function executeFunctionCall(functionName, parameters, context) {
345
442
  });
346
443
  }
347
444
  // Parse server and tool name from function name
348
- // First try underscore format (sanitized), then fallback to dot format
349
- let parts = functionName.split("_");
350
- let serverId = "unknown";
351
- let toolName = functionName;
352
- if (parts.length >= 2) {
353
- // Handle underscore format (sanitized names)
354
- const firstPart = parts[0];
355
- if (firstPart && typeof firstPart === "string" && firstPart.length > 0) {
356
- serverId = firstPart;
357
- }
358
- else {
359
- serverId = "unknown";
360
- }
361
- toolName = parts.slice(1).join("_"); // Rejoin in case tool name had underscores
362
- }
363
- else {
364
- // Fallback to dot format for backward compatibility
365
- parts = functionName.split(".");
366
- if (parts.length === 2) {
367
- const parsedServerId = parts[0];
368
- const parsedToolName = parts[1];
369
- if (parsedServerId && parsedToolName) {
370
- serverId = parsedServerId;
371
- toolName = parsedToolName;
372
- }
373
- }
374
- else {
375
- // Can't parse - try executing as-is through unified registry
376
- mcpLogger.debug(`[${functionTag}] Cannot parse function name format: ${functionName}, trying unified registry`);
377
- const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
378
- return result;
379
- }
445
+ const { serverId, toolName } = parseFunctionName(functionName);
446
+ if (serverId === "unknown") {
447
+ // Can't parse - try executing as-is through unified registry
448
+ mcpLogger.debug(`[${functionTag}] Cannot parse function name format: ${functionName}, trying unified registry`);
449
+ const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
450
+ return result;
380
451
  }
381
452
  // Handle built-in NeuroLink servers directly
382
453
  if (serverId === "neurolink-utility" ||
@@ -541,3 +612,31 @@ export async function isFunctionCallingAvailable() {
541
612
  return false;
542
613
  }
543
614
  }
615
+ /**
616
+ * Utility function to create a named tool object for debugging
617
+ */
618
+ export function createNamedTool(name, toolDef) {
619
+ return {
620
+ name,
621
+ description: toolDef.description,
622
+ parameters: toolDef.parameters,
623
+ execute: toolDef.execute,
624
+ };
625
+ }
626
+ /**
627
+ * Get tools with proper name properties for debugging
628
+ */
629
+ export async function getToolsWithNames() {
630
+ try {
631
+ const { toolsObject } = await getAvailableFunctionTools();
632
+ const namedTools = {};
633
+ for (const [name, tool] of Object.entries(toolsObject)) {
634
+ namedTools[name] = createNamedTool(name, tool);
635
+ }
636
+ return namedTools;
637
+ }
638
+ catch (error) {
639
+ mcpLogger.warn("[getToolsWithNames] Failed to get tools with names:", error);
640
+ return {};
641
+ }
642
+ }
@@ -13,7 +13,7 @@ export declare const initializeMCPTools: (sessionId: string, client: NeuroLinkMC
13
13
  * Get all available tools across all servers
14
14
  * Useful for documentation and discovery
15
15
  */
16
- export declare function getAllAvailableTools(): Promise<Array<{
16
+ export declare function getAllAvailableTools(inMemoryServers?: Map<string, any>): Promise<Array<{
17
17
  serverId: string;
18
18
  serverTitle: string;
19
19
  toolName: string;
@@ -139,8 +139,52 @@ export const initializeMCPTools = async (sessionId, client, context) => {
139
139
  * Get all available tools across all servers
140
140
  * Useful for documentation and discovery
141
141
  */
142
- export async function getAllAvailableTools() {
142
+ export async function getAllAvailableTools(inMemoryServers) {
143
143
  const tools = [];
144
+ // Add in-memory server tools first
145
+ if (inMemoryServers) {
146
+ for (const [serverId, serverConfig] of inMemoryServers) {
147
+ const server = serverConfig.server;
148
+ if (server && server.tools) {
149
+ // Handle both Map and object formats
150
+ const toolEntries = server.tools instanceof Map
151
+ ? Array.from(server.tools.entries())
152
+ : Object.entries(server.tools || {});
153
+ for (const [toolName, toolInfo] of toolEntries) {
154
+ const prefix = `${serverId}_`;
155
+ const finalToolName = toolName.length > 64 - prefix.length
156
+ ? toolName.substring(0, 64 - prefix.length)
157
+ : toolName;
158
+ const namespacedName = sanitizeToolName(`${prefix}${finalToolName}`);
159
+ // Handle different tool info structures
160
+ let description = `Tool from ${serverId}`;
161
+ let isImplemented = true;
162
+ if (toolInfo) {
163
+ // Check if it's a tool info object with description
164
+ if (typeof toolInfo.description === "string") {
165
+ description = toolInfo.description;
166
+ }
167
+ else if (typeof toolInfo === "function") {
168
+ // It's a raw function, no description available
169
+ description = `${toolName} from ${serverId}`;
170
+ }
171
+ // Check implementation status
172
+ if (typeof toolInfo.isImplemented === "boolean") {
173
+ isImplemented = toolInfo.isImplemented;
174
+ }
175
+ }
176
+ tools.push({
177
+ serverId,
178
+ serverTitle: server.title || serverId,
179
+ toolName,
180
+ namespacedName,
181
+ description,
182
+ isImplemented,
183
+ });
184
+ }
185
+ }
186
+ }
187
+ }
144
188
  const servers = await mcpConfig.getServers();
145
189
  servers.forEach((server) => {
146
190
  Object.entries(server.tools).forEach(([toolName, tool]) => {
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { toolRegistry, defaultToolRegistry, } from "./tool-registry.js";
7
7
  import { mcpLogger } from "./logging.js";
8
+ import { ServiceRegistry } from "../core/service-registry.js";
8
9
  let isInitialized = false;
9
10
  /**
10
11
  * Initialize NeuroLink MCP system by registering built-in servers
@@ -15,19 +16,28 @@ export async function initializeNeuroLinkMCP(targetRegistry) {
15
16
  }
16
17
  mcpLogger.debug("Initializing built-in MCP servers...");
17
18
  try {
19
+ // First, register AIProviderFactory in ServiceRegistry to break circular dependencies
20
+ ServiceRegistry.register("AIProviderFactory", async () => {
21
+ const { AIProviderFactory } = await import("../core/factory.js");
22
+ return AIProviderFactory;
23
+ });
24
+ mcpLogger.debug("Registered AIProviderFactory in ServiceRegistry");
18
25
  // Import utility server dynamically to avoid circular dependencies
19
- // Note: AI core server temporarily disabled due to circular dependency issues
20
26
  const { utilityServer } = await import("./servers/utilities/utility-server.js");
21
27
  // Register built-in NeuroLink servers with specified registry (or default)
22
28
  const registry = targetRegistry || toolRegistry;
23
29
  await registry.registerServer(utilityServer.id, utilityServer);
24
30
  mcpLogger.debug(`Registered neurolink-utility server with built-in tools in ${targetRegistry ? "target" : "default"} registry`);
25
- // TODO: Re-enable AI core server once circular dependencies are resolved
26
- // const { aiCoreServer } = await import('./servers/ai-providers/ai-core-server.js');
27
- // await registry.registerServer(aiCoreServer.id, aiCoreServer);
28
- // mcpLogger.debug('Registered neurolink-ai-core server with AI tools');
31
+ // Now safe to import and register AI core server
32
+ const { aiCoreServer } = await import("./servers/ai-providers/ai-core-server.js");
33
+ await registry.registerServer(aiCoreServer.id, aiCoreServer);
34
+ mcpLogger.debug("Registered neurolink-ai-core server with AI tools");
35
+ // Register direct tools server
36
+ const { directToolsServer } = await import("./servers/agent/direct-tools-server.js");
37
+ await registry.registerServer(directToolsServer.id, directToolsServer);
38
+ mcpLogger.debug("Registered neurolink-direct server with direct tools");
29
39
  const stats = await registry.getStats();
30
- mcpLogger.info(`Initialization complete: ${stats.totalServers} server, ${stats.totalTools} tools available`);
40
+ mcpLogger.info(`Initialization complete: ${stats.totalServers} servers, ${stats.totalTools} tools available`);
31
41
  isInitialized = true;
32
42
  }
33
43
  catch (error) {
@@ -70,6 +70,7 @@ export declare class NeuroLinkMCPClient extends EventEmitter {
70
70
  * Get registered tools
71
71
  */
72
72
  getTools(): Record<string, {
73
+ name: string;
73
74
  description?: string;
74
75
  inputSchema?: unknown;
75
76
  }>;
@@ -244,11 +244,26 @@ Response (JSON array only):`;
244
244
  exists: async () => false,
245
245
  },
246
246
  path: {
247
- join: (...paths) => require("path").join(...paths),
248
- resolve: (...paths) => require("path").resolve(...paths),
249
- relative: (from, to) => require("path").relative(from, to),
250
- dirname: (path) => require("path").dirname(path),
251
- basename: (path, ext) => require("path").basename(path, ext),
247
+ join: (...paths) => {
248
+ const pathModule = require("path");
249
+ return pathModule.join(...paths);
250
+ },
251
+ resolve: (...paths) => {
252
+ const pathModule = require("path");
253
+ return pathModule.resolve(...paths);
254
+ },
255
+ relative: (from, to) => {
256
+ const pathModule = require("path");
257
+ return pathModule.relative(from, to);
258
+ },
259
+ dirname: (pathArg) => {
260
+ const pathModule = require("path");
261
+ return pathModule.dirname(pathArg);
262
+ },
263
+ basename: (pathArg, ext) => {
264
+ const pathModule = require("path");
265
+ return pathModule.basename(pathArg, ext);
266
+ },
252
267
  },
253
268
  grantedPermissions: [],
254
269
  log: console.log,
@@ -409,6 +424,7 @@ Please provide a natural response based on the tool results.`;
409
424
  const tools = {};
410
425
  for (const [name, tool] of this.tools) {
411
426
  tools[name] = {
427
+ name: name, // Include the tool name as a property
412
428
  description: tool.description,
413
429
  inputSchema: tool.inputSchema,
414
430
  };