@ai.ntellect/core 0.6.17 → 0.6.19

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.
Files changed (78) hide show
  1. package/.mocharc.json +1 -2
  2. package/README.md +123 -178
  3. package/dist/graph/controller.js +29 -6
  4. package/dist/graph/index.js +302 -62
  5. package/dist/index.js +21 -6
  6. package/dist/interfaces/index.js +15 -0
  7. package/dist/modules/agenda/adapters/node-cron/index.js +29 -0
  8. package/dist/modules/agenda/index.js +140 -0
  9. package/dist/{services/embedding.js → modules/embedding/adapters/ai/index.js} +24 -7
  10. package/dist/modules/embedding/index.js +59 -0
  11. package/dist/modules/memory/adapters/in-memory/index.js +210 -0
  12. package/dist/{memory → modules/memory}/adapters/meilisearch/index.js +97 -2
  13. package/dist/{memory → modules/memory}/adapters/redis/index.js +77 -15
  14. package/dist/modules/memory/index.js +103 -0
  15. package/dist/utils/{stringifiy-zod-schema.js → generate-action-schema.js} +5 -5
  16. package/graph/controller.ts +37 -13
  17. package/graph/index.ts +348 -73
  18. package/index.ts +24 -6
  19. package/interfaces/index.ts +346 -27
  20. package/modules/agenda/adapters/node-cron/index.ts +25 -0
  21. package/modules/agenda/index.ts +159 -0
  22. package/modules/embedding/adapters/ai/index.ts +42 -0
  23. package/modules/embedding/index.ts +45 -0
  24. package/modules/memory/adapters/in-memory/index.ts +203 -0
  25. package/{memory → modules/memory}/adapters/meilisearch/index.ts +114 -12
  26. package/modules/memory/adapters/redis/index.ts +164 -0
  27. package/modules/memory/index.ts +93 -0
  28. package/package.json +3 -1
  29. package/test/graph/index.test.ts +646 -0
  30. package/test/modules/agenda/node-cron.test.ts +286 -0
  31. package/test/modules/embedding/ai.test.ts +78 -0
  32. package/test/modules/memory/adapters/in-memory.test.ts +153 -0
  33. package/test/{memory → modules/memory}/adapters/meilisearch.test.ts +79 -75
  34. package/test/modules/memory/adapters/redis.test.ts +169 -0
  35. package/test/modules/memory/base.test.ts +230 -0
  36. package/test/services/agenda.test.ts +279 -280
  37. package/types/index.ts +82 -203
  38. package/utils/{stringifiy-zod-schema.ts → generate-action-schema.ts} +3 -3
  39. package/app/README.md +0 -36
  40. package/app/app/favicon.ico +0 -0
  41. package/app/app/globals.css +0 -21
  42. package/app/app/gun.ts +0 -0
  43. package/app/app/layout.tsx +0 -18
  44. package/app/app/page.tsx +0 -321
  45. package/app/eslint.config.mjs +0 -16
  46. package/app/next.config.ts +0 -7
  47. package/app/package-lock.json +0 -5912
  48. package/app/package.json +0 -31
  49. package/app/pnpm-lock.yaml +0 -4031
  50. package/app/postcss.config.mjs +0 -8
  51. package/app/public/file.svg +0 -1
  52. package/app/public/globe.svg +0 -1
  53. package/app/public/next.svg +0 -1
  54. package/app/public/vercel.svg +0 -1
  55. package/app/public/window.svg +0 -1
  56. package/app/tailwind.config.ts +0 -18
  57. package/app/tsconfig.json +0 -27
  58. package/dist/memory/index.js +0 -9
  59. package/dist/services/agenda.js +0 -115
  60. package/dist/services/queue.js +0 -142
  61. package/dist/utils/experimental-graph-rag.js +0 -152
  62. package/dist/utils/generate-object.js +0 -111
  63. package/dist/utils/inject-actions.js +0 -16
  64. package/dist/utils/queue-item-transformer.js +0 -24
  65. package/dist/utils/sanitize-results.js +0 -60
  66. package/memory/adapters/redis/index.ts +0 -103
  67. package/memory/index.ts +0 -22
  68. package/services/agenda.ts +0 -118
  69. package/services/embedding.ts +0 -26
  70. package/services/queue.ts +0 -145
  71. package/test/memory/adapters/redis.test.ts +0 -159
  72. package/test/memory/base.test.ts +0 -225
  73. package/test/services/queue.test.ts +0 -286
  74. package/utils/experimental-graph-rag.ts +0 -170
  75. package/utils/generate-object.ts +0 -117
  76. package/utils/inject-actions.ts +0 -19
  77. package/utils/queue-item-transformer.ts +0 -38
  78. package/utils/sanitize-results.ts +0 -66
