@juspay/neurolink 6.1.0 → 6.2.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 (283) hide show
  1. package/CHANGELOG.md +10 -6
  2. package/dist/cli/commands/config.d.ts +13 -13
  3. package/dist/cli/index.js +3 -9
  4. package/dist/core/analytics.d.ts +11 -1
  5. package/dist/core/analytics.js +2 -2
  6. package/dist/core/base-provider.js +4 -18
  7. package/dist/core/dynamic-models.d.ts +8 -8
  8. package/dist/core/factory.js +3 -11
  9. package/dist/index.d.ts +2 -4
  10. package/dist/index.js +2 -11
  11. package/dist/lib/core/analytics.d.ts +11 -1
  12. package/dist/lib/core/analytics.js +2 -2
  13. package/dist/lib/core/base-provider.js +4 -18
  14. package/dist/lib/core/dynamic-models.d.ts +8 -8
  15. package/dist/lib/core/factory.js +3 -11
  16. package/dist/lib/index.d.ts +2 -4
  17. package/dist/lib/index.js +2 -11
  18. package/dist/lib/mcp/factory.d.ts +1 -1
  19. package/dist/lib/mcp/index.d.ts +7 -19
  20. package/dist/lib/mcp/index.js +15 -56
  21. package/dist/lib/neurolink.d.ts +1 -9
  22. package/dist/lib/neurolink.js +21 -70
  23. package/dist/lib/providers/amazon-bedrock.js +5 -16
  24. package/dist/lib/providers/anthropic-baseprovider.js +3 -21
  25. package/dist/lib/providers/anthropic.js +4 -7
  26. package/dist/lib/providers/azure-openai.js +4 -2
  27. package/dist/lib/providers/google-vertex.js +5 -9
  28. package/dist/lib/providers/huggingFace.js +5 -10
  29. package/dist/lib/providers/mistral.js +5 -8
  30. package/dist/lib/providers/openAI.js +4 -7
  31. package/dist/lib/utils/providerConfig.d.ts +117 -0
  32. package/dist/lib/utils/providerConfig.js +353 -0
  33. package/dist/lib/utils/providerUtils.d.ts +2 -1
  34. package/dist/lib/utils/providerUtils.js +53 -36
  35. package/dist/lib/utils/timeout.d.ts +72 -1
  36. package/dist/lib/utils/timeout.js +203 -2
  37. package/dist/mcp/factory.d.ts +1 -1
  38. package/dist/mcp/index.d.ts +7 -19
  39. package/dist/mcp/index.js +15 -56
  40. package/dist/neurolink.d.ts +1 -9
  41. package/dist/neurolink.js +21 -70
  42. package/dist/providers/amazon-bedrock.js +5 -16
  43. package/dist/providers/anthropic-baseprovider.js +3 -21
  44. package/dist/providers/anthropic.js +4 -7
  45. package/dist/providers/azure-openai.js +4 -2
  46. package/dist/providers/google-vertex.js +5 -9
  47. package/dist/providers/huggingFace.js +5 -10
  48. package/dist/providers/mistral.js +5 -8
  49. package/dist/providers/openAI.js +4 -7
  50. package/dist/utils/providerConfig.d.ts +117 -0
  51. package/dist/utils/providerConfig.js +353 -0
  52. package/dist/utils/providerUtils.d.ts +2 -1
  53. package/dist/utils/providerUtils.js +53 -36
  54. package/dist/utils/timeout.d.ts +72 -1
  55. package/dist/utils/timeout.js +203 -2
  56. package/package.json +1 -1
  57. package/dist/chat/client-utils.d.ts +0 -95
  58. package/dist/chat/client-utils.js +0 -315
  59. package/dist/chat/index.d.ts +0 -24
  60. package/dist/chat/index.js +0 -33
  61. package/dist/chat/session-storage.d.ts +0 -77
  62. package/dist/chat/session-storage.js +0 -233
  63. package/dist/chat/session.d.ts +0 -96
  64. package/dist/chat/session.js +0 -257
  65. package/dist/chat/sse-handler.d.ts +0 -49
  66. package/dist/chat/sse-handler.js +0 -259
  67. package/dist/chat/types.d.ts +0 -74
  68. package/dist/chat/types.js +0 -5
  69. package/dist/chat/websocket-chat-handler.d.ts +0 -37
  70. package/dist/chat/websocket-chat-handler.js +0 -262
  71. package/dist/cli/commands/mcp.d.ts +0 -20
  72. package/dist/cli/commands/mcp.js +0 -1272
  73. package/dist/core/defaults.d.ts +0 -19
  74. package/dist/core/defaults.js +0 -29
  75. package/dist/core/evaluation-config.d.ts +0 -29
  76. package/dist/core/evaluation-config.js +0 -144
  77. package/dist/factories/compatibility-factory.d.ts +0 -35
  78. package/dist/factories/compatibility-factory.js +0 -71
  79. package/dist/factories/provider-generate-factory.d.ts +0 -20
  80. package/dist/factories/provider-generate-factory.js +0 -93
  81. package/dist/lib/chat/client-utils.d.ts +0 -95
  82. package/dist/lib/chat/client-utils.js +0 -315
  83. package/dist/lib/chat/index.d.ts +0 -24
  84. package/dist/lib/chat/index.js +0 -33
  85. package/dist/lib/chat/session-storage.d.ts +0 -77
  86. package/dist/lib/chat/session-storage.js +0 -233
  87. package/dist/lib/chat/session.d.ts +0 -96
  88. package/dist/lib/chat/session.js +0 -257
  89. package/dist/lib/chat/sse-handler.d.ts +0 -49
  90. package/dist/lib/chat/sse-handler.js +0 -259
  91. package/dist/lib/chat/types.d.ts +0 -74
  92. package/dist/lib/chat/types.js +0 -5
  93. package/dist/lib/chat/websocket-chat-handler.d.ts +0 -37
  94. package/dist/lib/chat/websocket-chat-handler.js +0 -262
  95. package/dist/lib/core/defaults.d.ts +0 -19
  96. package/dist/lib/core/defaults.js +0 -29
  97. package/dist/lib/core/evaluation-config.d.ts +0 -29
  98. package/dist/lib/core/evaluation-config.js +0 -144
  99. package/dist/lib/factories/compatibility-factory.d.ts +0 -35
  100. package/dist/lib/factories/compatibility-factory.js +0 -71
  101. package/dist/lib/factories/provider-generate-factory.d.ts +0 -20
  102. package/dist/lib/factories/provider-generate-factory.js +0 -93
  103. package/dist/lib/mcp/adapters/plugin-bridge.d.ts +0 -40
  104. package/dist/lib/mcp/adapters/plugin-bridge.js +0 -89
  105. package/dist/lib/mcp/auto-discovery.d.ts +0 -62
  106. package/dist/lib/mcp/auto-discovery.js +0 -149
  107. package/dist/lib/mcp/client.d.ts +0 -68
  108. package/dist/lib/mcp/client.js +0 -248
  109. package/dist/lib/mcp/config.d.ts +0 -31
  110. package/dist/lib/mcp/config.js +0 -99
  111. package/dist/lib/mcp/context-manager.d.ts +0 -171
  112. package/dist/lib/mcp/context-manager.js +0 -362
  113. package/dist/lib/mcp/contracts/mcp-contract.d.ts +0 -169
  114. package/dist/lib/mcp/contracts/mcp-contract.js +0 -58
  115. package/dist/lib/mcp/core/plugin-manager.d.ts +0 -46
  116. package/dist/lib/mcp/core/plugin-manager.js +0 -110
  117. package/dist/lib/mcp/demo/plugin-demo.d.ts +0 -20
  118. package/dist/lib/mcp/demo/plugin-demo.js +0 -118
  119. package/dist/lib/mcp/dynamic-chain-executor.d.ts +0 -225
  120. package/dist/lib/mcp/dynamic-chain-executor.js +0 -489
  121. package/dist/lib/mcp/dynamic-orchestrator.d.ts +0 -115
  122. package/dist/lib/mcp/dynamic-orchestrator.js +0 -351
  123. package/dist/lib/mcp/ecosystem.d.ts +0 -75
  124. package/dist/lib/mcp/ecosystem.js +0 -161
  125. package/dist/lib/mcp/error-manager.d.ts +0 -254
  126. package/dist/lib/mcp/error-manager.js +0 -501
  127. package/dist/lib/mcp/error-recovery.d.ts +0 -159
  128. package/dist/lib/mcp/error-recovery.js +0 -405
  129. package/dist/lib/mcp/external-client.d.ts +0 -88
  130. package/dist/lib/mcp/external-client.js +0 -331
  131. package/dist/lib/mcp/external-manager.d.ts +0 -112
  132. package/dist/lib/mcp/external-manager.js +0 -308
  133. package/dist/lib/mcp/function-calling.d.ts +0 -65
  134. package/dist/lib/mcp/function-calling.js +0 -642
  135. package/dist/lib/mcp/health-monitor.d.ts +0 -257
  136. package/dist/lib/mcp/health-monitor.js +0 -630
  137. package/dist/lib/mcp/initialize-tools.d.ts +0 -29
  138. package/dist/lib/mcp/initialize-tools.js +0 -261
  139. package/dist/lib/mcp/initialize.d.ts +0 -18
  140. package/dist/lib/mcp/initialize.js +0 -62
  141. package/dist/lib/mcp/manager.d.ts +0 -68
  142. package/dist/lib/mcp/manager.js +0 -176
  143. package/dist/lib/mcp/neurolink-mcp-client.d.ts +0 -97
  144. package/dist/lib/mcp/neurolink-mcp-client.js +0 -462
  145. package/dist/lib/mcp/orchestrator.d.ts +0 -302
  146. package/dist/lib/mcp/orchestrator.js +0 -703
  147. package/dist/lib/mcp/plugin-manager.d.ts +0 -98
  148. package/dist/lib/mcp/plugin-manager.js +0 -296
  149. package/dist/lib/mcp/plugins/core/filesystem-mcp.d.ts +0 -36
  150. package/dist/lib/mcp/plugins/core/filesystem-mcp.js +0 -142
  151. package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +0 -37
  152. package/dist/lib/mcp/plugins/filesystem-mcp.js +0 -54
  153. package/dist/lib/mcp/security-manager.d.ts +0 -87
  154. package/dist/lib/mcp/security-manager.js +0 -344
  155. package/dist/lib/mcp/semaphore-manager.d.ts +0 -137
  156. package/dist/lib/mcp/semaphore-manager.js +0 -329
  157. package/dist/lib/mcp/session-manager.d.ts +0 -187
  158. package/dist/lib/mcp/session-manager.js +0 -400
  159. package/dist/lib/mcp/session-persistence.d.ts +0 -93
  160. package/dist/lib/mcp/session-persistence.js +0 -301
  161. package/dist/lib/mcp/tool-integration.d.ts +0 -58
  162. package/dist/lib/mcp/tool-integration.js +0 -203
  163. package/dist/lib/mcp/transport-manager.d.ts +0 -154
  164. package/dist/lib/mcp/transport-manager.js +0 -334
  165. package/dist/lib/mcp/unified-mcp.d.ts +0 -133
  166. package/dist/lib/mcp/unified-mcp.js +0 -251
  167. package/dist/lib/mcp/unified-registry.d.ts +0 -165
  168. package/dist/lib/mcp/unified-registry.js +0 -538
  169. package/dist/lib/providers/analytics-helper.d.ts +0 -38
  170. package/dist/lib/providers/analytics-helper.js +0 -216
  171. package/dist/lib/providers/function-calling-provider.d.ts +0 -142
  172. package/dist/lib/providers/function-calling-provider.js +0 -630
  173. package/dist/lib/providers/mcp-provider.d.ts +0 -75
  174. package/dist/lib/providers/mcp-provider.js +0 -283
  175. package/dist/lib/providers/timeout-wrapper.d.ts +0 -40
  176. package/dist/lib/providers/timeout-wrapper.js +0 -100
  177. package/dist/lib/sdk/tool-extension.d.ts +0 -181
  178. package/dist/lib/sdk/tool-extension.js +0 -284
  179. package/dist/lib/services/streaming/streaming-manager.d.ts +0 -29
  180. package/dist/lib/services/streaming/streaming-manager.js +0 -245
  181. package/dist/lib/services/types.d.ts +0 -156
  182. package/dist/lib/services/types.js +0 -2
  183. package/dist/lib/services/websocket/websocket-server.d.ts +0 -34
  184. package/dist/lib/services/websocket/websocket-server.js +0 -305
  185. package/dist/lib/utils/provider-validation.d.ts +0 -36
  186. package/dist/lib/utils/provider-validation.js +0 -625
  187. package/dist/lib/utils/providerUtils-fixed.d.ts +0 -8
  188. package/dist/lib/utils/providerUtils-fixed.js +0 -94
  189. package/dist/lib/utils/streaming-utils.d.ts +0 -79
  190. package/dist/lib/utils/streaming-utils.js +0 -198
  191. package/dist/lib/utils/timeout-manager.d.ts +0 -75
  192. package/dist/lib/utils/timeout-manager.js +0 -244
  193. package/dist/mcp/adapters/plugin-bridge.d.ts +0 -40
  194. package/dist/mcp/adapters/plugin-bridge.js +0 -89
  195. package/dist/mcp/auto-discovery.d.ts +0 -62
  196. package/dist/mcp/auto-discovery.js +0 -149
  197. package/dist/mcp/client.d.ts +0 -68
  198. package/dist/mcp/client.js +0 -248
  199. package/dist/mcp/config.d.ts +0 -31
  200. package/dist/mcp/config.js +0 -99
  201. package/dist/mcp/context-manager.d.ts +0 -171
  202. package/dist/mcp/context-manager.js +0 -362
  203. package/dist/mcp/contracts/mcp-contract.d.ts +0 -169
  204. package/dist/mcp/contracts/mcp-contract.js +0 -58
  205. package/dist/mcp/core/plugin-manager.d.ts +0 -46
  206. package/dist/mcp/core/plugin-manager.js +0 -110
  207. package/dist/mcp/demo/plugin-demo.d.ts +0 -20
  208. package/dist/mcp/demo/plugin-demo.js +0 -118
  209. package/dist/mcp/dynamic-chain-executor.d.ts +0 -225
  210. package/dist/mcp/dynamic-chain-executor.js +0 -489
  211. package/dist/mcp/dynamic-orchestrator.d.ts +0 -115
  212. package/dist/mcp/dynamic-orchestrator.js +0 -351
  213. package/dist/mcp/ecosystem.d.ts +0 -75
  214. package/dist/mcp/ecosystem.js +0 -162
  215. package/dist/mcp/error-manager.d.ts +0 -254
  216. package/dist/mcp/error-manager.js +0 -501
  217. package/dist/mcp/error-recovery.d.ts +0 -159
  218. package/dist/mcp/error-recovery.js +0 -405
  219. package/dist/mcp/external-client.d.ts +0 -88
  220. package/dist/mcp/external-client.js +0 -331
  221. package/dist/mcp/external-manager.d.ts +0 -112
  222. package/dist/mcp/external-manager.js +0 -308
  223. package/dist/mcp/function-calling.d.ts +0 -65
  224. package/dist/mcp/function-calling.js +0 -642
  225. package/dist/mcp/health-monitor.d.ts +0 -257
  226. package/dist/mcp/health-monitor.js +0 -630
  227. package/dist/mcp/initialize-tools.d.ts +0 -29
  228. package/dist/mcp/initialize-tools.js +0 -262
  229. package/dist/mcp/initialize.d.ts +0 -18
  230. package/dist/mcp/initialize.js +0 -62
  231. package/dist/mcp/manager.d.ts +0 -68
  232. package/dist/mcp/manager.js +0 -176
  233. package/dist/mcp/neurolink-mcp-client.d.ts +0 -97
  234. package/dist/mcp/neurolink-mcp-client.js +0 -462
  235. package/dist/mcp/orchestrator.d.ts +0 -302
  236. package/dist/mcp/orchestrator.js +0 -703
  237. package/dist/mcp/plugin-manager.d.ts +0 -98
  238. package/dist/mcp/plugin-manager.js +0 -297
  239. package/dist/mcp/plugins/core/filesystem-mcp.d.ts +0 -36
  240. package/dist/mcp/plugins/core/filesystem-mcp.js +0 -142
  241. package/dist/mcp/plugins/core/neurolink-mcp.json +0 -17
  242. package/dist/mcp/plugins/filesystem-mcp.d.ts +0 -37
  243. package/dist/mcp/plugins/filesystem-mcp.js +0 -54
  244. package/dist/mcp/security-manager.d.ts +0 -87
  245. package/dist/mcp/security-manager.js +0 -344
  246. package/dist/mcp/semaphore-manager.d.ts +0 -137
  247. package/dist/mcp/semaphore-manager.js +0 -329
  248. package/dist/mcp/session-manager.d.ts +0 -187
  249. package/dist/mcp/session-manager.js +0 -400
  250. package/dist/mcp/session-persistence.d.ts +0 -93
  251. package/dist/mcp/session-persistence.js +0 -302
  252. package/dist/mcp/tool-integration.d.ts +0 -58
  253. package/dist/mcp/tool-integration.js +0 -203
  254. package/dist/mcp/transport-manager.d.ts +0 -154
  255. package/dist/mcp/transport-manager.js +0 -335
  256. package/dist/mcp/unified-mcp.d.ts +0 -133
  257. package/dist/mcp/unified-mcp.js +0 -251
  258. package/dist/mcp/unified-registry.d.ts +0 -165
  259. package/dist/mcp/unified-registry.js +0 -539
  260. package/dist/providers/analytics-helper.d.ts +0 -38
  261. package/dist/providers/analytics-helper.js +0 -216
  262. package/dist/providers/function-calling-provider.d.ts +0 -142
  263. package/dist/providers/function-calling-provider.js +0 -630
  264. package/dist/providers/mcp-provider.d.ts +0 -75
  265. package/dist/providers/mcp-provider.js +0 -283
  266. package/dist/providers/timeout-wrapper.d.ts +0 -40
  267. package/dist/providers/timeout-wrapper.js +0 -100
  268. package/dist/sdk/tool-extension.d.ts +0 -181
  269. package/dist/sdk/tool-extension.js +0 -284
  270. package/dist/services/streaming/streaming-manager.d.ts +0 -29
  271. package/dist/services/streaming/streaming-manager.js +0 -245
  272. package/dist/services/types.d.ts +0 -156
  273. package/dist/services/types.js +0 -2
  274. package/dist/services/websocket/websocket-server.d.ts +0 -34
  275. package/dist/services/websocket/websocket-server.js +0 -306
  276. package/dist/utils/provider-validation.d.ts +0 -36
  277. package/dist/utils/provider-validation.js +0 -625
  278. package/dist/utils/providerUtils-fixed.d.ts +0 -8
  279. package/dist/utils/providerUtils-fixed.js +0 -94
  280. package/dist/utils/streaming-utils.d.ts +0 -79
  281. package/dist/utils/streaming-utils.js +0 -198
  282. package/dist/utils/timeout-manager.d.ts +0 -75
  283. package/dist/utils/timeout-manager.js +0 -244
