@juspay/neurolink 7.38.1 → 7.39.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 +6 -0
- package/dist/hitl/hitlErrors.d.ts +38 -0
- package/dist/hitl/hitlErrors.js +54 -0
- package/dist/hitl/hitlManager.d.ts +100 -0
- package/dist/hitl/hitlManager.js +457 -0
- package/dist/hitl/index.d.ts +8 -0
- package/dist/hitl/index.js +9 -0
- package/dist/hitl/types.d.ts +196 -0
- package/dist/hitl/types.js +8 -0
- package/dist/lib/hitl/hitlErrors.d.ts +38 -0
- package/dist/lib/hitl/hitlErrors.js +54 -0
- package/dist/lib/hitl/hitlManager.d.ts +100 -0
- package/dist/lib/hitl/hitlManager.js +457 -0
- package/dist/lib/hitl/index.d.ts +8 -0
- package/dist/lib/hitl/index.js +9 -0
- package/dist/lib/hitl/types.d.ts +196 -0
- package/dist/lib/hitl/types.js +8 -0
- package/dist/lib/mcp/externalServerManager.d.ts +11 -0
- package/dist/lib/mcp/externalServerManager.js +69 -2
- package/dist/lib/mcp/toolRegistry.d.ts +11 -0
- package/dist/lib/mcp/toolRegistry.js +69 -3
- package/dist/lib/neurolink.d.ts +27 -0
- package/dist/lib/neurolink.js +146 -0
- package/dist/mcp/externalServerManager.d.ts +11 -0
- package/dist/mcp/externalServerManager.js +69 -2
- package/dist/mcp/toolRegistry.d.ts +11 -0
- package/dist/mcp/toolRegistry.js +69 -3
- package/dist/neurolink.d.ts +27 -0
- package/dist/neurolink.js +146 -0
- package/package.json +1 -1
package/dist/mcp/toolRegistry.js
CHANGED
@@ -9,17 +9,38 @@ import { shouldDisableBuiltinTools } from "../utils/toolUtils.js";
|
|
9
9
|
import { directAgentTools } from "../agent/directTools.js";
|
10
10
|
import { detectCategory, createMCPServerInfo } from "../utils/mcpDefaults.js";
|
11
11
|
import { FlexibleToolValidator } from "./flexibleToolValidator.js";
|
12
|
+
import { HITLUserRejectedError, HITLTimeoutError } from "../hitl/hitlErrors.js";
|
12
13
|
export class MCPToolRegistry extends MCPRegistry {
|
13
14
|
tools = new Map();
|
14
15
|
toolImplementations = new Map(); // Store actual tool implementations
|
15
16
|
toolExecutionStats = new Map();
|
16
17
|
builtInServerInfos = []; // DIRECT storage for MCPServerInfo
|
18
|
+
hitlManager; // Optional HITL manager for safety mechanisms
|
17
19
|
constructor() {
|
18
20
|
super();
|
19
21
|
if (!shouldDisableBuiltinTools()) {
|
20
22
|
this.registerDirectTools();
|
21
23
|
}
|
22
24
|
}
|
25
|
+
/**
|
26
|
+
* Set HITL manager for human-in-the-loop safety mechanisms
|
27
|
+
* @param hitlManager - HITL manager instance (optional, can be undefined to disable)
|
28
|
+
*/
|
29
|
+
setHITLManager(hitlManager) {
|
30
|
+
this.hitlManager = hitlManager;
|
31
|
+
if (hitlManager && hitlManager.isEnabled()) {
|
32
|
+
registryLogger.info("HITL safety mechanisms enabled for tool execution");
|
33
|
+
}
|
34
|
+
else {
|
35
|
+
registryLogger.debug("HITL safety mechanisms disabled or not configured");
|
36
|
+
}
|
37
|
+
}
|
38
|
+
/**
|
39
|
+
* Get current HITL manager
|
40
|
+
*/
|
41
|
+
getHITLManager() {
|
42
|
+
return this.hitlManager;
|
43
|
+
}
|
23
44
|
/**
|
24
45
|
* Register all direct tools from directAgentTools
|
25
46
|
*/
|
@@ -237,9 +258,54 @@ export class MCPToolRegistry extends MCPRegistry {
|
|
237
258
|
if (!toolImpl || typeof toolImpl?.execute !== "function") {
|
238
259
|
throw new Error(`Tool '${toolName}' implementation not found or not executable`);
|
239
260
|
}
|
240
|
-
//
|
241
|
-
|
242
|
-
|
261
|
+
// HITL Safety Check: Request confirmation if required
|
262
|
+
let finalArgs = args;
|
263
|
+
if (this.hitlManager && this.hitlManager.isEnabled()) {
|
264
|
+
const requiresConfirmation = this.hitlManager.requiresConfirmation(toolName, args);
|
265
|
+
if (requiresConfirmation) {
|
266
|
+
registryLogger.info(`Tool '${toolName}' requires HITL confirmation`);
|
267
|
+
try {
|
268
|
+
const confirmationResult = await this.hitlManager.requestConfirmation(toolName, args, {
|
269
|
+
serverId: tool.serverId,
|
270
|
+
sessionId: execContext.sessionId,
|
271
|
+
userId: execContext.userId,
|
272
|
+
});
|
273
|
+
if (!confirmationResult.approved) {
|
274
|
+
// User rejected the tool execution
|
275
|
+
throw new HITLUserRejectedError(`Tool execution rejected by user: ${confirmationResult.reason || "No reason provided"}`, toolName, confirmationResult.reason);
|
276
|
+
}
|
277
|
+
// User approved - use modified arguments if provided
|
278
|
+
if (confirmationResult.modifiedArguments !== undefined) {
|
279
|
+
finalArgs = confirmationResult.modifiedArguments;
|
280
|
+
registryLogger.info(`Tool '${toolName}' arguments modified by user`);
|
281
|
+
}
|
282
|
+
registryLogger.info(`Tool '${toolName}' approved for execution (response time: ${confirmationResult.responseTime}ms)`);
|
283
|
+
}
|
284
|
+
catch (error) {
|
285
|
+
if (error instanceof HITLTimeoutError) {
|
286
|
+
// Timeout occurred - user didn't respond in time
|
287
|
+
registryLogger.warn(`Tool '${toolName}' execution timed out waiting for user confirmation`);
|
288
|
+
throw error;
|
289
|
+
}
|
290
|
+
else if (error instanceof HITLUserRejectedError) {
|
291
|
+
// User explicitly rejected
|
292
|
+
registryLogger.info(`Tool '${toolName}' execution rejected by user`);
|
293
|
+
throw error;
|
294
|
+
}
|
295
|
+
else {
|
296
|
+
// Other HITL error (configuration, system error, etc.)
|
297
|
+
registryLogger.error(`HITL confirmation failed for tool '${toolName}':`, error);
|
298
|
+
throw new Error(`HITL confirmation failed: ${error instanceof Error ? error.message : String(error)}`);
|
299
|
+
}
|
300
|
+
}
|
301
|
+
}
|
302
|
+
else {
|
303
|
+
registryLogger.debug(`Tool '${toolName}' does not require HITL confirmation`);
|
304
|
+
}
|
305
|
+
}
|
306
|
+
// Execute the actual tool (with potentially modified arguments)
|
307
|
+
registryLogger.debug(`Executing tool '${toolName}' with args:`, finalArgs);
|
308
|
+
const toolResult = await toolImpl.execute(finalArgs, execContext);
|
243
309
|
// Properly wrap raw results in ToolResult format
|
244
310
|
let result;
|
245
311
|
// Check if result is already a ToolResult object
|
package/dist/neurolink.d.ts
CHANGED
@@ -16,6 +16,7 @@ import type { BatchOperationResult } from "./types/typeAliases.js";
|
|
16
16
|
import type { ConversationMemoryConfig, ChatMessage } from "./types/conversation.js";
|
17
17
|
import { ConversationMemoryManager } from "./core/conversationMemoryManager.js";
|
18
18
|
import { RedisConversationMemoryManager } from "./core/redisConversationMemoryManager.js";
|
19
|
+
import type { HITLConfig } from "./hitl/types.js";
|
19
20
|
import type { ExternalMCPServerInstance, ExternalMCPOperationResult, ExternalMCPToolInfo } from "./types/externalMcp.js";
|
20
21
|
export interface ProviderStatus {
|
21
22
|
provider: string;
|
@@ -68,6 +69,7 @@ export declare class NeuroLink {
|
|
68
69
|
private conversationMemoryNeedsInit;
|
69
70
|
private conversationMemoryConfig?;
|
70
71
|
private enableOrchestration;
|
72
|
+
private hitlManager?;
|
71
73
|
/**
|
72
74
|
* Context storage for tool execution
|
73
75
|
* This context will be merged with any runtime context passed by the AI model
|
@@ -82,6 +84,11 @@ export declare class NeuroLink {
|
|
82
84
|
* @param config.conversationMemory.maxSessions - Maximum number of concurrent sessions (default: 100)
|
83
85
|
* @param config.conversationMemory.maxTurnsPerSession - Maximum conversation turns per session (default: 50)
|
84
86
|
* @param config.enableOrchestration - Whether to enable smart model orchestration (default: false)
|
87
|
+
* @param config.hitl - Configuration for Human-in-the-Loop safety features
|
88
|
+
* @param config.hitl.enabled - Whether to enable HITL tool confirmation (default: false)
|
89
|
+
* @param config.hitl.dangerousActions - Keywords that trigger confirmation (default: ['delete', 'remove', 'drop'])
|
90
|
+
* @param config.hitl.timeout - Confirmation timeout in milliseconds (default: 30000)
|
91
|
+
* @param config.hitl.allowArgumentModification - Allow users to modify tool parameters (default: true)
|
85
92
|
*
|
86
93
|
* @example
|
87
94
|
* ```typescript
|
@@ -101,15 +108,27 @@ export declare class NeuroLink {
|
|
101
108
|
* const neurolink = new NeuroLink({
|
102
109
|
* enableOrchestration: true
|
103
110
|
* });
|
111
|
+
*
|
112
|
+
* // With HITL safety features
|
113
|
+
* const neurolink = new NeuroLink({
|
114
|
+
* hitl: {
|
115
|
+
* enabled: true,
|
116
|
+
* dangerousActions: ['delete', 'remove', 'drop', 'truncate'],
|
117
|
+
* timeout: 30000,
|
118
|
+
* allowArgumentModification: true
|
119
|
+
* }
|
120
|
+
* });
|
104
121
|
* ```
|
105
122
|
*
|
106
123
|
* @throws {Error} When provider registry setup fails
|
107
124
|
* @throws {Error} When conversation memory initialization fails (if enabled)
|
108
125
|
* @throws {Error} When external server manager initialization fails
|
126
|
+
* @throws {Error} When HITL configuration is invalid (if enabled)
|
109
127
|
*/
|
110
128
|
constructor(config?: {
|
111
129
|
conversationMemory?: Partial<ConversationMemoryConfig>;
|
112
130
|
enableOrchestration?: boolean;
|
131
|
+
hitl?: HITLConfig;
|
113
132
|
});
|
114
133
|
/**
|
115
134
|
* Initialize provider registry with security settings
|
@@ -119,6 +138,14 @@ export declare class NeuroLink {
|
|
119
138
|
* Initialize conversation memory if enabled
|
120
139
|
*/
|
121
140
|
private initializeConversationMemory;
|
141
|
+
/**
|
142
|
+
* Initialize HITL (Human-in-the-Loop) if enabled
|
143
|
+
*/
|
144
|
+
private initializeHITL;
|
145
|
+
/**
|
146
|
+
* Set up HITL event forwarding to main emitter
|
147
|
+
*/
|
148
|
+
private setupHITLEventForwarding;
|
122
149
|
/**
|
123
150
|
* Initialize external server manager with event handlers
|
124
151
|
*/
|
package/dist/neurolink.js
CHANGED
@@ -33,6 +33,7 @@ import { ErrorFactory, NeuroLinkError, withTimeout, withRetry, isRetriableError,
|
|
33
33
|
import { EventEmitter } from "events";
|
34
34
|
import { getConversationMessages, storeConversationTurn, } from "./utils/conversationMemory.js";
|
35
35
|
import { ExternalServerManager } from "./mcp/externalServerManager.js";
|
36
|
+
import { HITLManager } from "./hitl/hitlManager.js";
|
36
37
|
// Import direct tools server for automatic registration
|
37
38
|
import { directToolsServer } from "./mcp/servers/agent/directToolsServer.js";
|
38
39
|
// Import orchestration components
|
@@ -84,6 +85,8 @@ export class NeuroLink {
|
|
84
85
|
conversationMemoryConfig;
|
85
86
|
// Add orchestration property
|
86
87
|
enableOrchestration;
|
88
|
+
// HITL (Human-in-the-Loop) support
|
89
|
+
hitlManager;
|
87
90
|
/**
|
88
91
|
* Context storage for tool execution
|
89
92
|
* This context will be merged with any runtime context passed by the AI model
|
@@ -98,6 +101,11 @@ export class NeuroLink {
|
|
98
101
|
* @param config.conversationMemory.maxSessions - Maximum number of concurrent sessions (default: 100)
|
99
102
|
* @param config.conversationMemory.maxTurnsPerSession - Maximum conversation turns per session (default: 50)
|
100
103
|
* @param config.enableOrchestration - Whether to enable smart model orchestration (default: false)
|
104
|
+
* @param config.hitl - Configuration for Human-in-the-Loop safety features
|
105
|
+
* @param config.hitl.enabled - Whether to enable HITL tool confirmation (default: false)
|
106
|
+
* @param config.hitl.dangerousActions - Keywords that trigger confirmation (default: ['delete', 'remove', 'drop'])
|
107
|
+
* @param config.hitl.timeout - Confirmation timeout in milliseconds (default: 30000)
|
108
|
+
* @param config.hitl.allowArgumentModification - Allow users to modify tool parameters (default: true)
|
101
109
|
*
|
102
110
|
* @example
|
103
111
|
* ```typescript
|
@@ -117,11 +125,22 @@ export class NeuroLink {
|
|
117
125
|
* const neurolink = new NeuroLink({
|
118
126
|
* enableOrchestration: true
|
119
127
|
* });
|
128
|
+
*
|
129
|
+
* // With HITL safety features
|
130
|
+
* const neurolink = new NeuroLink({
|
131
|
+
* hitl: {
|
132
|
+
* enabled: true,
|
133
|
+
* dangerousActions: ['delete', 'remove', 'drop', 'truncate'],
|
134
|
+
* timeout: 30000,
|
135
|
+
* allowArgumentModification: true
|
136
|
+
* }
|
137
|
+
* });
|
120
138
|
* ```
|
121
139
|
*
|
122
140
|
* @throws {Error} When provider registry setup fails
|
123
141
|
* @throws {Error} When conversation memory initialization fails (if enabled)
|
124
142
|
* @throws {Error} When external server manager initialization fails
|
143
|
+
* @throws {Error} When HITL configuration is invalid (if enabled)
|
125
144
|
*/
|
126
145
|
constructor(config) {
|
127
146
|
// Initialize orchestration setting
|
@@ -137,6 +156,7 @@ export class NeuroLink {
|
|
137
156
|
this.initializeProviderRegistry(constructorId, constructorStartTime, constructorHrTimeStart);
|
138
157
|
this.initializeConversationMemory(config, constructorId, constructorStartTime, constructorHrTimeStart);
|
139
158
|
this.initializeExternalServerManager(constructorId, constructorStartTime, constructorHrTimeStart);
|
159
|
+
this.initializeHITL(config, constructorId, constructorStartTime, constructorHrTimeStart);
|
140
160
|
this.logConstructorComplete(constructorId, constructorStartTime, constructorHrTimeStart);
|
141
161
|
}
|
142
162
|
/**
|
@@ -198,6 +218,132 @@ export class NeuroLink {
|
|
198
218
|
});
|
199
219
|
}
|
200
220
|
}
|
221
|
+
/**
|
222
|
+
* Initialize HITL (Human-in-the-Loop) if enabled
|
223
|
+
*/
|
224
|
+
initializeHITL(config, constructorId, constructorStartTime, constructorHrTimeStart) {
|
225
|
+
if (config?.hitl?.enabled) {
|
226
|
+
const hitlInitStartTime = process.hrtime.bigint();
|
227
|
+
logger.debug(`[NeuroLink] 🛡️ LOG_POINT_C015_HITL_INIT_START`, {
|
228
|
+
logPoint: "C015_HITL_INIT_START",
|
229
|
+
constructorId,
|
230
|
+
timestamp: new Date().toISOString(),
|
231
|
+
elapsedMs: Date.now() - constructorStartTime,
|
232
|
+
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
233
|
+
hitlInitStartTimeNs: hitlInitStartTime.toString(),
|
234
|
+
hitlConfig: {
|
235
|
+
enabled: config.hitl.enabled,
|
236
|
+
dangerousActions: config.hitl.dangerousActions || [],
|
237
|
+
timeout: config.hitl.timeout || 30000,
|
238
|
+
allowArgumentModification: config.hitl.allowArgumentModification ?? true,
|
239
|
+
auditLogging: config.hitl.auditLogging ?? false,
|
240
|
+
},
|
241
|
+
message: "Starting HITL (Human-in-the-Loop) initialization",
|
242
|
+
});
|
243
|
+
try {
|
244
|
+
// Initialize HITL manager
|
245
|
+
this.hitlManager = new HITLManager(config.hitl);
|
246
|
+
// Inject HITL manager into tool registry
|
247
|
+
toolRegistry.setHITLManager(this.hitlManager);
|
248
|
+
// Inject HITL manager into external server manager
|
249
|
+
this.externalServerManager.setHITLManager(this.hitlManager);
|
250
|
+
// Set up HITL event forwarding to main emitter
|
251
|
+
this.setupHITLEventForwarding();
|
252
|
+
const hitlInitEndTime = process.hrtime.bigint();
|
253
|
+
const hitlInitDurationNs = hitlInitEndTime - hitlInitStartTime;
|
254
|
+
logger.debug(`[NeuroLink] ✅ LOG_POINT_C016_HITL_INIT_SUCCESS`, {
|
255
|
+
logPoint: "C016_HITL_INIT_SUCCESS",
|
256
|
+
constructorId,
|
257
|
+
timestamp: new Date().toISOString(),
|
258
|
+
elapsedMs: Date.now() - constructorStartTime,
|
259
|
+
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
260
|
+
hitlInitDurationNs: hitlInitDurationNs.toString(),
|
261
|
+
hitlInitDurationMs: Number(hitlInitDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
262
|
+
hasHitlManager: !!this.hitlManager,
|
263
|
+
message: "HITL (Human-in-the-Loop) initialized successfully",
|
264
|
+
});
|
265
|
+
logger.info(`[NeuroLink] HITL safety features enabled`, {
|
266
|
+
dangerousActions: config.hitl.dangerousActions?.length || 0,
|
267
|
+
timeout: config.hitl.timeout || 30000,
|
268
|
+
allowArgumentModification: config.hitl.allowArgumentModification ?? true,
|
269
|
+
auditLogging: config.hitl.auditLogging ?? false,
|
270
|
+
});
|
271
|
+
}
|
272
|
+
catch (error) {
|
273
|
+
const hitlInitErrorTime = process.hrtime.bigint();
|
274
|
+
const hitlInitDurationNs = hitlInitErrorTime - hitlInitStartTime;
|
275
|
+
logger.error(`[NeuroLink] ❌ LOG_POINT_C017_HITL_INIT_ERROR`, {
|
276
|
+
logPoint: "C017_HITL_INIT_ERROR",
|
277
|
+
constructorId,
|
278
|
+
timestamp: new Date().toISOString(),
|
279
|
+
elapsedMs: Date.now() - constructorStartTime,
|
280
|
+
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
281
|
+
hitlInitDurationNs: hitlInitDurationNs.toString(),
|
282
|
+
hitlInitDurationMs: Number(hitlInitDurationNs) / NANOSECOND_TO_MS_DIVISOR,
|
283
|
+
error: error instanceof Error ? error.message : String(error),
|
284
|
+
errorName: error instanceof Error ? error.name : "UnknownError",
|
285
|
+
errorStack: error instanceof Error ? error.stack : undefined,
|
286
|
+
message: "HITL (Human-in-the-Loop) initialization failed",
|
287
|
+
});
|
288
|
+
throw error;
|
289
|
+
}
|
290
|
+
}
|
291
|
+
else {
|
292
|
+
logger.debug(`[NeuroLink] 🚫 LOG_POINT_C018_HITL_DISABLED`, {
|
293
|
+
logPoint: "C018_HITL_DISABLED",
|
294
|
+
constructorId,
|
295
|
+
timestamp: new Date().toISOString(),
|
296
|
+
elapsedMs: Date.now() - constructorStartTime,
|
297
|
+
elapsedNs: (process.hrtime.bigint() - constructorHrTimeStart).toString(),
|
298
|
+
hasConfig: !!config,
|
299
|
+
hasHitlConfig: !!config?.hitl,
|
300
|
+
hitlEnabled: config?.hitl?.enabled || false,
|
301
|
+
reason: !config
|
302
|
+
? "NO_CONFIG"
|
303
|
+
: !config.hitl
|
304
|
+
? "NO_HITL_CONFIG"
|
305
|
+
: !config.hitl.enabled
|
306
|
+
? "HITL_DISABLED"
|
307
|
+
: "UNKNOWN",
|
308
|
+
message: "HITL (Human-in-the-Loop) not enabled - skipping initialization",
|
309
|
+
});
|
310
|
+
}
|
311
|
+
}
|
312
|
+
/**
|
313
|
+
* Set up HITL event forwarding to main emitter
|
314
|
+
*/
|
315
|
+
setupHITLEventForwarding() {
|
316
|
+
if (!this.hitlManager) {
|
317
|
+
return;
|
318
|
+
}
|
319
|
+
// Forward HITL confirmation requests to main emitter
|
320
|
+
this.hitlManager.on("hitl:confirmation-request", (event) => {
|
321
|
+
logger.debug("Forwarding HITL confirmation request", {
|
322
|
+
confirmationId: event.payload?.confirmationId,
|
323
|
+
toolName: event.payload?.toolName,
|
324
|
+
});
|
325
|
+
this.emitter.emit("hitl:confirmation-request", event);
|
326
|
+
});
|
327
|
+
// Forward HITL timeout events to main emitter
|
328
|
+
this.hitlManager.on("hitl:timeout", (event) => {
|
329
|
+
logger.debug("Forwarding HITL timeout event", {
|
330
|
+
confirmationId: event.payload?.confirmationId,
|
331
|
+
toolName: event.payload?.toolName,
|
332
|
+
});
|
333
|
+
this.emitter.emit("hitl:timeout", event);
|
334
|
+
});
|
335
|
+
// Listen for confirmation responses from main emitter and forward to HITL manager
|
336
|
+
this.emitter.on("hitl:confirmation-response", (event) => {
|
337
|
+
const typedEvent = event;
|
338
|
+
logger.debug("Received HITL confirmation response", {
|
339
|
+
confirmationId: typedEvent.payload?.confirmationId,
|
340
|
+
approved: typedEvent.payload?.approved,
|
341
|
+
});
|
342
|
+
// Forward to HITL manager
|
343
|
+
this.hitlManager?.emit("hitl:confirmation-response", typedEvent);
|
344
|
+
});
|
345
|
+
logger.debug("HITL event forwarding configured successfully");
|
346
|
+
}
|
201
347
|
/**
|
202
348
|
* Initialize external server manager with event handlers
|
203
349
|
*/
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@juspay/neurolink",
|
3
|
-
"version": "7.
|
3
|
+
"version": "7.39.0",
|
4
4
|
"description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
|
5
5
|
"author": {
|
6
6
|
"name": "Juspay Technologies",
|