@ai.ntellect/core 0.8.1 → 0.8.3

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 (47) hide show
  1. package/README.md +190 -118
  2. package/dist/graph/controller.d.ts +4 -5
  3. package/dist/graph/controller.d.ts.map +1 -1
  4. package/dist/graph/controller.js +10 -10
  5. package/dist/graph/controller.js.map +1 -1
  6. package/dist/graph/event-manager.d.ts.map +1 -1
  7. package/dist/graph/event-manager.js +4 -4
  8. package/dist/graph/event-manager.js.map +1 -1
  9. package/dist/graph/index.d.ts +5 -16
  10. package/dist/graph/index.d.ts.map +1 -1
  11. package/dist/graph/index.js +32 -52
  12. package/dist/graph/index.js.map +1 -1
  13. package/dist/graph/node.d.ts +1 -10
  14. package/dist/graph/node.d.ts.map +1 -1
  15. package/dist/graph/node.js +7 -36
  16. package/dist/graph/node.js.map +1 -1
  17. package/dist/graph/observer.d.ts +4 -0
  18. package/dist/graph/observer.d.ts.map +1 -1
  19. package/dist/graph/observer.js +27 -1
  20. package/dist/graph/observer.js.map +1 -1
  21. package/dist/modules/agent/agent.d.ts.map +1 -1
  22. package/dist/modules/agent/agent.js +3 -6
  23. package/dist/modules/agent/agent.js.map +1 -1
  24. package/dist/modules/agent/generic-assistant.d.ts.map +1 -1
  25. package/dist/modules/agent/generic-assistant.js +3 -3
  26. package/dist/modules/agent/generic-assistant.js.map +1 -1
  27. package/dist/modules/agent/generic-executor.d.ts +1 -0
  28. package/dist/modules/agent/generic-executor.d.ts.map +1 -1
  29. package/dist/modules/agent/generic-executor.js +24 -35
  30. package/dist/modules/agent/generic-executor.js.map +1 -1
  31. package/dist/modules/agent/llm-factory.d.ts.map +1 -1
  32. package/dist/types/index.d.ts +90 -25
  33. package/dist/types/index.d.ts.map +1 -1
  34. package/graph/controller.ts +10 -11
  35. package/graph/event-manager.ts +2 -14
  36. package/graph/index.ts +37 -67
  37. package/graph/node.ts +5 -39
  38. package/graph/observer.ts +35 -5
  39. package/modules/agent/agent.ts +7 -8
  40. package/modules/agent/generic-assistant.ts +7 -5
  41. package/modules/agent/generic-executor.ts +33 -40
  42. package/package.json +1 -1
  43. package/test/graph/controller.test.ts +62 -17
  44. package/test/graph/index.test.ts +128 -133
  45. package/test/graph/node.test.ts +38 -233
  46. package/test/graph/observer.test.ts +18 -23
  47. package/types/index.ts +91 -28
@@ -5,7 +5,6 @@ import sinon from "sinon";
5
5
  import { z } from "zod";
6
6
  import { GraphController } from "../../graph/controller";
7
7
  import { GraphFlow } from "../../graph/index";
8
- import { NodeParams } from "../../graph/node";
9
8
  import { GraphConfig, GraphContext, GraphNodeConfig } from "../../types";
10
9
 
11
10
  use(chaiAsPromised);
@@ -19,7 +18,7 @@ use(chaiAsPromised);
19
18
  * - eventPayload: optional object containing transaction metadata
20
19
  */
