@juspay/neurolink 1.6.0 → 1.10.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 (182) hide show
  1. package/CHANGELOG.md +200 -7
  2. package/README.md +101 -18
  3. package/dist/agent/direct-tools.d.ts +1203 -0
  4. package/dist/agent/direct-tools.js +387 -0
  5. package/dist/cli/commands/agent-generate.d.ts +2 -0
  6. package/dist/cli/commands/agent-generate.js +70 -0
  7. package/dist/cli/commands/config.d.ts +6 -6
  8. package/dist/cli/commands/config.js +326 -273
  9. package/dist/cli/commands/mcp.d.ts +2 -1
  10. package/dist/cli/commands/mcp.js +874 -146
  11. package/dist/cli/commands/ollama.d.ts +1 -1
  12. package/dist/cli/commands/ollama.js +153 -143
  13. package/dist/cli/index.js +687 -325
  14. package/dist/cli/utils/complete-setup.d.ts +19 -0
  15. package/dist/cli/utils/complete-setup.js +81 -0
  16. package/dist/cli/utils/env-manager.d.ts +44 -0
  17. package/dist/cli/utils/env-manager.js +226 -0
  18. package/dist/cli/utils/interactive-setup.d.ts +48 -0
  19. package/dist/cli/utils/interactive-setup.js +302 -0
  20. package/dist/core/dynamic-models.d.ts +208 -0
  21. package/dist/core/dynamic-models.js +250 -0
  22. package/dist/core/factory.d.ts +13 -6
  23. package/dist/core/factory.js +177 -62
  24. package/dist/core/types.d.ts +4 -2
  25. package/dist/core/types.js +4 -4
  26. package/dist/index.d.ts +16 -16
  27. package/dist/index.js +16 -16
  28. package/dist/lib/agent/direct-tools.d.ts +1203 -0
  29. package/dist/lib/agent/direct-tools.js +387 -0
  30. package/dist/lib/core/dynamic-models.d.ts +208 -0
  31. package/dist/lib/core/dynamic-models.js +250 -0
  32. package/dist/lib/core/factory.d.ts +13 -6
  33. package/dist/lib/core/factory.js +177 -62
  34. package/dist/lib/core/types.d.ts +4 -2
  35. package/dist/lib/core/types.js +4 -4
  36. package/dist/lib/index.d.ts +16 -16
  37. package/dist/lib/index.js +16 -16
  38. package/dist/lib/mcp/auto-discovery.d.ts +120 -0
  39. package/dist/lib/mcp/auto-discovery.js +793 -0
  40. package/dist/lib/mcp/client.d.ts +66 -0
  41. package/dist/lib/mcp/client.js +245 -0
  42. package/dist/lib/mcp/config.d.ts +31 -0
  43. package/dist/lib/mcp/config.js +74 -0
  44. package/dist/lib/mcp/context-manager.d.ts +4 -4
  45. package/dist/lib/mcp/context-manager.js +24 -18
  46. package/dist/lib/mcp/factory.d.ts +28 -11
  47. package/dist/lib/mcp/factory.js +36 -29
  48. package/dist/lib/mcp/function-calling.d.ts +51 -0
  49. package/dist/lib/mcp/function-calling.js +510 -0
  50. package/dist/lib/mcp/index.d.ts +190 -0
  51. package/dist/lib/mcp/index.js +156 -0
  52. package/dist/lib/mcp/initialize-tools.d.ts +28 -0
  53. package/dist/lib/mcp/initialize-tools.js +209 -0
  54. package/dist/lib/mcp/initialize.d.ts +17 -0
  55. package/dist/lib/mcp/initialize.js +51 -0
  56. package/dist/lib/mcp/logging.d.ts +71 -0
  57. package/dist/lib/mcp/logging.js +183 -0
  58. package/dist/lib/mcp/manager.d.ts +67 -0
  59. package/dist/lib/mcp/manager.js +176 -0
  60. package/dist/lib/mcp/neurolink-mcp-client.d.ts +96 -0
  61. package/dist/lib/mcp/neurolink-mcp-client.js +417 -0
  62. package/dist/lib/mcp/orchestrator.d.ts +3 -3
  63. package/dist/lib/mcp/orchestrator.js +46 -43
  64. package/dist/lib/mcp/registry.d.ts +12 -4
  65. package/dist/lib/mcp/registry.js +64 -37
  66. package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.d.ts +1 -1
  67. package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.js +204 -65
  68. package/dist/lib/mcp/servers/ai-providers/ai-core-server.js +142 -102
  69. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +6 -6
  70. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.js +197 -142
  71. package/dist/lib/mcp/servers/utilities/utility-server.d.ts +8 -0
  72. package/dist/lib/mcp/servers/utilities/utility-server.js +326 -0
  73. package/dist/lib/mcp/tool-integration.d.ts +67 -0
  74. package/dist/lib/mcp/tool-integration.js +179 -0
  75. package/dist/lib/mcp/unified-registry.d.ts +269 -0
  76. package/dist/lib/mcp/unified-registry.js +1411 -0
  77. package/dist/lib/neurolink.d.ts +68 -6
  78. package/dist/lib/neurolink.js +304 -42
  79. package/dist/lib/providers/agent-enhanced-provider.d.ts +59 -0
  80. package/dist/lib/providers/agent-enhanced-provider.js +242 -0
  81. package/dist/lib/providers/amazonBedrock.d.ts +3 -3
  82. package/dist/lib/providers/amazonBedrock.js +54 -50
  83. package/dist/lib/providers/anthropic.d.ts +2 -2
  84. package/dist/lib/providers/anthropic.js +92 -84
  85. package/dist/lib/providers/azureOpenAI.d.ts +2 -2
  86. package/dist/lib/providers/azureOpenAI.js +97 -86
  87. package/dist/lib/providers/function-calling-provider.d.ts +70 -0
  88. package/dist/lib/providers/function-calling-provider.js +359 -0
  89. package/dist/lib/providers/googleAIStudio.d.ts +10 -5
  90. package/dist/lib/providers/googleAIStudio.js +60 -38
  91. package/dist/lib/providers/googleVertexAI.d.ts +3 -3
  92. package/dist/lib/providers/googleVertexAI.js +96 -86
  93. package/dist/lib/providers/huggingFace.d.ts +3 -3
  94. package/dist/lib/providers/huggingFace.js +70 -63
  95. package/dist/lib/providers/index.d.ts +11 -11
  96. package/dist/lib/providers/index.js +18 -18
  97. package/dist/lib/providers/mcp-provider.d.ts +62 -0
  98. package/dist/lib/providers/mcp-provider.js +183 -0
  99. package/dist/lib/providers/mistralAI.d.ts +3 -3
  100. package/dist/lib/providers/mistralAI.js +42 -36
  101. package/dist/lib/providers/ollama.d.ts +4 -4
  102. package/dist/lib/providers/ollama.js +128 -98
  103. package/dist/lib/providers/openAI.d.ts +7 -3
  104. package/dist/lib/providers/openAI.js +45 -33
  105. package/dist/lib/utils/logger.js +2 -2
  106. package/dist/lib/utils/providerUtils-fixed.d.ts +8 -0
  107. package/dist/lib/utils/providerUtils-fixed.js +75 -0
  108. package/dist/lib/utils/providerUtils.d.ts +8 -1
  109. package/dist/lib/utils/providerUtils.js +63 -32
  110. package/dist/mcp/auto-discovery.d.ts +120 -0
  111. package/dist/mcp/auto-discovery.js +794 -0
  112. package/dist/mcp/client.d.ts +66 -0
  113. package/dist/mcp/client.js +245 -0
  114. package/dist/mcp/config.d.ts +31 -0
  115. package/dist/mcp/config.js +74 -0
  116. package/dist/mcp/context-manager.d.ts +4 -4
  117. package/dist/mcp/context-manager.js +24 -18
  118. package/dist/mcp/factory.d.ts +28 -11
  119. package/dist/mcp/factory.js +36 -29
  120. package/dist/mcp/function-calling.d.ts +51 -0
  121. package/dist/mcp/function-calling.js +510 -0
  122. package/dist/mcp/index.d.ts +190 -0
  123. package/dist/mcp/index.js +156 -0
  124. package/dist/mcp/initialize-tools.d.ts +28 -0
  125. package/dist/mcp/initialize-tools.js +210 -0
  126. package/dist/mcp/initialize.d.ts +17 -0
  127. package/dist/mcp/initialize.js +51 -0
  128. package/dist/mcp/logging.d.ts +71 -0
  129. package/dist/mcp/logging.js +183 -0
  130. package/dist/mcp/manager.d.ts +67 -0
  131. package/dist/mcp/manager.js +176 -0
  132. package/dist/mcp/neurolink-mcp-client.d.ts +96 -0
  133. package/dist/mcp/neurolink-mcp-client.js +417 -0
  134. package/dist/mcp/orchestrator.d.ts +3 -3
  135. package/dist/mcp/orchestrator.js +46 -43
  136. package/dist/mcp/registry.d.ts +12 -4
  137. package/dist/mcp/registry.js +64 -37
  138. package/dist/mcp/servers/ai-providers/ai-analysis-tools.d.ts +1 -1
  139. package/dist/mcp/servers/ai-providers/ai-analysis-tools.js +204 -65
  140. package/dist/mcp/servers/ai-providers/ai-core-server.js +142 -102
  141. package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +6 -6
  142. package/dist/mcp/servers/ai-providers/ai-workflow-tools.js +197 -142
  143. package/dist/mcp/servers/utilities/utility-server.d.ts +8 -0
  144. package/dist/mcp/servers/utilities/utility-server.js +326 -0
  145. package/dist/mcp/tool-integration.d.ts +67 -0
  146. package/dist/mcp/tool-integration.js +179 -0
  147. package/dist/mcp/unified-registry.d.ts +269 -0
  148. package/dist/mcp/unified-registry.js +1411 -0
  149. package/dist/neurolink.d.ts +68 -6
  150. package/dist/neurolink.js +304 -42
  151. package/dist/providers/agent-enhanced-provider.d.ts +59 -0
  152. package/dist/providers/agent-enhanced-provider.js +242 -0
  153. package/dist/providers/amazonBedrock.d.ts +3 -3
  154. package/dist/providers/amazonBedrock.js +54 -50
  155. package/dist/providers/anthropic.d.ts +2 -2
  156. package/dist/providers/anthropic.js +92 -84
  157. package/dist/providers/azureOpenAI.d.ts +2 -2
  158. package/dist/providers/azureOpenAI.js +97 -86
  159. package/dist/providers/function-calling-provider.d.ts +70 -0
  160. package/dist/providers/function-calling-provider.js +359 -0
  161. package/dist/providers/googleAIStudio.d.ts +10 -5
  162. package/dist/providers/googleAIStudio.js +60 -38
  163. package/dist/providers/googleVertexAI.d.ts +3 -3
  164. package/dist/providers/googleVertexAI.js +96 -86
  165. package/dist/providers/huggingFace.d.ts +3 -3
  166. package/dist/providers/huggingFace.js +70 -63
  167. package/dist/providers/index.d.ts +11 -11
  168. package/dist/providers/index.js +18 -18
  169. package/dist/providers/mcp-provider.d.ts +62 -0
  170. package/dist/providers/mcp-provider.js +183 -0
  171. package/dist/providers/mistralAI.d.ts +3 -3
  172. package/dist/providers/mistralAI.js +42 -36
  173. package/dist/providers/ollama.d.ts +4 -4
  174. package/dist/providers/ollama.js +128 -98
  175. package/dist/providers/openAI.d.ts +7 -3
  176. package/dist/providers/openAI.js +45 -33
  177. package/dist/utils/logger.js +2 -2
  178. package/dist/utils/providerUtils-fixed.d.ts +8 -0
  179. package/dist/utils/providerUtils-fixed.js +75 -0
  180. package/dist/utils/providerUtils.d.ts +8 -1
  181. package/dist/utils/providerUtils.js +63 -32
  182. package/package.json +182 -160