package/graph/index.ts CHANGED
@@ -1,47 +1,131 @@
1
- import { GraphConfig, GraphContext, GraphDefinition, Node } from "../types";
2
- import EventEmitter from "events";
1
+ import { EventEmitter } from "events";
3
2
  import { ZodSchema } from "zod";
3
+ import { IEventEmitter } from "../interfaces";
4
+ import { GraphContext, GraphDefinition, Node } from "../types";
4
5
 
5
- export class Graph<T extends ZodSchema> {
6
+ /**
7
+ * @module GraphFlow
8
+ * @description A flexible workflow engine that manages the execution of nodes in a graph-like structure.
9
+ *
10
+ * Key features:
11
+ * - Multiple branches support
12
+ * - Conditional branching (runs first matching condition, or all if none have conditions)
13
+ * - Event-driven nodes
14
+ * - Zod validation of context/inputs/outputs
15
+ * - Automatic retry on node failures
16
+ *
17
+ * @template T - Extends ZodSchema for type validation
18
+ */
19
+ export class GraphFlow<T extends ZodSchema> {
6
20
  private nodes: Map<string, Node<T>>;
7
21
  private context: GraphContext<T>;
8
22
  public validator?: T;
9
- private eventEmitter: EventEmitter;
23
+ private eventEmitter: IEventEmitter;
10
24
  private globalErrorHandler?: (error: Error, context: GraphContext<T>) => void;
25
+ private graphEvents?: string[];
26
+ private entryNode?: string;
11
27
 
12
- constructor(public name: string, config: GraphConfig<T>) {
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
+ */
33
+ constructor(public name: string, config: GraphDefinition<T>) {
13
34
  this.nodes = new Map(config.nodes.map((node) => [node.name, node]));
14
- this.context = config.initialContext || ({} as GraphContext<T>);
15
- this.validator = config.validator;
16
- this.globalErrorHandler = config.globalErrorHandler;
17
- this.eventEmitter = new EventEmitter();
35
+ this.validator = config.schema;
36
+ this.context = config.schema.parse(config.context) as GraphContext<T>;
37
+ this.globalErrorHandler = config.onError;
38
+ this.eventEmitter = config.eventEmitter || new EventEmitter();
39
+ this.graphEvents = config.events;
40
+
18
41
  this.setupEventListeners();
42
+ this.setupGraphEventListeners();
19
43
  }
20
44
 
45
+ /**
46
+ * Creates a new context for execution
47
+ * @private
48
+ * @returns {GraphContext<T>} A cloned context to prevent pollution during parallel execution
49
+ */
21
50
  private createNewContext(): GraphContext<T> {
22
51
  return structuredClone(this.context);
23
52
  }
24
53
 
54
+ /**
55
+ * Sets up event listeners for node-based events
56
+ * @private
57
+ * @description Attaches all node-based event triggers while preserving external listeners
58
+ */
25
59
  private setupEventListeners(): void {
60
+ // First remove only the existing node-based listeners that we might have created previously
61
+ // We do NOT remove, for example, "nodeStarted" or "nodeCompleted" listeners that test code added.
62
+ for (const [eventName, listener] of this.eventEmitter
63
+ .rawListeners("*")
64
+ .entries()) {
65
+ // This can be tricky—EventEmitter doesn't directly let you remove by "type" of listener.
66
+ // Alternatively, we can store references in a separate structure.
67
+ // For simplicity, let's do a full removeAllListeners() on node-specified events (only),
68
+ // then re-add them below, but keep the test-based events like "nodeStarted" or "nodeCompleted".
69
+ }
70
+
71
+ // The simplest approach: removeAllListeners for each event that is declared as a node event
72
+ // so we don't stack up duplicates:
73
+ const allEvents = new Set<string>();
26
74
  for (const node of this.nodes.values()) {
27
- node.events?.forEach((event) => {
28
- this.eventEmitter.on(event, async (data?: Partial<GraphContext<T>>) => {
29
- const context = this.createNewContext();
30
- if (data) Object.assign(context, data);
31
- await this.executeNode(node.name, context);
75
+ if (node.events) {
76
+ node.events.forEach((evt) => allEvents.add(evt));
77
+ }
78
+ }
79
+ for (const evt of allEvents) {
80
+ // remove only those events that are used by nodes
81
+ this.eventEmitter.removeAllListeners(evt);
82
+ }
83
+
84
+ // Now re-add the node-based event triggers
85
+ for (const node of this.nodes.values()) {
86
+ if (node.events && node.events.length > 0) {
87
+ node.events.forEach((event) => {
88
+ this.eventEmitter.on(
89
+ event,
90
+ async (data?: Partial<GraphContext<T>>) => {
91
+ const freshContext = this.createNewContext();
92
+ if (data) Object.assign(freshContext, data);
93
+
94
+ // If triggered by an event, we pass "true" so event-driven node will skip `next`.
95
+ await this.executeNode(
96
+ node.name,
97
+ freshContext,
98
+ undefined,
99
+ /* triggeredByEvent= */ true
100
+ );
101
+ }
102
+ );
32
103
  });
33
- });
104
+ }
34
105
  }
35
106
  }
107
+
108
+ /**
109
+ * Executes a specific node in the graph
110
+ * @private
111
+ * @param {string} nodeName - Name of the node to execute
112
+ * @param {GraphContext<T>} context - Current execution context
113
+ * @param {any} inputs - Input parameters for the node
114
+ * @param {boolean} triggeredByEvent - Whether the execution was triggered by an event
115
+ * @returns {Promise<void>}
116
+ */
36
117
  private async executeNode(
37
118
  nodeName: string,
38
119
  context: GraphContext<T>,
39
- params?: any
120
+ inputs?: any,
121
+ triggeredByEvent: boolean = false
40
122
  ): Promise<void> {
41
123
  const node = this.nodes.get(nodeName);
42
- if (!node) throw new Error(`❌ Node ${nodeName} not found`);
124
+ if (!node) throw new Error(`❌ Node "${nodeName}" not found.`);
43
125
 
44
- if (node.condition && !node.condition(context)) return;
126
+ if (node.condition && !node.condition(context)) {
127
+ return;
128
+ }
45
129
 
46
130
  let attempts = 0;
47
131
  const maxAttempts = node.retry?.maxAttempts || 1;
@@ -49,43 +133,67 @@ export class Graph<T extends ZodSchema> {
49
133
 
50
134
  while (attempts < maxAttempts) {
51
135
  try {
52
- let validatedParams;
53
-
54
- // Si le nœud a un `parameters`, on valide `params` avant exécution
55
- if (node.parameters) {
56
- if (!params) {
136
+ let validatedInputs;
137
+ if (node.inputs) {
138
+ if (!inputs) {
57
139
  throw new Error(
58
- `❌ Paramètres requis pour le nœud "${nodeName}" mais reçus: ${params}`
140
+ `❌ Inputs required for node "${nodeName}" but received: ${inputs}`
59
141
  );
60
142
  }
61
- validatedParams = node.parameters.parse(params);
143
+ validatedInputs = node.inputs.parse(inputs);
62
144
  }
63
145
 
64
146
  this.eventEmitter.emit("nodeStarted", { name: nodeName, context });
65
- if (node.execute) {
66
- await node.execute(context);
67
- } else if (node.executeWithParams) {
68
- if (!validatedParams) {
69
- throw new Error(
70
- `❌ Paramètres invalides pour le nœud "${nodeName}"`
71
- );
72
- }
73
- await node.executeWithParams(context, validatedParams);
147
+
148
+ // Execute the node
149
+ await node.execute(context, validatedInputs);
150
+
151
+ if (node.outputs) {
152
+ node.outputs.parse(context);
74
153
  }
75
154
 
76
155
  this.validateContext(context);
77
-
78
156
  this.eventEmitter.emit("nodeCompleted", { name: nodeName, context });
79
157
 
80
- if (node.next) {
81
- await Promise.all(
82
- node.next.map((nextNode) => this.executeNode(nextNode, context))
83
- );
158
+ // IMPORTANT: Si le nœud est déclenché par un événement et a des événements définis,
159
+ // on arrête ici et on ne suit pas la chaîne next
160
+ if (triggeredByEvent && node.events && node.events.length > 0) {
161
+ this.context = structuredClone(context);
162
+ return;
163
+ }
164
+
165
+ // Gérer les nœuds suivants
166
+ if (node.next && node.next.length > 0) {
167
+ const branchContexts: GraphContext<T>[] = [];
168
+
169
+ // Exécuter toutes les branches valides
170
+ for (const nextNodeName of node.next) {
171
+ const nextNode = this.nodes.get(nextNodeName);
172
+ if (!nextNode) continue;
173
+
174
+ const branchContext = structuredClone(context);
175
+
176
+ // Si le nœud a une condition et qu'elle n'est pas remplie, passer au suivant
177
+ if (nextNode.condition && !nextNode.condition(branchContext)) {
178
+ continue;
179
+ }
180
+
181
+ await this.executeNode(nextNodeName, branchContext);
182
+ branchContexts.push(branchContext);
183
+ }
184
+
185
+ // Fusionner les résultats des branches dans l'ordre
186
+ if (branchContexts.length > 0) {
187
+ const finalContext = branchContexts[branchContexts.length - 1];
188
+ Object.assign(context, finalContext);
189
+ }
84
190
  }
191
+
192
+ // Mettre à jour le contexte global
193
+ this.context = structuredClone(context);
85
194
  return;
86
195
  } catch (error) {
87
196
  attempts++;
88
-
89
197
  if (attempts >= maxAttempts) {
90
198
  this.eventEmitter.emit("nodeError", { nodeName, error });
91
199
  node.onError?.(error as Error);
@@ -97,97 +205,264 @@ export class Graph<T extends ZodSchema> {
97
205
  `[Graph ${this.name}] Retry attempt ${attempts} for node ${nodeName}`,
98
206
  { error }
99
207
  );
100
-
101
208
  await new Promise((resolve) => setTimeout(resolve, delay));
102
209
  }
103
210
  }
104
211
  }
105
212
 
213
+ /**
214
+ * Validates the current context against the schema
215
+ * @private
216
+ * @param {GraphContext<T>} context - Context to validate
217
+ * @throws {Error} If validation fails
218
+ */
106
219
  private validateContext(context: GraphContext<T>): void {
107
220
  if (this.validator) {
108
221
  this.validator.parse(context);
109
222
  }
110
223
  }
111
224
 
225
+ /**
226
+ * Executes the graph flow starting from a specific node
227
+ * @param {string} startNode - Name of the node to start execution from
228
+ * @param {Partial<GraphContext<T>>} inputContext - Optional partial context to merge with current context
229
+ * @param {any} inputParams - Optional input parameters for the start node
230
+ * @returns {Promise<GraphContext<T>>} Final context after execution
231
+ */
112
232
  async execute(
113
233
  startNode: string,
114
234
  inputContext?: Partial<GraphContext<T>>,
115
235
  inputParams?: any
116
236
  ): Promise<GraphContext<T>> {
237
+ // Fresh local context from the global
117
238
  const context = this.createNewContext();
118
239
  if (inputContext) Object.assign(context, inputContext);
119
240
 
241
+ // Emit "graphStarted"
120
242
  this.eventEmitter.emit("graphStarted", { name: this.name });
243
+
121
244
  try {
122
- await this.executeNode(startNode, context, inputParams);
123
- this.eventEmitter.emit("graphCompleted", { name: this.name, context });
124
- return context;
245
+ // Because we're calling explicitly, it's NOT triggered by an event
246
+ await this.executeNode(
247
+ startNode,
248
+ context,
249
+ inputParams,
250
+ /* triggeredByEvent= */ false
251
+ );
252
+
253
+ // Emit "graphCompleted"
254
+ this.eventEmitter.emit("graphCompleted", {
255
+ name: this.name,
256
+ context: this.context,
257
+ });
258
+
259
+ // Return a snapshot of the final global context
260
+ return structuredClone(this.context);
125
261
  } catch (error) {
262
+ // Emit "graphError"
126
263
  this.eventEmitter.emit("graphError", { name: this.name, error });
127
- this.globalErrorHandler?.(error as Error, context); // Gestionnaire d'erreurs global
264
+ this.globalErrorHandler?.(error as Error, context);
128
265
  throw error;
129
266
  }
130
267
  }
131
268
 
132
- emit(
269
+ /**
270
+ * Emits an event to trigger event-based nodes
271
+ * @param {string} eventName - Name of the event to emit
272
+ * @param {Partial<GraphContext<T>>} data - Optional data to merge with context
273
+ * @returns {Promise<GraphContext<T>>} Updated context after event handling
274
+ */
275
+ public async emit(
133
276
  eventName: string,
134
277
  data?: Partial<GraphContext<T>>
135
278
  ): Promise<GraphContext<T>> {
136
- return new Promise((resolve, reject) => {
137
- if (data) Object.assign(this.context, data); // ✅ Met à jour le contexte global
279
+ // Merge data into a fresh copy of the global context if desired
280
+ const context = this.createNewContext();
281
+ if (data) Object.assign(context, data);
138
282
 
139
- this.eventEmitter.emit(eventName, this.context); // Utilise le contexte global
283
+ // Just emit the event; the node-based event listeners in setupEventListeners()
284
+ // will handle calling "executeNode(...)"
285
+ this.eventEmitter.emit(eventName, context);
140
286
 
141
- const eventNodes = Array.from(this.nodes.values()).filter((node) =>
142
- node.events?.includes(eventName)
143
- );
144
- if (eventNodes.length === 0) return resolve(this.context);
145
-
146
- Promise.all(
147
- eventNodes.map(
148
- (node) =>
149
- new Promise<void>((resolve) => {
150
- this.eventEmitter.once("nodeCompleted", ({ nodeName }) => {
151
- if (nodeName === node.name) resolve();
152
- });
153
- })
154
- )
155
- )
156
- .then(() => resolve(this.context))
157
- .catch(reject);
158
- });
287
+ // Return the updated global context
288
+ return this.getContext();
159
289
  }
160
290
 
291
+ /**
292
+ * Registers an event handler
293
+ * @param {string} eventName - Name of the event to listen for
294
+ * @param {Function} handler - Handler function to execute when event is emitted
295
+ */
161
296
  on(eventName: string, handler: (...args: any[]) => void): void {
162
297
  this.eventEmitter.on(eventName, handler);
163
298
  }
164
299
 
165
- loadDefinition(definition: GraphDefinition<T>): void {
300
+ /**
301
+ * Updates the graph definition with new configuration
302
+ * @param {GraphDefinition<T>} definition - New graph definition
303
+ */
304
+ load(definition: GraphDefinition<T>): void {
305
+ // Clear all existing nodes
166
306
  this.nodes.clear();
167
- Object.values(definition.nodes).forEach((node) =>
168
- this.nodes.set(node.name, node)
169
- );
170
- this.setupEventListeners();
307
+ // Wipe out old node-based event listeners
308
+ // (We keep external test listeners like "nodeStarted" or "nodeCompleted".)
309
+ if (definition.nodes?.length) {
310
+ const allEvents = new Set<string>();
311
+ definition.nodes.forEach((n) =>
312
+ n.events?.forEach((evt) => allEvents.add(evt))
313
+ );
314
+ for (const evt of allEvents) {
315
+ this.eventEmitter.removeAllListeners(evt);
316
+ }
317
+ }
318
+
319
+ // Add in new nodes
320
+ definition.nodes.forEach((node) => this.nodes.set(node.name, node));
321
+
322
+ // Parse the new context
323
+ this.context = definition.schema.parse(
324
+ definition.context
325
+ ) as GraphContext<T>;
326
+ this.validator = definition.schema;
327
+
328
+ // Store entry node
329
+ this.entryNode = definition.entryNode;
330
+ // Store graph events
331
+ this.graphEvents = definition.events;
332
+
333
+ // Re-setup only node-based event triggers
334
+ for (const node of this.nodes.values()) {
335
+ if (node.events && node.events.length > 0) {
336
+ node.events.forEach((event) => {
337
+ this.eventEmitter.on(
338
+ event,
339
+ async (data?: Partial<GraphContext<T>>) => {
340
+ const freshContext = structuredClone(this.context);
341
+ if (data) Object.assign(freshContext, data);
342
+ await this.executeNode(node.name, freshContext, undefined, true);
343
+ }
344
+ );
345
+ });
346
+ }
347
+ }
348
+
349
+ // Re-setup graph event listeners
350
+ this.setupGraphEventListeners();
171
351
  }
172
352
 
353
+ /**
354
+ * Returns the current context
355
+ * @returns {GraphContext<T>} Current graph context
356
+ */
173
357
  getContext(): GraphContext<T> {
174
358
  return structuredClone(this.context);
175
359
  }
176
360
 
361
+ /**
362
+ * Logs a message with optional data
363
+ * @param {string} message - Message to log
364
+ * @param {any} data - Optional data to log
365
+ */
177
366
  log(message: string, data?: any): void {
178
367
  console.log(`[Graph ${this.name}] ${message}`, data);
179
368
  }
180
369
 
370
+ /**
371
+ * Adds a new node to the graph
372
+ * @param {Node<T>} node - Node to add
373
+ * @throws {Error} If node with same name already exists
374
+ */
181
375
  addNode(node: Node<T>): void {
182
376
  this.nodes.set(node.name, node);
183
- this.setupEventListeners();
377
+ if (node.events && node.events.length > 0) {
378
+ for (const evt of node.events) {
379
+ this.eventEmitter.on(evt, async (data?: Partial<GraphContext<T>>) => {
380
+ const freshContext = this.createNewContext();
381
+ if (data) Object.assign(freshContext, data);
382
+ await this.executeNode(node.name, freshContext, undefined, true);
383
+ });
384
+ }
385
+ }
184
386
  }
185
387
 
388
+ /**
389
+ * Removes a node from the graph
390
+ * @param {string} nodeName - Name of the node to remove
391
+ */
186
392
  removeNode(nodeName: string): void {
393
+ const node = this.nodes.get(nodeName);
394
+ if (!node) return;
395
+
396
+ // remove the node from the map
187
397
  this.nodes.delete(nodeName);
398
+
399
+ // remove any of its event-based listeners
400
+ if (node.events && node.events.length > 0) {
401
+ for (const evt of node.events) {
402
+ // removeAllListeners(evt) would also remove other node listeners,
403
+ // so we need a more fine-grained approach. Ideally, we should keep a reference
404
+ // to the exact listener function we attached. For brevity, let's remove all for that event:
405
+ this.eventEmitter.removeAllListeners(evt);
406
+ }
407
+ // Then reattach the others that remain in the graph
408
+ for (const n of this.nodes.values()) {
409
+ if (n.events && n.events.length > 0) {
410
+ n.events.forEach((e) => {
411
+ this.eventEmitter.on(e, async (data?: Partial<GraphContext<T>>) => {
412
+ const freshContext = this.createNewContext();
413
+ if (data) Object.assign(freshContext, data);
414
+ await this.executeNode(n.name, freshContext, undefined, true);
415
+ });
416
+ });
417
+ }
418
+ }
419
+ }
188
420
  }
189
421
 
422
+ /**
423
+ * Returns all nodes in the graph
424
+ * @returns {Node<T>[]} Array of all nodes
425
+ */
190
426
  getNodes(): Node<T>[] {
191
427
  return Array.from(this.nodes.values());
192
428
  }
429
+
430
+ private setupGraphEventListeners(): void {
431
+ if (this.graphEvents && this.graphEvents.length > 0) {
432
+ this.graphEvents.forEach((event) => {
433
+ this.eventEmitter.on(event, async (data?: Partial<GraphContext<T>>) => {
434
+ const freshContext = this.createNewContext();
435
+ if (data) Object.assign(freshContext, data);
436
+
437
+ // Emit "graphStarted"
438
+ this.eventEmitter.emit("graphStarted", { name: this.name });
439
+
440
+ try {
441
+ // Execute the graph starting from the entry node
442
+ if (!this.entryNode) {
443
+ throw new Error("No entry node defined for graph event handling");
444
+ }
445
+
446
+ await this.executeNode(
447
+ this.entryNode,
448
+ freshContext,
449
+ undefined,
450
+ false
451
+ );
452
+
453
+ // Emit "graphCompleted"
454
+ this.eventEmitter.emit("graphCompleted", {
455
+ name: this.name,
456
+ context: this.context,
457
+ });
458
+ } catch (error) {
459
+ // Emit "graphError"
460
+ this.eventEmitter.emit("graphError", { name: this.name, error });
461
+ this.globalErrorHandler?.(error as Error, freshContext);
462
+ throw error;
463
+ }
464
+ });
465
+ });
466
+ }
467
+ }
193
468
  }
package/index.ts CHANGED
@@ -1,11 +1,29 @@
1
+ /**
2
+ * @module @ai.ntellect/core
3
+ * @description Core module with workflow functionality, providing graph management,
4
+ * memory storage, agenda scheduling, and embedding capabilities.
5
+ *
6
+ * This module exports various components:
7
+ * - Graph management and controller
8
+ * - Memory storage adapters (Meilisearch, Redis)
9
+ * - Agenda scheduling with node-cron adapter
10
+ * - Embedding functionality with AI adapter
11
+ * - Utility functions for action schema generation and header building
12
+ */
13
+
1
14
  export * from "./graph";
2
15
  export * from "./graph/controller";
3
- export * from "./memory";
4
- export * from "./memory/adapters/meilisearch";
5
- export * from "./memory/adapters/redis";
16
+ export * from "./modules/memory";
17
+ export * from "./modules/memory/adapters/meilisearch";
18
+ export * from "./modules/memory/adapters/redis";
6
19
 
7
20
  export * from "./interfaces";
8
- export * from "./services/agenda";
9
- export * from "./services/embedding";
21
+ export * from "./modules/agenda";
22
+ export * from "./modules/agenda/adapters/node-cron";
23
+ export * from "./modules/embedding";
24
+ export * from "./modules/embedding/adapters/ai";
25
+
10
26
  export * from "./types";
11
- export * from "./utils/stringifiy-zod-schema";
27
+
28
+ export * from "./utils/generate-action-schema";
29
+ export * from "./utils/header-builder";