21
20
  const TestSchema = z.object({
22
- value: z.number().default(0),
21
+ value: z.number().min(0).default(0),
23
22
  counter: z.number().default(0),
24
23
  message: z.string().default(""),
25
24
  eventPayload: z
@@ -51,11 +50,11 @@ describe("GraphFlow", function () {
51
50
 
52
51
  beforeEach(() => {
53
52
  eventEmitter = new EventEmitter();
54
- graph = new GraphFlow("TestGraph", {
53
+ graph = new GraphFlow({
55
54
  name: "TestGraph",
55
+ schema: TestSchema,
56
56
  nodes: [],
57
57
  context: { value: 0 },
58
- schema: TestSchema,
59
58
  eventEmitter: eventEmitter,
60
59
  });
61
60
  });
@@ -165,10 +164,9 @@ describe("GraphFlow", function () {
165
164
 
166
165
  graph.addNode(simpleNode);
167
166
  await graph.execute("simpleNode", invalidContext as any);
168
- } catch (error) {
169
- expect((error as Error & { errors: any[] }).errors[0].message).to.include(
170
- "Expected number"
171
- );
167
+ expect.fail("Should have thrown an error");
168
+ } catch (error: any) {
169
+ expect(error.message).to.include("Expected number");
172
170
  }
173
171
  });
174
172
 
@@ -181,23 +179,22 @@ describe("GraphFlow", function () {
181
179
  * Ensures type safety and data consistency in node interactions
182
180
  */
183
181
  it("should execute a node with validated params and outputs", async function () {
184
- const paramNode: GraphNodeConfig<TestSchema, { increment: number }> = {
185
- name: "paramNode",
186
- params: z.object({
187
- increment: z.number(),
188
- }),
189
- execute: async (context, params?: { increment: number }) => {
190
- if (!params) throw new Error("params required");
191
- context.value = (context.value ?? 0) + params.increment;
192
- },
193
- next: [],
194
- };
195
-
196
- graph.addNode(paramNode);
197
- await graph.execute("paramNode", { increment: 5 });
182
+ const graph = new GraphFlow({
183
+ name: "test",
184
+ schema: TestSchema,
185
+ nodes: [
186
+ {
187
+ name: "validatedNode",
188
+ execute: async (context: GraphContext<TestSchema>) => {
189
+ context.value = 5;
190
+ },
191
+ },
192
+ ],
193
+ context: { value: 0, counter: 0, message: "" },
194
+ });
198
195
 
199
- const context = graph.getContext();
200
- expect(context.value).to.equal(5);
196
+ await graph.execute("validatedNode");
197
+ expect(graph.getContext().value).to.equal(5);
201
198
  });
202
199
 
203
200
  /**
@@ -251,8 +248,8 @@ describe("GraphFlow", function () {
251
248
  },
252
249
  };
253
250
 
254
- const graph = new GraphFlow("test", {
255
- name: "test",
251
+ const graph = new GraphFlow({
252
+ name: "retryGraph",
256
253
  schema: TestSchema,
257
254
  context: { value: 0 },
258
255
  nodes: [retryNode],
@@ -292,10 +289,10 @@ describe("GraphFlow", function () {
292
289
 
293
290
  const newDefinition: GraphConfig<TestSchema> = {
294
291
  name: "TestGraph",
295
- entryNode: "A",
292
+ schema: TestSchema,
296
293
  nodes: [nodeA, nodeB],
297
294
  context: { value: 0 },
298
- schema: TestSchema,
295
+ entryNode: "A",
299
296
  };
300
297
 
301
298
  graph.load(newDefinition);
@@ -307,93 +304,107 @@ describe("GraphFlow", function () {
307
304
  * Tests input validation error handling
308
305
  */
309
306
  it("should throw error when node input validation fails", async () => {
310
- const node: GraphNodeConfig<TestSchema> = {
311
- name: "test",
312
- params: z.object({
313
- value: z.number().min(0),
314
- }),
315
- execute: async (context, params) => {
316
- if (!params) throw new Error("params required");
317
- context.value = params.value;
318
- },
319
- };
320
-
321
- const graph = new GraphFlow("test", {
307
+ const graph = new GraphFlow({
322
308
  name: "test",
323
309
  schema: TestSchema,
324
- context: { value: 0 },
325
- nodes: [node],
310
+ nodes: [
311
+ {
312
+ name: "test",
313
+ execute: async (context: GraphContext<TestSchema>) => {
314
+ context.value = -1;
315
+ },
316
+ },
317
+ ],
318
+ context: { value: 0, counter: 0, message: "" },
326
319
  });
327
320
 
328
321
  try {
329
322
  await graph.execute("test", { value: -1 });
330
323
  expect.fail("Should have thrown an error");
331
324
  } catch (error: any) {
332
- expect(error.message).to.include("Number must be greater than or equal");
325
+ expect(error.message).to.include(
326
+ "Number must be greater than or equal to 0"
327
+ );
333
328
  }
334
329
  });
330
+
335
331
  /**
336
332
  * Tests successful input/output validation flow
337
333
  */
338
- it("should successfully validate both params and outputs", async function () {
339
- const graph = new GraphFlow("test", {
334
+ it("should execute a node with validated context", async function () {
335
+ const graph = new GraphFlow({
340
336
  name: "test",
337
+ schema: TestSchema,
341
338
  nodes: [
342
339
  {
343
340
  name: "validatedNode",
344
- params: z.object({
345
- increment: z.number().min(0).max(5),
346
- }),
347
- execute: async (
348
- context: GraphContext<TestSchema>,
349
- params?: NodeParams
350
- ) => {
351
- if (!params) throw new Error("params required");
352
- context.value = (context.value ?? 0) + params.increment;
341
+ execute: async (context: GraphContext<TestSchema>) => {
342
+ context.value = 5;
353
343
  },
354
344
  },
355
345
  ],
356
- schema: TestSchema,
357
346
  context: { value: 0, counter: 0, message: "" },
358
347
  });
359
348
 
360
- // Test avec valeur valide
361
- await graph.execute("validatedNode", { increment: 3 });
362
- expect(graph.getContext().value).to.equal(3);
363
-
364
- // Test avec valeur invalide
365
- await expect(
366
- graph.execute("validatedNode", { increment: 10 })
367
- ).to.be.rejectedWith("Number must be less than or equal to 5");
349
+ await graph.execute("validatedNode");
350
+ expect(graph.getContext().value).to.equal(5);
368
351
  });
369
352
 
370
- /**
371
- * Tests handling of missing required params
372
- */
373
- it("should throw error when required params are missing", async function () {
374
- const graph = new GraphFlow("test", {
353
+ it("should throw error when required context values are missing", async function () {
354
+ const graph = new GraphFlow({
375
355
  name: "test",
356
+ schema: TestSchema,
376
357
  nodes: [
377
358
  {
378
359
  name: "requiredInputNode",
379
- params: z.object({
380
- value: z.number(),
381
- }),
382
- execute: async (
383
- context: GraphContext<TestSchema>,
384
- params?: NodeParams
385
- ) => {
386
- context.counter = params?.value || 0;
360
+ execute: async (context: GraphContext<TestSchema>) => {
361
+ if (context.value === undefined) {
362
+ throw new Error("Value is required");
363
+ }
364
+ context.counter = context.value;
387
365
  },
388
366
  },
389
367
  ],
368
+ context: { value: 0, counter: 0, message: "" },
369
+ });
370
+
371
+ try {
372
+ graph["context"].value = undefined;
373
+ await graph.execute("requiredInputNode");
374
+ throw new Error("Should have thrown an error");
375
+ } catch (error: any) {
376
+ expect(error.message).to.equal("Value is required");
377
+ }
378
+ });
379
+
380
+ it("should validate context against schema constraints", async () => {
381
+ const graph = new GraphFlow({
382
+ name: "test",
390
383
  schema: TestSchema,
384
+ nodes: [
385
+ {
386
+ name: "validationNode",
387
+ execute: async (context: GraphContext<TestSchema>) => {
388
+ const newContext = { ...context, value: -1 };
389
+ const validationResult = TestSchema.safeParse(newContext);
390
+ if (!validationResult.success) {
391
+ throw new Error(validationResult.error.errors[0].message);
392
+ }
393
+ graph["context"] = newContext;
394
+ },
395
+ },
396
+ ],
391
397
  context: { value: 0, counter: 0, message: "" },
392
398
  });
393
399
 
394
- await expect(graph.execute("requiredInputNode")).to.be.rejectedWith(
395
- "Params required for node"
396
- );
400
+ try {
401
+ await graph.execute("validationNode");
402
+ throw new Error("Should have thrown an error");
403
+ } catch (error: any) {
404
+ expect(error.message).to.include(
405
+ "Number must be greater than or equal to 0"
406
+ );
407
+ }
397
408
  });
398
409
 
399
410
  /**
@@ -483,11 +494,11 @@ describe("GraphFlow", function () {
483
494
  */
484
495
  it("should handle parallel workflows using GraphController", async function () {
485
496
  // Graph 1
486
- const graph1 = new GraphFlow("Graph1", {
497
+ const graph1 = new GraphFlow({
487
498
  name: "Graph1",
488
- nodes: [],
489
- context: { value: 0 },
490
499
  schema: TestSchema,
500
+ context: { value: 0 },
501
+ nodes: [],
491
502
  });
492
503
 
493
504
  const processNode1: GraphNodeConfig<TestSchema> = {
@@ -506,11 +517,11 @@ describe("GraphFlow", function () {
506
517
  };
507
518
 
508
519
  // Graph 2
509
- const graph2 = new GraphFlow("Graph2", {
520
+ const graph2 = new GraphFlow({
510
521
  name: "Graph2",
511
- nodes: [],
512
- context: { value: 0 },
513
522
  schema: TestSchema,
523
+ context: { value: 0 },
524
+ nodes: [],
514
525
  });
515
526
 
516
527
  const processNode2: GraphNodeConfig<TestSchema> = {
@@ -549,11 +560,11 @@ describe("GraphFlow", function () {
549
560
  */
550
561
  it("should handle sequential workflows using GraphController", async function () {
551
562
  // Graph 1
552
- const graph1 = new GraphFlow("Graph1", {
563
+ const graph1 = new GraphFlow({
553
564
  name: "Graph1",
554
- nodes: [],
555
- context: { value: 1 },
556
565
  schema: TestSchema,
566
+ context: { value: 1 },
567
+ nodes: [],
557
568
  });
558
569
 
559
570
  const startNode1: GraphNodeConfig<TestSchema> = {
@@ -564,11 +575,11 @@ describe("GraphFlow", function () {
564
575
  };
565
576
 
566
577
  // Graph 2
567
- const graph2 = new GraphFlow("Graph2", {
578
+ const graph2 = new GraphFlow({
568
579
  name: "Graph2",
569
- nodes: [],
570
- context: { value: 3 },
571
580
  schema: TestSchema,
581
+ context: { value: 3 },
582
+ nodes: [],
572
583
  });
573
584
 
574
585
  const startNode2: GraphNodeConfig<TestSchema> = {
@@ -629,58 +640,42 @@ describe("GraphFlow", function () {
629
640
  expect(result.value).to.equal(6); // 1 (waitingNode) + 5 (finalNode)
630
641
  });
631
642
 
632
- // Test de validation des paramètres
633
- it("should successfully validate params", async () => {
634
- const graph = new GraphFlow("test", {
643
+ it("should wait for correlated events", async function () {
644
+ const graph = new GraphFlow({
635
645
  name: "test",
646
+ schema: TestSchema,
636
647
  nodes: [
637
648
  {
638
- name: "validationNode",
639
- params: z.object({
640
- value: z.number().max(10),
641
- }),
642
- execute: async (
643
- context: GraphContext<TestSchema>,
644
- params?: NodeParams
645
- ) => {
646
- context.counter = params?.value || 0;
649
+ name: "correlatedEventsNode",
650
+ when: {
651
+ events: ["eventA", "eventB"],
652
+ timeout: 1000,
653
+ strategy: {
654
+ type: "correlate",
655
+ correlation: (events) => {
656
+ const eventA = events.find((e) => e.type === "eventA");
657
+ const eventB = events.find((e) => e.type === "eventB");
658
+ return eventA?.payload?.id === eventB?.payload?.id;
659
+ },
660
+ },
661
+ },
662
+ execute: async (context: GraphContext<TestSchema>) => {
663
+ context.message = "Correlated events received";
647
664
  },
648
665
  },
649
666
  ],
650
- schema: TestSchema,
651
667
  context: { value: 0, counter: 0, message: "" },
652
668
  });
653
669
 
654
- // Test avec valeur invalide
655
- await expect(
656
- graph.execute("validationNode", { value: 20 })
657
- ).to.be.rejectedWith("Number must be less than or equal to 10");
658
- });
670
+ const execution = graph.execute("correlatedEventsNode");
659
671
 
660
- // Test des paramètres requis
661
- it("should throw error when required params are missing", async () => {
662
- const graph = new GraphFlow("test", {
663
- name: "test",
664
- nodes: [
665
- {
666
- name: "requiredInputNode",
667
- params: z.object({
668
- value: z.number(),
669
- }),
670
- execute: async (
671
- context: GraphContext<TestSchema>,
672
- params?: NodeParams
673
- ) => {
674
- context.counter = params?.value || 0;
675
- },
676
- },
677
- ],
678
- schema: TestSchema,
679
- context: { value: 0, counter: 0, message: "" },
680
- });
672
+ // Émettre les événements corrélés
673
+ setTimeout(() => {
674
+ graph.emit("eventA", { id: "123", status: "completed" });
675
+ graph.emit("eventB", { id: "123", status: "available" });
676
+ }, 100);
681
677
 
682
- await expect(graph.execute("requiredInputNode")).to.be.rejectedWith(
683
- "Params required for node"
684
- );
678
+ await execution;
679
+ expect(graph.getContext().message).to.equal("Correlated events received");
685
680
  });
686
681
  });