@@ -0,0 +1,417 @@
1
+ /**
2
+ * NeuroLink MCP Client with Automatic Tool Detection
3
+ * Implements automatic tool execution based on prompt analysis
4
+ * Following Lighthouse's pattern of prompt-based tool invocation
5
+ */
6
+ import { EventEmitter } from "events";
7
+ import { logger } from "../utils/logger.js";
8
+ import { v4 as uuidv4 } from "uuid";
9
+ /**
10
+ * NeuroLink MCP Client with Automatic Tool Detection
11
+ */
12
+ export class NeuroLinkMCPClient extends EventEmitter {
13
+ provider;
14
+ tools = new Map();
15
+ toolPatterns = [];
16
+ config;
17
+ sessionId;
18
+ executionCount = 0;
19
+ constructor(config) {
20
+ super();
21
+ this.provider = config.provider;
22
+ this.config = config;
23
+ this.sessionId = config.sessionId || uuidv4();
24
+ this.initializeDefaultPatterns();
25
+ logger.info(`[NeuroLink MCP Client] Initialized with automatic tool detection`, {
26
+ sessionId: this.sessionId,
27
+ provider: config.providerName,
28
+ model: config.modelName,
29
+ });
30
+ }
31
+ /**
32
+ * Initialize default tool detection patterns
33
+ */
34
+ initializeDefaultPatterns() {
35
+ // NO HARDCODED PATTERNS! Let AI decide which tools to use
36
+ // This is TRUE automatic tool detection
37
+ }
38
+ /**
39
+ * Register a tool with automatic detection patterns
40
+ */
41
+ registerTool(tool, patterns) {
42
+ this.tools.set(tool.name, tool);
43
+ // Add custom patterns if provided
44
+ if (patterns) {
45
+ this.toolPatterns.push(patterns);
46
+ }
47
+ logger.debug(`[NeuroLink MCP Client] Registered tool: ${tool.name}`, {
48
+ hasPatterns: !!patterns,
49
+ sessionId: this.sessionId,
50
+ });
51
+ this.emit("tool:registered", { toolName: tool.name });
52
+ }
53
+ /**
54
+ * Extract tool parameters using AI
55
+ * No hardcoded patterns - let AI figure out the parameters
56
+ */
57
+ async extractToolParameters(toolName, tool, prompt) {
58
+ // If the tool has no input schema, no parameters needed
59
+ if (!tool.inputSchema) {
60
+ return {};
61
+ }
62
+ // Get the schema information
63
+ let schemaDescription = "";
64
+ try {
65
+ // Convert schema to a readable format
66
+ if (typeof tool.inputSchema === "object" && tool.inputSchema !== null) {
67
+ schemaDescription = JSON.stringify(tool.inputSchema, null, 2);
68
+ }
69
+ }
70
+ catch (error) {
71
+ logger.warn(`[NeuroLink MCP Client] Could not serialize schema for ${toolName}`);
72
+ return {};
73
+ }
74
+ // Ask AI to extract parameters
75
+ const extractionPrompt = `Extract the parameters needed for the tool "${toolName}" from the user prompt.
76
+
77
+ Tool: ${toolName}
78
+ Description: ${tool.description}
79
+ Input Schema: ${schemaDescription}
80
+
81
+ User prompt: "${prompt}"
82
+
83
+ Instructions:
84
+ 1. Analyze the user prompt to extract values for the tool parameters
85
+ 2. Return ONLY a JSON object with the extracted parameters
86
+ 3. If a parameter cannot be extracted from the prompt, omit it or use a reasonable default
87
+ 4. Make sure the JSON is valid and matches the schema
88
+
89
+ Examples:
90
+ - Prompt: "What's the weather in New York?" → {"location": "New York"}
91
+ - Prompt: "Calculate 5 + 3" → {"expression": "5 + 3"}
92
+ - Prompt: "What time is it?" → {} (no parameters needed)
93
+
94
+ Response (JSON object only):`;
95
+ try {
96
+ const response = await this.provider.generateText({
97
+ prompt: extractionPrompt,
98
+ temperature: 0,
99
+ maxTokens: 200,
100
+ });
101
+ if (response?.text) {
102
+ // Extract JSON object from response
103
+ const match = response.text.match(/\{([^}]*)\}/);
104
+ if (match) {
105
+ try {
106
+ const params = JSON.parse(match[0]);
107
+ logger.debug(`[NeuroLink MCP Client] Extracted parameters for ${toolName}`, params);
108
+ return params;
109
+ }
110
+ catch (parseError) {
111
+ logger.error(`[NeuroLink MCP Client] Failed to parse parameters`, parseError);
112
+ }
113
+ }
114
+ }
115
+ }
116
+ catch (error) {
117
+ logger.error(`[NeuroLink MCP Client] Failed to extract parameters with AI`, error);
118
+ }
119
+ return {};
120
+ }
121
+ /**
122
+ * Analyze prompt to detect required tools
123
+ * TRUE AUTOMATIC DETECTION - AI decides which tools to use
124
+ */
125
+ async analyzePrompt(prompt) {
126
+ const detectedTools = [];
127
+ // No patterns! Always use AI to detect tools
128
+ if (this.tools.size > 0) {
129
+ const toolList = Array.from(this.tools.values()).map((tool) => ({
130
+ name: tool.name,
131
+ description: tool.description,
132
+ }));
133
+ const analysisPrompt = `Analyze this user prompt and determine which tools should be used to answer it properly.
134
+
135
+ User prompt: "${prompt}"
136
+
137
+ Available tools:
138
+ ${toolList.map((t) => `- ${t.name}: ${t.description}`).join("\n")}
139
+
140
+ Instructions:
141
+ 1. Analyze what the user is asking for
142
+ 2. Determine which tools would be helpful to answer the question
143
+ 3. Return ONLY a JSON array of tool names that should be used
144
+ 4. If no tools are needed, return an empty array []
145
+ 5. Be selective - only choose tools that are directly relevant
146
+
147
+ Examples:
148
+ - "What time is it?" → ["neurolink-utility_get-current-time"]
149
+ - "Calculate 5 + 3" → ["neurolink-utility_calculator"]
150
+ - "What is the capital of France?" → []
151
+ - "What's the weather in NYC?" → ["neurolink-utility_get-weather"]
152
+
153
+ Response (JSON array only):`;
154
+ try {
155
+ const response = await this.provider.generateText({
156
+ prompt: analysisPrompt,
157
+ temperature: 0,
158
+ maxTokens: 200,
159
+ });
160
+ if (response?.text) {
161
+ // Extract JSON array from response
162
+ const match = response.text.match(/\[([^\]]*)\]/);
163
+ if (match) {
164
+ try {
165
+ const toolNames = JSON.parse(match[0]);
166
+ // Filter to only include tools that actually exist
167
+ const validTools = toolNames.filter((name) => {
168
+ // Check exact match first
169
+ if (this.tools.has(name)) {
170
+ return true;
171
+ }
172
+ // Check for partial matches (e.g., "get-current-time" matches "neurolink-utility_get-current-time")
173
+ for (const [registeredName] of this.tools) {
174
+ if (registeredName.endsWith(`_${name}`) ||
175
+ registeredName.includes(name)) {
176
+ // Replace with the full registered name
177
+ const index = toolNames.indexOf(name);
178
+ if (index !== -1) {
179
+ toolNames[index] = registeredName;
180
+ }
181
+ return true;
182
+ }
183
+ }
184
+ return false;
185
+ });
186
+ detectedTools.push(...validTools);
187
+ }
188
+ catch (parseError) {
189
+ logger.error(`[NeuroLink MCP Client] Failed to parse tool names`, parseError);
190
+ }
191
+ }
192
+ }
193
+ }
194
+ catch (error) {
195
+ logger.error(`[NeuroLink MCP Client] Failed to analyze prompt with AI`, error);
196
+ }
197
+ }
198
+ logger.info(`[NeuroLink MCP Client] AI detected tools for prompt`, {
199
+ prompt: prompt.substring(0, 50),
200
+ detectedTools,
201
+ sessionId: this.sessionId,
202
+ });
203
+ return detectedTools;
204
+ }
205
+ /**
206
+ * Execute detected tools
207
+ */
208
+ async executeTools(toolNames, prompt) {
209
+ const results = [];
210
+ for (const toolName of toolNames) {
211
+ const tool = this.tools.get(toolName);
212
+ if (!tool) {
213
+ logger.warn(`[NeuroLink MCP Client] Tool not found: ${toolName}`);
214
+ continue;
215
+ }
216
+ // Extract parameters for the tool using AI
217
+ const params = await this.extractToolParameters(toolName, tool, prompt);
218
+ // Create execution context
219
+ const context = {
220
+ sessionId: this.sessionId,
221
+ userId: this.config.userId,
222
+ organizationId: this.config.organizationId,
223
+ aiProvider: this.config.providerName,
224
+ modelId: this.config.modelName,
225
+ timestamp: Date.now(),
226
+ };
227
+ // Emit tool start event
228
+ this.executionCount++;
229
+ const executionId = `exec-${this.executionCount}`;
230
+ this.emit("tool:start", {
231
+ executionId,
232
+ toolName,
233
+ params,
234
+ });
235
+ const startTime = Date.now();
236
+ try {
237
+ // Execute the tool
238
+ const result = await tool.execute(params, context);
239
+ const executionTime = Date.now() - startTime;
240
+ results.push({
241
+ toolName,
242
+ result,
243
+ executionTime,
244
+ });
245
+ // Emit tool end event
246
+ this.emit("tool:end", {
247
+ executionId,
248
+ toolName,
249
+ result,
250
+ executionTime,
251
+ });
252
+ logger.info(`[NeuroLink MCP Client] Tool executed successfully`, {
253
+ toolName,
254
+ executionTime,
255
+ success: result.success,
256
+ });
257
+ }
258
+ catch (error) {
259
+ const executionTime = Date.now() - startTime;
260
+ const errorResult = {
261
+ success: false,
262
+ error: error instanceof Error ? error.message : String(error),
263
+ };
264
+ results.push({
265
+ toolName,
266
+ result: errorResult,
267
+ executionTime,
268
+ });
269
+ // Emit tool error event
270
+ this.emit("tool:error", {
271
+ executionId,
272
+ toolName,
273
+ error: errorResult.error,
274
+ executionTime,
275
+ });
276
+ logger.error(`[NeuroLink MCP Client] Tool execution failed`, {
277
+ toolName,
278
+ error: errorResult.error,
279
+ executionTime,
280
+ });
281
+ }
282
+ }
283
+ return results;
284
+ }
285
+ /**
286
+ * Generate response with tool results incorporated
287
+ */
288
+ async generateResponse(prompt, toolResults) {
289
+ // If no tools were used, generate regular response
290
+ if (toolResults.length === 0) {
291
+ const response = await this.provider.generateText({ prompt });
292
+ return response?.text || "";
293
+ }
294
+ // Extract human-readable results from tool executions
295
+ const toolResultsText = toolResults
296
+ .map((tr) => {
297
+ if (tr.result.success && tr.result.data) {
298
+ // Check if tool result has a displayString or other human-readable format
299
+ const data = tr.result.data;
300
+ // For time tool, use the displayString
301
+ if (data.displayString) {
302
+ return data.displayString;
303
+ }
304
+ // For other tools, try to extract meaningful text
305
+ if (data.formatted) {
306
+ return data.formatted;
307
+ }
308
+ // For complex results, create a summary
309
+ if (typeof data === "object") {
310
+ // Try to find the most relevant field
311
+ if (data.result) {
312
+ return String(data.result);
313
+ }
314
+ if (data.output) {
315
+ return String(data.output);
316
+ }
317
+ if (data.text) {
318
+ return String(data.text);
319
+ }
320
+ if (data.value) {
321
+ return String(data.value);
322
+ }
323
+ // For time-specific fields
324
+ if (data.localTime) {
325
+ return `The current time is ${data.localTime} in ${data.actualTimezone || data.requestedTimezone}`;
326
+ }
327
+ }
328
+ // Fallback to stringified result
329
+ return JSON.stringify(data);
330
+ }
331
+ else {
332
+ return `Tool ${tr.toolName} failed: ${tr.result.error}`;
333
+ }
334
+ })
335
+ .join("\n");
336
+ // For single tool results with displayString, return directly
337
+ if (toolResults.length === 1) {
338
+ const toolResult = toolResults[0];
339
+ if (toolResult.result.success && toolResult.result.data) {
340
+ const data = toolResult.result.data;
341
+ if (data.displayString) {
342
+ return data.displayString;
343
+ }
344
+ }
345
+ }
346
+ // For more complex queries, let the AI incorporate the results
347
+ const enhancedPrompt = `User question: ${prompt}
348
+
349
+ Tool results: ${toolResultsText}
350
+
351
+ Please provide a natural response based on the tool results.`;
352
+ // Generate final response
353
+ const response = await this.provider.generateText({
354
+ prompt: enhancedPrompt,
355
+ temperature: 0.7,
356
+ maxTokens: 1000,
357
+ });
358
+ return response?.text || toolResultsText;
359
+ }
360
+ /**
361
+ * Send a prompt and automatically execute any needed tools
362
+ */
363
+ async sendPrompt(prompt) {
364
+ logger.info(`[NeuroLink MCP Client] Processing prompt with automatic tool detection`, {
365
+ prompt: prompt.substring(0, 100),
366
+ sessionId: this.sessionId,
367
+ });
368
+ // Step 1: Analyze prompt for tool needs
369
+ const toolsNeeded = await this.analyzePrompt(prompt);
370
+ // Step 2: Execute tools if needed
371
+ const toolResults = await this.executeTools(toolsNeeded, prompt);
372
+ // Step 3: Generate response with tool results
373
+ const response = await this.generateResponse(prompt, toolResults);
374
+ return response;
375
+ }
376
+ /**
377
+ * Get registered tools
378
+ */
379
+ getTools() {
380
+ const tools = {};
381
+ for (const [name, tool] of this.tools) {
382
+ tools[name] = {
383
+ description: tool.description,
384
+ inputSchema: tool.inputSchema,
385
+ };
386
+ }
387
+ return tools;
388
+ }
389
+ /**
390
+ * Get session statistics
391
+ */
392
+ getStats() {
393
+ return {
394
+ sessionId: this.sessionId,
395
+ toolCount: this.tools.size,
396
+ patternCount: this.toolPatterns.length,
397
+ executionCount: this.executionCount,
398
+ provider: this.config.providerName,
399
+ model: this.config.modelName,
400
+ };
401
+ }
402
+ /**
403
+ * Clean up resources
404
+ */
405
+ async cleanup() {
406
+ this.tools.clear();
407
+ this.toolPatterns = [];
408
+ this.removeAllListeners();
409
+ logger.info(`[NeuroLink MCP Client] Cleaned up session ${this.sessionId}`);
410
+ }
411
+ }
412
+ /**
413
+ * Create a new NeuroLink MCP Client instance
414
+ */
415
+ export function createNeuroLinkMCPClient(config) {
416
+ return new NeuroLinkMCPClient(config);
417
+ }
@@ -3,9 +3,9 @@
3
3
  * Central orchestrator for coordinated tool execution with pipeline management
