@juspay/neurolink 1.5.3 → 1.9.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.
- package/CHANGELOG.md +241 -1
- package/README.md +113 -20
- package/dist/agent/direct-tools.d.ts +1203 -0
- package/dist/agent/direct-tools.js +387 -0
- package/dist/cli/commands/agent-generate.d.ts +2 -0
- package/dist/cli/commands/agent-generate.js +70 -0
- package/dist/cli/commands/config.d.ts +76 -9
- package/dist/cli/commands/config.js +358 -233
- package/dist/cli/commands/mcp.d.ts +2 -1
- package/dist/cli/commands/mcp.js +874 -146
- package/dist/cli/commands/ollama.d.ts +8 -0
- package/dist/cli/commands/ollama.js +333 -0
- package/dist/cli/index.js +591 -327
- package/dist/cli/utils/complete-setup.d.ts +19 -0
- package/dist/cli/utils/complete-setup.js +81 -0
- package/dist/cli/utils/env-manager.d.ts +44 -0
- package/dist/cli/utils/env-manager.js +226 -0
- package/dist/cli/utils/interactive-setup.d.ts +48 -0
- package/dist/cli/utils/interactive-setup.js +302 -0
- package/dist/core/dynamic-models.d.ts +208 -0
- package/dist/core/dynamic-models.js +250 -0
- package/dist/core/factory.d.ts +13 -6
- package/dist/core/factory.js +180 -50
- package/dist/core/types.d.ts +8 -3
- package/dist/core/types.js +7 -4
- package/dist/index.d.ts +16 -16
- package/dist/index.js +16 -16
- package/dist/lib/agent/direct-tools.d.ts +1203 -0
- package/dist/lib/agent/direct-tools.js +387 -0
- package/dist/lib/core/dynamic-models.d.ts +208 -0
- package/dist/lib/core/dynamic-models.js +250 -0
- package/dist/lib/core/factory.d.ts +13 -6
- package/dist/lib/core/factory.js +180 -50
- package/dist/lib/core/types.d.ts +8 -3
- package/dist/lib/core/types.js +7 -4
- package/dist/lib/index.d.ts +16 -16
- package/dist/lib/index.js +16 -16
- package/dist/lib/mcp/auto-discovery.d.ts +120 -0
- package/dist/lib/mcp/auto-discovery.js +793 -0
- package/dist/lib/mcp/client.d.ts +66 -0
- package/dist/lib/mcp/client.js +245 -0
- package/dist/lib/mcp/config.d.ts +31 -0
- package/dist/lib/mcp/config.js +74 -0
- package/dist/lib/mcp/context-manager.d.ts +4 -4
- package/dist/lib/mcp/context-manager.js +24 -18
- package/dist/lib/mcp/factory.d.ts +28 -11
- package/dist/lib/mcp/factory.js +36 -29
- package/dist/lib/mcp/function-calling.d.ts +51 -0
- package/dist/lib/mcp/function-calling.js +510 -0
- package/dist/lib/mcp/index.d.ts +190 -0
- package/dist/lib/mcp/index.js +156 -0
- package/dist/lib/mcp/initialize-tools.d.ts +28 -0
- package/dist/lib/mcp/initialize-tools.js +209 -0
- package/dist/lib/mcp/initialize.d.ts +17 -0
- package/dist/lib/mcp/initialize.js +51 -0
- package/dist/lib/mcp/logging.d.ts +71 -0
- package/dist/lib/mcp/logging.js +183 -0
- package/dist/lib/mcp/manager.d.ts +67 -0
- package/dist/lib/mcp/manager.js +176 -0
- package/dist/lib/mcp/neurolink-mcp-client.d.ts +96 -0
- package/dist/lib/mcp/neurolink-mcp-client.js +417 -0
- package/dist/lib/mcp/orchestrator.d.ts +3 -3
- package/dist/lib/mcp/orchestrator.js +46 -43
- package/dist/lib/mcp/registry.d.ts +2 -2
- package/dist/lib/mcp/registry.js +42 -33
- package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.d.ts +1 -1
- package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.js +205 -66
- package/dist/lib/mcp/servers/ai-providers/ai-core-server.js +143 -99
- package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +6 -6
- package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.js +404 -251
- package/dist/lib/mcp/servers/utilities/utility-server.d.ts +8 -0
- package/dist/lib/mcp/servers/utilities/utility-server.js +326 -0
- package/dist/lib/mcp/tool-integration.d.ts +67 -0
- package/dist/lib/mcp/tool-integration.js +179 -0
- package/dist/lib/mcp/unified-registry.d.ts +269 -0
- package/dist/lib/mcp/unified-registry.js +1411 -0
- package/dist/lib/neurolink.d.ts +68 -6
- package/dist/lib/neurolink.js +314 -42
- package/dist/lib/providers/agent-enhanced-provider.d.ts +59 -0
- package/dist/lib/providers/agent-enhanced-provider.js +242 -0
- package/dist/lib/providers/amazonBedrock.d.ts +3 -3
- package/dist/lib/providers/amazonBedrock.js +54 -50
- package/dist/lib/providers/anthropic.d.ts +2 -2
- package/dist/lib/providers/anthropic.js +92 -84
- package/dist/lib/providers/azureOpenAI.d.ts +2 -2
- package/dist/lib/providers/azureOpenAI.js +97 -86
- package/dist/lib/providers/function-calling-provider.d.ts +70 -0
- package/dist/lib/providers/function-calling-provider.js +359 -0
- package/dist/lib/providers/googleAIStudio.d.ts +10 -5
- package/dist/lib/providers/googleAIStudio.js +60 -38
- package/dist/lib/providers/googleVertexAI.d.ts +3 -3
- package/dist/lib/providers/googleVertexAI.js +96 -86
- package/dist/lib/providers/huggingFace.d.ts +31 -0
- package/dist/lib/providers/huggingFace.js +362 -0
- package/dist/lib/providers/index.d.ts +14 -8
- package/dist/lib/providers/index.js +18 -12
- package/dist/lib/providers/mcp-provider.d.ts +62 -0
- package/dist/lib/providers/mcp-provider.js +183 -0
- package/dist/lib/providers/mistralAI.d.ts +32 -0
- package/dist/lib/providers/mistralAI.js +223 -0
- package/dist/lib/providers/ollama.d.ts +51 -0
- package/dist/lib/providers/ollama.js +508 -0
- package/dist/lib/providers/openAI.d.ts +7 -3
- package/dist/lib/providers/openAI.js +45 -33
- package/dist/lib/utils/logger.js +2 -2
- package/dist/lib/utils/providerUtils.js +59 -22
- package/dist/mcp/auto-discovery.d.ts +120 -0
- package/dist/mcp/auto-discovery.js +794 -0
- package/dist/mcp/client.d.ts +66 -0
- package/dist/mcp/client.js +245 -0
- package/dist/mcp/config.d.ts +31 -0
- package/dist/mcp/config.js +74 -0
- package/dist/mcp/context-manager.d.ts +4 -4
- package/dist/mcp/context-manager.js +24 -18
- package/dist/mcp/factory.d.ts +28 -11
- package/dist/mcp/factory.js +36 -29
- package/dist/mcp/function-calling.d.ts +51 -0
- package/dist/mcp/function-calling.js +510 -0
- package/dist/mcp/index.d.ts +190 -0
- package/dist/mcp/index.js +156 -0
- package/dist/mcp/initialize-tools.d.ts +28 -0
- package/dist/mcp/initialize-tools.js +210 -0
- package/dist/mcp/initialize.d.ts +17 -0
- package/dist/mcp/initialize.js +51 -0
- package/dist/mcp/logging.d.ts +71 -0
- package/dist/mcp/logging.js +183 -0
- package/dist/mcp/manager.d.ts +67 -0
- package/dist/mcp/manager.js +176 -0
- package/dist/mcp/neurolink-mcp-client.d.ts +96 -0
- package/dist/mcp/neurolink-mcp-client.js +417 -0
- package/dist/mcp/orchestrator.d.ts +3 -3
- package/dist/mcp/orchestrator.js +46 -43
- package/dist/mcp/registry.d.ts +2 -2
- package/dist/mcp/registry.js +42 -33
- package/dist/mcp/servers/ai-providers/ai-analysis-tools.d.ts +1 -1
- package/dist/mcp/servers/ai-providers/ai-analysis-tools.js +205 -66
- package/dist/mcp/servers/ai-providers/ai-core-server.js +143 -99
- package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +6 -6
- package/dist/mcp/servers/ai-providers/ai-workflow-tools.js +404 -253
- package/dist/mcp/servers/utilities/utility-server.d.ts +8 -0
- package/dist/mcp/servers/utilities/utility-server.js +326 -0
- package/dist/mcp/tool-integration.d.ts +67 -0
- package/dist/mcp/tool-integration.js +179 -0
- package/dist/mcp/unified-registry.d.ts +269 -0
- package/dist/mcp/unified-registry.js +1411 -0
- package/dist/neurolink.d.ts +68 -6
- package/dist/neurolink.js +314 -42
- package/dist/providers/agent-enhanced-provider.d.ts +59 -0
- package/dist/providers/agent-enhanced-provider.js +242 -0
- package/dist/providers/amazonBedrock.d.ts +3 -3
- package/dist/providers/amazonBedrock.js +54 -50
- package/dist/providers/anthropic.d.ts +2 -2
- package/dist/providers/anthropic.js +92 -84
- package/dist/providers/azureOpenAI.d.ts +2 -2
- package/dist/providers/azureOpenAI.js +97 -86
- package/dist/providers/function-calling-provider.d.ts +70 -0
- package/dist/providers/function-calling-provider.js +359 -0
- package/dist/providers/googleAIStudio.d.ts +10 -5
- package/dist/providers/googleAIStudio.js +60 -38
- package/dist/providers/googleVertexAI.d.ts +3 -3
- package/dist/providers/googleVertexAI.js +96 -86
- package/dist/providers/huggingFace.d.ts +31 -0
- package/dist/providers/huggingFace.js +362 -0
- package/dist/providers/index.d.ts +14 -8
- package/dist/providers/index.js +18 -12
- package/dist/providers/mcp-provider.d.ts +62 -0
- package/dist/providers/mcp-provider.js +183 -0
- package/dist/providers/mistralAI.d.ts +32 -0
- package/dist/providers/mistralAI.js +223 -0
- package/dist/providers/ollama.d.ts +51 -0
- package/dist/providers/ollama.js +508 -0
- package/dist/providers/openAI.d.ts +7 -3
- package/dist/providers/openAI.js +45 -33
- package/dist/utils/logger.js +2 -2
- package/dist/utils/providerUtils.js +59 -22
- package/package.json +28 -4
package/dist/lib/mcp/registry.js
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
* Central registry for managing MCP servers and tools with execution capabilities
|
|
4
4
|
* Supports tool discovery, registration, and orchestrated execution
|
|
5
5
|
*/
|
|
6
|
-
import { ContextManager, ContextValidator } from
|
|
6
|
+
import { ContextManager, ContextValidator } from "./context-manager.js";
|
|
7
|
+
import { registryLogger, mcpLogger } from "./logging.js";
|
|
7
8
|
/**
|
|
8
9
|
* Central MCP Tool Registry
|
|
9
10
|
* Manages all MCP servers and their tools with advanced execution capabilities
|
|
@@ -26,9 +27,10 @@ export class MCPToolRegistry {
|
|
|
26
27
|
* @throws Error if server ID already exists
|
|
27
28
|
*/
|
|
28
29
|
async registerServer(server) {
|
|
29
|
-
// Check for duplicate server ID
|
|
30
|
+
// Check for duplicate server ID - if already registered, skip silently
|
|
30
31
|
if (this.servers.has(server.id)) {
|
|
31
|
-
|
|
32
|
+
mcpLogger.debug(`Server with ID '${server.id}' is already registered, skipping registration`);
|
|
33
|
+
return;
|
|
32
34
|
}
|
|
33
35
|
// Register the server
|
|
34
36
|
this.servers.set(server.id, server);
|
|
@@ -36,7 +38,7 @@ export class MCPToolRegistry {
|
|
|
36
38
|
for (const [toolName, tool] of Object.entries(server.tools)) {
|
|
37
39
|
await this.registerToolFromServer(server, toolName, tool);
|
|
38
40
|
}
|
|
39
|
-
|
|
41
|
+
registryLogger.debug(`Registered server '${server.id}' with ${Object.keys(server.tools).length} tools`);
|
|
40
42
|
}
|
|
41
43
|
/**
|
|
42
44
|
* Register a single tool from a server
|
|
@@ -55,7 +57,7 @@ export class MCPToolRegistry {
|
|
|
55
57
|
serverCategory: server.category,
|
|
56
58
|
qualifiedName,
|
|
57
59
|
simpleName,
|
|
58
|
-
registeredAt: Date.now()
|
|
60
|
+
registeredAt: Date.now(),
|
|
59
61
|
};
|
|
60
62
|
// Register with both qualified and simple names
|
|
61
63
|
this.tools.set(qualifiedName, registration);
|
|
@@ -64,7 +66,7 @@ export class MCPToolRegistry {
|
|
|
64
66
|
this.tools.set(simpleName, registration);
|
|
65
67
|
}
|
|
66
68
|
else {
|
|
67
|
-
|
|
69
|
+
registryLogger.warn(`Tool name conflict: '${simpleName}' already exists, use qualified name '${qualifiedName}'`);
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
/**
|
|
@@ -78,7 +80,7 @@ export class MCPToolRegistry {
|
|
|
78
80
|
*/
|
|
79
81
|
async executeTool(toolName, params, context, options = {}) {
|
|
80
82
|
const startTime = Date.now();
|
|
81
|
-
const { validateInput = true, validatePermissions = true, trackMetrics = true, timeoutMs = 30000 } = options;
|
|
83
|
+
const { validateInput = true, validatePermissions = true, trackMetrics = true, timeoutMs = 30000, } = options;
|
|
82
84
|
try {
|
|
83
85
|
// Find the tool
|
|
84
86
|
const registration = this.tools.get(toolName);
|
|
@@ -90,11 +92,12 @@ export class MCPToolRegistry {
|
|
|
90
92
|
if (validatePermissions) {
|
|
91
93
|
const contextValidation = ContextValidator.validateContext(context);
|
|
92
94
|
if (!contextValidation.isValid) {
|
|
93
|
-
throw new Error(`Context validation failed: ${contextValidation.errors.join(
|
|
95
|
+
throw new Error(`Context validation failed: ${contextValidation.errors.join(", ")}`);
|
|
94
96
|
}
|
|
95
97
|
// Check tool permissions
|
|
96
|
-
if (tool.permissions &&
|
|
97
|
-
|
|
98
|
+
if (tool.permissions &&
|
|
99
|
+
!ContextValidator.hasPermissions(context, tool.permissions)) {
|
|
100
|
+
throw new Error(`Insufficient permissions for tool '${toolName}'. Required: ${tool.permissions.join(", ")}`);
|
|
98
101
|
}
|
|
99
102
|
}
|
|
100
103
|
// Validate input parameters if schema provided
|
|
@@ -123,8 +126,8 @@ export class MCPToolRegistry {
|
|
|
123
126
|
serverTitle,
|
|
124
127
|
sessionId: context.sessionId,
|
|
125
128
|
timestamp: Date.now(),
|
|
126
|
-
executionTime
|
|
127
|
-
}
|
|
129
|
+
executionTime,
|
|
130
|
+
},
|
|
128
131
|
};
|
|
129
132
|
// Track metrics
|
|
130
133
|
if (trackMetrics) {
|
|
@@ -137,10 +140,10 @@ export class MCPToolRegistry {
|
|
|
137
140
|
}
|
|
138
141
|
catch (error) {
|
|
139
142
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
140
|
-
|
|
143
|
+
registryLogger.warn(`Output validation warning for tool '${toolName}': ${errorMessage}`);
|
|
141
144
|
}
|
|
142
145
|
}
|
|
143
|
-
|
|
146
|
+
registryLogger.debug(`Executed tool '${toolName}' in ${executionTime}ms - ${result.success ? "SUCCESS" : "FAILED"}`);
|
|
144
147
|
return enhancedResult;
|
|
145
148
|
}
|
|
146
149
|
catch (error) {
|
|
@@ -157,10 +160,10 @@ export class MCPToolRegistry {
|
|
|
157
160
|
toolName,
|
|
158
161
|
sessionId: context.sessionId,
|
|
159
162
|
timestamp: Date.now(),
|
|
160
|
-
executionTime
|
|
161
|
-
}
|
|
163
|
+
executionTime,
|
|
164
|
+
},
|
|
162
165
|
};
|
|
163
|
-
|
|
166
|
+
registryLogger.error(`Tool execution failed '${toolName}': ${errorMessage}`);
|
|
164
167
|
return errorResult;
|
|
165
168
|
}
|
|
166
169
|
}
|
|
@@ -175,7 +178,8 @@ export class MCPToolRegistry {
|
|
|
175
178
|
// Get unique tools (prefer qualified names over simple names)
|
|
176
179
|
const uniqueTools = new Map();
|
|
177
180
|
for (const [name, registration] of this.tools) {
|
|
178
|
-
if (name.includes(
|
|
181
|
+
if (name.includes(".")) {
|
|
182
|
+
// Qualified name
|
|
179
183
|
uniqueTools.set(registration.qualifiedName, registration);
|
|
180
184
|
}
|
|
181
185
|
else if (!uniqueTools.has(registration.qualifiedName)) {
|
|
@@ -183,9 +187,10 @@ export class MCPToolRegistry {
|
|
|
183
187
|
}
|
|
184
188
|
}
|
|
185
189
|
for (const registration of uniqueTools.values()) {
|
|
186
|
-
const { tool, serverId, serverTitle, serverCategory, qualifiedName, simpleName } = registration;
|
|
190
|
+
const { tool, serverId, serverTitle, serverCategory, qualifiedName, simpleName, } = registration;
|
|
187
191
|
// Apply filters
|
|
188
|
-
if (criteria.name &&
|
|
192
|
+
if (criteria.name &&
|
|
193
|
+
!simpleName.toLowerCase().includes(criteria.name.toLowerCase())) {
|
|
189
194
|
continue;
|
|
190
195
|
}
|
|
191
196
|
if (criteria.category && tool.category !== criteria.category) {
|
|
@@ -194,15 +199,17 @@ export class MCPToolRegistry {
|
|
|
194
199
|
if (criteria.serverId && serverId !== criteria.serverId) {
|
|
195
200
|
continue;
|
|
196
201
|
}
|
|
197
|
-
if (criteria.serverCategory &&
|
|
202
|
+
if (criteria.serverCategory &&
|
|
203
|
+
serverCategory !== criteria.serverCategory) {
|
|
198
204
|
continue;
|
|
199
205
|
}
|
|
200
|
-
if (criteria.implemented !== undefined &&
|
|
206
|
+
if (criteria.implemented !== undefined &&
|
|
207
|
+
tool.isImplemented !== criteria.implemented) {
|
|
201
208
|
continue;
|
|
202
209
|
}
|
|
203
210
|
if (criteria.permissions && criteria.permissions.length > 0) {
|
|
204
211
|
const toolPermissions = tool.permissions || [];
|
|
205
|
-
const hasAllPermissions = criteria.permissions.every(p => toolPermissions.includes(p));
|
|
212
|
+
const hasAllPermissions = criteria.permissions.every((p) => toolPermissions.includes(p));
|
|
206
213
|
if (!hasAllPermissions) {
|
|
207
214
|
continue;
|
|
208
215
|
}
|
|
@@ -216,7 +223,7 @@ export class MCPToolRegistry {
|
|
|
216
223
|
category: tool.category,
|
|
217
224
|
serverCategory,
|
|
218
225
|
permissions: tool.permissions,
|
|
219
|
-
isImplemented: tool.isImplemented
|
|
226
|
+
isImplemented: tool.isImplemented,
|
|
220
227
|
});
|
|
221
228
|
}
|
|
222
229
|
return tools.sort((a, b) => a.qualifiedName.localeCompare(b.qualifiedName));
|
|
@@ -239,7 +246,7 @@ export class MCPToolRegistry {
|
|
|
239
246
|
return {
|
|
240
247
|
tool: registration.tool,
|
|
241
248
|
server,
|
|
242
|
-
registration
|
|
249
|
+
registration,
|
|
243
250
|
};
|
|
244
251
|
}
|
|
245
252
|
/**
|
|
@@ -252,22 +259,24 @@ export class MCPToolRegistry {
|
|
|
252
259
|
const serversByCategory = {};
|
|
253
260
|
// Count tools by category
|
|
254
261
|
for (const registration of this.tools.values()) {
|
|
255
|
-
const category = registration.tool.category ||
|
|
262
|
+
const category = registration.tool.category || "uncategorized";
|
|
256
263
|
toolsByCategory[category] = (toolsByCategory[category] || 0) + 1;
|
|
257
264
|
}
|
|
258
265
|
// Count servers by category
|
|
259
266
|
for (const server of this.servers.values()) {
|
|
260
|
-
const category = server.category ||
|
|
267
|
+
const category = server.category || "uncategorized";
|
|
261
268
|
serversByCategory[category] = (serversByCategory[category] || 0) + 1;
|
|
262
269
|
}
|
|
263
270
|
return {
|
|
264
271
|
totalServers: this.servers.size,
|
|
265
|
-
totalTools: new Set(Array.from(this.tools.values()).map(r => r.qualifiedName)).size,
|
|
272
|
+
totalTools: new Set(Array.from(this.tools.values()).map((r) => r.qualifiedName)).size,
|
|
266
273
|
toolsByCategory,
|
|
267
274
|
serversByCategory,
|
|
268
275
|
executionCount: this.executionCount,
|
|
269
|
-
averageExecutionTime: this.executionCount > 0
|
|
270
|
-
|
|
276
|
+
averageExecutionTime: this.executionCount > 0
|
|
277
|
+
? this.totalExecutionTime / this.executionCount
|
|
278
|
+
: 0,
|
|
279
|
+
errorRate: this.executionCount > 0 ? this.errorCount / this.executionCount : 0,
|
|
271
280
|
};
|
|
272
281
|
}
|
|
273
282
|
/**
|
|
@@ -293,7 +302,7 @@ export class MCPToolRegistry {
|
|
|
293
302
|
}
|
|
294
303
|
// Remove the server
|
|
295
304
|
this.servers.delete(serverId);
|
|
296
|
-
|
|
305
|
+
registryLogger.debug(`Unregistered server '${serverId}' and ${toolsToRemove.length} tools`);
|
|
297
306
|
return true;
|
|
298
307
|
}
|
|
299
308
|
/**
|
|
@@ -305,7 +314,7 @@ export class MCPToolRegistry {
|
|
|
305
314
|
this.executionCount = 0;
|
|
306
315
|
this.totalExecutionTime = 0;
|
|
307
316
|
this.errorCount = 0;
|
|
308
|
-
|
|
317
|
+
registryLogger.debug("Cleared all servers and tools");
|
|
309
318
|
}
|
|
310
319
|
/**
|
|
311
320
|
* Create timeout promise wrapper
|
|
@@ -320,7 +329,7 @@ export class MCPToolRegistry {
|
|
|
320
329
|
promise,
|
|
321
330
|
new Promise((_, reject) => {
|
|
322
331
|
setTimeout(() => reject(new Error(timeoutMessage)), timeoutMs);
|
|
323
|
-
})
|
|
332
|
+
}),
|
|
324
333
|
]);
|
|
325
334
|
}
|
|
326
335
|
/**
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* AI-focused MCP tools for usage analysis, performance benchmarking, and parameter optimization
|
|
4
4
|
* Tools: analyze-ai-usage, benchmark-provider-performance, optimize-prompt-parameters
|
|
5
5
|
*/
|
|
6
|
-
import type { NeuroLinkMCPTool } from
|
|
6
|
+
import type { NeuroLinkMCPTool } from "../../factory.js";
|
|
7
7
|
/**
|
|
8
8
|
* AI Usage Analysis Tool
|
|
9
9
|
* Analyzes AI usage patterns, token consumption, and cost optimization opportunities
|
|
@@ -3,46 +3,88 @@
|
|
|
3
3
|
* AI-focused MCP tools for usage analysis, performance benchmarking, and parameter optimization
|
|
4
4
|
* Tools: analyze-ai-usage, benchmark-provider-performance, optimize-prompt-parameters
|
|
5
5
|
*/
|
|
6
|
-
import { z } from
|
|
7
|
-
import { AIProviderFactory } from
|
|
8
|
-
import { getBestProvider, getAvailableProviders } from
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
import { AIProviderFactory } from "../../../core/factory.js";
|
|
8
|
+
import { getBestProvider, getAvailableProviders, } from "../../../utils/providerUtils.js";
|
|
9
9
|
/**
|
|
10
10
|
* Input Schemas for AI Analysis Tools
|
|
11
11
|
*/
|
|
12
12
|
const AnalyzeUsageSchema = z.object({
|
|
13
13
|
sessionId: z.string().optional(),
|
|
14
|
-
timeRange: z.enum([
|
|
15
|
-
provider: z
|
|
14
|
+
timeRange: z.enum(["1h", "24h", "7d", "30d"]).default("24h"),
|
|
15
|
+
provider: z
|
|
16
|
+
.enum([
|
|
17
|
+
"openai",
|
|
18
|
+
"bedrock",
|
|
19
|
+
"vertex",
|
|
20
|
+
"anthropic",
|
|
21
|
+
"google-ai",
|
|
22
|
+
"azure",
|
|
23
|
+
"huggingface",
|
|
24
|
+
"ollama",
|
|
25
|
+
"mistral",
|
|
26
|
+
])
|
|
27
|
+
.optional(),
|
|
16
28
|
includeTokenBreakdown: z.boolean().default(true),
|
|
17
|
-
includeCostEstimation: z.boolean().default(true)
|
|
29
|
+
includeCostEstimation: z.boolean().default(true),
|
|
18
30
|
});
|
|
19
31
|
const BenchmarkSchema = z.object({
|
|
20
|
-
providers: z
|
|
32
|
+
providers: z
|
|
33
|
+
.array(z.enum([
|
|
34
|
+
"openai",
|
|
35
|
+
"bedrock",
|
|
36
|
+
"vertex",
|
|
37
|
+
"anthropic",
|
|
38
|
+
"google-ai",
|
|
39
|
+
"azure",
|
|
40
|
+
"huggingface",
|
|
41
|
+
"ollama",
|
|
42
|
+
"mistral",
|
|
43
|
+
]))
|
|
44
|
+
.optional(),
|
|
21
45
|
testPrompts: z.array(z.string()).optional(),
|
|
22
46
|
iterations: z.number().min(1).max(5).default(2),
|
|
23
|
-
metrics: z
|
|
24
|
-
|
|
47
|
+
metrics: z
|
|
48
|
+
.array(z.enum(["latency", "quality", "cost", "tokens"]))
|
|
49
|
+
.default(["latency", "quality"]),
|
|
50
|
+
maxTokens: z.number().positive().default(100),
|
|
25
51
|
});
|
|
26
52
|
const OptimizeParametersSchema = z.object({
|
|
27
|
-
prompt: z.string().min(1,
|
|
28
|
-
provider: z
|
|
53
|
+
prompt: z.string().min(1, "Prompt is required for optimization"),
|
|
54
|
+
provider: z
|
|
55
|
+
.enum([
|
|
56
|
+
"openai",
|
|
57
|
+
"bedrock",
|
|
58
|
+
"vertex",
|
|
59
|
+
"anthropic",
|
|
60
|
+
"google-ai",
|
|
61
|
+
"azure",
|
|
62
|
+
"huggingface",
|
|
63
|
+
"ollama",
|
|
64
|
+
"mistral",
|
|
65
|
+
])
|
|
66
|
+
.optional(),
|
|
29
67
|
targetLength: z.number().positive().optional(),
|
|
30
|
-
style: z
|
|
31
|
-
|
|
32
|
-
|
|
68
|
+
style: z
|
|
69
|
+
.enum(["creative", "balanced", "precise", "factual"])
|
|
70
|
+
.default("balanced"),
|
|
71
|
+
optimizeFor: z
|
|
72
|
+
.enum(["speed", "quality", "cost", "tokens"])
|
|
73
|
+
.default("quality"),
|
|
74
|
+
iterations: z.number().min(1).max(3).default(2),
|
|
33
75
|
});
|
|
34
76
|
/**
|
|
35
77
|
* AI Usage Analysis Tool
|
|
36
78
|
* Analyzes AI usage patterns, token consumption, and cost optimization opportunities
|
|
37
79
|
*/
|
|
38
80
|
export const analyzeAIUsageTool = {
|
|
39
|
-
name:
|
|
40
|
-
description:
|
|
41
|
-
category:
|
|
81
|
+
name: "analyze-ai-usage",
|
|
82
|
+
description: "Analyze AI usage patterns, token consumption, and cost optimization opportunities",
|
|
83
|
+
category: "ai-analysis",
|
|
42
84
|
inputSchema: AnalyzeUsageSchema,
|
|
43
85
|
isImplemented: true,
|
|
44
|
-
permissions: [
|
|
45
|
-
version:
|
|
86
|
+
permissions: ["read", "analytics"],
|
|
87
|
+
version: "1.2.0", // Updated version with real AI
|
|
46
88
|
execute: async (params, context) => {
|
|
47
89
|
const startTime = Date.now();
|
|
48
90
|
try {
|
|
@@ -55,68 +97,105 @@ export const analyzeAIUsageTool = {
|
|
|
55
97
|
const analysisPrompt = `
|
|
56
98
|
Analyze hypothetical AI usage data for a project based on the following parameters.
|
|
57
99
|
Time Range: ${params.timeRange}
|
|
58
|
-
Provider Focus: ${params.provider ||
|
|
100
|
+
Provider Focus: ${params.provider || "all"}
|
|
59
101
|
|
|
60
102
|
Generate a realistic analysis including:
|
|
61
103
|
1. A summary of usage statistics (totalRequests, totalTokens).
|
|
62
|
-
2. A breakdown of usage by provider (OpenAI, Bedrock, Vertex).
|
|
104
|
+
2. A breakdown of usage by provider (OpenAI, Bedrock, Vertex, Google AI, Anthropic, Azure, Hugging Face, Ollama, Mistral).
|
|
63
105
|
3. Key insights and actionable recommendations for cost and performance optimization.
|
|
64
106
|
|
|
65
107
|
Return the result as a valid JSON object with keys: "analysis", "insights".
|
|
66
108
|
- "analysis" should contain: timeRange, totalRequests, totalTokens, and a "providers" object.
|
|
67
109
|
- "insights" should contain: mostUsedProvider, avgCostPerToken, peakUsageHours, costOptimizationPotential, and an array of "recommendations".
|
|
68
110
|
`;
|
|
69
|
-
const result = await provider.generateText({
|
|
111
|
+
const result = await provider.generateText({
|
|
112
|
+
prompt: analysisPrompt,
|
|
113
|
+
maxTokens: 800,
|
|
114
|
+
temperature: 0.5,
|
|
115
|
+
});
|
|
70
116
|
if (!result || !result.text) {
|
|
71
|
-
throw new Error(
|
|
117
|
+
throw new Error("AI provider returned no result for usage analysis.");
|
|
72
118
|
}
|
|
73
119
|
const parsedData = JSON.parse(result.text);
|
|
74
120
|
const executionTime = Date.now() - startTime;
|
|
75
121
|
return {
|
|
76
122
|
success: true,
|
|
77
|
-
data: {
|
|
78
|
-
|
|
79
|
-
|
|
123
|
+
data: {
|
|
124
|
+
...parsedData,
|
|
125
|
+
generatedAt: new Date().toISOString(),
|
|
126
|
+
sessionId: context.sessionId,
|
|
127
|
+
},
|
|
128
|
+
usage: {
|
|
129
|
+
...result.usage,
|
|
130
|
+
executionTime,
|
|
131
|
+
provider: providerName,
|
|
132
|
+
model: "analysis-engine",
|
|
133
|
+
},
|
|
134
|
+
metadata: {
|
|
135
|
+
toolName: "analyze-ai-usage",
|
|
136
|
+
serverId: "neurolink-ai-core",
|
|
137
|
+
sessionId: context.sessionId,
|
|
138
|
+
timestamp: Date.now(),
|
|
139
|
+
executionTime,
|
|
140
|
+
},
|
|
80
141
|
};
|
|
81
142
|
}
|
|
82
143
|
catch (error) {
|
|
83
144
|
const executionTime = Date.now() - startTime;
|
|
84
145
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
85
|
-
return {
|
|
146
|
+
return {
|
|
147
|
+
success: false,
|
|
148
|
+
error: errorMessage,
|
|
149
|
+
metadata: {
|
|
150
|
+
toolName: "analyze-ai-usage",
|
|
151
|
+
serverId: "neurolink-ai-core",
|
|
152
|
+
sessionId: context.sessionId,
|
|
153
|
+
timestamp: Date.now(),
|
|
154
|
+
executionTime,
|
|
155
|
+
},
|
|
156
|
+
};
|
|
86
157
|
}
|
|
87
|
-
}
|
|
158
|
+
},
|
|
88
159
|
};
|
|
89
160
|
/**
|
|
90
161
|
* Provider Performance Benchmarking Tool
|
|
91
162
|
* Benchmarks AI provider performance across latency, quality, and cost metrics
|
|
92
163
|
*/
|
|
93
164
|
export const benchmarkProviderPerformanceTool = {
|
|
94
|
-
name:
|
|
95
|
-
description:
|
|
96
|
-
category:
|
|
165
|
+
name: "benchmark-provider-performance",
|
|
166
|
+
description: "Benchmark AI provider performance across latency, quality, and cost metrics",
|
|
167
|
+
category: "ai-analysis",
|
|
97
168
|
inputSchema: BenchmarkSchema,
|
|
98
169
|
isImplemented: true,
|
|
99
|
-
permissions: [
|
|
100
|
-
version:
|
|
170
|
+
permissions: ["read", "benchmark"],
|
|
171
|
+
version: "1.1.0", // Updated version with real AI
|
|
101
172
|
execute: async (params, context) => {
|
|
102
173
|
const startTime = Date.now();
|
|
103
174
|
try {
|
|
104
175
|
const providersToTest = params.providers || getAvailableProviders();
|
|
105
|
-
const testPrompts = params.testPrompts || [
|
|
176
|
+
const testPrompts = params.testPrompts || [
|
|
177
|
+
"Explain quantum computing in simple terms",
|
|
178
|
+
];
|
|
106
179
|
const benchmarkResults = [];
|
|
107
180
|
for (const providerName of providersToTest) {
|
|
108
181
|
const provider = await AIProviderFactory.createProvider(providerName);
|
|
109
182
|
if (!provider) {
|
|
110
|
-
benchmarkResults.push({
|
|
183
|
+
benchmarkResults.push({
|
|
184
|
+
provider: providerName,
|
|
185
|
+
error: "Failed to create provider.",
|
|
186
|
+
});
|
|
111
187
|
continue;
|
|
112
188
|
}
|
|
113
189
|
let totalLatency = 0, totalTokens = 0, successfulTests = 0;
|
|
114
190
|
for (const prompt of testPrompts) {
|
|
115
191
|
for (let i = 0; i < params.iterations; i++) {
|
|
116
192
|
const testStartTime = Date.now();
|
|
117
|
-
const result = await provider.generateText({
|
|
193
|
+
const result = await provider.generateText({
|
|
194
|
+
prompt,
|
|
195
|
+
maxTokens: params.maxTokens,
|
|
196
|
+
});
|
|
118
197
|
if (result && result.usage) {
|
|
119
|
-
totalLatency +=
|
|
198
|
+
totalLatency += Date.now() - testStartTime;
|
|
120
199
|
totalTokens += result.usage.totalTokens || 0;
|
|
121
200
|
successfulTests++;
|
|
122
201
|
}
|
|
@@ -125,91 +204,151 @@ export const benchmarkProviderPerformanceTool = {
|
|
|
125
204
|
benchmarkResults.push({
|
|
126
205
|
provider: providerName,
|
|
127
206
|
metrics: {
|
|
128
|
-
avgLatency: successfulTests > 0
|
|
207
|
+
avgLatency: successfulTests > 0
|
|
208
|
+
? Math.round(totalLatency / successfulTests)
|
|
209
|
+
: 0,
|
|
129
210
|
totalTokens: totalTokens,
|
|
130
|
-
successRate: successfulTests / (testPrompts.length * params.iterations) *
|
|
131
|
-
|
|
211
|
+
successRate: (successfulTests / (testPrompts.length * params.iterations)) *
|
|
212
|
+
100,
|
|
213
|
+
},
|
|
132
214
|
});
|
|
133
215
|
}
|
|
134
216
|
const executionTime = Date.now() - startTime;
|
|
135
217
|
return {
|
|
136
218
|
success: true,
|
|
137
|
-
data: {
|
|
138
|
-
|
|
139
|
-
|
|
219
|
+
data: {
|
|
220
|
+
results: benchmarkResults,
|
|
221
|
+
benchmarkedAt: new Date().toISOString(),
|
|
222
|
+
},
|
|
223
|
+
usage: {
|
|
224
|
+
executionTime,
|
|
225
|
+
provider: "benchmark-engine",
|
|
226
|
+
model: "multi-provider",
|
|
227
|
+
},
|
|
228
|
+
metadata: {
|
|
229
|
+
toolName: "benchmark-provider-performance",
|
|
230
|
+
serverId: "neurolink-ai-core",
|
|
231
|
+
sessionId: context.sessionId,
|
|
232
|
+
timestamp: Date.now(),
|
|
233
|
+
executionTime,
|
|
234
|
+
},
|
|
140
235
|
};
|
|
141
236
|
}
|
|
142
237
|
catch (error) {
|
|
143
238
|
const executionTime = Date.now() - startTime;
|
|
144
239
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
145
|
-
return {
|
|
240
|
+
return {
|
|
241
|
+
success: false,
|
|
242
|
+
error: errorMessage,
|
|
243
|
+
metadata: {
|
|
244
|
+
toolName: "benchmark-provider-performance",
|
|
245
|
+
serverId: "neurolink-ai-core",
|
|
246
|
+
sessionId: context.sessionId,
|
|
247
|
+
timestamp: Date.now(),
|
|
248
|
+
executionTime,
|
|
249
|
+
},
|
|
250
|
+
};
|
|
146
251
|
}
|
|
147
|
-
}
|
|
252
|
+
},
|
|
148
253
|
};
|
|
149
254
|
/**
|
|
150
255
|
* Prompt Parameter Optimization Tool
|
|
151
256
|
* Optimizes prompt parameters (temperature, max tokens) for better AI output quality and efficiency
|
|
152
257
|
*/
|
|
153
258
|
export const optimizePromptParametersTool = {
|
|
154
|
-
name:
|
|
155
|
-
description:
|
|
156
|
-
category:
|
|
259
|
+
name: "optimize-prompt-parameters",
|
|
260
|
+
description: "Optimize prompt parameters (temperature, max tokens) for better AI output quality and efficiency",
|
|
261
|
+
category: "ai-optimization",
|
|
157
262
|
inputSchema: OptimizeParametersSchema,
|
|
158
263
|
isImplemented: true,
|
|
159
|
-
permissions: [
|
|
160
|
-
version:
|
|
264
|
+
permissions: ["read", "optimize"],
|
|
265
|
+
version: "1.1.0", // Updated version with real AI
|
|
161
266
|
execute: async (params, context) => {
|
|
162
267
|
const startTime = Date.now();
|
|
163
268
|
try {
|
|
164
|
-
const providerName = params.provider || await getBestProvider();
|
|
269
|
+
const providerName = params.provider || (await getBestProvider());
|
|
165
270
|
const provider = await AIProviderFactory.createProvider(providerName);
|
|
166
|
-
if (!provider)
|
|
271
|
+
if (!provider) {
|
|
167
272
|
throw new Error(`Failed to create provider: ${providerName}`);
|
|
273
|
+
}
|
|
168
274
|
const optimizationResults = [];
|
|
169
275
|
const temperatures = [0.2, 0.7, 1.0]; // Test a range of temperatures
|
|
170
276
|
for (const temp of temperatures) {
|
|
171
|
-
const result = await provider.generateText({
|
|
277
|
+
const result = await provider.generateText({
|
|
278
|
+
prompt: params.prompt,
|
|
279
|
+
temperature: temp,
|
|
280
|
+
maxTokens: params.targetLength || 250,
|
|
281
|
+
});
|
|
172
282
|
if (result) {
|
|
173
283
|
optimizationResults.push({
|
|
174
284
|
parameters: { temperature: temp },
|
|
175
285
|
output: result.text,
|
|
176
|
-
usage: result.usage
|
|
286
|
+
usage: result.usage,
|
|
177
287
|
});
|
|
178
288
|
}
|
|
179
289
|
}
|
|
180
290
|
const analysisProvider = await AIProviderFactory.createProvider(await getBestProvider());
|
|
181
|
-
if (!analysisProvider)
|
|
182
|
-
throw new Error(
|
|
291
|
+
if (!analysisProvider) {
|
|
292
|
+
throw new Error("Failed to create analysis provider.");
|
|
293
|
+
}
|
|
183
294
|
const analysisPrompt = `
|
|
184
295
|
Analyze the following AI-generated responses for the prompt "${params.prompt}" based on the optimization goal of "${params.optimizeFor}".
|
|
185
296
|
|
|
186
297
|
Responses:
|
|
187
|
-
${optimizationResults.map((r, i) => `Response ${i + 1} (Temp: ${r.parameters.temperature}):\n${r.output}`).join(
|
|
298
|
+
${optimizationResults.map((r, i) => `Response ${i + 1} (Temp: ${r.parameters.temperature}):\n${r.output}`).join("\n\n")}
|
|
188
299
|
|
|
189
300
|
Determine which set of parameters is optimal and provide a recommendation.
|
|
190
301
|
Return a valid JSON object with keys: "optimalParameters", "reasoning", "recommendations".
|
|
191
302
|
`;
|
|
192
|
-
const analysisResult = await analysisProvider.generateText({
|
|
193
|
-
|
|
194
|
-
|
|
303
|
+
const analysisResult = await analysisProvider.generateText({
|
|
304
|
+
prompt: analysisPrompt,
|
|
305
|
+
maxTokens: 500,
|
|
306
|
+
});
|
|
307
|
+
if (!analysisResult || !analysisResult.text) {
|
|
308
|
+
throw new Error("Optimization analysis failed.");
|
|
309
|
+
}
|
|
195
310
|
const parsedAnalysis = JSON.parse(analysisResult.text);
|
|
196
311
|
const executionTime = Date.now() - startTime;
|
|
197
312
|
return {
|
|
198
313
|
success: true,
|
|
199
314
|
data: {
|
|
200
|
-
optimization: {
|
|
315
|
+
optimization: {
|
|
316
|
+
originalPrompt: params.prompt,
|
|
317
|
+
optimizeFor: params.optimizeFor,
|
|
318
|
+
provider: providerName,
|
|
319
|
+
},
|
|
201
320
|
results: optimizationResults,
|
|
202
321
|
recommendations: parsedAnalysis,
|
|
203
|
-
optimizedAt: new Date().toISOString()
|
|
322
|
+
optimizedAt: new Date().toISOString(),
|
|
323
|
+
},
|
|
324
|
+
usage: {
|
|
325
|
+
executionTime,
|
|
326
|
+
provider: "optimization-engine",
|
|
327
|
+
model: "multi-provider",
|
|
328
|
+
},
|
|
329
|
+
metadata: {
|
|
330
|
+
toolName: "optimize-prompt-parameters",
|
|
331
|
+
serverId: "neurolink-ai-core",
|
|
332
|
+
sessionId: context.sessionId,
|
|
333
|
+
timestamp: Date.now(),
|
|
334
|
+
executionTime,
|
|
204
335
|
},
|
|
205
|
-
usage: { executionTime, provider: 'optimization-engine', model: 'multi-provider' },
|
|
206
|
-
metadata: { toolName: 'optimize-prompt-parameters', serverId: 'neurolink-ai-core', sessionId: context.sessionId, timestamp: Date.now(), executionTime }
|
|
207
336
|
};
|
|
208
337
|
}
|
|
209
338
|
catch (error) {
|
|
210
339
|
const executionTime = Date.now() - startTime;
|
|
211
340
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
212
|
-
return {
|
|
341
|
+
return {
|
|
342
|
+
success: false,
|
|
343
|
+
error: errorMessage,
|
|
344
|
+
metadata: {
|
|
345
|
+
toolName: "optimize-prompt-parameters",
|
|
346
|
+
serverId: "neurolink-ai-core",
|
|
347
|
+
sessionId: context.sessionId,
|
|
348
|
+
timestamp: Date.now(),
|
|
349
|
+
executionTime,
|
|
350
|
+
},
|
|
351
|
+
};
|
|
213
352
|
}
|
|
214
|
-
}
|
|
353
|
+
},
|
|
215
354
|
};
|