@juspay/neurolink 4.0.0 → 4.1.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 +14 -5
- package/README.md +150 -92
- package/dist/lib/mcp/dynamic-chain-executor.d.ts +201 -0
- package/dist/lib/mcp/dynamic-chain-executor.js +489 -0
- package/dist/lib/mcp/dynamic-orchestrator.d.ts +109 -0
- package/dist/lib/mcp/dynamic-orchestrator.js +351 -0
- package/dist/lib/mcp/error-manager.d.ts +254 -0
- package/dist/lib/mcp/error-manager.js +501 -0
- package/dist/lib/mcp/error-recovery.d.ts +158 -0
- package/dist/lib/mcp/error-recovery.js +405 -0
- package/dist/lib/mcp/health-monitor.d.ts +256 -0
- package/dist/lib/mcp/health-monitor.js +621 -0
- package/dist/lib/mcp/orchestrator.d.ts +136 -5
- package/dist/lib/mcp/orchestrator.js +316 -9
- package/dist/lib/mcp/registry.d.ts +22 -0
- package/dist/lib/mcp/registry.js +24 -0
- package/dist/lib/mcp/semaphore-manager.d.ts +137 -0
- package/dist/lib/mcp/semaphore-manager.js +329 -0
- package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
- package/dist/lib/mcp/session-manager.d.ts +186 -0
- package/dist/lib/mcp/session-manager.js +400 -0
- package/dist/lib/mcp/session-persistence.d.ts +93 -0
- package/dist/lib/mcp/session-persistence.js +298 -0
- package/dist/lib/mcp/transport-manager.d.ts +153 -0
- package/dist/lib/mcp/transport-manager.js +330 -0
- package/dist/lib/mcp/unified-registry.d.ts +42 -1
- package/dist/lib/mcp/unified-registry.js +122 -2
- package/dist/lib/neurolink.d.ts +75 -0
- package/dist/lib/neurolink.js +104 -0
- package/dist/mcp/dynamic-chain-executor.d.ts +201 -0
- package/dist/mcp/dynamic-chain-executor.js +489 -0
- package/dist/mcp/dynamic-orchestrator.d.ts +109 -0
- package/dist/mcp/dynamic-orchestrator.js +351 -0
- package/dist/mcp/error-manager.d.ts +254 -0
- package/dist/mcp/error-manager.js +501 -0
- package/dist/mcp/error-recovery.d.ts +158 -0
- package/dist/mcp/error-recovery.js +405 -0
- package/dist/mcp/health-monitor.d.ts +256 -0
- package/dist/mcp/health-monitor.js +621 -0
- package/dist/mcp/orchestrator.d.ts +136 -5
- package/dist/mcp/orchestrator.js +316 -9
- package/dist/mcp/plugins/core/neurolink-mcp.json +15 -15
- package/dist/mcp/registry.d.ts +22 -0
- package/dist/mcp/registry.js +24 -0
- package/dist/mcp/semaphore-manager.d.ts +137 -0
- package/dist/mcp/semaphore-manager.js +329 -0
- package/dist/mcp/session-manager.d.ts +186 -0
- package/dist/mcp/session-manager.js +400 -0
- package/dist/mcp/session-persistence.d.ts +93 -0
- package/dist/mcp/session-persistence.js +299 -0
- package/dist/mcp/transport-manager.d.ts +153 -0
- package/dist/mcp/transport-manager.js +331 -0
- package/dist/mcp/unified-registry.d.ts +42 -1
- package/dist/mcp/unified-registry.js +122 -2
- package/dist/neurolink.d.ts +75 -0
- package/dist/neurolink.js +104 -0
- package/package.json +245 -244
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NeuroLink Dynamic AI-Driven Tool Orchestrator
|
|
3
|
+
* Enables AI to dynamically select and execute tools based on task requirements
|
|
4
|
+
* Based on patterns from reference implementations
|
|
5
|
+
*/
|
|
6
|
+
import { MCPOrchestrator } from "./orchestrator.js";
|
|
7
|
+
import { createExecutionContext } from "./context-manager.js";
|
|
8
|
+
import { ErrorCategory, ErrorSeverity } from "./error-manager.js";
|
|
9
|
+
import { aiCoreServer } from "./servers/ai-providers/ai-core-server.js";
|
|
10
|
+
/**
|
|
11
|
+
* AI prompt templates for tool selection
|
|
12
|
+
*/
|
|
13
|
+
const TOOL_SELECTION_PROMPT = `You are an intelligent tool orchestrator. Analyze the user's request and available tools to determine the best tool to use next.
|
|
14
|
+
|
|
15
|
+
User Request: {prompt}
|
|
16
|
+
|
|
17
|
+
Available Tools:
|
|
18
|
+
{tools}
|
|
19
|
+
|
|
20
|
+
Previous Results:
|
|
21
|
+
{previousResults}
|
|
22
|
+
|
|
23
|
+
Based on the request and previous results, select the most appropriate tool to use next.
|
|
24
|
+
Respond with a JSON object containing:
|
|
25
|
+
- toolName: The exact name of the tool to use
|
|
26
|
+
- args: An object containing the arguments for the tool
|
|
27
|
+
- reasoning: Brief explanation of why this tool was chosen
|
|
28
|
+
- confidence: A number between 0 and 1 indicating your confidence in this choice
|
|
29
|
+
- shouldContinue: Boolean indicating if more tools should be executed after this one
|
|
30
|
+
|
|
31
|
+
Example response:
|
|
32
|
+
{
|
|
33
|
+
"toolName": "search-code",
|
|
34
|
+
"args": {"query": "function calculateTotal", "path": "/src"},
|
|
35
|
+
"reasoning": "Need to find the calculateTotal function to understand the calculation logic",
|
|
36
|
+
"confidence": 0.9,
|
|
37
|
+
"shouldContinue": true
|
|
38
|
+
}`;
|
|
39
|
+
/**
|
|
40
|
+
* Dynamic orchestrator with AI-driven tool selection
|
|
41
|
+
*/
|
|
42
|
+
export class DynamicOrchestrator extends MCPOrchestrator {
|
|
43
|
+
constructor(registry, contextManager, semaphoreManager, sessionManager, errorManager) {
|
|
44
|
+
super(registry, contextManager, semaphoreManager, sessionManager, errorManager);
|
|
45
|
+
}
|
|
46
|
+
defaultOptions = {
|
|
47
|
+
maxIterations: 10,
|
|
48
|
+
requireConfidence: 0.7,
|
|
49
|
+
includeReasoning: true,
|
|
50
|
+
allowParallel: false,
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Execute a dynamic tool chain where AI decides which tools to use
|
|
54
|
+
*
|
|
55
|
+
* @param prompt User's task or request
|
|
56
|
+
* @param contextRequest Context creation request
|
|
57
|
+
* @param options Dynamic execution options
|
|
58
|
+
* @returns Dynamic tool chain result
|
|
59
|
+
*/
|
|
60
|
+
async executeDynamicToolChain(prompt, contextRequest = {}, options = {}) {
|
|
61
|
+
const startTime = Date.now();
|
|
62
|
+
const mergedOptions = { ...this.defaultOptions, ...options };
|
|
63
|
+
const results = [];
|
|
64
|
+
const decisions = [];
|
|
65
|
+
let error;
|
|
66
|
+
let iterations = 0;
|
|
67
|
+
let session;
|
|
68
|
+
try {
|
|
69
|
+
// Create or get session
|
|
70
|
+
const context = await this.contextManager.createContext(contextRequest);
|
|
71
|
+
session = await this.sessionManager.createSession(context);
|
|
72
|
+
// Get available tools
|
|
73
|
+
const availableTools = await this.registry.listTools(context);
|
|
74
|
+
const toolsDescription = availableTools
|
|
75
|
+
.map((tool) => `- ${tool.name}: ${tool.description || "No description"}`)
|
|
76
|
+
.join("\n");
|
|
77
|
+
let shouldContinue = true;
|
|
78
|
+
while (shouldContinue &&
|
|
79
|
+
iterations < (mergedOptions.maxIterations || 10)) {
|
|
80
|
+
iterations++;
|
|
81
|
+
// Prepare context for AI decision
|
|
82
|
+
const previousResultsSummary = results
|
|
83
|
+
.slice(-3) // Last 3 results for context
|
|
84
|
+
.map((r, i) => {
|
|
85
|
+
const resultData = r.success && r.data ? JSON.stringify(r.data) : "No data";
|
|
86
|
+
const summary = resultData.length > 200
|
|
87
|
+
? resultData.slice(0, 200) + "..."
|
|
88
|
+
: resultData;
|
|
89
|
+
return `Result ${i + 1}: ${summary}`;
|
|
90
|
+
})
|
|
91
|
+
.join("\n");
|
|
92
|
+
// Get AI decision on next tool
|
|
93
|
+
const decision = await this.getAIToolDecision(prompt, toolsDescription, previousResultsSummary, mergedOptions.customSystemPrompt);
|
|
94
|
+
// Add decision to array if includeReasoning is true
|
|
95
|
+
if (mergedOptions.includeReasoning) {
|
|
96
|
+
decisions.push(decision);
|
|
97
|
+
}
|
|
98
|
+
// Validate confidence threshold
|
|
99
|
+
if (decision.confidence < (mergedOptions.requireConfidence || 0.7)) {
|
|
100
|
+
if (process.env.NEUROLINK_DEBUG === "true") {
|
|
101
|
+
console.log(`[DynamicOrchestrator] Low confidence (${decision.confidence}), stopping execution`);
|
|
102
|
+
}
|
|
103
|
+
shouldContinue = false;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
shouldContinue = decision.shouldContinue;
|
|
107
|
+
// Execute the selected tool
|
|
108
|
+
try {
|
|
109
|
+
const toolResult = await this.registry.executeTool(decision.toolName, decision.args, context);
|
|
110
|
+
results.push({
|
|
111
|
+
success: true,
|
|
112
|
+
data: toolResult,
|
|
113
|
+
metadata: {
|
|
114
|
+
toolName: decision.toolName,
|
|
115
|
+
executionTime: Date.now() - startTime,
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
// Update session with tool result
|
|
119
|
+
session.toolHistory.push({
|
|
120
|
+
success: true,
|
|
121
|
+
data: toolResult,
|
|
122
|
+
metadata: {
|
|
123
|
+
toolName: decision.toolName,
|
|
124
|
+
executionTime: Date.now() - startTime,
|
|
125
|
+
},
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch (toolError) {
|
|
129
|
+
const errorResult = {
|
|
130
|
+
success: false,
|
|
131
|
+
error: toolError instanceof Error
|
|
132
|
+
? toolError
|
|
133
|
+
: new Error(String(toolError)),
|
|
134
|
+
metadata: {
|
|
135
|
+
toolName: decision.toolName,
|
|
136
|
+
executionTime: Date.now() - startTime,
|
|
137
|
+
},
|
|
138
|
+
};
|
|
139
|
+
results.push(errorResult);
|
|
140
|
+
session.toolHistory.push(errorResult);
|
|
141
|
+
// Let AI decide if it should continue after error
|
|
142
|
+
if (!decision.shouldContinue) {
|
|
143
|
+
break;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
// Safety check for infinite loops
|
|
147
|
+
if (iterations >= (mergedOptions.maxIterations || 10)) {
|
|
148
|
+
if (process.env.NEUROLINK_DEBUG === "true") {
|
|
149
|
+
console.log(`[DynamicOrchestrator] Reached max iterations (${mergedOptions.maxIterations})`);
|
|
150
|
+
}
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Generate final output based on all results
|
|
155
|
+
const finalOutput = await this.generateFinalOutput(prompt, results, decisions);
|
|
156
|
+
return {
|
|
157
|
+
success: true,
|
|
158
|
+
iterations,
|
|
159
|
+
results,
|
|
160
|
+
decisions: mergedOptions.includeReasoning ? decisions : [],
|
|
161
|
+
finalOutput,
|
|
162
|
+
totalDuration: Date.now() - startTime,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
catch (err) {
|
|
166
|
+
error = err instanceof Error ? err : new Error(String(err));
|
|
167
|
+
// Record error
|
|
168
|
+
this.errorManager.recordError(error, {
|
|
169
|
+
category: ErrorCategory.TOOL_ERROR,
|
|
170
|
+
severity: ErrorSeverity.HIGH,
|
|
171
|
+
toolName: "dynamic-orchestrator",
|
|
172
|
+
sessionId: session?.id,
|
|
173
|
+
});
|
|
174
|
+
return {
|
|
175
|
+
success: false,
|
|
176
|
+
iterations,
|
|
177
|
+
results,
|
|
178
|
+
decisions: mergedOptions.includeReasoning ? decisions : [],
|
|
179
|
+
error,
|
|
180
|
+
totalDuration: Date.now() - startTime,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
finally {
|
|
184
|
+
// Update session activity if session was created
|
|
185
|
+
if (session) {
|
|
186
|
+
session.lastActivity = Date.now();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Get AI decision on which tool to use next
|
|
192
|
+
*
|
|
193
|
+
* @private
|
|
194
|
+
*/
|
|
195
|
+
async getAIToolDecision(prompt, toolsDescription, previousResults, customSystemPrompt) {
|
|
196
|
+
const systemPrompt = customSystemPrompt ||
|
|
197
|
+
TOOL_SELECTION_PROMPT.replace("{prompt}", prompt)
|
|
198
|
+
.replace("{tools}", toolsDescription)
|
|
199
|
+
.replace("{previousResults}", previousResults || "None yet");
|
|
200
|
+
try {
|
|
201
|
+
// Use AI Core Server to get tool decision
|
|
202
|
+
const generateTextTool = aiCoreServer.tools["generate-text"];
|
|
203
|
+
if (!generateTextTool) {
|
|
204
|
+
throw new Error("generate-text tool not found");
|
|
205
|
+
}
|
|
206
|
+
const aiResponse = await generateTextTool.execute({
|
|
207
|
+
prompt: "Select the next tool to execute based on the context provided.",
|
|
208
|
+
systemPrompt,
|
|
209
|
+
provider: "google-ai", // Use fast model for decisions
|
|
210
|
+
model: "gemini-2.5-flash",
|
|
211
|
+
temperature: 0.3, // Lower temperature for more consistent decisions
|
|
212
|
+
maxTokens: 500,
|
|
213
|
+
}, createExecutionContext());
|
|
214
|
+
// Parse AI response
|
|
215
|
+
if (!aiResponse.success) {
|
|
216
|
+
throw new Error(String(aiResponse.error || "AI generation failed"));
|
|
217
|
+
}
|
|
218
|
+
const responseText = aiResponse.data?.text || "";
|
|
219
|
+
// Extract JSON from response (handle markdown code blocks)
|
|
220
|
+
const jsonMatch = responseText.match(/```json\n?([\s\S]*?)\n?```/) ||
|
|
221
|
+
responseText.match(/\{[\s\S]*\}/);
|
|
222
|
+
if (!jsonMatch) {
|
|
223
|
+
throw new Error("AI response did not contain valid JSON");
|
|
224
|
+
}
|
|
225
|
+
const decision = JSON.parse(jsonMatch[1] || jsonMatch[0]);
|
|
226
|
+
// Validate decision structure
|
|
227
|
+
if (!decision.toolName || !decision.args) {
|
|
228
|
+
throw new Error("Invalid tool decision structure");
|
|
229
|
+
}
|
|
230
|
+
return {
|
|
231
|
+
toolName: decision.toolName,
|
|
232
|
+
args: decision.args || {},
|
|
233
|
+
reasoning: decision.reasoning || "No reasoning provided",
|
|
234
|
+
confidence: decision.confidence || 0.8,
|
|
235
|
+
shouldContinue: decision.shouldContinue !== false,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
// Fallback decision on error
|
|
240
|
+
if (process.env.NEUROLINK_DEBUG === "true") {
|
|
241
|
+
console.error("[DynamicOrchestrator] Error getting AI decision:", error);
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
toolName: "list-tools", // Safe default
|
|
245
|
+
args: {},
|
|
246
|
+
reasoning: "Error in AI decision, falling back to tool listing",
|
|
247
|
+
confidence: 0.5,
|
|
248
|
+
shouldContinue: false,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Generate final output based on all execution results
|
|
254
|
+
*
|
|
255
|
+
* @private
|
|
256
|
+
*/
|
|
257
|
+
async generateFinalOutput(prompt, results, decisions) {
|
|
258
|
+
// Prepare summary of execution
|
|
259
|
+
const executionSummary = results
|
|
260
|
+
.map((r, i) => {
|
|
261
|
+
const decision = decisions[i];
|
|
262
|
+
const toolName = r.metadata?.toolName || "unknown";
|
|
263
|
+
const resultData = r.success && r.data ? JSON.stringify(r.data) : "No data";
|
|
264
|
+
const resultSummary = resultData.length > 300
|
|
265
|
+
? resultData.slice(0, 300) + "..."
|
|
266
|
+
: resultData;
|
|
267
|
+
return `Step ${i + 1}: ${toolName}
|
|
268
|
+
Reasoning: ${decision?.reasoning || "N/A"}
|
|
269
|
+
Result: ${r.success ? resultSummary : "Error: " + (r.error instanceof Error ? r.error.message : String(r.error))}`;
|
|
270
|
+
})
|
|
271
|
+
.join("\n\n");
|
|
272
|
+
const summaryPrompt = `Based on the following tool execution results, provide a comprehensive answer to the user's request.
|
|
273
|
+
|
|
274
|
+
User Request: ${prompt}
|
|
275
|
+
|
|
276
|
+
Execution Summary:
|
|
277
|
+
${executionSummary}
|
|
278
|
+
|
|
279
|
+
Provide a clear, concise answer that addresses the user's request based on the tool results.`;
|
|
280
|
+
try {
|
|
281
|
+
// Use AI to generate final summary
|
|
282
|
+
const generateTextTool = aiCoreServer.tools["generate-text"];
|
|
283
|
+
if (!generateTextTool) {
|
|
284
|
+
throw new Error("generate-text tool not found");
|
|
285
|
+
}
|
|
286
|
+
const aiResponse = await generateTextTool.execute({
|
|
287
|
+
prompt: summaryPrompt,
|
|
288
|
+
provider: "google-ai",
|
|
289
|
+
model: "gemini-2.5-pro",
|
|
290
|
+
temperature: 0.7,
|
|
291
|
+
maxTokens: 1000,
|
|
292
|
+
}, createExecutionContext());
|
|
293
|
+
if (!aiResponse.success) {
|
|
294
|
+
throw new Error(String(aiResponse.error || "AI generation failed"));
|
|
295
|
+
}
|
|
296
|
+
return aiResponse.data?.text || "";
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
// Fallback to simple summary
|
|
300
|
+
return `Executed ${results.length} tools to address your request. ${results.filter((r) => r.success).length} succeeded, ${results.filter((r) => !r.success).length} failed.`;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Execute parallel dynamic tool chains for complex tasks
|
|
305
|
+
*
|
|
306
|
+
* @param prompts Multiple prompts to execute in parallel
|
|
307
|
+
* @param contextRequest Shared context request
|
|
308
|
+
* @param options Dynamic execution options
|
|
309
|
+
* @returns Array of dynamic tool chain results
|
|
310
|
+
*/
|
|
311
|
+
async executeParallelDynamicChains(prompts, contextRequest = {}, options = {}) {
|
|
312
|
+
if (!options.allowParallel) {
|
|
313
|
+
throw new Error("Parallel execution not enabled in options");
|
|
314
|
+
}
|
|
315
|
+
// Execute all chains in parallel
|
|
316
|
+
const promises = prompts.map((prompt) => this.executeDynamicToolChain(prompt, contextRequest, options));
|
|
317
|
+
return Promise.all(promises);
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Get statistics including dynamic execution metrics
|
|
321
|
+
*/
|
|
322
|
+
getStats() {
|
|
323
|
+
const baseStats = super.getStats();
|
|
324
|
+
// Add dynamic orchestrator specific stats
|
|
325
|
+
return {
|
|
326
|
+
...baseStats,
|
|
327
|
+
dynamicOrchestrator: {
|
|
328
|
+
// Additional metrics can be added here
|
|
329
|
+
features: {
|
|
330
|
+
aiToolSelection: true,
|
|
331
|
+
iterativeExecution: true,
|
|
332
|
+
parallelSupport: true,
|
|
333
|
+
reasoningCapture: true,
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Create a dynamic orchestrator instance
|
|
341
|
+
*
|
|
342
|
+
* @param registry Tool registry
|
|
343
|
+
* @param contextManager Context manager
|
|
344
|
+
* @param semaphoreManager Semaphore manager (optional)
|
|
345
|
+
* @param sessionManager Session manager (optional)
|
|
346
|
+
* @param errorManager Error manager (optional)
|
|
347
|
+
* @returns Dynamic orchestrator instance
|
|
348
|
+
*/
|
|
349
|
+
export function createDynamicOrchestrator(registry, contextManager, semaphoreManager, sessionManager, errorManager) {
|
|
350
|
+
return new DynamicOrchestrator(registry, contextManager, semaphoreManager, sessionManager, errorManager);
|
|
351
|
+
}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NeuroLink MCP Enhanced Error Handling System
|
|
3
|
+
* Provides comprehensive error tracking, categorization, and debugging capabilities
|
|
4
|
+
* Based on error accumulation patterns from Cline
|
|
5
|
+
*/
|
|
6
|
+
import type { NeuroLinkExecutionContext } from "./factory.js";
|
|
7
|
+
/**
|
|
8
|
+
* Error categories for classification
|
|
9
|
+
*/
|
|
10
|
+
export declare enum ErrorCategory {
|
|
11
|
+
TOOL_ERROR = "TOOL_ERROR",
|
|
12
|
+
NETWORK_ERROR = "NETWORK_ERROR",
|
|
13
|
+
VALIDATION_ERROR = "VALIDATION_ERROR",
|
|
14
|
+
TIMEOUT_ERROR = "TIMEOUT_ERROR",
|
|
15
|
+
PERMISSION_ERROR = "PERMISSION_ERROR",
|
|
16
|
+
CONFIGURATION_ERROR = "CONFIGURATION_ERROR",
|
|
17
|
+
CONNECTION_ERROR = "CONNECTION_ERROR",
|
|
18
|
+
UNKNOWN_ERROR = "UNKNOWN_ERROR"
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Error severity levels
|
|
22
|
+
*/
|
|
23
|
+
export declare enum ErrorSeverity {
|
|
24
|
+
LOW = "LOW",
|
|
25
|
+
MEDIUM = "MEDIUM",
|
|
26
|
+
HIGH = "HIGH",
|
|
27
|
+
CRITICAL = "CRITICAL"
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Enhanced error entry with rich context
|
|
31
|
+
*/
|
|
32
|
+
export interface ErrorEntry {
|
|
33
|
+
id: string;
|
|
34
|
+
timestamp: number;
|
|
35
|
+
category: ErrorCategory;
|
|
36
|
+
severity: ErrorSeverity;
|
|
37
|
+
error: Error;
|
|
38
|
+
context: {
|
|
39
|
+
sessionId?: string;
|
|
40
|
+
toolName?: string;
|
|
41
|
+
parameters?: any;
|
|
42
|
+
executionContext?: NeuroLinkExecutionContext;
|
|
43
|
+
};
|
|
44
|
+
stackTrace?: string;
|
|
45
|
+
recovery?: {
|
|
46
|
+
attempted: boolean;
|
|
47
|
+
successful?: boolean;
|
|
48
|
+
recovered?: boolean;
|
|
49
|
+
fallbackUsed?: boolean;
|
|
50
|
+
nextAction?: string;
|
|
51
|
+
delay?: number;
|
|
52
|
+
suggestion?: string;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Error statistics
|
|
57
|
+
*/
|
|
58
|
+
export interface ErrorStats {
|
|
59
|
+
totalErrors: number;
|
|
60
|
+
errorsByCategory: Record<ErrorCategory, number>;
|
|
61
|
+
errorsBySeverity: Record<ErrorSeverity, number>;
|
|
62
|
+
errorRate: number;
|
|
63
|
+
lastError?: ErrorEntry;
|
|
64
|
+
mostFrequentError?: {
|
|
65
|
+
message: string;
|
|
66
|
+
count: number;
|
|
67
|
+
category: ErrorCategory;
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Options for error manager configuration
|
|
72
|
+
*/
|
|
73
|
+
export interface ErrorManagerOptions {
|
|
74
|
+
maxHistorySize?: number;
|
|
75
|
+
enableStackTrace?: boolean;
|
|
76
|
+
autoRecovery?: boolean;
|
|
77
|
+
errorRateWindow?: number;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Enhanced Error Manager with accumulation and analysis capabilities
|
|
81
|
+
*/
|
|
82
|
+
export declare class ErrorManager {
|
|
83
|
+
private errorHistory;
|
|
84
|
+
private maxHistorySize;
|
|
85
|
+
private enableStackTrace;
|
|
86
|
+
private autoRecovery;
|
|
87
|
+
private errorRateWindow;
|
|
88
|
+
private errorCounter;
|
|
89
|
+
private errorFrequency;
|
|
90
|
+
private categoryCounts;
|
|
91
|
+
private severityCounts;
|
|
92
|
+
private errorRecovery;
|
|
93
|
+
constructor(options?: ErrorManagerOptions);
|
|
94
|
+
/**
|
|
95
|
+
* Record an error with context
|
|
96
|
+
*
|
|
97
|
+
* @param error The error to record
|
|
98
|
+
* @param context Additional context about the error
|
|
99
|
+
* @returns The created error entry
|
|
100
|
+
*/
|
|
101
|
+
recordError(error: Error | unknown, context?: {
|
|
102
|
+
category?: ErrorCategory;
|
|
103
|
+
severity?: ErrorSeverity;
|
|
104
|
+
sessionId?: string;
|
|
105
|
+
toolName?: string;
|
|
106
|
+
parameters?: any;
|
|
107
|
+
executionContext?: NeuroLinkExecutionContext;
|
|
108
|
+
}): Promise<ErrorEntry>;
|
|
109
|
+
/**
|
|
110
|
+
* Get error history
|
|
111
|
+
*
|
|
112
|
+
* @param filter Optional filter criteria
|
|
113
|
+
* @returns Filtered error history
|
|
114
|
+
*/
|
|
115
|
+
getErrorHistory(filter?: {
|
|
116
|
+
category?: ErrorCategory;
|
|
117
|
+
severity?: ErrorSeverity;
|
|
118
|
+
sessionId?: string;
|
|
119
|
+
toolName?: string;
|
|
120
|
+
since?: number;
|
|
121
|
+
limit?: number;
|
|
122
|
+
}): ErrorEntry[];
|
|
123
|
+
/**
|
|
124
|
+
* Get error statistics
|
|
125
|
+
*
|
|
126
|
+
* @returns Current error statistics
|
|
127
|
+
*/
|
|
128
|
+
getStats(): ErrorStats;
|
|
129
|
+
/**
|
|
130
|
+
* Clear error history
|
|
131
|
+
*/
|
|
132
|
+
clearHistory(): void;
|
|
133
|
+
/**
|
|
134
|
+
* Get recovery suggestions for an error
|
|
135
|
+
*
|
|
136
|
+
* @param error The error entry
|
|
137
|
+
* @returns Recovery suggestion
|
|
138
|
+
*/
|
|
139
|
+
getRecoverySuggestion(error: ErrorEntry): string;
|
|
140
|
+
/**
|
|
141
|
+
* Categorize error based on message and type
|
|
142
|
+
*
|
|
143
|
+
* @private
|
|
144
|
+
*/
|
|
145
|
+
private categorizeError;
|
|
146
|
+
/**
|
|
147
|
+
* Determine error severity
|
|
148
|
+
*
|
|
149
|
+
* @private
|
|
150
|
+
*/
|
|
151
|
+
private determineSeverity;
|
|
152
|
+
/**
|
|
153
|
+
* Add error to circular buffer
|
|
154
|
+
*
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
private addToHistory;
|
|
158
|
+
/**
|
|
159
|
+
* Update error statistics
|
|
160
|
+
*
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
private updateStatistics;
|
|
164
|
+
/**
|
|
165
|
+
* Attempt automatic recovery
|
|
166
|
+
*
|
|
167
|
+
* @private
|
|
168
|
+
*/
|
|
169
|
+
private attemptRecovery;
|
|
170
|
+
/**
|
|
171
|
+
* Generate unique error ID
|
|
172
|
+
*
|
|
173
|
+
* @private
|
|
174
|
+
*/
|
|
175
|
+
private generateErrorId;
|
|
176
|
+
/**
|
|
177
|
+
* Detect error patterns in recent history
|
|
178
|
+
*
|
|
179
|
+
* @param timeWindow Time window to analyze (ms)
|
|
180
|
+
* @returns Detected patterns with counts and severity
|
|
181
|
+
*/
|
|
182
|
+
detectPatterns(timeWindow?: number): {
|
|
183
|
+
patterns: Array<{
|
|
184
|
+
pattern: string;
|
|
185
|
+
count: number;
|
|
186
|
+
errors: ErrorEntry[];
|
|
187
|
+
severity: ErrorSeverity;
|
|
188
|
+
recommendation: string;
|
|
189
|
+
}>;
|
|
190
|
+
correlations: Array<{
|
|
191
|
+
error1: string;
|
|
192
|
+
error2: string;
|
|
193
|
+
correlation: number;
|
|
194
|
+
}>;
|
|
195
|
+
};
|
|
196
|
+
/**
|
|
197
|
+
* Detect correlations between errors
|
|
198
|
+
*
|
|
199
|
+
* @private
|
|
200
|
+
*/
|
|
201
|
+
private detectCorrelations;
|
|
202
|
+
/**
|
|
203
|
+
* Get error trends over time
|
|
204
|
+
*
|
|
205
|
+
* @param bucketSize Time bucket size in ms (default: 1 minute)
|
|
206
|
+
* @param timeWindow Total time window to analyze
|
|
207
|
+
* @returns Error counts per time bucket
|
|
208
|
+
*/
|
|
209
|
+
getErrorTrends(bucketSize?: number, timeWindow?: number): Array<{
|
|
210
|
+
timestamp: number;
|
|
211
|
+
count: number;
|
|
212
|
+
categories: Record<ErrorCategory, number>;
|
|
213
|
+
}>;
|
|
214
|
+
/**
|
|
215
|
+
* Get recovery statistics
|
|
216
|
+
*
|
|
217
|
+
* @returns Recovery statistics from error recovery system
|
|
218
|
+
*/
|
|
219
|
+
getRecoveryStats(): {
|
|
220
|
+
totalAttempts: number;
|
|
221
|
+
successfulRecoveries: number;
|
|
222
|
+
failedRecoveries: number;
|
|
223
|
+
circuitBreakerStates: Record<string, import("./error-recovery.js").CircuitState>;
|
|
224
|
+
patternMatches: Record<string, number>;
|
|
225
|
+
};
|
|
226
|
+
/**
|
|
227
|
+
* Reset circuit breaker for specific resource
|
|
228
|
+
*
|
|
229
|
+
* @param resourceId Resource identifier (usually tool name)
|
|
230
|
+
*/
|
|
231
|
+
resetCircuitBreaker(resourceId: string): void;
|
|
232
|
+
/**
|
|
233
|
+
* Get error insights and recommendations
|
|
234
|
+
*
|
|
235
|
+
* @returns Insights based on error analysis
|
|
236
|
+
*/
|
|
237
|
+
getInsights(): {
|
|
238
|
+
criticalIssues: string[];
|
|
239
|
+
recommendations: string[];
|
|
240
|
+
healthScore: number;
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Default error manager instance
|
|
245
|
+
*/
|
|
246
|
+
export declare const defaultErrorManager: ErrorManager;
|
|
247
|
+
/**
|
|
248
|
+
* Utility function to record error with default manager
|
|
249
|
+
*
|
|
250
|
+
* @param error Error to record
|
|
251
|
+
* @param context Error context
|
|
252
|
+
* @returns Error entry
|
|
253
|
+
*/
|
|
254
|
+
export declare function recordError(error: Error | unknown, context?: Parameters<ErrorManager["recordError"]>[1]): Promise<ErrorEntry>;
|