4
4
  * Coordinates factory, registry, context, and AI tools for seamless operation
5
5
  */
6
- import type { ToolResult } from './factory.js';
7
- import { MCPToolRegistry, type ToolExecutionOptions } from './registry.js';
8
- import { ContextManager, type ContextRequest } from './context-manager.js';
6
+ import type { ToolResult } from "./factory.js";
7
+ import { MCPToolRegistry, type ToolExecutionOptions } from "./registry.js";
8
+ import { ContextManager, type ContextRequest } from "./context-manager.js";
9
9
  /**
10
10
  * Pipeline execution options
11
11
  */
@@ -3,9 +3,9 @@
3
3
  * Central orchestrator for coordinated tool execution with pipeline management
4
4
  * Coordinates factory, registry, context, and AI tools for seamless operation
5
5
  */
6
- import { MCPToolRegistry, defaultToolRegistry } from './registry.js';
7
- import { ContextManager, defaultContextManager, createExecutionContext } from './context-manager.js';
8
- import { aiCoreServer } from './servers/ai-providers/ai-core-server.js';
6
+ import { MCPToolRegistry, defaultToolRegistry, } from "./registry.js";
7
+ import { ContextManager, defaultContextManager, createExecutionContext, } from "./context-manager.js";
8
+ import { aiCoreServer } from "./servers/ai-providers/ai-core-server.js";
9
9
  /**
10
10
  * NeuroLink MCP Tool Orchestrator
11
11
  * Central coordination engine for tool execution, pipelines, and AI operations
@@ -26,10 +26,10 @@ export class MCPOrchestrator {
26
26
  async initializeDefaultServers() {
27
27
  try {
28
28
  await this.registry.registerServer(aiCoreServer);
29
- console.log('[Orchestrator] Initialized with AI Core Server');
29
+ console.log("[Orchestrator] Initialized with AI Core Server");
30
30
  }
31
31
  catch (error) {
32
- console.warn('[Orchestrator] Failed to register AI Core Server:', error);
32
+ console.warn("[Orchestrator] Failed to register AI Core Server:", error);
33
33
  }
34
34
  }
35
35
  /**
@@ -47,7 +47,7 @@ export class MCPOrchestrator {
47
47
  console.log(`[Orchestrator] Executing tool '${toolName}' in session ${context.sessionId}`);
48
48
  // Execute tool through registry
49
49
  const result = await this.registry.executeTool(toolName, params, context, options);
50
- console.log(`[Orchestrator] Tool '${toolName}' execution ${result.success ? 'completed' : 'failed'}`);
50
+ console.log(`[Orchestrator] Tool '${toolName}' execution ${result.success ? "completed" : "failed"}`);
51
51
  return result;
52
52
  }
53
53
  /**
@@ -61,11 +61,11 @@ export class MCPOrchestrator {
61
61
  async executePipeline(steps, contextRequest = {}, options = {}) {
62
62
  const startTime = Date.now();
63
63
  const pipelineId = this.generatePipelineId();
64
- const { stopOnError = true, parallel = false, timeout = 60000, trackMetrics = true, validateInputs = true } = options;
64
+ const { stopOnError = true, parallel = false, timeout = 60000, trackMetrics = true, validateInputs = true, } = options;
65
65
  // Create shared execution context
66
66
  const context = this.contextManager.createContext({
67
67
  ...contextRequest,
68
- sessionId: contextRequest.sessionId || pipelineId
68
+ sessionId: contextRequest.sessionId || pipelineId,
69
69
  });
70
70
  const results = new Map();
71
71
  const errors = new Map();
@@ -79,7 +79,7 @@ export class MCPOrchestrator {
79
79
  timeout,
80
80
  trackMetrics,
81
81
  validateInputs,
82
- stopOnError
82
+ stopOnError,
83
83
  });
84
84
  }
85
85
  else {
@@ -92,12 +92,12 @@ export class MCPOrchestrator {
92
92
  ...step.options,
93
93
  validateInput: validateInputs,
94
94
  trackMetrics,
95
- timeoutMs: timeout / steps.length // Distribute timeout across steps
95
+ timeoutMs: timeout / steps.length, // Distribute timeout across steps
96
96
  });
97
97
  results.set(stepId, stepResult);
98
98
  stepsExecuted++;
99
99
  if (!stepResult.success) {
100
- errors.set(stepId, stepResult.error || 'Unknown error');
100
+ errors.set(stepId, stepResult.error || "Unknown error");
101
101
  if (stopOnError) {
102
102
  console.error(`[Orchestrator] Pipeline ${pipelineId} stopped due to error in step ${stepId}`);
103
103
  break;
@@ -117,7 +117,7 @@ export class MCPOrchestrator {
117
117
  }
118
118
  const executionTime = Date.now() - startTime;
119
119
  const success = errors.size === 0 || !stopOnError;
120
- console.log(`[Orchestrator] Pipeline ${pipelineId} completed in ${executionTime}ms - ${success ? 'SUCCESS' : 'FAILED'}`);
120
+ console.log(`[Orchestrator] Pipeline ${pipelineId} completed in ${executionTime}ms - ${success ? "SUCCESS" : "FAILED"}`);
121
121
  return {
122
122
  success,
123
123
  results,
@@ -129,8 +129,8 @@ export class MCPOrchestrator {
129
129
  pipelineId,
130
130
  sessionId: context.sessionId,
131
131
  timestamp: Date.now(),
132
- parallel
133
- }
132
+ parallel,
133
+ },
134
134
  };
135
135
  }
136
136
  catch (error) {
@@ -140,7 +140,7 @@ export class MCPOrchestrator {
140
140
  return {
141
141
  success: false,
142
142
  results,
143
- errors: new Map([['pipeline', errorMessage]]),
143
+ errors: new Map([["pipeline", errorMessage]]),
144
144
  executionTime,
145
145
  stepsExecuted,
146
146
  stepsSkipped,
@@ -148,8 +148,8 @@ export class MCPOrchestrator {
148
148
  pipelineId,
149
149
  sessionId: context.sessionId,
150
150
  timestamp: Date.now(),
151
- parallel
152
- }
151
+ parallel,
152
+ },
153
153
  };
154
154
  }
155
155
  }
@@ -172,29 +172,29 @@ export class MCPOrchestrator {
172
172
  // Step 1: Provider selection (if not specified)
173
173
  if (!options.provider) {
174
174
  steps.push({
175
- stepId: 'select-provider',
176
- toolName: 'select-provider',
175
+ stepId: "select-provider",
176
+ toolName: "select-provider",
177
177
  params: {
178
178
  requirements: {
179
179
  maxTokens: options.maxTokens,
180
- costEfficient: true
181
- }
182
- }
180
+ costEfficient: true,
181
+ },
182
+ },
183
183
  });
184
184
  }
185
185
  // Step 2: Text generation
186
186
  steps.push({
187
- stepId: 'generate-text',
188
- toolName: 'generate-text',
187
+ stepId: "generate-text",
188
+ toolName: "generate-text",
189
189
  params: {
190
190
  prompt,
191
191
  provider: options.provider,
192
192
  model: options.model,
193
193
  temperature: options.temperature,
194
194
  maxTokens: options.maxTokens,
195
- systemPrompt: options.systemPrompt
195
+ systemPrompt: options.systemPrompt,
196
196
  },
197
- dependsOn: options.provider ? [] : ['select-provider']
197
+ dependsOn: options.provider ? [] : ["select-provider"],
198
198
  });
199
199
  // Step 3: Custom tools (if specified)
200
200
  if (options.customTools && options.customTools.length > 0) {
@@ -202,8 +202,10 @@ export class MCPOrchestrator {
202
202
  steps.push({
203
203
  stepId: `custom-${toolName}`,
204
204
  toolName,
205
- params: { /* tool-specific params */},
206
- dependsOn: ['generate-text']
205
+ params: {
206
+ /* tool-specific params */
207
+ },
208
+ dependsOn: ["generate-text"],
207
209
  });
