@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.
- package/README.md +190 -118
- package/dist/graph/controller.d.ts +4 -5
- package/dist/graph/controller.d.ts.map +1 -1
- package/dist/graph/controller.js +10 -10
- package/dist/graph/controller.js.map +1 -1
- package/dist/graph/event-manager.d.ts.map +1 -1
- package/dist/graph/event-manager.js +4 -4
- package/dist/graph/event-manager.js.map +1 -1
- package/dist/graph/index.d.ts +5 -16
- package/dist/graph/index.d.ts.map +1 -1
- package/dist/graph/index.js +32 -52
- package/dist/graph/index.js.map +1 -1
- package/dist/graph/node.d.ts +1 -10
- package/dist/graph/node.d.ts.map +1 -1
- package/dist/graph/node.js +7 -36
- package/dist/graph/node.js.map +1 -1
- package/dist/graph/observer.d.ts +4 -0
- package/dist/graph/observer.d.ts.map +1 -1
- package/dist/graph/observer.js +27 -1
- package/dist/graph/observer.js.map +1 -1
- package/dist/modules/agent/agent.d.ts.map +1 -1
- package/dist/modules/agent/agent.js +3 -6
- package/dist/modules/agent/agent.js.map +1 -1
- package/dist/modules/agent/generic-assistant.d.ts.map +1 -1
- package/dist/modules/agent/generic-assistant.js +3 -3
- package/dist/modules/agent/generic-assistant.js.map +1 -1
- package/dist/modules/agent/generic-executor.d.ts +1 -0
- package/dist/modules/agent/generic-executor.d.ts.map +1 -1
- package/dist/modules/agent/generic-executor.js +24 -35
- package/dist/modules/agent/generic-executor.js.map +1 -1
- package/dist/modules/agent/llm-factory.d.ts.map +1 -1
- package/dist/types/index.d.ts +90 -25
- package/dist/types/index.d.ts.map +1 -1
- package/graph/controller.ts +10 -11
- package/graph/event-manager.ts +2 -14
- package/graph/index.ts +37 -67
- package/graph/node.ts +5 -39
- package/graph/observer.ts +35 -5
- package/modules/agent/agent.ts +7 -8
- package/modules/agent/generic-assistant.ts +7 -5
- package/modules/agent/generic-executor.ts +33 -40
- package/package.json +1 -1
- package/test/graph/controller.test.ts +62 -17
- package/test/graph/index.test.ts +128 -133
- package/test/graph/node.test.ts +38 -233
- package/test/graph/observer.test.ts +18 -23
- package/types/index.ts +91 -28
package/test/graph/index.test.ts
CHANGED
@@ -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(
|
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
|
-
|
169
|
-
|
170
|
-
|
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
|
185
|
-
name: "
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
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
|
-
|
200
|
-
expect(
|
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(
|
255
|
-
name: "
|
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
|
-
|
292
|
+
schema: TestSchema,
|
296
293
|
nodes: [nodeA, nodeB],
|
297
294
|
context: { value: 0 },
|
298
|
-
|
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
|
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
|
-
|
325
|
-
|
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(
|
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
|
339
|
-
const graph = new GraphFlow(
|
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
|
-
|
345
|
-
|
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
|
-
|
361
|
-
|
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
|
-
|
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
|
-
|
380
|
-
value
|
381
|
-
|
382
|
-
|
383
|
-
context
|
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
|
-
|
395
|
-
|
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(
|
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(
|
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(
|
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(
|
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
|
-
|
633
|
-
|
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: "
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
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
|
-
|
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
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
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
|
683
|
-
|
684
|
-
);
|
678
|
+
await execution;
|
679
|
+
expect(graph.getContext().message).to.equal("Correlated events received");
|
685
680
|
});
|
686
681
|
});
|