@juspay/neurolink 7.29.1 → 7.29.2
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 +6 -0
- package/dist/cli/commands/config.d.ts +3 -3
- package/dist/cli/commands/mcp.js +25 -0
- package/dist/cli/factories/commandFactory.d.ts +1 -0
- package/dist/cli/factories/commandFactory.js +115 -21
- package/dist/cli/index.js +8 -0
- package/dist/core/factory.js +77 -4
- package/dist/factories/providerFactory.js +3 -0
- package/dist/factories/providerRegistry.js +2 -2
- package/dist/lib/core/factory.js +77 -4
- package/dist/lib/factories/providerFactory.js +3 -0
- package/dist/lib/factories/providerRegistry.js +2 -2
- package/dist/lib/mcp/externalServerManager.js +13 -14
- package/dist/lib/mcp/flexibleToolValidator.d.ts +50 -0
- package/dist/lib/mcp/flexibleToolValidator.js +161 -0
- package/dist/lib/mcp/toolRegistry.d.ts +2 -2
- package/dist/lib/mcp/toolRegistry.js +25 -50
- package/dist/lib/neurolink.d.ts +2 -0
- package/dist/lib/neurolink.js +137 -69
- package/dist/lib/providers/amazonBedrock.d.ts +47 -6
- package/dist/lib/providers/amazonBedrock.js +282 -23
- package/dist/lib/providers/aws/credentialProvider.d.ts +58 -0
- package/dist/lib/providers/aws/credentialProvider.js +267 -0
- package/dist/lib/providers/aws/credentialTester.d.ts +49 -0
- package/dist/lib/providers/aws/credentialTester.js +394 -0
- package/dist/lib/proxy/awsProxyIntegration.d.ts +23 -0
- package/dist/lib/proxy/awsProxyIntegration.js +285 -0
- package/dist/lib/proxy/proxyFetch.d.ts +9 -5
- package/dist/lib/proxy/proxyFetch.js +232 -98
- package/dist/lib/proxy/utils/noProxyUtils.d.ts +39 -0
- package/dist/lib/proxy/utils/noProxyUtils.js +149 -0
- package/dist/lib/types/providers.d.ts +43 -0
- package/dist/lib/utils/providerConfig.d.ts +1 -0
- package/dist/lib/utils/providerConfig.js +2 -1
- package/dist/lib/utils/providerHealth.js +123 -5
- package/dist/mcp/externalServerManager.js +13 -14
- package/dist/mcp/flexibleToolValidator.d.ts +50 -0
- package/dist/mcp/flexibleToolValidator.js +161 -0
- package/dist/mcp/toolRegistry.d.ts +2 -2
- package/dist/mcp/toolRegistry.js +25 -50
- package/dist/neurolink.d.ts +2 -0
- package/dist/neurolink.js +137 -69
- package/dist/providers/amazonBedrock.d.ts +47 -6
- package/dist/providers/amazonBedrock.js +282 -23
- package/dist/providers/aws/credentialProvider.d.ts +58 -0
- package/dist/providers/aws/credentialProvider.js +267 -0
- package/dist/providers/aws/credentialTester.d.ts +49 -0
- package/dist/providers/aws/credentialTester.js +394 -0
- package/dist/proxy/awsProxyIntegration.d.ts +23 -0
- package/dist/proxy/awsProxyIntegration.js +285 -0
- package/dist/proxy/proxyFetch.d.ts +9 -5
- package/dist/proxy/proxyFetch.js +232 -98
- package/dist/proxy/utils/noProxyUtils.d.ts +39 -0
- package/dist/proxy/utils/noProxyUtils.js +149 -0
- package/dist/types/providers.d.ts +43 -0
- package/dist/utils/providerConfig.d.ts +1 -0
- package/dist/utils/providerConfig.js +2 -1
- package/dist/utils/providerHealth.js +123 -5
- package/package.json +5 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlexibleToolValidator - Universal Safety Checks Only
|
|
3
|
+
*
|
|
4
|
+
* Following Anthropic's MCP specification which intentionally leaves tool naming flexible,
|
|
5
|
+
* this validator only blocks truly dangerous cases to support maximum MCP tool compatibility.
|
|
6
|
+
*
|
|
7
|
+
* Phase 1 Implementation:
|
|
8
|
+
* - Universal safety checks only (empty names, control characters, excessive length)
|
|
9
|
+
* - No context-specific validation or arbitrary pattern restrictions
|
|
10
|
+
* - Designed to support ALL legitimate MCP tools (github.create_repo, filesystem.read_file, etc.)
|
|
11
|
+
*/
|
|
12
|
+
export interface FlexibleValidationResult {
|
|
13
|
+
isValid: boolean;
|
|
14
|
+
error?: string;
|
|
15
|
+
warnings?: string[];
|
|
16
|
+
}
|
|
17
|
+
export declare class FlexibleToolValidator {
|
|
18
|
+
private static readonly MAX_TOOL_NAME_LENGTH;
|
|
19
|
+
private static readonly MIN_TOOL_NAME_LENGTH;
|
|
20
|
+
/**
|
|
21
|
+
* Validate tool name with universal safety checks only
|
|
22
|
+
*
|
|
23
|
+
* This method only blocks truly dangerous cases:
|
|
24
|
+
* 1. Empty or whitespace-only names
|
|
25
|
+
* 2. Control characters that could break systems
|
|
26
|
+
* 3. Excessively long names that could cause memory issues
|
|
27
|
+
*
|
|
28
|
+
* Everything else is allowed to support maximum MCP tool compatibility.
|
|
29
|
+
*/
|
|
30
|
+
static validateToolName(toolId: string): FlexibleValidationResult;
|
|
31
|
+
/**
|
|
32
|
+
* Validate tool information with minimal safety checks
|
|
33
|
+
*/
|
|
34
|
+
static validateToolInfo(toolId: string, toolInfo: {
|
|
35
|
+
description?: string;
|
|
36
|
+
serverId?: string;
|
|
37
|
+
}): FlexibleValidationResult;
|
|
38
|
+
/**
|
|
39
|
+
* Get information about what this validator checks
|
|
40
|
+
*/
|
|
41
|
+
static getValidationInfo(): {
|
|
42
|
+
philosophy: string;
|
|
43
|
+
checks: string[];
|
|
44
|
+
whatIsAllowed: string[];
|
|
45
|
+
examples: {
|
|
46
|
+
valid: string[];
|
|
47
|
+
invalid: string[];
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FlexibleToolValidator - Universal Safety Checks Only
|
|
3
|
+
*
|
|
4
|
+
* Following Anthropic's MCP specification which intentionally leaves tool naming flexible,
|
|
5
|
+
* this validator only blocks truly dangerous cases to support maximum MCP tool compatibility.
|
|
6
|
+
*
|
|
7
|
+
* Phase 1 Implementation:
|
|
8
|
+
* - Universal safety checks only (empty names, control characters, excessive length)
|
|
9
|
+
* - No context-specific validation or arbitrary pattern restrictions
|
|
10
|
+
* - Designed to support ALL legitimate MCP tools (github.create_repo, filesystem.read_file, etc.)
|
|
11
|
+
*/
|
|
12
|
+
import { registryLogger } from "../utils/logger.js";
|
|
13
|
+
export class FlexibleToolValidator {
|
|
14
|
+
// Universal safety limits (generous to support all legitimate tools)
|
|
15
|
+
static MAX_TOOL_NAME_LENGTH = 1000; // Much more generous than npm's 214
|
|
16
|
+
static MIN_TOOL_NAME_LENGTH = 1;
|
|
17
|
+
/**
|
|
18
|
+
* Validate tool name with universal safety checks only
|
|
19
|
+
*
|
|
20
|
+
* This method only blocks truly dangerous cases:
|
|
21
|
+
* 1. Empty or whitespace-only names
|
|
22
|
+
* 2. Control characters that could break systems
|
|
23
|
+
* 3. Excessively long names that could cause memory issues
|
|
24
|
+
*
|
|
25
|
+
* Everything else is allowed to support maximum MCP tool compatibility.
|
|
26
|
+
*/
|
|
27
|
+
static validateToolName(toolId) {
|
|
28
|
+
const warnings = [];
|
|
29
|
+
// Safety Check 1: Empty or whitespace-only names
|
|
30
|
+
if (!toolId || typeof toolId !== "string") {
|
|
31
|
+
return {
|
|
32
|
+
isValid: false,
|
|
33
|
+
error: "Tool name is required and must be a string",
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
// Safety Check 2: Control characters that could break systems (check BEFORE trimming!)
|
|
37
|
+
// Only block truly dangerous control characters, not printable characters
|
|
38
|
+
//
|
|
39
|
+
// This regex blocks dangerous C0 control characters and DEL:
|
|
40
|
+
// - \x00-\x08: NULL, SOH, STX, ETX, EOT, ENQ, ACK, BEL, BS
|
|
41
|
+
// - \x0B: Vertical Tab (VT)
|
|
42
|
+
// - \x0C: Form Feed (FF)
|
|
43
|
+
// - \x0E-\x1F: SO, SI, DLE, DC1-4, NAK, SYN, ETB, CAN, EM, SUB, ESC, FS-US
|
|
44
|
+
// - \x7F: DEL
|
|
45
|
+
//
|
|
46
|
+
// Explicitly ALLOWS these printable control characters:
|
|
47
|
+
// - \x09: TAB (horizontal tab) - commonly used in text
|
|
48
|
+
// - \x0A: LF (line feed) - commonly used in text
|
|
49
|
+
// - \x0D: CR (carriage return) - commonly used in text
|
|
50
|
+
// eslint-disable-next-line no-control-regex
|
|
51
|
+
const hasControlCharacters = /[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/.test(toolId);
|
|
52
|
+
if (hasControlCharacters) {
|
|
53
|
+
return {
|
|
54
|
+
isValid: false,
|
|
55
|
+
error: "Tool name contains control characters that could break systems",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const trimmedName = toolId.trim();
|
|
59
|
+
if (trimmedName.length === 0) {
|
|
60
|
+
return {
|
|
61
|
+
isValid: false,
|
|
62
|
+
error: "Tool name cannot be empty or whitespace-only",
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Safety Check 3: Length limits (very generous)
|
|
66
|
+
if (trimmedName.length < this.MIN_TOOL_NAME_LENGTH) {
|
|
67
|
+
return {
|
|
68
|
+
isValid: false,
|
|
69
|
+
error: `Tool name must be at least ${this.MIN_TOOL_NAME_LENGTH} character long`,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (trimmedName.length > this.MAX_TOOL_NAME_LENGTH) {
|
|
73
|
+
return {
|
|
74
|
+
isValid: false,
|
|
75
|
+
error: `Tool name exceeds maximum length of ${this.MAX_TOOL_NAME_LENGTH} characters`,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Optional warnings for unusual but not dangerous patterns
|
|
79
|
+
if (trimmedName !== toolId) {
|
|
80
|
+
warnings.push("Tool name has leading/trailing whitespace (will be trimmed)");
|
|
81
|
+
}
|
|
82
|
+
if (trimmedName.length > 200) {
|
|
83
|
+
warnings.push("Tool name is unusually long but allowed");
|
|
84
|
+
}
|
|
85
|
+
registryLogger.debug(`✅ FlexibleToolValidator: Tool '${toolId}' passed universal safety checks`);
|
|
86
|
+
return {
|
|
87
|
+
isValid: true,
|
|
88
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Validate tool information with minimal safety checks
|
|
93
|
+
*/
|
|
94
|
+
static validateToolInfo(toolId, toolInfo) {
|
|
95
|
+
// First validate the tool name
|
|
96
|
+
const nameValidation = this.validateToolName(toolId);
|
|
97
|
+
if (!nameValidation.isValid) {
|
|
98
|
+
return nameValidation;
|
|
99
|
+
}
|
|
100
|
+
const warnings = [...(nameValidation.warnings || [])];
|
|
101
|
+
// Minimal safety checks for tool info
|
|
102
|
+
if (toolInfo.description && typeof toolInfo.description !== "string") {
|
|
103
|
+
return {
|
|
104
|
+
isValid: false,
|
|
105
|
+
error: "Tool description must be a string if provided",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
if (toolInfo.serverId && typeof toolInfo.serverId !== "string") {
|
|
109
|
+
return {
|
|
110
|
+
isValid: false,
|
|
111
|
+
error: "Tool serverId must be a string if provided",
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
registryLogger.debug(`✅ FlexibleToolValidator: Tool info for '${toolId}' passed validation`);
|
|
115
|
+
return {
|
|
116
|
+
isValid: true,
|
|
117
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Get information about what this validator checks
|
|
122
|
+
*/
|
|
123
|
+
static getValidationInfo() {
|
|
124
|
+
return {
|
|
125
|
+
philosophy: "Maximum flexibility with universal safety only - following Anthropic's MCP specification",
|
|
126
|
+
checks: [
|
|
127
|
+
"Empty or whitespace-only names",
|
|
128
|
+
"Excessive length (over 1000 characters)",
|
|
129
|
+
"Control characters that could break systems",
|
|
130
|
+
],
|
|
131
|
+
whatIsAllowed: [
|
|
132
|
+
"Dots (github.create_repo, filesystem.read_file)",
|
|
133
|
+
"Hyphens and underscores (my-tool, user_helper)",
|
|
134
|
+
"Numbers (tool1, my_tool_v2)",
|
|
135
|
+
"Unicode characters (🚀_tool, café_manager)",
|
|
136
|
+
"Mixed case (createRepo, ReadFile)",
|
|
137
|
+
"Long descriptive names (enterprise_database_connection_manager)",
|
|
138
|
+
"Any legitimate MCP tool naming pattern",
|
|
139
|
+
],
|
|
140
|
+
examples: {
|
|
141
|
+
valid: [
|
|
142
|
+
"github.create_repo",
|
|
143
|
+
"filesystem.read_file",
|
|
144
|
+
"my-custom-tool",
|
|
145
|
+
"user_helper",
|
|
146
|
+
"tool1",
|
|
147
|
+
"🚀_rocket_tool",
|
|
148
|
+
"enterprise.database.connection.manager",
|
|
149
|
+
"UPPERCASE_TOOL",
|
|
150
|
+
"mixed_Case.Tool-Name_123",
|
|
151
|
+
],
|
|
152
|
+
invalid: [
|
|
153
|
+
"", // Empty
|
|
154
|
+
" ", // Whitespace only
|
|
155
|
+
"tool\x00", // Control character
|
|
156
|
+
"a".repeat(1001), // Too long
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -29,7 +29,7 @@ export interface ToolExecutionOptions {
|
|
|
29
29
|
}
|
|
30
30
|
export declare class MCPToolRegistry extends MCPRegistry {
|
|
31
31
|
private tools;
|
|
32
|
-
private
|
|
32
|
+
private toolImplementations;
|
|
33
33
|
private toolExecutionStats;
|
|
34
34
|
private builtInServerInfos;
|
|
35
35
|
constructor();
|
|
@@ -122,7 +122,7 @@ export declare class MCPToolRegistry extends MCPRegistry {
|
|
|
122
122
|
* Register a tool with implementation directly
|
|
123
123
|
* This is used for external MCP server tools
|
|
124
124
|
*/
|
|
125
|
-
registerTool(toolId: string, toolInfo: ToolInfo, toolImpl: ToolImplementation): void
|
|
125
|
+
registerTool(toolId: string, toolInfo: ToolInfo, toolImpl: ToolImplementation): Promise<void>;
|
|
126
126
|
/**
|
|
127
127
|
* Remove a tool
|
|
128
128
|
*/
|
|
@@ -8,9 +8,10 @@ import { randomUUID } from "crypto";
|
|
|
8
8
|
import { shouldDisableBuiltinTools } from "../utils/toolUtils.js";
|
|
9
9
|
import { directAgentTools } from "../agent/directTools.js";
|
|
10
10
|
import { detectCategory, createMCPServerInfo } from "../utils/mcpDefaults.js";
|
|
11
|
+
import { FlexibleToolValidator } from "./flexibleToolValidator.js";
|
|
11
12
|
export class MCPToolRegistry extends MCPRegistry {
|
|
12
13
|
tools = new Map();
|
|
13
|
-
|
|
14
|
+
toolImplementations = new Map(); // Store actual tool implementations
|
|
14
15
|
toolExecutionStats = new Map();
|
|
15
16
|
builtInServerInfos = []; // DIRECT storage for MCPServerInfo
|
|
16
17
|
constructor() {
|
|
@@ -38,7 +39,7 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
38
39
|
category: detectCategory({ isBuiltIn: true, serverId: "direct" }),
|
|
39
40
|
};
|
|
40
41
|
this.tools.set(toolId, toolInfo);
|
|
41
|
-
this.
|
|
42
|
+
this.toolImplementations.set(toolId, {
|
|
42
43
|
execute: async (params, context) => {
|
|
43
44
|
try {
|
|
44
45
|
// Direct tools from AI SDK expect their specific parameter structure
|
|
@@ -153,7 +154,7 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
153
154
|
// Register only with fully-qualified toolId to avoid collisions
|
|
154
155
|
this.tools.set(toolId, toolInfo);
|
|
155
156
|
// Store the actual tool implementation for execution using toolId as key
|
|
156
|
-
this.
|
|
157
|
+
this.toolImplementations.set(toolId, {
|
|
157
158
|
execute: tool.execute ||
|
|
158
159
|
(async () => {
|
|
159
160
|
throw new Error(`Tool ${tool.name} has no execute function`);
|
|
@@ -234,9 +235,9 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
234
235
|
...context,
|
|
235
236
|
};
|
|
236
237
|
// Get the tool implementation using the resolved toolId
|
|
237
|
-
const toolImpl = this.
|
|
238
|
+
const toolImpl = this.toolImplementations.get(toolId);
|
|
238
239
|
registryLogger.debug(`Looking for tool '${toolName}' (toolId: '${toolId}'), found: ${!!toolImpl}, type: ${typeof toolImpl?.execute}`);
|
|
239
|
-
registryLogger.debug(`Available tools:`, Array.from(this.
|
|
240
|
+
registryLogger.debug(`Available tools:`, Array.from(this.toolImplementations.keys()));
|
|
240
241
|
if (!toolImpl || typeof toolImpl?.execute !== "function") {
|
|
241
242
|
throw new Error(`Tool '${toolName}' implementation not found or not executable`);
|
|
242
243
|
}
|
|
@@ -450,55 +451,25 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
450
451
|
* Register a tool with implementation directly
|
|
451
452
|
* This is used for external MCP server tools
|
|
452
453
|
*/
|
|
453
|
-
registerTool(toolId, toolInfo, toolImpl) {
|
|
454
|
+
async registerTool(toolId, toolInfo, toolImpl) {
|
|
454
455
|
registryLogger.debug(`Registering tool: ${toolId}`);
|
|
455
|
-
//
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
(
|
|
463
|
-
|
|
464
|
-
}
|
|
465
|
-
catch (error) {
|
|
466
|
-
// Fallback: skip validation if import fails (graceful degradation)
|
|
467
|
-
registryLogger.warn("Tool validation module not available, skipping advanced validation", {
|
|
468
|
-
error: error instanceof Error ? error.message : String(error),
|
|
469
|
-
});
|
|
470
|
-
// Create minimal validation functions
|
|
471
|
-
validateTool = () => { }; // No-op
|
|
472
|
-
isToolNameAvailable = () => true; // Allow all names
|
|
473
|
-
suggestToolNames = () => ["alternative_tool"];
|
|
474
|
-
}
|
|
475
|
-
// Check if tool name is available (not reserved)
|
|
476
|
-
if (!isToolNameAvailable(toolId)) {
|
|
477
|
-
const suggestions = suggestToolNames(toolId);
|
|
478
|
-
registryLogger.error(`Tool registration failed for ${toolId}: Name not available`);
|
|
479
|
-
throw new Error(`Tool name '${toolId}' is not available (reserved or invalid format). ` +
|
|
480
|
-
`Suggested alternatives: ${suggestions.slice(0, 3).join(", ")}`);
|
|
456
|
+
// Universal safety validation using FlexibleToolValidator
|
|
457
|
+
// Only blocks truly dangerous cases to support maximum MCP tool compatibility
|
|
458
|
+
const validation = FlexibleToolValidator.validateToolInfo(toolId, {
|
|
459
|
+
description: toolInfo.description,
|
|
460
|
+
serverId: toolInfo.serverId,
|
|
461
|
+
});
|
|
462
|
+
if (!validation.isValid) {
|
|
463
|
+
registryLogger.error(`Tool registration failed for ${toolId}: ${validation.error}`);
|
|
464
|
+
throw new Error(`Tool validation failed: ${validation.error}`);
|
|
481
465
|
}
|
|
482
|
-
//
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
execute: async () => "",
|
|
486
|
-
parameters: undefined,
|
|
487
|
-
metadata: {
|
|
488
|
-
category: toolInfo.category,
|
|
489
|
-
serverId: toolInfo.serverId,
|
|
490
|
-
},
|
|
491
|
-
};
|
|
492
|
-
// Use comprehensive validation logic
|
|
493
|
-
try {
|
|
494
|
-
validateTool(toolId, toolForValidation);
|
|
495
|
-
}
|
|
496
|
-
catch (error) {
|
|
497
|
-
registryLogger.error(`Tool registration failed for ${toolId}:`, error instanceof Error ? error.message : String(error));
|
|
498
|
-
throw error;
|
|
466
|
+
// Log any warnings but allow registration to proceed
|
|
467
|
+
if (validation.warnings && validation.warnings.length > 0) {
|
|
468
|
+
registryLogger.warn(`Tool registration warnings for ${toolId}:`, validation.warnings);
|
|
499
469
|
}
|
|
470
|
+
registryLogger.debug(`✅ Tool '${toolId}' passed flexible validation - registration proceeding`);
|
|
500
471
|
this.tools.set(toolId, toolInfo);
|
|
501
|
-
this.
|
|
472
|
+
this.toolImplementations.set(toolId, toolImpl);
|
|
502
473
|
registryLogger.debug(`Successfully registered tool: ${toolId}`);
|
|
503
474
|
}
|
|
504
475
|
/**
|
|
@@ -509,6 +480,7 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
509
480
|
let removed = false;
|
|
510
481
|
if (this.tools.has(toolName)) {
|
|
511
482
|
this.tools.delete(toolName);
|
|
483
|
+
this.toolImplementations.delete(toolName); // Fix memory leak
|
|
512
484
|
this.toolExecutionStats.delete(toolName);
|
|
513
485
|
registryLogger.info(`Removed tool: ${toolName}`);
|
|
514
486
|
removed = true;
|
|
@@ -518,6 +490,7 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
518
490
|
for (const [toolId, tool] of Array.from(this.tools.entries())) {
|
|
519
491
|
if (tool.name === toolName) {
|
|
520
492
|
this.tools.delete(toolId);
|
|
493
|
+
this.toolImplementations.delete(toolId); // Fix memory leak
|
|
521
494
|
this.toolExecutionStats.delete(toolId);
|
|
522
495
|
registryLogger.info(`Removed tool: ${toolId}`);
|
|
523
496
|
removed = true;
|
|
@@ -567,6 +540,8 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
|
567
540
|
for (const [toolId, tool] of this.tools.entries()) {
|
|
568
541
|
if (tool.serverId === serverId) {
|
|
569
542
|
this.tools.delete(toolId);
|
|
543
|
+
this.toolImplementations.delete(toolId); // Fix memory leak
|
|
544
|
+
this.toolExecutionStats.delete(toolId); // Fix memory leak
|
|
570
545
|
removedTools.push(toolId);
|
|
571
546
|
}
|
|
572
547
|
}
|
package/dist/lib/neurolink.d.ts
CHANGED
|
@@ -54,6 +54,8 @@ export declare class NeuroLink {
|
|
|
54
54
|
* @param toolName - Name of the tool
|
|
55
55
|
* @param startTime - Timestamp when tool execution started
|
|
56
56
|
* @param success - Whether the tool execution was successful
|
|
57
|
+
* @param result - The result of the tool execution (optional)
|
|
58
|
+
* @param error - The error if execution failed (optional)
|
|
57
59
|
*/
|
|
58
60
|
private emitToolEndEvent;
|
|
59
61
|
private conversationMemory?;
|