@ai.ntellect/core 0.6.21 → 0.7.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/.mocharc.json +2 -1
- package/README.md +61 -85
- package/graph/controller.ts +1 -1
- package/graph/event-manager.ts +288 -0
- package/graph/index.ts +153 -367
- package/graph/logger.ts +70 -0
- package/graph/node.ts +398 -0
- package/graph/observer.ts +361 -0
- package/interfaces/index.ts +102 -1
- package/modules/agenda/index.ts +3 -16
- package/package.json +10 -5
- package/test/graph/index.test.ts +244 -113
- package/test/graph/observer.test.ts +398 -0
- package/test/modules/agenda/node-cron.test.ts +37 -16
- package/test/modules/memory/adapters/in-memory.test.ts +2 -2
- package/test/modules/memory/adapters/meilisearch.test.ts +28 -24
- package/test/modules/memory/base.test.ts +3 -3
- package/tsconfig.json +4 -2
- package/types/index.ts +23 -2
- package/dist/graph/controller.js +0 -72
- package/dist/graph/index.js +0 -501
- package/dist/index.js +0 -41
- package/dist/interfaces/index.js +0 -17
- package/dist/modules/agenda/adapters/node-cron/index.js +0 -29
- package/dist/modules/agenda/index.js +0 -140
- package/dist/modules/embedding/adapters/ai/index.js +0 -57
- package/dist/modules/embedding/index.js +0 -59
- package/dist/modules/memory/adapters/in-memory/index.js +0 -210
- package/dist/modules/memory/adapters/meilisearch/index.js +0 -320
- package/dist/modules/memory/adapters/redis/index.js +0 -158
- package/dist/modules/memory/index.js +0 -103
- package/dist/types/index.js +0 -2
- package/dist/utils/generate-action-schema.js +0 -43
- package/dist/utils/header-builder.js +0 -34
- package/test/modules/embedding/ai.test.ts +0 -78
- package/test/modules/memory/adapters/redis.test.ts +0 -169
- package/test/services/agenda.test.ts +0 -279
package/dist/graph/controller.js
DELETED
@@ -1,72 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
-
});
|
10
|
-
};
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
-
exports.GraphController = void 0;
|
13
|
-
/**
|
14
|
-
* Controller class for managing the execution of graph flows
|
15
|
-
* Handles both sequential and parallel execution of multiple graphs
|
16
|
-
*/
|
17
|
-
class GraphController {
|
18
|
-
/**
|
19
|
-
* Executes multiple graphs sequentially
|
20
|
-
* @param graphs - Array of GraphFlow instances to execute
|
21
|
-
* @param startNodes - Array of starting node identifiers for each graph
|
22
|
-
* @param inputContexts - Optional array of initial contexts for each graph
|
23
|
-
* @returns Map containing results of each graph execution, keyed by graph name and index
|
24
|
-
* @template T - Zod schema type for graph context validation
|
25
|
-
*/
|
26
|
-
static executeSequential(graphs, startNodes, inputs) {
|
27
|
-
return __awaiter(this, void 0, void 0, function* () {
|
28
|
-
const results = new Map();
|
29
|
-
for (let i = 0; i < graphs.length; i++) {
|
30
|
-
const result = yield graphs[i].execute(startNodes[i], inputs[i]);
|
31
|
-
results.set(`${graphs[i].name}-${i}`, result);
|
32
|
-
}
|
33
|
-
return Array.from(results.values());
|
34
|
-
});
|
35
|
-
}
|
36
|
-
/**
|
37
|
-
* Executes multiple graphs in parallel with optional concurrency control
|
38
|
-
* @param graphs - Array of GraphFlow instances to execute
|
39
|
-
* @param startNodes - Array of starting node identifiers for each graph
|
40
|
-
* @param inputContexts - Optional array of initial contexts for each graph
|
41
|
-
* @param inputs - Optional array of additional inputs for each graph
|
42
|
-
* @param concurrencyLimit - Optional limit on number of concurrent graph executions
|
43
|
-
* @returns Map containing results of each graph execution, keyed by graph name
|
44
|
-
* @template T - Zod schema type for graph context validation
|
45
|
-
*/
|
46
|
-
static executeParallel(graphs, startNodes, concurrency, inputs) {
|
47
|
-
return __awaiter(this, void 0, void 0, function* () {
|
48
|
-
const results = new Map();
|
49
|
-
if (inputs) {
|
50
|
-
inputs = inputs.map((input) => input || {});
|
51
|
-
}
|
52
|
-
if (concurrency) {
|
53
|
-
for (let i = 0; i < graphs.length; i += concurrency) {
|
54
|
-
const batchResults = yield Promise.all(graphs
|
55
|
-
.slice(i, i + concurrency)
|
56
|
-
.map((graph, index) => graph.execute(startNodes[i + index], inputs === null || inputs === void 0 ? void 0 : inputs[i + index])));
|
57
|
-
batchResults.forEach((result, index) => {
|
58
|
-
results.set(`${graphs[i + index].name}`, result);
|
59
|
-
});
|
60
|
-
}
|
61
|
-
}
|
62
|
-
else {
|
63
|
-
const allResults = yield Promise.all(graphs.map((graph, index) => graph.execute(startNodes[index], (inputs === null || inputs === void 0 ? void 0 : inputs[index]) || {})));
|
64
|
-
allResults.forEach((result, index) => {
|
65
|
-
results.set(`${graphs[index].name}`, result);
|
66
|
-
});
|
67
|
-
}
|
68
|
-
return Array.from(results.values());
|
69
|
-
});
|
70
|
-
}
|
71
|
-
}
|
72
|
-
exports.GraphController = GraphController;
|
package/dist/graph/index.js
DELETED
@@ -1,501 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
-
});
|
10
|
-
};
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
-
exports.GraphFlow = void 0;
|
13
|
-
const events_1 = require("events");
|
14
|
-
/**
|
15
|
-
* @module GraphFlow
|
16
|
-
* @description A flexible workflow engine that manages the execution of nodes in a graph-like structure.
|
17
|
-
*
|
18
|
-
* Key features:
|
19
|
-
* - Multiple branches support
|
20
|
-
* - Conditional branching (runs first matching condition, or all if none have conditions)
|
21
|
-
* - Event-driven nodes
|
22
|
-
* - Zod validation of context/inputs/outputs
|
23
|
-
* - Automatic retry on node failures
|
24
|
-
*
|
25
|
-
* @template T - Extends ZodSchema for type validation
|
26
|
-
*/
|
27
|
-
class GraphFlow {
|
28
|
-
/**
|
29
|
-
* Creates a new instance of GraphFlow
|
30
|
-
* @param {string} name - The name of the graph flow
|
31
|
-
* @param {GraphDefinition<T>} config - Configuration object containing nodes, schema, context, and error handlers
|
32
|
-
* @param {Object} options - Optional options for the graph flow
|
33
|
-
*/
|
34
|
-
constructor(name, config, options = {}) {
|
35
|
-
var _a;
|
36
|
-
this.name = name;
|
37
|
-
this.logs = [];
|
38
|
-
this.verbose = false;
|
39
|
-
this.nodes = new Map(config.nodes.map((node) => [node.name, node]));
|
40
|
-
this.validator = config.schema;
|
41
|
-
this.context = config.schema.parse(config.context);
|
42
|
-
this.globalErrorHandler = config.onError;
|
43
|
-
this.eventEmitter =
|
44
|
-
config.eventEmitter || new events_1.EventEmitter();
|
45
|
-
this.graphEvents = config.events;
|
46
|
-
this.verbose = (_a = options.verbose) !== null && _a !== void 0 ? _a : false;
|
47
|
-
this.setupEventListeners();
|
48
|
-
this.setupGraphEventListeners();
|
49
|
-
}
|
50
|
-
/**
|
51
|
-
* Creates a new context for execution
|
52
|
-
* @private
|
53
|
-
* @returns {GraphContext<T>} A cloned context to prevent pollution during parallel execution
|
54
|
-
*/
|
55
|
-
createNewContext() {
|
56
|
-
return structuredClone(this.context);
|
57
|
-
}
|
58
|
-
/**
|
59
|
-
* Sets up event listeners for node-based events
|
60
|
-
* @private
|
61
|
-
* @description Attaches all node-based event triggers while preserving external listeners
|
62
|
-
*/
|
63
|
-
setupEventListeners() {
|
64
|
-
// First remove only the existing node-based listeners that we might have created previously
|
65
|
-
// We do NOT remove, for example, "nodeStarted" or "nodeCompleted" listeners that test code added.
|
66
|
-
for (const [eventName, listener] of this.eventEmitter
|
67
|
-
.rawListeners("*")
|
68
|
-
.entries()) {
|
69
|
-
// This can be tricky—EventEmitter doesn't directly let you remove by "type" of listener.
|
70
|
-
// Alternatively, we can store references in a separate structure.
|
71
|
-
// For simplicity, let's do a full removeAllListeners() on node-specified events (only),
|
72
|
-
// then re-add them below, but keep the test-based events like "nodeStarted" or "nodeCompleted".
|
73
|
-
}
|
74
|
-
// The simplest approach: removeAllListeners for each event that is declared as a node event
|
75
|
-
// so we don't stack up duplicates:
|
76
|
-
const allEvents = new Set();
|
77
|
-
for (const node of this.nodes.values()) {
|
78
|
-
if (node.events) {
|
79
|
-
node.events.forEach((evt) => allEvents.add(evt));
|
80
|
-
}
|
81
|
-
}
|
82
|
-
for (const evt of allEvents) {
|
83
|
-
// remove only those events that are used by nodes
|
84
|
-
this.eventEmitter.removeAllListeners(evt);
|
85
|
-
}
|
86
|
-
// Now re-add the node-based event triggers
|
87
|
-
for (const node of this.nodes.values()) {
|
88
|
-
if (node.events && node.events.length > 0) {
|
89
|
-
node.events.forEach((event) => {
|
90
|
-
this.eventEmitter.on(event, (data) => __awaiter(this, void 0, void 0, function* () {
|
91
|
-
const freshContext = this.createNewContext();
|
92
|
-
if (data)
|
93
|
-
Object.assign(freshContext, data);
|
94
|
-
// If triggered by an event, we pass "true" so event-driven node will skip `next`.
|
95
|
-
yield this.executeNode(node.name, freshContext, undefined,
|
96
|
-
/* triggeredByEvent= */ true);
|
97
|
-
}));
|
98
|
-
});
|
99
|
-
}
|
100
|
-
}
|
101
|
-
}
|
102
|
-
addLog(message) {
|
103
|
-
const logMessage = `[${new Date().toISOString()}] ${message}`;
|
104
|
-
this.logs.push(logMessage);
|
105
|
-
if (this.verbose) {
|
106
|
-
console.log(`[${this.name}] ${message}`);
|
107
|
-
}
|
108
|
-
}
|
109
|
-
/**
|
110
|
-
* Enable or disable verbose logging
|
111
|
-
* @param {boolean} enabled - Whether to enable verbose logging
|
112
|
-
*/
|
113
|
-
setVerbose(enabled) {
|
114
|
-
this.verbose = enabled;
|
115
|
-
}
|
116
|
-
/**
|
117
|
-
* Get current verbose setting
|
118
|
-
* @returns {boolean} Current verbose setting
|
119
|
-
*/
|
120
|
-
isVerbose() {
|
121
|
-
return this.verbose;
|
122
|
-
}
|
123
|
-
/**
|
124
|
-
* Executes a specific node in the graph
|
125
|
-
* @private
|
126
|
-
* @param {string} nodeName - Name of the node to execute
|
127
|
-
* @param {GraphContext<T>} context - Current execution context
|
128
|
-
* @param {any} inputs - Input parameters for the node
|
129
|
-
* @param {boolean} triggeredByEvent - Whether the execution was triggered by an event
|
130
|
-
* @returns {Promise<void>}
|
131
|
-
*/
|
132
|
-
executeNode(nodeName_1, context_1, inputs_1) {
|
133
|
-
return __awaiter(this, arguments, void 0, function* (nodeName, context, inputs, triggeredByEvent = false) {
|
134
|
-
var _a;
|
135
|
-
const node = this.nodes.get(nodeName);
|
136
|
-
if (!node)
|
137
|
-
throw new Error(`Node "${nodeName}" not found.`);
|
138
|
-
this.addLog(`🚀 Starting node "${nodeName}"`);
|
139
|
-
this.eventEmitter.emit("nodeStarted", { name: nodeName });
|
140
|
-
try {
|
141
|
-
const localContext = structuredClone(context);
|
142
|
-
if (node.condition && !node.condition(localContext)) {
|
143
|
-
this.addLog(`⏭️ Skipping node "${nodeName}" - condition not met`);
|
144
|
-
return;
|
145
|
-
}
|
146
|
-
// Validate inputs
|
147
|
-
if (node.inputs) {
|
148
|
-
if (!inputs) {
|
149
|
-
this.addLog(`❌ Missing required inputs for node "${nodeName}"`);
|
150
|
-
throw new Error(`Inputs required for node "${nodeName}"`);
|
151
|
-
}
|
152
|
-
this.addLog(`📥 Validating inputs for node "${nodeName}"`);
|
153
|
-
inputs = node.inputs.parse(inputs);
|
154
|
-
}
|
155
|
-
// Handle retry logic
|
156
|
-
if (node.retry && node.retry.maxAttempts > 0) {
|
157
|
-
let attempts = 0;
|
158
|
-
let lastError = null;
|
159
|
-
while (attempts < node.retry.maxAttempts) {
|
160
|
-
try {
|
161
|
-
this.addLog(`🔄 Attempt ${attempts + 1}/${node.retry.maxAttempts}`);
|
162
|
-
yield node.execute(localContext, inputs);
|
163
|
-
lastError = null;
|
164
|
-
break;
|
165
|
-
}
|
166
|
-
catch (error) {
|
167
|
-
lastError = error;
|
168
|
-
attempts++;
|
169
|
-
this.addLog(`❌ Attempt ${attempts} failed: ${error.message}`);
|
170
|
-
if (attempts === node.retry.maxAttempts) {
|
171
|
-
// Si toutes les tentatives ont échoué et qu'il y a un gestionnaire d'échec
|
172
|
-
if (node.retry.onRetryFailed) {
|
173
|
-
this.addLog(`🔄 Executing retry failure handler for node "${nodeName}"`);
|
174
|
-
try {
|
175
|
-
yield node.retry.onRetryFailed(lastError, localContext);
|
176
|
-
// Si le gestionnaire d'échec réussit, on continue l'exécution
|
177
|
-
// SEULEMENT si le gestionnaire a explicitement retourné true
|
178
|
-
if (node.retry.continueOnFailed) {
|
179
|
-
this.addLog(`✅ Retry failure handler succeeded for node "${nodeName}" - continuing execution`);
|
180
|
-
break;
|
181
|
-
}
|
182
|
-
else {
|
183
|
-
this.addLog(`⚠️ Retry failure handler executed but node "${nodeName}" will still fail`);
|
184
|
-
throw lastError;
|
185
|
-
}
|
186
|
-
}
|
187
|
-
catch (handlerError) {
|
188
|
-
this.addLog(`❌ Retry failure handler failed for node "${nodeName}": ${handlerError.message}`);
|
189
|
-
throw handlerError;
|
190
|
-
}
|
191
|
-
}
|
192
|
-
// Si pas de gestionnaire d'échec ou si le gestionnaire a échoué
|
193
|
-
throw lastError;
|
194
|
-
}
|
195
|
-
if (attempts < node.retry.maxAttempts) {
|
196
|
-
this.addLog(`⏳ Waiting ${node.retry.delay}ms before next attempt`);
|
197
|
-
yield new Promise((resolve) => { var _a; return setTimeout(resolve, ((_a = node.retry) === null || _a === void 0 ? void 0 : _a.delay) || 0); });
|
198
|
-
}
|
199
|
-
}
|
200
|
-
}
|
201
|
-
}
|
202
|
-
else {
|
203
|
-
yield node.execute(localContext, inputs);
|
204
|
-
}
|
205
|
-
// Validate outputs
|
206
|
-
if (node.outputs) {
|
207
|
-
this.addLog(`📤 Validating outputs for node "${nodeName}"`);
|
208
|
-
node.outputs.parse(localContext);
|
209
|
-
}
|
210
|
-
Object.assign(context, localContext);
|
211
|
-
this.addLog(`✅ Node "${nodeName}" executed successfully ${JSON.stringify(context)}`);
|
212
|
-
this.eventEmitter.emit("nodeCompleted", { name: nodeName });
|
213
|
-
// Handle waitForEvent
|
214
|
-
if (node.waitForEvent && !triggeredByEvent) {
|
215
|
-
this.addLog(`⏳ Node "${nodeName}" waiting for events: ${(_a = node.events) === null || _a === void 0 ? void 0 : _a.join(", ")}`);
|
216
|
-
yield new Promise((resolve) => {
|
217
|
-
var _a;
|
218
|
-
const eventHandler = () => {
|
219
|
-
this.addLog(`🚀 Event received for node "${nodeName}"`);
|
220
|
-
resolve();
|
221
|
-
};
|
222
|
-
(_a = node.events) === null || _a === void 0 ? void 0 : _a.forEach((event) => {
|
223
|
-
this.eventEmitter.once(event, eventHandler);
|
224
|
-
});
|
225
|
-
});
|
226
|
-
const nextNodes = typeof node.next === "function"
|
227
|
-
? node.next(context)
|
228
|
-
: node.next || [];
|
229
|
-
if (nextNodes.length > 0) {
|
230
|
-
this.addLog(`➡️ Executing next nodes: ${nextNodes.join(", ")}`);
|
231
|
-
// Execute next nodes
|
232
|
-
for (const nextNodeName of nextNodes) {
|
233
|
-
this.addLog(`🔄 Starting branch for node "${nextNodeName}"`);
|
234
|
-
const nextNode = this.nodes.get(nextNodeName);
|
235
|
-
if (nextNode) {
|
236
|
-
yield this.executeNode(nextNodeName, context, undefined, nextNode.waitForEvent);
|
237
|
-
}
|
238
|
-
this.addLog(`✅ Branch "${nextNodeName}" completed`);
|
239
|
-
}
|
240
|
-
this.eventEmitter.emit("graphCompleted", {
|
241
|
-
name: this.name,
|
242
|
-
context: this.context,
|
243
|
-
});
|
244
|
-
return;
|
245
|
-
}
|
246
|
-
}
|
247
|
-
// Execute next nodes
|
248
|
-
const nextNodes = typeof node.next === "function"
|
249
|
-
? node.next(localContext)
|
250
|
-
: node.next || [];
|
251
|
-
if (nextNodes.length > 0) {
|
252
|
-
this.addLog(`➡️ Executing next nodes: ${nextNodes.join(", ")}`);
|
253
|
-
// Execute next nodes
|
254
|
-
for (const nextNodeName of nextNodes) {
|
255
|
-
this.addLog(`🔄 Starting branch for node "${nextNodeName}"`);
|
256
|
-
const nextNode = this.nodes.get(nextNodeName);
|
257
|
-
if (nextNode) {
|
258
|
-
yield this.executeNode(nextNodeName, context, undefined, nextNode.waitForEvent);
|
259
|
-
}
|
260
|
-
this.addLog(`✅ Branch "${nextNodeName}" completed`);
|
261
|
-
}
|
262
|
-
}
|
263
|
-
// Mettre à jour le contexte global
|
264
|
-
Object.assign(this.context, context);
|
265
|
-
}
|
266
|
-
catch (error) {
|
267
|
-
this.addLog(`❌ Error in node "${nodeName}": ${error.message}`);
|
268
|
-
this.eventEmitter.emit("nodeError", { name: nodeName, error });
|
269
|
-
throw error;
|
270
|
-
}
|
271
|
-
});
|
272
|
-
}
|
273
|
-
/**
|
274
|
-
* Validates the current context against the schema
|
275
|
-
* @private
|
276
|
-
* @param {GraphContext<T>} context - Context to validate
|
277
|
-
* @throws {Error} If validation fails
|
278
|
-
*/
|
279
|
-
validateContext(context) {
|
280
|
-
if (this.validator) {
|
281
|
-
this.validator.parse(context);
|
282
|
-
}
|
283
|
-
}
|
284
|
-
/**
|
285
|
-
* Executes the graph flow starting from a specific node
|
286
|
-
* @param {string} startNode - Name of the node to start execution from
|
287
|
-
* @param {Partial<GraphContext<T>>} inputContext - Optional partial context to merge with current context
|
288
|
-
* @param {any} inputParams - Optional input parameters for the start node
|
289
|
-
* @returns {Promise<GraphContext<T>>} Final context after execution
|
290
|
-
*/
|
291
|
-
execute(startNode, inputParams, inputContext) {
|
292
|
-
return __awaiter(this, void 0, void 0, function* () {
|
293
|
-
var _a;
|
294
|
-
if (inputParams) {
|
295
|
-
// Merge inputParams into context
|
296
|
-
Object.assign(this.context, inputParams);
|
297
|
-
}
|
298
|
-
if (inputContext) {
|
299
|
-
Object.assign(this.context, inputContext);
|
300
|
-
}
|
301
|
-
this.eventEmitter.emit("graphStarted", { name: this.name });
|
302
|
-
try {
|
303
|
-
yield this.executeNode(startNode, this.context, inputParams, false);
|
304
|
-
this.eventEmitter.emit("graphCompleted", {
|
305
|
-
name: this.name,
|
306
|
-
context: this.context,
|
307
|
-
});
|
308
|
-
return this.getContext();
|
309
|
-
}
|
310
|
-
catch (error) {
|
311
|
-
this.eventEmitter.emit("graphError", { name: this.name, error });
|
312
|
-
(_a = this.globalErrorHandler) === null || _a === void 0 ? void 0 : _a.call(this, error, this.context);
|
313
|
-
throw error;
|
314
|
-
}
|
315
|
-
});
|
316
|
-
}
|
317
|
-
/**
|
318
|
-
* Emits an event to trigger event-based nodes
|
319
|
-
* @param {string} eventName - Name of the event to emit
|
320
|
-
* @param {Partial<GraphContext<T>>} data - Optional data to merge with context
|
321
|
-
* @returns {Promise<GraphContext<T>>} Updated context after event handling
|
322
|
-
*/
|
323
|
-
emit(eventName, data) {
|
324
|
-
return __awaiter(this, void 0, void 0, function* () {
|
325
|
-
const workingContext = this.createNewContext();
|
326
|
-
if (data) {
|
327
|
-
Object.assign(workingContext, data);
|
328
|
-
}
|
329
|
-
const eventNodes = Array.from(this.nodes.values()).filter((node) => { var _a; return (_a = node.events) === null || _a === void 0 ? void 0 : _a.includes(eventName); });
|
330
|
-
// Exécuter les nœuds d'événements séquentiellement
|
331
|
-
for (const node of eventNodes) {
|
332
|
-
yield this.executeNode(node.name, workingContext, undefined, true);
|
333
|
-
}
|
334
|
-
// Mettre à jour le contexte global
|
335
|
-
this.context = workingContext;
|
336
|
-
return this.getContext();
|
337
|
-
});
|
338
|
-
}
|
339
|
-
/**
|
340
|
-
* Registers an event handler
|
341
|
-
* @param {string} eventName - Name of the event to listen for
|
342
|
-
* @param {Function} handler - Handler function to execute when event is emitted
|
343
|
-
*/
|
344
|
-
on(eventName, handler) {
|
345
|
-
this.eventEmitter.on(eventName, handler);
|
346
|
-
}
|
347
|
-
/**
|
348
|
-
* Updates the graph definition with new configuration
|
349
|
-
* @param {GraphDefinition<T>} definition - New graph definition
|
350
|
-
*/
|
351
|
-
load(definition) {
|
352
|
-
var _a;
|
353
|
-
// Clear all existing nodes
|
354
|
-
this.nodes.clear();
|
355
|
-
// Wipe out old node-based event listeners
|
356
|
-
// (We keep external test listeners like "nodeStarted" or "nodeCompleted".)
|
357
|
-
if ((_a = definition.nodes) === null || _a === void 0 ? void 0 : _a.length) {
|
358
|
-
const allEvents = new Set();
|
359
|
-
definition.nodes.forEach((n) => { var _a; return (_a = n.events) === null || _a === void 0 ? void 0 : _a.forEach((evt) => allEvents.add(evt)); });
|
360
|
-
for (const evt of allEvents) {
|
361
|
-
this.eventEmitter.removeAllListeners(evt);
|
362
|
-
}
|
363
|
-
}
|
364
|
-
// Add in new nodes
|
365
|
-
definition.nodes.forEach((node) => this.nodes.set(node.name, node));
|
366
|
-
// Parse the new context
|
367
|
-
this.context = definition.schema.parse(definition.context);
|
368
|
-
this.validator = definition.schema;
|
369
|
-
// Store entry node
|
370
|
-
this.entryNode = definition.entryNode;
|
371
|
-
// Store graph events
|
372
|
-
this.graphEvents = definition.events;
|
373
|
-
// Re-setup only node-based event triggers
|
374
|
-
for (const node of this.nodes.values()) {
|
375
|
-
if (node.events && node.events.length > 0) {
|
376
|
-
node.events.forEach((event) => {
|
377
|
-
this.eventEmitter.on(event, (data) => __awaiter(this, void 0, void 0, function* () {
|
378
|
-
const freshContext = structuredClone(this.context);
|
379
|
-
if (data)
|
380
|
-
Object.assign(freshContext, data);
|
381
|
-
yield this.executeNode(node.name, freshContext, undefined, true);
|
382
|
-
}));
|
383
|
-
});
|
384
|
-
}
|
385
|
-
}
|
386
|
-
// Re-setup graph event listeners
|
387
|
-
this.setupGraphEventListeners();
|
388
|
-
}
|
389
|
-
/**
|
390
|
-
* Gets a copy of the current context
|
391
|
-
* @returns {GraphContext<T>} A deep copy of the current context
|
392
|
-
*/
|
393
|
-
getContext() {
|
394
|
-
return structuredClone(this.context);
|
395
|
-
}
|
396
|
-
/**
|
397
|
-
* Logs a message with optional data
|
398
|
-
* @param {string} message - Message to log
|
399
|
-
* @param {any} data - Optional data to log
|
400
|
-
*/
|
401
|
-
log(message, data) {
|
402
|
-
console.log(`[Graph ${this.name}] ${message}`, data);
|
403
|
-
}
|
404
|
-
/**
|
405
|
-
* Adds a new node to the graph
|
406
|
-
* @param {Node<T>} node - Node to add
|
407
|
-
* @throws {Error} If node with same name already exists
|
408
|
-
*/
|
409
|
-
addNode(node) {
|
410
|
-
this.nodes.set(node.name, node);
|
411
|
-
if (node.events && node.events.length > 0) {
|
412
|
-
for (const evt of node.events) {
|
413
|
-
this.eventEmitter.on(evt, (data) => __awaiter(this, void 0, void 0, function* () {
|
414
|
-
const freshContext = this.createNewContext();
|
415
|
-
if (data)
|
416
|
-
Object.assign(freshContext, data);
|
417
|
-
yield this.executeNode(node.name, freshContext, undefined, true);
|
418
|
-
}));
|
419
|
-
}
|
420
|
-
}
|
421
|
-
}
|
422
|
-
/**
|
423
|
-
* Removes a node from the graph
|
424
|
-
* @param {string} nodeName - Name of the node to remove
|
425
|
-
*/
|
426
|
-
removeNode(nodeName) {
|
427
|
-
const node = this.nodes.get(nodeName);
|
428
|
-
if (!node)
|
429
|
-
return;
|
430
|
-
// remove the node from the map
|
431
|
-
this.nodes.delete(nodeName);
|
432
|
-
// remove any of its event-based listeners
|
433
|
-
if (node.events && node.events.length > 0) {
|
434
|
-
for (const evt of node.events) {
|
435
|
-
// removeAllListeners(evt) would also remove other node listeners,
|
436
|
-
// so we need a more fine-grained approach. Ideally, we should keep a reference
|
437
|
-
// to the exact listener function we attached. For brevity, let's remove all for that event:
|
438
|
-
this.eventEmitter.removeAllListeners(evt);
|
439
|
-
}
|
440
|
-
// Then reattach the others that remain in the graph
|
441
|
-
for (const n of this.nodes.values()) {
|
442
|
-
if (n.events && n.events.length > 0) {
|
443
|
-
n.events.forEach((e) => {
|
444
|
-
this.eventEmitter.on(e, (data) => __awaiter(this, void 0, void 0, function* () {
|
445
|
-
const freshContext = this.createNewContext();
|
446
|
-
if (data)
|
447
|
-
Object.assign(freshContext, data);
|
448
|
-
yield this.executeNode(n.name, freshContext, undefined, true);
|
449
|
-
}));
|
450
|
-
});
|
451
|
-
}
|
452
|
-
}
|
453
|
-
}
|
454
|
-
}
|
455
|
-
/**
|
456
|
-
* Returns all nodes in the graph
|
457
|
-
* @returns {Node<T>[]} Array of all nodes
|
458
|
-
*/
|
459
|
-
getNodes() {
|
460
|
-
return Array.from(this.nodes.values());
|
461
|
-
}
|
462
|
-
setupGraphEventListeners() {
|
463
|
-
if (this.graphEvents && this.graphEvents.length > 0) {
|
464
|
-
this.graphEvents.forEach((event) => {
|
465
|
-
this.eventEmitter.on(event, (data) => __awaiter(this, void 0, void 0, function* () {
|
466
|
-
var _a;
|
467
|
-
const freshContext = this.createNewContext();
|
468
|
-
if (data)
|
469
|
-
Object.assign(freshContext, data);
|
470
|
-
// Emit "graphStarted"
|
471
|
-
this.eventEmitter.emit("graphStarted", { name: this.name });
|
472
|
-
try {
|
473
|
-
// Execute the graph starting from the entry node
|
474
|
-
if (!this.entryNode) {
|
475
|
-
throw new Error("No entry node defined for graph event handling");
|
476
|
-
}
|
477
|
-
yield this.executeNode(this.entryNode, freshContext, undefined, false);
|
478
|
-
// Emit "graphCompleted"
|
479
|
-
this.eventEmitter.emit("graphCompleted", {
|
480
|
-
name: this.name,
|
481
|
-
context: this.context,
|
482
|
-
});
|
483
|
-
}
|
484
|
-
catch (error) {
|
485
|
-
// Emit "graphError"
|
486
|
-
this.eventEmitter.emit("graphError", { name: this.name, error });
|
487
|
-
(_a = this.globalErrorHandler) === null || _a === void 0 ? void 0 : _a.call(this, error, freshContext);
|
488
|
-
throw error;
|
489
|
-
}
|
490
|
-
}));
|
491
|
-
});
|
492
|
-
}
|
493
|
-
}
|
494
|
-
getLogs() {
|
495
|
-
return [...this.logs];
|
496
|
-
}
|
497
|
-
clearLogs() {
|
498
|
-
this.logs = [];
|
499
|
-
}
|
500
|
-
}
|
501
|
-
exports.GraphFlow = GraphFlow;
|
package/dist/index.js
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
/**
|
3
|
-
* @module @ai.ntellect/core
|
4
|
-
* @description Core module with workflow functionality, providing graph management,
|
5
|
-
* memory storage, agenda scheduling, and embedding capabilities.
|
6
|
-
*
|
7
|
-
* This module exports various components:
|
8
|
-
* - Graph management and controller
|
9
|
-
* - Memory storage adapters (Meilisearch, Redis)
|
10
|
-
* - Agenda scheduling with node-cron adapter
|
11
|
-
* - Embedding functionality with AI adapter
|
12
|
-
* - Utility functions for action schema generation and header building
|
13
|
-
*/
|
14
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
15
|
-
if (k2 === undefined) k2 = k;
|
16
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
17
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
18
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
19
|
-
}
|
20
|
-
Object.defineProperty(o, k2, desc);
|
21
|
-
}) : (function(o, m, k, k2) {
|
22
|
-
if (k2 === undefined) k2 = k;
|
23
|
-
o[k2] = m[k];
|
24
|
-
}));
|
25
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
26
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
27
|
-
};
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
29
|
-
__exportStar(require("./graph/controller"), exports);
|
30
|
-
__exportStar(require("./graph/index"), exports);
|
31
|
-
__exportStar(require("./modules/memory"), exports);
|
32
|
-
__exportStar(require("./modules/memory/adapters/meilisearch"), exports);
|
33
|
-
__exportStar(require("./modules/memory/adapters/redis"), exports);
|
34
|
-
__exportStar(require("./interfaces"), exports);
|
35
|
-
__exportStar(require("./modules/agenda"), exports);
|
36
|
-
__exportStar(require("./modules/agenda/adapters/node-cron"), exports);
|
37
|
-
__exportStar(require("./modules/embedding"), exports);
|
38
|
-
__exportStar(require("./modules/embedding/adapters/ai"), exports);
|
39
|
-
__exportStar(require("./types"), exports);
|
40
|
-
__exportStar(require("./utils/generate-action-schema"), exports);
|
41
|
-
__exportStar(require("./utils/header-builder"), exports);
|
package/dist/interfaces/index.js
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.BaseMemory = void 0;
|
4
|
-
/**
|
5
|
-
* Abstract base class for memory implementations
|
6
|
-
* @abstract
|
7
|
-
*/
|
8
|
-
class BaseMemory {
|
9
|
-
/**
|
10
|
-
* Creates an instance of BaseMemory
|
11
|
-
* @param {IMemoryAdapter} adapter - Memory adapter implementation
|
12
|
-
*/
|
13
|
-
constructor(adapter) {
|
14
|
-
this.adapter = adapter;
|
15
|
-
}
|
16
|
-
}
|
17
|
-
exports.BaseMemory = BaseMemory;
|
@@ -1,29 +0,0 @@
|
|
1
|
-
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
6
|
-
exports.NodeCronAdapter = void 0;
|
7
|
-
const node_cron_1 = __importDefault(require("node-cron"));
|
8
|
-
/**
|
9
|
-
* @module NodeCronAdapter
|
10
|
-
* @description Adapter implementation for node-cron service.
|
11
|
-
* Provides a bridge between the application's scheduling interface and the node-cron library.
|
12
|
-
* @implements {ICronService}
|
13
|
-
*/
|
14
|
-
class NodeCronAdapter {
|
15
|
-
/**
|
16
|
-
* Schedules a new cron job
|
17
|
-
* @param {string} expression - Cron expression defining the schedule
|
18
|
-
* @param {Function} callback - Function to be executed when the schedule triggers
|
19
|
-
* @returns {ICronJob} Interface for controlling the scheduled job
|
20
|
-
*/
|
21
|
-
schedule(expression, callback) {
|
22
|
-
const job = node_cron_1.default.schedule(expression, callback);
|
23
|
-
return {
|
24
|
-
start: () => job.start(),
|
25
|
-
stop: () => job.stop(),
|
26
|
-
};
|
27
|
-
}
|
28
|
-
}
|
29
|
-
exports.NodeCronAdapter = NodeCronAdapter;
|