@@ -1,642 +0,0 @@
1
- /**
2
- * MCP Function-Calling Integration
3
- * Converts MCP tools to AI SDK function definitions and handles function calls
4
- * Enables true AI function calling with discovered MCP tools
5
- */
6
- import { tool } from "ai";
7
- import { z } from "zod";
8
- import { unifiedRegistry } from "./unified-registry.js";
9
- import { createExecutionContext } from "./context-manager.js";
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
- }
105
- /**
106
- * Convert MCP tool to AI SDK function definition
107
- */
108
- export function mcpToolToAISDKTool(tool, serverId) {
109
- // Create basic JSON Schema for AI SDK
110
- const parameters = {
111
- type: "object",
112
- properties: {},
113
- required: [],
114
- };
115
- // If we have an input schema, try to extract basic information
116
- if (tool.inputSchema) {
117
- try {
118
- // For now, create a simple schema that accepts any object
119
- // This could be enhanced with proper Zod-to-JSON-Schema conversion
120
- parameters.properties = {
121
- // Generic parameter support
122
- data: {
123
- type: "object",
124
- description: "Tool parameters",
125
- },
126
- };
127
- }
128
- catch (error) {
129
- mcpLogger.warn(`[Function-Calling] Failed to convert schema for tool ${tool.name}:`, error);
130
- }
131
- }
132
- return {
133
- description: tool.description,
134
- parameters,
135
- execute: async (args) => {
136
- // This will be handled by the AI SDK's function calling mechanism
137
- // We'll implement the actual execution in the provider level
138
- mcpLogger.debug(`[Function-Calling] AI SDK tool executed: ${serverId}.${tool.name}`, args);
139
- return {
140
- success: true,
141
- message: "Tool execution handled by MCP integration",
142
- };
143
- },
144
- };
145
- }
146
- /**
147
- * Get all available MCP tools as AI SDK function definitions
148
- */
149
- export async function getAvailableFunctionTools() {
150
- const functionTag = "getAvailableFunctionTools";
151
- const tools = [];
152
- const toolsObject = {};
153
- const toolMap = new Map();
154
- try {
155
- // Add overall timeout for the entire function
156
- const overallTimeoutMs = process.env.NODE_ENV === "test" ? 30000 : 15000; // 30s for tests, 15s for production
157
- let overallTimeoutId;
158
- const overallTimeoutPromise = new Promise((_, reject) => {
159
- overallTimeoutId = setTimeout(() => {
160
- mcpLogger.warn(`[${functionTag}] Overall timeout reached, returning empty tools`);
161
- reject(new Error("getAvailableFunctionTools overall timeout"));
162
- }, overallTimeoutMs);
163
- // CRITICAL FIX: Unref timeout to prevent event loop hanging
164
- overallTimeoutId.unref();
165
- });
166
- const toolsLoadingPromise = (async () => {
167
- try {
168
- // Ensure NeuroLink MCP is initialized first
169
- const { initializeNeuroLinkMCP } = await import("./initialize.js");
170
- await initializeNeuroLinkMCP();
171
- // Ensure unified registry is initialized
172
- await unifiedRegistry.initialize();
173
- // Try to activate important servers like filesystem
174
- mcpLogger.debug(`[${functionTag}] Attempting to activate important servers...`);
175
- try {
176
- // Get auto-discovered servers
177
- const autoServers = unifiedRegistry.getAutoDiscoveredServers();
178
- // Try to activate filesystem server specifically
179
- for (const server of autoServers) {
180
- if (server.metadata.name.includes("filesystem")) {
181
- mcpLogger.debug(`[${functionTag}] Activating filesystem server: ${server.metadata.name}`);
182
- const serverName = server.metadata.name;
183
- if (typeof serverName === "string" && serverName.length > 0) {
184
- // @ts-ignore - serverName is verified as string with length > 0 above
185
- await unifiedRegistry.lazyActivateServer(serverName);
186
- }
187
- }
188
- }
189
- }
190
- catch (error) {
191
- mcpLogger.debug(`[${functionTag}] Error activating servers: ${error}`);
192
- }
193
- // Get all tools from unified registry directly
194
- const allTools = await unifiedRegistry.listAllTools();
195
- mcpLogger.debug(`[${functionTag}] Found ${allTools.length} total tools`);
196
- // Try to activate servers that have "-tools" entries to get real tools
197
- const serversToActivate = allTools
198
- .filter((tool) => tool.name.endsWith("-tools") || tool.name.includes("placeholder"))
199
- .map((tool) => tool.server);
200
- mcpLogger.debug(`[${functionTag}] Attempting to activate ${serversToActivate.length} servers for real tool discovery`);
201
- // Activate servers to convert placeholders to real tools
202
- for (const serverId of [...new Set(serversToActivate)].filter((id) => typeof id === "string" && id !== "unknown")) {
203
- try {
204
- mcpLogger.debug(`[${functionTag}] Activating server: ${serverId}`);
205
- // Get the server entry from auto-discovered or manual servers
206
- const autoServers = unifiedRegistry.getAutoDiscoveredServers();
207
- const manualServers = unifiedRegistry.getManualServers();
208
- const serverEntry = autoServers.find((s) => s.metadata.name === serverId) ||
209
- manualServers.get(serverId);
210
- if (serverEntry && serverId.length > 0) {
211
- await unifiedRegistry.lazyActivateServer(serverId);
212
- }
213
- else {
214
- mcpLogger.debug(`[${functionTag}] Server entry not found for: ${serverId || "undefined"}`);
215
- }
216
- }
217
- catch (error) {
218
- mcpLogger.debug(`[${functionTag}] Failed to activate server ${serverId}:`, error);
219
- }
220
- }
221
- // Get tools again after activation
222
- const activatedTools = await unifiedRegistry.listAllTools();
223
- mcpLogger.debug(`[${functionTag}] Found ${activatedTools.length} total tools after activation`);
224
- // Filter to get real, individual tools (not placeholder or grouped tools)
225
- const realTools = activatedTools.filter((toolInfo) => {
226
- // Skip placeholder tools that weren't activated
227
- if (toolInfo.name.includes("placeholder") &&
228
- toolInfo.isImplemented === false) {
229
- return false;
230
- }
231
- // Skip grouped "-tools" entries unless they're the only ones available
232
- if (toolInfo.name.endsWith("-tools")) {
233
- // Check if we have individual tools from the same server
234
- const serverTools = activatedTools.filter((t) => t.server === toolInfo.server &&
235
- !t.name.endsWith("-tools") &&
236
- !t.name.includes("placeholder"));
237
- // If we have individual tools, skip the grouped entry
238
- if (serverTools.length > 0) {
239
- return false;
240
- }
241
- // Otherwise, include the grouped tool (better than nothing)
242
- }
243
- // Include all other real tools
244
- return true;
245
- });
246
- mcpLogger.debug(`[${functionTag}] Filtered to ${realTools.length} real tools from ${activatedTools.length} total`);
247
- // Process tools and create function definitions
248
- for (const toolInfo of realTools) {
249
- try {
250
- // Check if tool name already includes server info (e.g., from unified registry)
251
- let functionName;
252
- let originalFunctionName;
253
- // Convert server name to underscore format to check if it's embedded in tool name
254
- const serverName = typeof toolInfo.serverId === "string"
255
- ? toolInfo.serverId
256
- : "unknown";
257
- const sanitizedServerCheck = serverName.replace(/[^a-zA-Z0-9_]/g, "_");
258
- if (toolInfo.name.includes(sanitizedServerCheck) ||
259
- toolInfo.name.endsWith("-tools") ||
260
- toolInfo.name.startsWith("github_com_") ||
261
- toolInfo.name.length > 50) {
262
- // Tool name already includes server info, sanitize and shorten it
263
- let sanitized = toolInfo.name.replace(/[^a-zA-Z0-9_]/g, "_");
264
- // Shorten long MCP server names
265
- if (sanitized.startsWith("github_com_modelcontextprotocol_servers_tree_main_src_")) {
266
- // Replace the long prefix with just 'mcp_'
267
- sanitized =
268
- "mcp_" +
269
- sanitized.substring("github_com_modelcontextprotocol_servers_tree_main_src_"
270
- .length);
271
- mcpLogger.debug(`[${functionTag}] Shortened MCP name: ${toolInfo.name} -> ${sanitized}`);
272
- }
273
- else if (sanitized.startsWith("github_com_") &&
274
- sanitized.length > 64) {
275
- // Shorten other github paths
276
- const parts = sanitized.split("_");
277
- // Keep only the meaningful parts (skip github_com)
278
- sanitized = parts.slice(2).join("_");
279
- mcpLogger.debug(`[${functionTag}] Shortened github name: ${toolInfo.name} -> ${sanitized}`);
280
- }
281
- // If still too long, truncate intelligently
282
- if (sanitized.length > 64) {
283
- // Keep the ending part which usually has the actual tool name
284
- sanitized = sanitized.substring(sanitized.length - 63);
285
- }
286
- // Ensure it starts with a letter or underscore (Google AI requirement)
287
- if (!/^[a-zA-Z_]/.test(sanitized)) {
288
- sanitized = "_" + sanitized;
289
- }
290
- // Final length check after adding prefix
291
- if (sanitized.length > 64) {
292
- // For filesystem tools, create a shorter name
293
- if (sanitized.includes("filesystem")) {
294
- const toolPart = sanitized.split("_").pop() || "tool";
295
- sanitized = "fs_" + toolPart;
296
- }
297
- else {
298
- // Generic truncation from the beginning, keeping the end
299
- sanitized = "_" + sanitized.substring(sanitized.length - 63);
300
- }
301
- }
302
- functionName = sanitized;
303
- originalFunctionName = toolInfo.name;
304
- }
305
- else {
306
- // Tool name doesn't include server info, create compound name
307
- const serverName = typeof toolInfo.serverId === "string"
308
- ? toolInfo.serverId
309
- : "unknown";
310
- const sanitizedServerName = serverName.replace(/[^a-zA-Z0-9_]/g, "_");
311
- const sanitizedToolName = toolInfo.name.replace(/[^a-zA-Z0-9_]/g, "_");
312
- // Check if it's a filesystem tool from MCP
313
- if (sanitizedServerName.includes("modelcontextprotocol") &&
314
- sanitizedServerName.includes("filesystem")) {
315
- functionName = `mcp_${sanitizedToolName}`;
316
- }
317
- else if (sanitizedServerName.length > 40) {
318
- // For other long server names, use a shortened version
319
- const serverParts = sanitizedServerName.split("_");
320
- const shortServer = serverParts.length > 2
321
- ? serverParts.slice(-2).join("_")
322
- : sanitizedServerName.substring(0, 20);
323
- functionName = `${shortServer}_${sanitizedToolName}`;
324
- }
325
- else {
326
- functionName = `${sanitizedServerName}_${sanitizedToolName}`;
327
- }
328
- // Ensure it starts with a letter or underscore
329
- if (!/^[a-zA-Z_]/.test(functionName)) {
330
- functionName = "_" + functionName;
331
- }
332
- // Final length check
333
- if (functionName.length > 64) {
334
- // Create a very short version
335
- functionName = `tool_${sanitizedToolName}`;
336
- if (functionName.length > 64) {
337
- functionName = sanitizedToolName.substring(0, 63);
338
- if (!/^[a-zA-Z_]/.test(functionName)) {
339
- functionName = "_" + functionName.substring(1);
340
- }
341
- }
342
- }
343
- originalFunctionName = `${toolInfo.server || "unknown"}.${toolInfo.name}`;
344
- }
345
- // Create AI SDK tool using the proper tool() helper
346
- const aiTool = tool({
347
- description: toolInfo.description || `Tool from ${toolInfo.server}`,
348
- parameters: z.object({
349
- // Create a generic parameter schema for all MCP tools
350
- input: z
351
- .unknown()
352
- .optional()
353
- .describe("Input parameters for the tool"),
354
- }),
355
- execute: async ({ input }) => {
356
- mcpLogger.debug(`[Function-Calling] AI SDK tool executed: ${functionName}`, { input });
357
- try {
358
- // Execute the actual MCP tool
359
- const result = await executeFunctionCall(functionName, input || {});
360
- if (result.success) {
361
- return (result.data || {
362
- success: true,
363
- message: "Tool executed successfully",
364
- });
365
- }
366
- else {
367
- return { error: result.error || "Tool execution failed" };
368
- }
369
- }
370
- catch (error) {
371
- mcpLogger.error(`[Function-Calling] Tool execution error: ${functionName}`, error);
372
- return {
373
- error: error instanceof Error ? error.message : String(error),
374
- };
375
- }
376
- },
377
- });
378
- tools.push(aiTool);
379
- // Store tool with proper name association
380
- toolsObject[functionName] = aiTool;
381
- // Store mapping for execution - CRITICAL: Use sanitized functionName as key
382
- toolMap.set(functionName, {
383
- serverId: typeof toolInfo.serverId === "string"
384
- ? toolInfo.serverId
385
- : "unknown",
386
- toolName: toolInfo.name,
387
- });
388
- mcpLogger.debug(`[${functionTag}] Converted tool: ${functionName} (original: ${originalFunctionName})`);
389
- }
390
- catch (error) {
391
- mcpLogger.warn(`[${functionTag}] Failed to convert tool ${toolInfo.name}:`, error);
392
- }
393
- }
394
- mcpLogger.debug(`[${functionTag}] Converted ${tools.length} tools for function calling`);
395
- // Log the tool names for debugging
396
- const toolNames = Array.from(toolMap.keys());
397
- mcpLogger.debug(`[${functionTag}] Tool names:`, toolNames);
398
- mcpLogger.debug(`[${functionTag}] First 5 tool names:`, toolNames.slice(0, 5));
399
- if (overallTimeoutId) {
400
- clearTimeout(overallTimeoutId);
401
- }
402
- return { tools, toolsObject, toolMap };
403
- }
404
- catch (error) {
405
- if (overallTimeoutId) {
406
- clearTimeout(overallTimeoutId);
407
- }
408
- throw error;
409
- }
410
- })();
411
- return await Promise.race([toolsLoadingPromise, overallTimeoutPromise]);
412
- }
413
- catch (error) {
414
- mcpLogger.error(`[${functionTag}] Error getting function tools:`, error);
415
- return { tools: [], toolsObject: {}, toolMap: new Map() };
416
- }
417
- }
418
- /**
419
- * Execute MCP tool from AI function call
420
- */
421
- export async function executeFunctionCall(functionName, parameters, context) {
422
- const functionTag = "executeFunctionCall";
423
- try {
424
- // CRITICAL FIX: Unwrap 'input' parameter if it exists
425
- // AI function calling wraps parameters in { input: { actualParams } }
426
- // but MCP tools expect direct parameters
427
- let actualParameters = parameters;
428
- if (parameters.input &&
429
- typeof parameters.input === "object" &&
430
- parameters.input !== null) {
431
- actualParameters = parameters.input;
432
- mcpLogger.debug(`[${functionTag}] Unwrapped input parameter for ${functionName}`, { original: parameters, unwrapped: actualParameters });
433
- }
434
- mcpLogger.debug(`[${functionTag}] Executing function call: ${functionName}`, { parameters: actualParameters });
435
- // Create context if not provided
436
- let finalContext = context;
437
- if (!finalContext) {
438
- finalContext = createExecutionContext({
439
- sessionId: `function-call-${Date.now()}`,
440
- userId: "ai-function-caller",
441
- aiProvider: "function-calling",
442
- });
443
- }
444
- // Parse server and tool name from function name
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;
451
- }
452
- // Handle built-in NeuroLink servers directly
453
- if (serverId === "neurolink-utility" ||
454
- serverId === "neurolink-ai-core" ||
455
- serverId === "neurolink_utility" ||
456
- serverId === "neurolink_ai_core") {
457
- mcpLogger.debug(`[${functionTag}] Executing built-in tool: ${toolName} from ${serverId}`);
458
- // Import and execute from default registry
459
- const { defaultToolRegistry } = await import("./tool-registry.js");
460
- return await defaultToolRegistry.executeTool(toolName, actualParameters, finalContext);
461
- }
462
- // Handle filesystem server with special activation logic
463
- if (serverId === "filesystem") {
464
- mcpLogger.debug(`[${functionTag}] Executing filesystem tool: ${toolName}`);
465
- try {
466
- // First, try to execute through unified registry
467
- const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
468
- if (result.success) {
469
- return result;
470
- }
471
- }
472
- catch {
473
- mcpLogger.debug(`[${functionTag}] Unified registry execution failed for ${functionName}, trying fallback`);
474
- }
475
- // Fallback: Try to trigger activation and retry
476
- try {
477
- // Force activation by attempting to activate the filesystem server directly
478
- // This should convert placeholders to real tools
479
- await unifiedRegistry.initialize();
480
- // Try a few common activation patterns
481
- const activationAttempts = [
482
- `${serverId}.list_directory`,
483
- `${serverId}.${toolName}`,
484
- toolName,
485
- ];
486
- for (const attempt of activationAttempts) {
487
- try {
488
- const result = await unifiedRegistry.executeTool(attempt, actualParameters, finalContext);
489
- if (result.success) {
490
- mcpLogger.debug(`[${functionTag}] Filesystem tool executed successfully with: ${attempt}`);
491
- return result;
492
- }
493
- }
494
- catch {
495
- // Continue to next attempt
496
- }
497
- }
498
- // If all attempts fail, return a helpful error
499
- return {
500
- success: false,
501
- error: `Filesystem tool '${toolName}' could not be activated. Available parameters: ${JSON.stringify(actualParameters)}`,
502
- metadata: {
503
- functionName,
504
- timestamp: Date.now(),
505
- source: "function-calling-filesystem-fallback",
506
- },
507
- };
508
- }
509
- catch (fallbackError) {
510
- mcpLogger.error(`[${functionTag}] Filesystem fallback failed:`, fallbackError);
511
- return {
512
- success: false,
513
- error: `Filesystem tool execution failed: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`,
514
- metadata: {
515
- functionName,
516
- timestamp: Date.now(),
517
- source: "function-calling-filesystem-fallback",
518
- },
519
- };
520
- }
521
- }
522
- // For other tools, use unified registry
523
- mcpLogger.debug(`[${functionTag}] Executing through unified registry: ${functionName}`);
524
- const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
525
- mcpLogger.debug(`[${functionTag}] Function call completed: ${functionName}`, {
526
- success: result.success,
527
- hasData: !!result.data,
528
- });
529
- return result;
530
- }
531
- catch (error) {
532
- const errorMessage = error instanceof Error ? error.message : String(error);
533
- mcpLogger.error(`[${functionTag}] Function call failed: ${functionName}`, {
534
- error: errorMessage,
535
- });
536
- return {
537
- success: false,
538
- error: errorMessage,
539
- metadata: {
540
- functionName,
541
- timestamp: Date.now(),
542
- source: "function-calling-integration",
543
- },
544
- };
545
- }
546
- }
547
- /**
548
- * Handle multiple function calls and format results for AI
549
- */
550
- export async function handleFunctionCalls(functionCalls, context) {
551
- const functionTag = "handleFunctionCalls";
552
- const results = [];
553
- mcpLogger.debug(`[${functionTag}] Handling ${functionCalls.length} function calls`);
554
- for (const call of functionCalls) {
555
- const result = await executeFunctionCall(call.name, call.parameters, context);
556
- // Format result for AI consumption
557
- let formattedForAI = "";
558
- if (result.success) {
559
- if (typeof result.data === "string") {
560
- formattedForAI = result.data;
561
- }
562
- else if (result.data) {
563
- formattedForAI = JSON.stringify(result.data, null, 2);
564
- }
565
- else {
566
- formattedForAI = "Function executed successfully (no data returned)";
567
- }
568
- }
569
- else {
570
- formattedForAI = `Error: ${result.error || "Function execution failed"}`;
571
- }
572
- results.push({
573
- id: call.id,
574
- result,
575
- formattedForAI,
576
- });
577
- }
578
- return results;
579
- }
580
- /**
581
- * Create a subset of tools for specific categories or capabilities
582
- */
583
- export async function getFunctionToolsForCategory(category, maxTools) {
584
- const { tools, toolMap } = await getAvailableFunctionTools();
585
- if (!category) {
586
- return maxTools
587
- ? {
588
- tools: tools.slice(0, maxTools),
589
- toolMap,
590
- }
591
- : { tools, toolMap };
592
- }
593
- // Filter by category (simplified - just include all for now)
594
- const filteredTools = tools;
595
- return maxTools
596
- ? {
597
- tools: filteredTools.slice(0, maxTools),
598
- toolMap,
599
- }
600
- : { tools: filteredTools, toolMap };
601
- }
602
- /**
603
- * Check if function calling is available
604
- */
605
- export async function isFunctionCallingAvailable() {
606
- try {
607
- const { tools } = await getAvailableFunctionTools();
608
- return tools.length > 0;
609
- }
610
- catch (error) {
611
- mcpLogger.warn("[isFunctionCallingAvailable] Failed to check availability:", error);
612
- return false;
613
- }
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
- }