208
210
  }
209
211
  }
@@ -211,14 +213,14 @@ export class MCPOrchestrator {
211
213
  const pipelineResult = await this.executePipeline(steps, contextRequest, {
212
214
  stopOnError: true,
213
215
  parallel: false,
214
- trackMetrics: true
216
+ trackMetrics: true,
215
217
  });
216
218
  const executionTime = Date.now() - startTime;
217
219
  // Extract text generation result
218
- const textResult = pipelineResult.results.get('generate-text');
219
- const providerResult = pipelineResult.results.get('select-provider');
220
+ const textResult = pipelineResult.results.get("generate-text");
221
+ const providerResult = pipelineResult.results.get("select-provider");
220
222
  if (!textResult || !textResult.success) {
221
- throw new Error('Text generation failed');
223
+ throw new Error("Text generation failed");
222
224
  }
223
225
  const toolsUsed = Array.from(pipelineResult.results.keys());
224
226
  console.log(`[Orchestrator] Text pipeline completed in ${executionTime}ms`);
@@ -232,8 +234,8 @@ export class MCPOrchestrator {
232
234
  metadata: {
233
235
  sessionId: context.sessionId,
234
236
  timestamp: Date.now(),
235
- toolsUsed
236
- }
237
+ toolsUsed,
238
+ },
237
239
  };
