@juspay/neurolink 4.0.0 → 4.1.1
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 +20 -5
- package/README.md +59 -1
- 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/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 +2 -1
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dynamic AI Tool Chain Executor
|
|
3
|
+
* Allows AI to dynamically decide tool execution sequences based on context and results
|
|
4
|
+
*/
|
|
5
|
+
import { ErrorCategory, ErrorSeverity } from "./error-manager.js";
|
|
6
|
+
/**
|
|
7
|
+
* Simple AI Chain Planner using heuristics
|
|
8
|
+
*/
|
|
9
|
+
export class HeuristicChainPlanner {
|
|
10
|
+
name = "heuristic";
|
|
11
|
+
async planNextStep(goal, availableTools, executionHistory, accumulatedContext) {
|
|
12
|
+
// Simple heuristic-based planning
|
|
13
|
+
const usedTools = new Set(executionHistory.map((h) => h.toolName));
|
|
14
|
+
const availableUnused = availableTools.filter((t) => !usedTools.has(t.name));
|
|
15
|
+
if (availableUnused.length === 0) {
|
|
16
|
+
return null; // No more tools to try
|
|
17
|
+
}
|
|
18
|
+
// Select tool based on goal keywords and context
|
|
19
|
+
const goalLower = goal.toLowerCase();
|
|
20
|
+
let selectedTool = availableUnused[0];
|
|
21
|
+
let confidence = 0.3;
|
|
22
|
+
// Keyword-based tool selection
|
|
23
|
+
for (const tool of availableUnused) {
|
|
24
|
+
const toolDesc = tool.description.toLowerCase();
|
|
25
|
+
let toolConfidence = 0.3;
|
|
26
|
+
// Check for keyword matches
|
|
27
|
+
if (goalLower.includes("fetch") && toolDesc.includes("fetch")) {
|
|
28
|
+
toolConfidence += 0.4;
|
|
29
|
+
}
|
|
30
|
+
if (goalLower.includes("process") && toolDesc.includes("process")) {
|
|
31
|
+
toolConfidence += 0.4;
|
|
32
|
+
}
|
|
33
|
+
if (goalLower.includes("analyze") && toolDesc.includes("analy")) {
|
|
34
|
+
toolConfidence += 0.4;
|
|
35
|
+
}
|
|
36
|
+
if (goalLower.includes("data") && toolDesc.includes("data")) {
|
|
37
|
+
toolConfidence += 0.3;
|
|
38
|
+
}
|
|
39
|
+
if (toolConfidence > confidence) {
|
|
40
|
+
confidence = toolConfidence;
|
|
41
|
+
selectedTool = tool;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
// Generate parameters based on context and previous results
|
|
45
|
+
const parameters = this.generateParameters(selectedTool, accumulatedContext, executionHistory);
|
|
46
|
+
return {
|
|
47
|
+
stepId: `step-${Date.now()}`,
|
|
48
|
+
toolName: selectedTool.name,
|
|
49
|
+
parameters,
|
|
50
|
+
reasoning: `Selected ${selectedTool.name} based on goal keywords and available context`,
|
|
51
|
+
confidence: Math.min(confidence, 0.8),
|
|
52
|
+
expectedOutcome: `Execute ${selectedTool.name} to progress towards: ${goal}`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
async evaluateResult(step, result, goal) {
|
|
56
|
+
if (!result.success) {
|
|
57
|
+
return {
|
|
58
|
+
goalAchieved: false,
|
|
59
|
+
confidence: 0.1,
|
|
60
|
+
nextAction: "retry",
|
|
61
|
+
reasoning: `Tool ${step.toolName} failed: ${result.error?.message}"`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// Simple goal completion heuristic
|
|
65
|
+
const goalKeywords = goal.toLowerCase().split(" ");
|
|
66
|
+
const resultString = JSON.stringify(result.result || {}).toLowerCase();
|
|
67
|
+
const matchedKeywords = goalKeywords.filter((keyword) => resultString.includes(keyword) || keyword.length < 3);
|
|
68
|
+
const completionRatio = matchedKeywords.length / goalKeywords.length;
|
|
69
|
+
const goalAchieved = completionRatio > 0.6;
|
|
70
|
+
return {
|
|
71
|
+
goalAchieved,
|
|
72
|
+
confidence: completionRatio,
|
|
73
|
+
nextAction: goalAchieved ? "complete" : "continue",
|
|
74
|
+
reasoning: goalAchieved
|
|
75
|
+
? `Goal appears achieved based on result content`
|
|
76
|
+
: `Goal not yet achieved (${Math.round(completionRatio * 100)}% match), continuing`,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
generateParameters(tool, context, history) {
|
|
80
|
+
const params = {};
|
|
81
|
+
// Extract useful data from previous results
|
|
82
|
+
const lastResult = history[history.length - 1];
|
|
83
|
+
if (lastResult?.result) {
|
|
84
|
+
// Pass relevant data from previous step
|
|
85
|
+
if (typeof lastResult.result === "object") {
|
|
86
|
+
Object.assign(params, lastResult.result);
|
|
87
|
+
}
|
|
88
|
+
else if (typeof lastResult.result === "string") {
|
|
89
|
+
params.input = lastResult.result;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Add context data
|
|
93
|
+
Object.assign(params, context);
|
|
94
|
+
return params;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Advanced AI Chain Planner using actual AI model
|
|
99
|
+
*/
|
|
100
|
+
export class AIModelChainPlanner {
|
|
101
|
+
name = "ai-model";
|
|
102
|
+
aiModel;
|
|
103
|
+
constructor(aiModel = "gpt-4") {
|
|
104
|
+
this.aiModel = aiModel;
|
|
105
|
+
}
|
|
106
|
+
async planNextStep(goal, availableTools, executionHistory, accumulatedContext) {
|
|
107
|
+
const prompt = this.buildPlanningPrompt(goal, availableTools, executionHistory, accumulatedContext);
|
|
108
|
+
try {
|
|
109
|
+
// This would integrate with actual AI service
|
|
110
|
+
// For now, return a structured response format
|
|
111
|
+
const aiResponse = await this.callAIModel(prompt);
|
|
112
|
+
return this.parseAIResponse(aiResponse);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
// Fallback to heuristic planning
|
|
116
|
+
console.warn("AI planning failed, falling back to heuristic", error);
|
|
117
|
+
const fallback = new HeuristicChainPlanner();
|
|
118
|
+
return fallback.planNextStep(goal, availableTools, executionHistory, accumulatedContext);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
async evaluateResult(step, result, goal) {
|
|
122
|
+
const prompt = this.buildEvaluationPrompt(step, result, goal);
|
|
123
|
+
try {
|
|
124
|
+
const aiResponse = await this.callAIModel(prompt);
|
|
125
|
+
return this.parseEvaluationResponse(aiResponse);
|
|
126
|
+
}
|
|
127
|
+
catch (error) {
|
|
128
|
+
// Fallback to heuristic evaluation
|
|
129
|
+
const fallback = new HeuristicChainPlanner();
|
|
130
|
+
return fallback.evaluateResult(step, result, goal);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
buildPlanningPrompt(goal, availableTools, executionHistory, accumulatedContext) {
|
|
134
|
+
return `
|
|
135
|
+
You are an AI tool chain planner. Your job is to select the next tool to execute towards achieving a goal.
|
|
136
|
+
|
|
137
|
+
GOAL: ${goal}
|
|
138
|
+
|
|
139
|
+
AVAILABLE TOOLS:
|
|
140
|
+
${availableTools.map((t) => `- ${t.name}: ${t.description}`).join("\n")}
|
|
141
|
+
|
|
142
|
+
EXECUTION HISTORY:
|
|
143
|
+
${executionHistory.map((h) => `${h.toolName}: ${h.success ? "SUCCESS" : "FAILED"} - ${JSON.stringify(h.result || h.error?.message)}`).join("\n")}
|
|
144
|
+
|
|
145
|
+
ACCUMULATED CONTEXT:
|
|
146
|
+
${JSON.stringify(accumulatedContext, null, 2)}
|
|
147
|
+
|
|
148
|
+
Select the next tool to execute, or return null if the goal is achieved or no progress can be made.
|
|
149
|
+
|
|
150
|
+
Respond in JSON format:
|
|
151
|
+
{
|
|
152
|
+
"toolName": "tool-name",
|
|
153
|
+
"parameters": { /* tool parameters */ },
|
|
154
|
+
"reasoning": "why this tool was selected",
|
|
155
|
+
"confidence": 0.8,
|
|
156
|
+
"expectedOutcome": "what this step should achieve"
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
If no tool should be executed, return: {"toolName": null}
|
|
160
|
+
`;
|
|
161
|
+
}
|
|
162
|
+
buildEvaluationPrompt(step, result, goal) {
|
|
163
|
+
return `
|
|
164
|
+
Evaluate whether the goal has been achieved after executing a tool.
|
|
165
|
+
|
|
166
|
+
GOAL: ${goal}
|
|
167
|
+
|
|
168
|
+
EXECUTED STEP:
|
|
169
|
+
Tool: ${step.toolName}
|
|
170
|
+
Reasoning: ${step.reasoning}
|
|
171
|
+
Expected: ${step.expectedOutcome}
|
|
172
|
+
|
|
173
|
+
ACTUAL RESULT:
|
|
174
|
+
Success: ${result.success}
|
|
175
|
+
Result: ${JSON.stringify(result.result || result.error?.message)}
|
|
176
|
+
|
|
177
|
+
Respond in JSON format:
|
|
178
|
+
{
|
|
179
|
+
"goalAchieved": true/false,
|
|
180
|
+
"confidence": 0.8,
|
|
181
|
+
"nextAction": "continue"|"retry"|"abort"|"complete",
|
|
182
|
+
"reasoning": "explanation of evaluation"
|
|
183
|
+
}
|
|
184
|
+
`;
|
|
185
|
+
}
|
|
186
|
+
async callAIModel(prompt) {
|
|
187
|
+
// Mock AI response for now
|
|
188
|
+
// In real implementation, this would call the actual AI service
|
|
189
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
190
|
+
// Return mock structured response
|
|
191
|
+
if (prompt.includes("Select the next tool")) {
|
|
192
|
+
return JSON.stringify({
|
|
193
|
+
toolName: "mock-tool",
|
|
194
|
+
parameters: { input: "mock" },
|
|
195
|
+
reasoning: "Mock AI selection",
|
|
196
|
+
confidence: 0.7,
|
|
197
|
+
expectedOutcome: "Mock execution",
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
return JSON.stringify({
|
|
202
|
+
goalAchieved: false,
|
|
203
|
+
confidence: 0.6,
|
|
204
|
+
nextAction: "continue",
|
|
205
|
+
reasoning: "Mock AI evaluation",
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
parseAIResponse(response) {
|
|
210
|
+
try {
|
|
211
|
+
const parsed = JSON.parse(response);
|
|
212
|
+
if (!parsed.toolName) {
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
stepId: `ai-step-${Date.now()}`,
|
|
217
|
+
toolName: parsed.toolName,
|
|
218
|
+
parameters: parsed.parameters || {},
|
|
219
|
+
reasoning: parsed.reasoning || "AI selected tool",
|
|
220
|
+
confidence: parsed.confidence || 0.5,
|
|
221
|
+
expectedOutcome: parsed.expectedOutcome || "Execute tool",
|
|
222
|
+
};
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
console.warn("Failed to parse AI response", error);
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
parseEvaluationResponse(response) {
|
|
230
|
+
try {
|
|
231
|
+
const parsed = JSON.parse(response);
|
|
232
|
+
return {
|
|
233
|
+
goalAchieved: parsed.goalAchieved || false,
|
|
234
|
+
confidence: parsed.confidence || 0.5,
|
|
235
|
+
nextAction: parsed.nextAction || "continue",
|
|
236
|
+
reasoning: parsed.reasoning || "AI evaluation",
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
catch (error) {
|
|
240
|
+
return {
|
|
241
|
+
goalAchieved: false,
|
|
242
|
+
confidence: 0.3,
|
|
243
|
+
nextAction: "continue",
|
|
244
|
+
reasoning: "Failed to parse AI evaluation",
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Dynamic Chain Executor
|
|
251
|
+
*/
|
|
252
|
+
export class DynamicChainExecutor {
|
|
253
|
+
orchestrator;
|
|
254
|
+
registry;
|
|
255
|
+
errorManager;
|
|
256
|
+
planner;
|
|
257
|
+
constructor(orchestrator, registry, errorManager, planner) {
|
|
258
|
+
this.orchestrator = orchestrator;
|
|
259
|
+
this.registry = registry;
|
|
260
|
+
this.errorManager = errorManager;
|
|
261
|
+
this.planner = planner || new HeuristicChainPlanner();
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Execute dynamic tool chain to achieve a goal
|
|
265
|
+
*
|
|
266
|
+
* @param goal The goal to achieve
|
|
267
|
+
* @param initialContext Initial context data
|
|
268
|
+
* @param userContext User execution context
|
|
269
|
+
* @param options Execution options
|
|
270
|
+
* @returns Chain execution result
|
|
271
|
+
*/
|
|
272
|
+
async executeChain(goal, initialContext = {}, userContext, options = {}) {
|
|
273
|
+
const startTime = Date.now();
|
|
274
|
+
const maxSteps = options.maxSteps || 10;
|
|
275
|
+
const executionContext = {
|
|
276
|
+
goal,
|
|
277
|
+
currentStep: 0,
|
|
278
|
+
executionHistory: [],
|
|
279
|
+
accumulatedContext: { ...initialContext },
|
|
280
|
+
userContext,
|
|
281
|
+
maxSteps,
|
|
282
|
+
aiModel: options.aiModel,
|
|
283
|
+
};
|
|
284
|
+
try {
|
|
285
|
+
const result = await this.executeChainSteps(executionContext);
|
|
286
|
+
return {
|
|
287
|
+
success: true,
|
|
288
|
+
goal,
|
|
289
|
+
totalSteps: result.executionHistory.length,
|
|
290
|
+
executionTime: Date.now() - startTime,
|
|
291
|
+
results: result.executionHistory,
|
|
292
|
+
finalResult: result.executionHistory[result.executionHistory.length - 1]?.result,
|
|
293
|
+
reasoning: "Chain execution completed",
|
|
294
|
+
metadata: {
|
|
295
|
+
toolsUsed: [
|
|
296
|
+
...new Set(result.executionHistory.map((h) => h.toolName)),
|
|
297
|
+
],
|
|
298
|
+
averageConfidence: this.calculateAverageConfidence(result.executionHistory),
|
|
299
|
+
contextEvolution: this.trackContextEvolution(result.executionHistory),
|
|
300
|
+
},
|
|
301
|
+
};
|
|
302
|
+
}
|
|
303
|
+
catch (error) {
|
|
304
|
+
await this.errorManager.recordError(error, {
|
|
305
|
+
category: ErrorCategory.TOOL_ERROR,
|
|
306
|
+
severity: ErrorSeverity.HIGH,
|
|
307
|
+
toolName: "dynamic-chain-executor",
|
|
308
|
+
executionContext: userContext,
|
|
309
|
+
});
|
|
310
|
+
return {
|
|
311
|
+
success: false,
|
|
312
|
+
goal,
|
|
313
|
+
totalSteps: executionContext.executionHistory.length,
|
|
314
|
+
executionTime: Date.now() - startTime,
|
|
315
|
+
results: executionContext.executionHistory,
|
|
316
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
317
|
+
reasoning: `Chain execution failed: ${error}`,
|
|
318
|
+
metadata: {
|
|
319
|
+
toolsUsed: [
|
|
320
|
+
...new Set(executionContext.executionHistory.map((h) => h.toolName)),
|
|
321
|
+
],
|
|
322
|
+
averageConfidence: this.calculateAverageConfidence(executionContext.executionHistory),
|
|
323
|
+
contextEvolution: this.trackContextEvolution(executionContext.executionHistory),
|
|
324
|
+
},
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* Execute chain steps iteratively
|
|
330
|
+
*
|
|
331
|
+
* @private
|
|
332
|
+
*/
|
|
333
|
+
async executeChainSteps(context) {
|
|
334
|
+
const availableTools = await this.registry.listTools();
|
|
335
|
+
while (context.currentStep < context.maxSteps) {
|
|
336
|
+
// Plan next step
|
|
337
|
+
const nextStep = await this.planner.planNextStep(context.goal, availableTools.map((tool) => ({
|
|
338
|
+
name: tool.name,
|
|
339
|
+
description: tool.description || "No description available",
|
|
340
|
+
inputSchema: tool.inputSchema || {},
|
|
341
|
+
})), context.executionHistory, context.accumulatedContext);
|
|
342
|
+
if (!nextStep) {
|
|
343
|
+
// No more steps to execute
|
|
344
|
+
break;
|
|
345
|
+
}
|
|
346
|
+
// Execute the planned step
|
|
347
|
+
const stepResult = await this.executeStep(nextStep, context);
|
|
348
|
+
context.executionHistory.push(stepResult);
|
|
349
|
+
// Update accumulated context
|
|
350
|
+
if (stepResult.success && stepResult.result) {
|
|
351
|
+
this.updateAccumulatedContext(context.accumulatedContext, stepResult.result);
|
|
352
|
+
}
|
|
353
|
+
// Evaluate if goal is achieved
|
|
354
|
+
const evaluation = await this.planner.evaluateResult(nextStep, stepResult, context.goal);
|
|
355
|
+
if (evaluation.goalAchieved || evaluation.nextAction === "complete") {
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
else if (evaluation.nextAction === "abort") {
|
|
359
|
+
throw new Error(`Chain execution aborted: ${evaluation.reasoning}`);
|
|
360
|
+
}
|
|
361
|
+
else if (evaluation.nextAction === "retry" && context.currentStep > 0) {
|
|
362
|
+
// Retry logic could be implemented here
|
|
363
|
+
console.warn(`Step retry suggested: ${evaluation.reasoning}`);
|
|
364
|
+
}
|
|
365
|
+
context.currentStep++;
|
|
366
|
+
}
|
|
367
|
+
return context;
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* Execute a single step
|
|
371
|
+
*
|
|
372
|
+
* @private
|
|
373
|
+
*/
|
|
374
|
+
async executeStep(step, context) {
|
|
375
|
+
const startTime = Date.now();
|
|
376
|
+
try {
|
|
377
|
+
const result = await this.orchestrator.executeTool(step.toolName, step.parameters, context.userContext);
|
|
378
|
+
return {
|
|
379
|
+
toolName: step.toolName,
|
|
380
|
+
success: true,
|
|
381
|
+
result,
|
|
382
|
+
timestamp: Date.now(),
|
|
383
|
+
executionTime: Date.now() - startTime,
|
|
384
|
+
context: {
|
|
385
|
+
stepId: step.stepId,
|
|
386
|
+
reasoning: step.reasoning,
|
|
387
|
+
confidence: step.confidence,
|
|
388
|
+
},
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
catch (error) {
|
|
392
|
+
return {
|
|
393
|
+
toolName: step.toolName,
|
|
394
|
+
success: false,
|
|
395
|
+
error: error instanceof Error ? error : new Error(String(error)),
|
|
396
|
+
timestamp: Date.now(),
|
|
397
|
+
executionTime: Date.now() - startTime,
|
|
398
|
+
context: {
|
|
399
|
+
stepId: step.stepId,
|
|
400
|
+
reasoning: step.reasoning,
|
|
401
|
+
confidence: step.confidence,
|
|
402
|
+
},
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Update accumulated context with new result
|
|
408
|
+
*
|
|
409
|
+
* @private
|
|
410
|
+
*/
|
|
411
|
+
updateAccumulatedContext(context, result) {
|
|
412
|
+
if (typeof result === "object" && result !== null) {
|
|
413
|
+
Object.assign(context, result);
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
context.lastResult = result;
|
|
417
|
+
}
|
|
418
|
+
context.lastUpdated = Date.now();
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Calculate average confidence across execution history
|
|
422
|
+
*
|
|
423
|
+
* @private
|
|
424
|
+
*/
|
|
425
|
+
calculateAverageConfidence(history) {
|
|
426
|
+
if (history.length === 0) {
|
|
427
|
+
return 0;
|
|
428
|
+
}
|
|
429
|
+
const confidences = history
|
|
430
|
+
.map((h) => h.context?.confidence || 0.5)
|
|
431
|
+
.filter((c) => typeof c === "number");
|
|
432
|
+
return confidences.length > 0
|
|
433
|
+
? confidences.reduce((sum, c) => sum + c, 0) / confidences.length
|
|
434
|
+
: 0.5;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Track context evolution through execution
|
|
438
|
+
*
|
|
439
|
+
* @private
|
|
440
|
+
*/
|
|
441
|
+
trackContextEvolution(history) {
|
|
442
|
+
const evolution = [];
|
|
443
|
+
history.forEach((result) => {
|
|
444
|
+
if (result.success && result.result) {
|
|
445
|
+
evolution.push({
|
|
446
|
+
step: result.toolName,
|
|
447
|
+
timestamp: result.timestamp,
|
|
448
|
+
dataKeys: typeof result.result === "object"
|
|
449
|
+
? Object.keys(result.result)
|
|
450
|
+
: ["primitive"],
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
return evolution;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Set AI planner
|
|
458
|
+
*
|
|
459
|
+
* @param planner AI chain planner instance
|
|
460
|
+
*/
|
|
461
|
+
setPlanner(planner) {
|
|
462
|
+
this.planner = planner;
|
|
463
|
+
}
|
|
464
|
+
/**
|
|
465
|
+
* Get current planner
|
|
466
|
+
*
|
|
467
|
+
* @returns Current AI chain planner
|
|
468
|
+
*/
|
|
469
|
+
getPlanner() {
|
|
470
|
+
return this.planner;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* Default dynamic chain executor instance
|
|
475
|
+
*/
|
|
476
|
+
export let defaultDynamicChainExecutor = null;
|
|
477
|
+
/**
|
|
478
|
+
* Initialize default dynamic chain executor
|
|
479
|
+
*
|
|
480
|
+
* @param orchestrator MCP orchestrator
|
|
481
|
+
* @param registry Tool registry
|
|
482
|
+
* @param errorManager Error manager
|
|
483
|
+
* @param planner Optional AI planner
|
|
484
|
+
* @returns Dynamic chain executor instance
|
|
485
|
+
*/
|
|
486
|
+
export function initializeDynamicChainExecutor(orchestrator, registry, errorManager, planner) {
|
|
487
|
+
defaultDynamicChainExecutor = new DynamicChainExecutor(orchestrator, registry, errorManager, planner);
|
|
488
|
+
return defaultDynamicChainExecutor;
|
|
489
|
+
}
|
|
@@ -0,0 +1,109 @@
|
|
|
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 type { ToolResult } from "./factory.js";
|
|
8
|
+
import type { ContextRequest } from "./context-manager.js";
|
|
9
|
+
/**
|
|
10
|
+
* Tool decision made by AI
|
|
11
|
+
*/
|
|
12
|
+
export interface ToolDecision {
|
|
13
|
+
toolName: string;
|
|
14
|
+
args: Record<string, any>;
|
|
15
|
+
reasoning: string;
|
|
16
|
+
confidence: number;
|
|
17
|
+
shouldContinue: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Dynamic tool chain execution options
|
|
21
|
+
*/
|
|
22
|
+
export interface DynamicToolChainOptions {
|
|
23
|
+
maxIterations?: number;
|
|
24
|
+
requireConfidence?: number;
|
|
25
|
+
includeReasoning?: boolean;
|
|
26
|
+
allowParallel?: boolean;
|
|
27
|
+
customSystemPrompt?: string;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Dynamic tool chain result
|
|
31
|
+
*/
|
|
32
|
+
export interface DynamicToolChainResult {
|
|
33
|
+
success: boolean;
|
|
34
|
+
iterations: number;
|
|
35
|
+
results: ToolResult[];
|
|
36
|
+
decisions: ToolDecision[];
|
|
37
|
+
finalOutput?: string;
|
|
38
|
+
error?: Error;
|
|
39
|
+
totalDuration: number;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Dynamic orchestrator with AI-driven tool selection
|
|
43
|
+
*/
|
|
44
|
+
export declare class DynamicOrchestrator extends MCPOrchestrator {
|
|
45
|
+
constructor(registry?: any, contextManager?: any, semaphoreManager?: any, sessionManager?: any, errorManager?: any);
|
|
46
|
+
private defaultOptions;
|
|
47
|
+
/**
|
|
48
|
+
* Execute a dynamic tool chain where AI decides which tools to use
|
|
49
|
+
*
|
|
50
|
+
* @param prompt User's task or request
|
|
51
|
+
* @param contextRequest Context creation request
|
|
52
|
+
* @param options Dynamic execution options
|
|
53
|
+
* @returns Dynamic tool chain result
|
|
54
|
+
*/
|
|
55
|
+
executeDynamicToolChain(prompt: string, contextRequest?: ContextRequest, options?: DynamicToolChainOptions): Promise<DynamicToolChainResult>;
|
|
56
|
+
/**
|
|
57
|
+
* Get AI decision on which tool to use next
|
|
58
|
+
*
|
|
59
|
+
* @private
|
|
60
|
+
*/
|
|
61
|
+
private getAIToolDecision;
|
|
62
|
+
/**
|
|
63
|
+
* Generate final output based on all execution results
|
|
64
|
+
*
|
|
65
|
+
* @private
|
|
66
|
+
*/
|
|
67
|
+
private generateFinalOutput;
|
|
68
|
+
/**
|
|
69
|
+
* Execute parallel dynamic tool chains for complex tasks
|
|
70
|
+
*
|
|
71
|
+
* @param prompts Multiple prompts to execute in parallel
|
|
72
|
+
* @param contextRequest Shared context request
|
|
73
|
+
* @param options Dynamic execution options
|
|
74
|
+
* @returns Array of dynamic tool chain results
|
|
75
|
+
*/
|
|
76
|
+
executeParallelDynamicChains(prompts: string[], contextRequest?: ContextRequest, options?: DynamicToolChainOptions): Promise<DynamicToolChainResult[]>;
|
|
77
|
+
/**
|
|
78
|
+
* Get statistics including dynamic execution metrics
|
|
79
|
+
*/
|
|
80
|
+
getStats(): {
|
|
81
|
+
dynamicOrchestrator: {
|
|
82
|
+
features: {
|
|
83
|
+
aiToolSelection: boolean;
|
|
84
|
+
iterativeExecution: boolean;
|
|
85
|
+
parallelSupport: boolean;
|
|
86
|
+
reasoningCapture: boolean;
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
registry: any;
|
|
90
|
+
context: any;
|
|
91
|
+
session: any;
|
|
92
|
+
error: any;
|
|
93
|
+
health?: any;
|
|
94
|
+
orchestrator: {
|
|
95
|
+
pipelinesExecuted: number;
|
|
96
|
+
};
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Create a dynamic orchestrator instance
|
|
101
|
+
*
|
|
102
|
+
* @param registry Tool registry
|
|
103
|
+
* @param contextManager Context manager
|
|
104
|
+
* @param semaphoreManager Semaphore manager (optional)
|
|
105
|
+
* @param sessionManager Session manager (optional)
|
|
106
|
+
* @param errorManager Error manager (optional)
|
|
107
|
+
* @returns Dynamic orchestrator instance
|
|
108
|
+
*/
|
|
109
|
+
export declare function createDynamicOrchestrator(registry: any, contextManager: any, semaphoreManager?: any, sessionManager?: any, errorManager?: any): DynamicOrchestrator;
|