238
240
  }
239
241
  catch (error) {
@@ -246,8 +248,8 @@ export class MCPOrchestrator {
246
248
  metadata: {
247
249
  sessionId: context.sessionId,
248
250
  timestamp: Date.now(),
249
- toolsUsed: []
250
- }
251
+ toolsUsed: [],
252
+ },
251
253
  };
252
254
  }
253
255
  }
@@ -261,8 +263,8 @@ export class MCPOrchestrator {
261
263
  registry: this.registry.getStats(),
262
264
  context: this.contextManager.getStats(),
263
265
  orchestrator: {
264
- pipelinesExecuted: this.pipelineCounter
265
- }
266
+ pipelinesExecuted: this.pipelineCounter,
267
+ },
266
268
  };
267
269
  }
268
270
  /**
@@ -283,14 +285,15 @@ export class MCPOrchestrator {
283
285
  const completed = new Set();
284
286
  const executing = new Set();
285
287
  while (completed.size < steps.length) {
286
- const readySteps = Array.from(stepMap.keys()).filter(stepId => {
287
- if (completed.has(stepId) || executing.has(stepId))
288
+ const readySteps = Array.from(stepMap.keys()).filter((stepId) => {
289
+ if (completed.has(stepId) || executing.has(stepId)) {
288
290
  return false;
291
+ }
289
292
  const dependencies = dependencyGraph.get(stepId) || [];
290
- return dependencies.every(dep => completed.has(dep));
293
+ return dependencies.every((dep) => completed.has(dep));
291
294
  });
292
295
  if (readySteps.length === 0) {
293
- throw new Error('Circular dependency detected in pipeline');
296
+ throw new Error("Circular dependency detected in pipeline");
294
297
  }
295
298
  // Execute ready steps in parallel
296
299
  const executePromises = readySteps.map(async (stepId) => {
@@ -300,7 +303,7 @@ export class MCPOrchestrator {
300
303
  const result = await this.registry.executeTool(step.toolName, step.params, context, { ...step.options, ...options });
301
304
  results.set(stepId, result);
302
305
  if (!result.success) {
303
- errors.set(stepId, result.error || 'Unknown error');
306
+ errors.set(stepId, result.error || "Unknown error");
304
307
  }
305
308
  }
306
309
  catch (error) {