@mastra/inngest 0.0.0-workflow-deno-20250616132510 → 0.0.0-working-memory-per-user-20250620161509
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 +40 -5
- package/dist/_tsup-dts-rollup.d.cts +46 -16
- package/dist/_tsup-dts-rollup.d.ts +46 -16
- package/dist/index.cjs +183 -19
- package/dist/index.js +183 -19
- package/package.json +6 -6
- package/src/index.test.ts +1368 -131
- package/src/index.ts +251 -26
package/src/index.test.ts
CHANGED
|
@@ -5,10 +5,12 @@ import { openai } from '@ai-sdk/openai';
|
|
|
5
5
|
import { serve } from '@hono/node-server';
|
|
6
6
|
import { realtimeMiddleware } from '@inngest/realtime';
|
|
7
7
|
import { createTool, Mastra, Telemetry } from '@mastra/core';
|
|
8
|
+
import type { StreamEvent } from '@mastra/core';
|
|
8
9
|
import { Agent } from '@mastra/core/agent';
|
|
9
10
|
import { RuntimeContext } from '@mastra/core/runtime-context';
|
|
10
11
|
import { createHonoServer } from '@mastra/deployer/server';
|
|
11
12
|
import { DefaultStorage } from '@mastra/libsql';
|
|
13
|
+
import { MockLanguageModelV1, simulateReadableStream } from 'ai/test';
|
|
12
14
|
import { $ } from 'execa';
|
|
13
15
|
import getPort from 'get-port';
|
|
14
16
|
import { Inngest } from 'inngest';
|
|
@@ -33,13 +35,15 @@ describe('MastraInngestWorkflow', () => {
|
|
|
33
35
|
ctx.inngestPort = inngestPort;
|
|
34
36
|
ctx.handlerPort = handlerPort;
|
|
35
37
|
ctx.containerName = containerName;
|
|
38
|
+
|
|
39
|
+
vi.restoreAllMocks();
|
|
36
40
|
});
|
|
37
41
|
|
|
38
42
|
afterEach<LocalTestContext>(async ctx => {
|
|
39
43
|
await $`docker stop ${ctx.containerName}`;
|
|
40
44
|
});
|
|
41
45
|
|
|
42
|
-
describe('Basic Workflow Execution', () => {
|
|
46
|
+
describe.sequential('Basic Workflow Execution', () => {
|
|
43
47
|
it('should execute a single step workflow successfully', async ctx => {
|
|
44
48
|
const inngest = new Inngest({
|
|
45
49
|
id: 'mastra',
|
|
@@ -91,11 +95,11 @@ describe('MastraInngestWorkflow', () => {
|
|
|
91
95
|
});
|
|
92
96
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
93
97
|
|
|
94
|
-
const run =
|
|
98
|
+
const run = workflow.createRun();
|
|
95
99
|
const result = await run.start({ inputData: {} });
|
|
96
100
|
|
|
97
101
|
expect(execute).toHaveBeenCalled();
|
|
98
|
-
expect(result.steps['step1']).
|
|
102
|
+
expect(result.steps['step1']).toMatchObject({
|
|
99
103
|
status: 'success',
|
|
100
104
|
output: { result: 'success' },
|
|
101
105
|
});
|
|
@@ -166,12 +170,12 @@ describe('MastraInngestWorkflow', () => {
|
|
|
166
170
|
});
|
|
167
171
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
168
172
|
|
|
169
|
-
const run =
|
|
173
|
+
const run = workflow.createRun();
|
|
170
174
|
const result = await run.start({ inputData: {} });
|
|
171
175
|
|
|
172
176
|
expect(step1Action).toHaveBeenCalled();
|
|
173
177
|
expect(step2Action).toHaveBeenCalled();
|
|
174
|
-
expect(result.steps).
|
|
178
|
+
expect(result.steps).toMatchObject({
|
|
175
179
|
input: {},
|
|
176
180
|
step1: { status: 'success', output: { value: 'step1' } },
|
|
177
181
|
step2: { status: 'success', output: { value: 'step2' } },
|
|
@@ -247,11 +251,11 @@ describe('MastraInngestWorkflow', () => {
|
|
|
247
251
|
});
|
|
248
252
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
249
253
|
|
|
250
|
-
const run =
|
|
254
|
+
const run = workflow.createRun();
|
|
251
255
|
const result = await run.start({ inputData: {} });
|
|
252
256
|
|
|
253
|
-
expect(executionOrder).
|
|
254
|
-
expect(result.steps).
|
|
257
|
+
expect(executionOrder).toMatchObject(['step1', 'step2']);
|
|
258
|
+
expect(result.steps).toMatchObject({
|
|
255
259
|
input: {},
|
|
256
260
|
step1: { status: 'success', output: { value: 'step1' } },
|
|
257
261
|
step2: { status: 'success', output: { value: 'step2' } },
|
|
@@ -321,13 +325,13 @@ describe('MastraInngestWorkflow', () => {
|
|
|
321
325
|
});
|
|
322
326
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
323
327
|
|
|
324
|
-
const run =
|
|
328
|
+
const run = workflow.createRun();
|
|
325
329
|
const startTime = Date.now();
|
|
326
330
|
const result = await run.start({ inputData: {} });
|
|
327
331
|
const endTime = Date.now();
|
|
328
332
|
|
|
329
333
|
expect(execute).toHaveBeenCalled();
|
|
330
|
-
expect(result.steps['step1']).
|
|
334
|
+
expect(result.steps['step1']).toMatchObject({
|
|
331
335
|
status: 'success',
|
|
332
336
|
output: { result: 'success' },
|
|
333
337
|
// payload: {},
|
|
@@ -335,7 +339,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
335
339
|
// endedAt: expect.any(Number),
|
|
336
340
|
});
|
|
337
341
|
|
|
338
|
-
expect(result.steps['step2']).
|
|
342
|
+
expect(result.steps['step2']).toMatchObject({
|
|
339
343
|
status: 'success',
|
|
340
344
|
output: { result: 'slept successfully: success' },
|
|
341
345
|
// payload: { result: 'success' },
|
|
@@ -413,13 +417,13 @@ describe('MastraInngestWorkflow', () => {
|
|
|
413
417
|
});
|
|
414
418
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
415
419
|
|
|
416
|
-
const run =
|
|
420
|
+
const run = workflow.createRun();
|
|
417
421
|
const startTime = Date.now();
|
|
418
422
|
const result = await run.start({ inputData: {} });
|
|
419
423
|
const endTime = Date.now();
|
|
420
424
|
|
|
421
425
|
expect(execute).toHaveBeenCalled();
|
|
422
|
-
expect(result.steps['step1']).
|
|
426
|
+
expect(result.steps['step1']).toMatchObject({
|
|
423
427
|
status: 'success',
|
|
424
428
|
output: { result: 'success' },
|
|
425
429
|
// payload: {},
|
|
@@ -427,7 +431,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
427
431
|
// endedAt: expect.any(Number),
|
|
428
432
|
});
|
|
429
433
|
|
|
430
|
-
expect(result.steps['step2']).
|
|
434
|
+
expect(result.steps['step2']).toMatchObject({
|
|
431
435
|
status: 'success',
|
|
432
436
|
output: { result: 'slept successfully: success' },
|
|
433
437
|
// payload: { result: 'success' },
|
|
@@ -439,6 +443,190 @@ describe('MastraInngestWorkflow', () => {
|
|
|
439
443
|
|
|
440
444
|
srv.close();
|
|
441
445
|
});
|
|
446
|
+
|
|
447
|
+
it('should execute a a waitForEvent step', async ctx => {
|
|
448
|
+
const inngest = new Inngest({
|
|
449
|
+
id: 'mastra',
|
|
450
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
454
|
+
|
|
455
|
+
const execute = vi.fn<any>().mockResolvedValue({ result: 'success' });
|
|
456
|
+
const step1 = createStep({
|
|
457
|
+
id: 'step1',
|
|
458
|
+
execute,
|
|
459
|
+
inputSchema: z.object({}),
|
|
460
|
+
outputSchema: z.object({ result: z.string() }),
|
|
461
|
+
});
|
|
462
|
+
const step2 = createStep({
|
|
463
|
+
id: 'step2',
|
|
464
|
+
execute: async ({ inputData, resumeData }) => {
|
|
465
|
+
return { result: inputData.result, resumed: resumeData };
|
|
466
|
+
},
|
|
467
|
+
inputSchema: z.object({ result: z.string() }),
|
|
468
|
+
outputSchema: z.object({ result: z.string(), resumed: z.any() }),
|
|
469
|
+
resumeSchema: z.any(),
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
const workflow = createWorkflow({
|
|
473
|
+
id: 'test-workflow',
|
|
474
|
+
inputSchema: z.object({}),
|
|
475
|
+
outputSchema: z.object({
|
|
476
|
+
result: z.string(),
|
|
477
|
+
resumed: z.any(),
|
|
478
|
+
}),
|
|
479
|
+
steps: [step1],
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
workflow.then(step1).waitForEvent('hello-event', step2).commit();
|
|
483
|
+
|
|
484
|
+
const mastra = new Mastra({
|
|
485
|
+
storage: new DefaultStorage({
|
|
486
|
+
url: ':memory:',
|
|
487
|
+
}),
|
|
488
|
+
workflows: {
|
|
489
|
+
'test-workflow': workflow,
|
|
490
|
+
},
|
|
491
|
+
server: {
|
|
492
|
+
apiRoutes: [
|
|
493
|
+
{
|
|
494
|
+
path: '/inngest/api',
|
|
495
|
+
method: 'ALL',
|
|
496
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
497
|
+
},
|
|
498
|
+
],
|
|
499
|
+
},
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
const app = await createHonoServer(mastra);
|
|
503
|
+
|
|
504
|
+
const srv = serve({
|
|
505
|
+
fetch: app.fetch,
|
|
506
|
+
port: (ctx as any).handlerPort,
|
|
507
|
+
});
|
|
508
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
509
|
+
|
|
510
|
+
const run = workflow.createRun();
|
|
511
|
+
const startTime = Date.now();
|
|
512
|
+
setTimeout(() => {
|
|
513
|
+
run.sendEvent('hello-event', { data: 'hello' });
|
|
514
|
+
}, 1000);
|
|
515
|
+
const result = await run.start({ inputData: {} });
|
|
516
|
+
const endTime = Date.now();
|
|
517
|
+
|
|
518
|
+
expect(execute).toHaveBeenCalled();
|
|
519
|
+
expect(result.steps['step1']).toMatchObject({
|
|
520
|
+
status: 'success',
|
|
521
|
+
output: { result: 'success' },
|
|
522
|
+
// payload: {},
|
|
523
|
+
// startedAt: expect.any(Number),
|
|
524
|
+
// endedAt: expect.any(Number),
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
expect(result.steps['step2']).toMatchObject({
|
|
528
|
+
status: 'success',
|
|
529
|
+
output: { result: 'success', resumed: { data: 'hello' } },
|
|
530
|
+
payload: { result: 'success' },
|
|
531
|
+
// resumePayload: { data: 'hello' },
|
|
532
|
+
startedAt: expect.any(Number),
|
|
533
|
+
endedAt: expect.any(Number),
|
|
534
|
+
});
|
|
535
|
+
|
|
536
|
+
expect(endTime - startTime).toBeGreaterThan(1000);
|
|
537
|
+
|
|
538
|
+
srv.close();
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
it('should execute a a waitForEvent step after timeout', async ctx => {
|
|
542
|
+
const inngest = new Inngest({
|
|
543
|
+
id: 'mastra',
|
|
544
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
545
|
+
});
|
|
546
|
+
|
|
547
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
548
|
+
|
|
549
|
+
const execute = vi.fn<any>().mockResolvedValue({ result: 'success' });
|
|
550
|
+
const step1 = createStep({
|
|
551
|
+
id: 'step1',
|
|
552
|
+
execute,
|
|
553
|
+
inputSchema: z.object({}),
|
|
554
|
+
outputSchema: z.object({ result: z.string() }),
|
|
555
|
+
});
|
|
556
|
+
const step2 = createStep({
|
|
557
|
+
id: 'step2',
|
|
558
|
+
execute: async ({ inputData, resumeData }) => {
|
|
559
|
+
return { result: inputData.result, resumed: resumeData };
|
|
560
|
+
},
|
|
561
|
+
inputSchema: z.object({ result: z.string() }),
|
|
562
|
+
outputSchema: z.object({ result: z.string(), resumed: z.any() }),
|
|
563
|
+
resumeSchema: z.any(),
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
const workflow = createWorkflow({
|
|
567
|
+
id: 'test-workflow',
|
|
568
|
+
inputSchema: z.object({}),
|
|
569
|
+
outputSchema: z.object({
|
|
570
|
+
result: z.string(),
|
|
571
|
+
resumed: z.any(),
|
|
572
|
+
}),
|
|
573
|
+
steps: [step1],
|
|
574
|
+
});
|
|
575
|
+
|
|
576
|
+
workflow.then(step1).waitForEvent('hello-event', step2, { timeout: 1000 }).commit();
|
|
577
|
+
|
|
578
|
+
const mastra = new Mastra({
|
|
579
|
+
storage: new DefaultStorage({
|
|
580
|
+
url: ':memory:',
|
|
581
|
+
}),
|
|
582
|
+
workflows: {
|
|
583
|
+
'test-workflow': workflow,
|
|
584
|
+
},
|
|
585
|
+
server: {
|
|
586
|
+
apiRoutes: [
|
|
587
|
+
{
|
|
588
|
+
path: '/inngest/api',
|
|
589
|
+
method: 'ALL',
|
|
590
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
591
|
+
},
|
|
592
|
+
],
|
|
593
|
+
},
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
const app = await createHonoServer(mastra);
|
|
597
|
+
|
|
598
|
+
const srv = serve({
|
|
599
|
+
fetch: app.fetch,
|
|
600
|
+
port: (ctx as any).handlerPort,
|
|
601
|
+
});
|
|
602
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
603
|
+
|
|
604
|
+
const run = workflow.createRun();
|
|
605
|
+
const startTime = Date.now();
|
|
606
|
+
const result = await run.start({ inputData: {} });
|
|
607
|
+
const endTime = Date.now();
|
|
608
|
+
|
|
609
|
+
expect(execute).toHaveBeenCalled();
|
|
610
|
+
expect(result.steps['step1']).toMatchObject({
|
|
611
|
+
status: 'success',
|
|
612
|
+
output: { result: 'success' },
|
|
613
|
+
// payload: {},
|
|
614
|
+
// startedAt: expect.any(Number),
|
|
615
|
+
// endedAt: expect.any(Number),
|
|
616
|
+
});
|
|
617
|
+
|
|
618
|
+
expect(result.steps['step2']).toMatchObject({
|
|
619
|
+
status: 'failed',
|
|
620
|
+
error: expect.any(String),
|
|
621
|
+
payload: { result: 'success' },
|
|
622
|
+
startedAt: expect.any(Number),
|
|
623
|
+
endedAt: expect.any(Number),
|
|
624
|
+
});
|
|
625
|
+
|
|
626
|
+
expect(endTime - startTime).toBeGreaterThan(1000);
|
|
627
|
+
|
|
628
|
+
srv.close();
|
|
629
|
+
});
|
|
442
630
|
});
|
|
443
631
|
|
|
444
632
|
describe('Variable Resolution', () => {
|
|
@@ -498,11 +686,11 @@ describe('MastraInngestWorkflow', () => {
|
|
|
498
686
|
port: (ctx as any).handlerPort,
|
|
499
687
|
});
|
|
500
688
|
|
|
501
|
-
const run =
|
|
689
|
+
const run = workflow.createRun();
|
|
502
690
|
const result = await run.start({ inputData: { inputData: 'test-input' } });
|
|
503
691
|
|
|
504
|
-
expect(result.steps.step1).
|
|
505
|
-
expect(result.steps.step2).
|
|
692
|
+
expect(result.steps.step1).toMatchObject({ status: 'success', output: { result: 'success' } });
|
|
693
|
+
expect(result.steps.step2).toMatchObject({ status: 'success', output: { result: 'success' } });
|
|
506
694
|
|
|
507
695
|
srv.close();
|
|
508
696
|
});
|
|
@@ -517,14 +705,14 @@ describe('MastraInngestWorkflow', () => {
|
|
|
517
705
|
|
|
518
706
|
const step1Action = vi.fn().mockImplementation(async ({ inputData }) => {
|
|
519
707
|
// Test accessing trigger data with correct type
|
|
520
|
-
expect(inputData).
|
|
708
|
+
expect(inputData).toMatchObject({ inputValue: 'test-input' });
|
|
521
709
|
return { value: 'step1-result' };
|
|
522
710
|
});
|
|
523
711
|
|
|
524
712
|
const step2Action = vi.fn().mockImplementation(async ({ getStepResult }) => {
|
|
525
713
|
// Test accessing previous step result with type
|
|
526
714
|
const step1Result = getStepResult(step1);
|
|
527
|
-
expect(step1Result).
|
|
715
|
+
expect(step1Result).toMatchObject({ value: 'step1-result' });
|
|
528
716
|
|
|
529
717
|
const failedStep = getStepResult(nonExecutedStep);
|
|
530
718
|
expect(failedStep).toBe(null);
|
|
@@ -585,12 +773,12 @@ describe('MastraInngestWorkflow', () => {
|
|
|
585
773
|
port: (ctx as any).handlerPort,
|
|
586
774
|
});
|
|
587
775
|
|
|
588
|
-
const run =
|
|
776
|
+
const run = workflow.createRun();
|
|
589
777
|
const result = await run.start({ inputData: { inputValue: 'test-input' } });
|
|
590
778
|
|
|
591
779
|
expect(step1Action).toHaveBeenCalled();
|
|
592
780
|
expect(step2Action).toHaveBeenCalled();
|
|
593
|
-
expect(result.steps).
|
|
781
|
+
expect(result.steps).toMatchObject({
|
|
594
782
|
input: { inputValue: 'test-input' },
|
|
595
783
|
step1: { status: 'success', output: { value: 'step1-result' } },
|
|
596
784
|
step2: { status: 'success', output: { value: 'step2-result' } },
|
|
@@ -652,7 +840,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
652
840
|
port: (ctx as any).handlerPort,
|
|
653
841
|
});
|
|
654
842
|
|
|
655
|
-
const run =
|
|
843
|
+
const run = workflow.createRun();
|
|
656
844
|
await run.start({ inputData: { inputData: 'test-input' } });
|
|
657
845
|
|
|
658
846
|
expect(execute).toHaveBeenCalledWith(
|
|
@@ -727,7 +915,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
727
915
|
port: (ctx as any).handlerPort,
|
|
728
916
|
});
|
|
729
917
|
|
|
730
|
-
const run =
|
|
918
|
+
const run = workflow.createRun();
|
|
731
919
|
const result = await run.start({ inputData: { cool: 'test-input' } });
|
|
732
920
|
|
|
733
921
|
expect(execute).toHaveBeenCalledWith(
|
|
@@ -736,7 +924,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
736
924
|
}),
|
|
737
925
|
);
|
|
738
926
|
|
|
739
|
-
expect(result.steps.step2).
|
|
927
|
+
expect(result.steps.step2).toMatchObject({ status: 'success', output: { result: { cool: 'test-input' } } });
|
|
740
928
|
|
|
741
929
|
srv.close();
|
|
742
930
|
});
|
|
@@ -809,7 +997,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
809
997
|
port: (ctx as any).handlerPort,
|
|
810
998
|
});
|
|
811
999
|
|
|
812
|
-
const run =
|
|
1000
|
+
const run = workflow.createRun();
|
|
813
1001
|
await run.start({ inputData: {} });
|
|
814
1002
|
|
|
815
1003
|
expect(step2Action).toHaveBeenCalledWith(
|
|
@@ -912,14 +1100,14 @@ describe('MastraInngestWorkflow', () => {
|
|
|
912
1100
|
port: (ctx as any).handlerPort,
|
|
913
1101
|
});
|
|
914
1102
|
|
|
915
|
-
const run =
|
|
1103
|
+
const run = workflow.createRun();
|
|
916
1104
|
const result = await run.start({ inputData: { status: 'success' } });
|
|
917
1105
|
srv.close();
|
|
918
1106
|
|
|
919
1107
|
expect(step1Action).toHaveBeenCalled();
|
|
920
1108
|
expect(step2Action).toHaveBeenCalled();
|
|
921
1109
|
expect(step3Action).not.toHaveBeenCalled();
|
|
922
|
-
expect(result.steps).
|
|
1110
|
+
expect(result.steps).toMatchObject({
|
|
923
1111
|
input: { status: 'success' },
|
|
924
1112
|
step1: { status: 'success', output: { status: 'success' } },
|
|
925
1113
|
step2: { status: 'success', output: { result: 'step2' } },
|
|
@@ -988,7 +1176,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
988
1176
|
port: (ctx as any).handlerPort,
|
|
989
1177
|
});
|
|
990
1178
|
|
|
991
|
-
const run =
|
|
1179
|
+
const run = workflow.createRun();
|
|
992
1180
|
let result: Awaited<ReturnType<typeof run.start>> | undefined = undefined;
|
|
993
1181
|
try {
|
|
994
1182
|
result = await run.start({ inputData: {} });
|
|
@@ -1000,7 +1188,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1000
1188
|
|
|
1001
1189
|
expect(step1Action).toHaveBeenCalled();
|
|
1002
1190
|
expect(step2Action).not.toHaveBeenCalled();
|
|
1003
|
-
expect(result?.steps).
|
|
1191
|
+
expect(result?.steps).toMatchObject({
|
|
1004
1192
|
input: {},
|
|
1005
1193
|
step1: { status: 'failed', error: 'Failed' },
|
|
1006
1194
|
});
|
|
@@ -1093,7 +1281,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1093
1281
|
port: (ctx as any).handlerPort,
|
|
1094
1282
|
});
|
|
1095
1283
|
|
|
1096
|
-
const run =
|
|
1284
|
+
const run = workflow.createRun();
|
|
1097
1285
|
const result = await run.start({ inputData: { status: 'success' } });
|
|
1098
1286
|
srv.close();
|
|
1099
1287
|
|
|
@@ -1176,18 +1364,17 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1176
1364
|
port: (ctx as any).handlerPort,
|
|
1177
1365
|
});
|
|
1178
1366
|
|
|
1179
|
-
const run =
|
|
1367
|
+
const run = workflow.createRun();
|
|
1180
1368
|
const result = await run.start({ inputData: { count: 5 } });
|
|
1181
1369
|
srv.close();
|
|
1182
1370
|
|
|
1183
1371
|
expect(step2Action).toHaveBeenCalled();
|
|
1184
|
-
expect(result.steps.step1).
|
|
1372
|
+
expect(result.steps.step1).toMatchObject({
|
|
1185
1373
|
status: 'success',
|
|
1186
1374
|
output: { count: 5 },
|
|
1187
1375
|
});
|
|
1188
|
-
expect(result.steps.step2).
|
|
1376
|
+
expect(result.steps.step2).toMatchObject({
|
|
1189
1377
|
status: 'success',
|
|
1190
|
-
output: undefined,
|
|
1191
1378
|
});
|
|
1192
1379
|
});
|
|
1193
1380
|
});
|
|
@@ -1245,7 +1432,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1245
1432
|
});
|
|
1246
1433
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
1247
1434
|
|
|
1248
|
-
const run =
|
|
1435
|
+
const run = workflow.createRun();
|
|
1249
1436
|
|
|
1250
1437
|
await expect(run.start({ inputData: {} })).resolves.toMatchObject({
|
|
1251
1438
|
steps: {
|
|
@@ -1329,7 +1516,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1329
1516
|
});
|
|
1330
1517
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
1331
1518
|
|
|
1332
|
-
const run =
|
|
1519
|
+
const run = workflow.createRun();
|
|
1333
1520
|
const result = await run.start({ inputData: {} });
|
|
1334
1521
|
|
|
1335
1522
|
expect(result.steps).toMatchObject({
|
|
@@ -1423,7 +1610,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1423
1610
|
});
|
|
1424
1611
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
1425
1612
|
|
|
1426
|
-
const run =
|
|
1613
|
+
const run = mainWorkflow.createRun();
|
|
1427
1614
|
const result = await run.start({ inputData: {} });
|
|
1428
1615
|
|
|
1429
1616
|
expect(result.steps).toMatchObject({
|
|
@@ -1551,12 +1738,12 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1551
1738
|
});
|
|
1552
1739
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
1553
1740
|
|
|
1554
|
-
const run =
|
|
1741
|
+
const run = workflow.createRun();
|
|
1555
1742
|
const result = await run.start({ inputData: {} });
|
|
1556
1743
|
|
|
1557
1744
|
expect(step2Action).toHaveBeenCalled();
|
|
1558
1745
|
expect(step3Action).not.toHaveBeenCalled();
|
|
1559
|
-
expect(result.steps.step2).
|
|
1746
|
+
expect(result.steps.step2).toMatchObject({ status: 'success', output: { result: 'step2' } });
|
|
1560
1747
|
|
|
1561
1748
|
srv.close();
|
|
1562
1749
|
});
|
|
@@ -1653,15 +1840,15 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1653
1840
|
});
|
|
1654
1841
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
1655
1842
|
|
|
1656
|
-
const run =
|
|
1843
|
+
const run = counterWorkflow.createRun();
|
|
1657
1844
|
const result = await run.start({ inputData: { target: 10, value: 0 } });
|
|
1658
1845
|
|
|
1659
1846
|
expect(increment).toHaveBeenCalledTimes(12);
|
|
1660
1847
|
expect(final).toHaveBeenCalledTimes(1);
|
|
1661
1848
|
// @ts-ignore
|
|
1662
|
-
expect(result.result).
|
|
1849
|
+
expect(result.result).toMatchObject({ finalValue: 12 });
|
|
1663
1850
|
// @ts-ignore
|
|
1664
|
-
expect(result.steps.increment.output).
|
|
1851
|
+
expect(result.steps.increment.output).toMatchObject({ value: 12 });
|
|
1665
1852
|
|
|
1666
1853
|
srv.close();
|
|
1667
1854
|
});
|
|
@@ -1756,15 +1943,15 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1756
1943
|
});
|
|
1757
1944
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
1758
1945
|
|
|
1759
|
-
const run =
|
|
1946
|
+
const run = counterWorkflow.createRun();
|
|
1760
1947
|
const result = await run.start({ inputData: { target: 10, value: 0 } });
|
|
1761
1948
|
|
|
1762
1949
|
expect(increment).toHaveBeenCalledTimes(12);
|
|
1763
1950
|
expect(final).toHaveBeenCalledTimes(1);
|
|
1764
1951
|
// @ts-ignore
|
|
1765
|
-
expect(result.result).
|
|
1952
|
+
expect(result.result).toMatchObject({ finalValue: 12 });
|
|
1766
1953
|
// @ts-ignore
|
|
1767
|
-
expect(result.steps.increment.output).
|
|
1954
|
+
expect(result.steps.increment.output).toMatchObject({ value: 12 });
|
|
1768
1955
|
|
|
1769
1956
|
srv.close();
|
|
1770
1957
|
});
|
|
@@ -1845,7 +2032,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1845
2032
|
});
|
|
1846
2033
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
1847
2034
|
|
|
1848
|
-
const run =
|
|
2035
|
+
const run = counterWorkflow.createRun();
|
|
1849
2036
|
const result = await run.start({ inputData: [{ value: 1 }, { value: 22 }, { value: 333 }] });
|
|
1850
2037
|
|
|
1851
2038
|
const endTime = Date.now();
|
|
@@ -1853,7 +2040,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1853
2040
|
expect(duration).toBeGreaterThan(1e3 * 3);
|
|
1854
2041
|
|
|
1855
2042
|
expect(map).toHaveBeenCalledTimes(3);
|
|
1856
|
-
expect(result.steps).
|
|
2043
|
+
expect(result.steps).toMatchObject({
|
|
1857
2044
|
input: [{ value: 1 }, { value: 22 }, { value: 333 }],
|
|
1858
2045
|
map: { status: 'success', output: [{ value: 12 }, { value: 33 }, { value: 344 }] },
|
|
1859
2046
|
final: { status: 'success', output: { finalValue: 1 + 11 + (22 + 11) + (333 + 11) } },
|
|
@@ -1998,16 +2185,16 @@ describe('MastraInngestWorkflow', () => {
|
|
|
1998
2185
|
});
|
|
1999
2186
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2000
2187
|
|
|
2001
|
-
const run =
|
|
2188
|
+
const run = counterWorkflow.createRun();
|
|
2002
2189
|
const result = await run.start({ inputData: { startValue: 1 } });
|
|
2003
2190
|
|
|
2004
2191
|
expect(start).toHaveBeenCalledTimes(1);
|
|
2005
2192
|
expect(other).toHaveBeenCalledTimes(0);
|
|
2006
2193
|
expect(final).toHaveBeenCalledTimes(1);
|
|
2007
2194
|
// @ts-ignore
|
|
2008
|
-
expect(result.steps.finalIf.output).
|
|
2195
|
+
expect(result.steps.finalIf.output).toMatchObject({ finalValue: 2 });
|
|
2009
2196
|
// @ts-ignore
|
|
2010
|
-
expect(result.steps.start.output).
|
|
2197
|
+
expect(result.steps.start.output).toMatchObject({ newValue: 2 });
|
|
2011
2198
|
|
|
2012
2199
|
srv.close();
|
|
2013
2200
|
});
|
|
@@ -2147,16 +2334,16 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2147
2334
|
});
|
|
2148
2335
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2149
2336
|
|
|
2150
|
-
const run =
|
|
2337
|
+
const run = counterWorkflow.createRun();
|
|
2151
2338
|
const result = await run.start({ inputData: { startValue: 6 } });
|
|
2152
2339
|
|
|
2153
2340
|
expect(start).toHaveBeenCalledTimes(1);
|
|
2154
2341
|
expect(other).toHaveBeenCalledTimes(1);
|
|
2155
2342
|
expect(final).toHaveBeenCalledTimes(1);
|
|
2156
2343
|
// @ts-ignore
|
|
2157
|
-
expect(result.steps['else-branch'].output).
|
|
2344
|
+
expect(result.steps['else-branch'].output).toMatchObject({ finalValue: 26 + 6 + 1 });
|
|
2158
2345
|
// @ts-ignore
|
|
2159
|
-
expect(result.steps.start.output).
|
|
2346
|
+
expect(result.steps.start.output).toMatchObject({ newValue: 7 });
|
|
2160
2347
|
|
|
2161
2348
|
srv.close();
|
|
2162
2349
|
});
|
|
@@ -2213,7 +2400,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2213
2400
|
).rejects.toThrow();
|
|
2214
2401
|
|
|
2215
2402
|
// Should pass validation
|
|
2216
|
-
const run =
|
|
2403
|
+
const run = workflow.createRun();
|
|
2217
2404
|
await run.start({
|
|
2218
2405
|
inputData: {
|
|
2219
2406
|
required: 'test',
|
|
@@ -2319,11 +2506,11 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2319
2506
|
});
|
|
2320
2507
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2321
2508
|
|
|
2322
|
-
const run =
|
|
2509
|
+
const run = workflow.createRun();
|
|
2323
2510
|
const result = await run.start({ inputData: {} });
|
|
2324
2511
|
|
|
2325
|
-
expect(result.steps['nested-a']).
|
|
2326
|
-
expect(result.steps['nested-b']).
|
|
2512
|
+
expect(result.steps['nested-a']).toMatchObject({ status: 'success', output: { result: 'success3' } });
|
|
2513
|
+
expect(result.steps['nested-b']).toMatchObject({ status: 'success', output: { result: 'success5' } });
|
|
2327
2514
|
|
|
2328
2515
|
srv.close();
|
|
2329
2516
|
});
|
|
@@ -2385,11 +2572,11 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2385
2572
|
});
|
|
2386
2573
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2387
2574
|
|
|
2388
|
-
const run =
|
|
2575
|
+
const run = workflow.createRun();
|
|
2389
2576
|
const result = await run.start({ inputData: {} });
|
|
2390
2577
|
|
|
2391
|
-
expect(result.steps.step1).
|
|
2392
|
-
expect(result.steps.step2).
|
|
2578
|
+
expect(result.steps.step1).toMatchObject({ status: 'success', output: { result: 'success' } });
|
|
2579
|
+
expect(result.steps.step2).toMatchObject({ status: 'failed', error: 'Step failed' });
|
|
2393
2580
|
expect(step1.execute).toHaveBeenCalledTimes(1);
|
|
2394
2581
|
expect(step2.execute).toHaveBeenCalledTimes(1); // 0 retries + 1 initial call
|
|
2395
2582
|
|
|
@@ -2442,11 +2629,11 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2442
2629
|
|
|
2443
2630
|
workflow.then(step1).then(step2).commit();
|
|
2444
2631
|
|
|
2445
|
-
const run =
|
|
2632
|
+
const run = workflow.createRun();
|
|
2446
2633
|
const result = await run.start({ inputData: {} });
|
|
2447
2634
|
|
|
2448
|
-
expect(result.steps.step1).
|
|
2449
|
-
expect(result.steps.step2).
|
|
2635
|
+
expect(result.steps.step1).toMatchObject({ status: 'success', output: { result: 'success' } });
|
|
2636
|
+
expect(result.steps.step2).toMatchObject({ status: 'failed', error: 'Step failed' });
|
|
2450
2637
|
expect(step1.execute).toHaveBeenCalledTimes(1);
|
|
2451
2638
|
expect(step2.execute).toHaveBeenCalledTimes(6); // 5 retries + 1 initial call
|
|
2452
2639
|
});
|
|
@@ -2517,15 +2704,14 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2517
2704
|
});
|
|
2518
2705
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2519
2706
|
|
|
2520
|
-
const
|
|
2521
|
-
const result = await run.start({ inputData: {} });
|
|
2707
|
+
const result = await workflow.createRun().start({ inputData: {} });
|
|
2522
2708
|
|
|
2523
2709
|
srv.close();
|
|
2524
2710
|
|
|
2525
2711
|
expect(step1Action).toHaveBeenCalled();
|
|
2526
2712
|
expect(toolAction).toHaveBeenCalled();
|
|
2527
|
-
expect(result.steps.step1).
|
|
2528
|
-
expect(result.steps['random-tool']).
|
|
2713
|
+
expect(result.steps.step1).toMatchObject({ status: 'success', output: { name: 'step1' } });
|
|
2714
|
+
expect(result.steps['random-tool']).toMatchObject({ status: 'success', output: { name: 'step1' } });
|
|
2529
2715
|
}, 10000);
|
|
2530
2716
|
});
|
|
2531
2717
|
|
|
@@ -2589,7 +2775,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2589
2775
|
});
|
|
2590
2776
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2591
2777
|
|
|
2592
|
-
const run =
|
|
2778
|
+
const run = workflow.createRun();
|
|
2593
2779
|
|
|
2594
2780
|
// Start watching the workflow
|
|
2595
2781
|
let cnt = 0;
|
|
@@ -2704,11 +2890,11 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2704
2890
|
});
|
|
2705
2891
|
|
|
2706
2892
|
// Verify execution completed successfully
|
|
2707
|
-
expect(executionResult.steps.step1).
|
|
2893
|
+
expect(executionResult.steps.step1).toMatchObject({
|
|
2708
2894
|
status: 'success',
|
|
2709
2895
|
output: { result: 'success1' },
|
|
2710
2896
|
});
|
|
2711
|
-
expect(executionResult.steps.step2).
|
|
2897
|
+
expect(executionResult.steps.step2).toMatchObject({
|
|
2712
2898
|
status: 'success',
|
|
2713
2899
|
output: { result: 'success2' },
|
|
2714
2900
|
});
|
|
@@ -2778,7 +2964,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2778
2964
|
const onTransition = vi.fn();
|
|
2779
2965
|
const onTransition2 = vi.fn();
|
|
2780
2966
|
|
|
2781
|
-
const run =
|
|
2967
|
+
const run = workflow.createRun();
|
|
2782
2968
|
|
|
2783
2969
|
run.watch(onTransition);
|
|
2784
2970
|
run.watch(onTransition2);
|
|
@@ -2788,7 +2974,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2788
2974
|
expect(onTransition).toHaveBeenCalledTimes(5);
|
|
2789
2975
|
expect(onTransition2).toHaveBeenCalledTimes(5);
|
|
2790
2976
|
|
|
2791
|
-
const run2 =
|
|
2977
|
+
const run2 = workflow.createRun();
|
|
2792
2978
|
|
|
2793
2979
|
run2.watch(onTransition2);
|
|
2794
2980
|
|
|
@@ -2797,7 +2983,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2797
2983
|
expect(onTransition).toHaveBeenCalledTimes(5);
|
|
2798
2984
|
expect(onTransition2).toHaveBeenCalledTimes(10);
|
|
2799
2985
|
|
|
2800
|
-
const run3 =
|
|
2986
|
+
const run3 = workflow.createRun();
|
|
2801
2987
|
|
|
2802
2988
|
run3.watch(onTransition);
|
|
2803
2989
|
|
|
@@ -2832,7 +3018,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2832
3018
|
outputSchema: z.object({}),
|
|
2833
3019
|
steps: [],
|
|
2834
3020
|
});
|
|
2835
|
-
const run =
|
|
3021
|
+
const run = workflow.createRun();
|
|
2836
3022
|
const run2 = workflow.createRun({ runId: run.runId });
|
|
2837
3023
|
|
|
2838
3024
|
expect(run.runId).toBeDefined();
|
|
@@ -2947,7 +3133,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2947
3133
|
});
|
|
2948
3134
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
2949
3135
|
|
|
2950
|
-
const run =
|
|
3136
|
+
const run = promptEvalWorkflow.createRun();
|
|
2951
3137
|
|
|
2952
3138
|
// Create a promise to track when the workflow is ready to resume
|
|
2953
3139
|
let resolveWorkflowSuspended: (value: unknown) => void;
|
|
@@ -2977,7 +3163,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
2977
3163
|
throw new Error('Resume failed to return a result');
|
|
2978
3164
|
}
|
|
2979
3165
|
|
|
2980
|
-
expect(resumeResult.steps).
|
|
3166
|
+
expect(resumeResult.steps).toMatchObject({
|
|
2981
3167
|
input: { input: 'test' },
|
|
2982
3168
|
getUserInput: { status: 'success', output: { userInput: 'test input' } },
|
|
2983
3169
|
promptAgent: { status: 'success', output: { modelOutput: 'test output' } },
|
|
@@ -3097,7 +3283,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3097
3283
|
});
|
|
3098
3284
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
3099
3285
|
|
|
3100
|
-
const run =
|
|
3286
|
+
const run = workflow.createRun();
|
|
3101
3287
|
|
|
3102
3288
|
const started = run.start({ inputData: { input: 'test' } });
|
|
3103
3289
|
|
|
@@ -3140,7 +3326,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3140
3326
|
throw new Error('Resume failed to return a result');
|
|
3141
3327
|
}
|
|
3142
3328
|
|
|
3143
|
-
expect(result.steps).
|
|
3329
|
+
expect(result.steps).toMatchObject({
|
|
3144
3330
|
input: { input: 'test' },
|
|
3145
3331
|
getUserInput: { status: 'success', output: { userInput: 'test input' } },
|
|
3146
3332
|
promptAgent: { status: 'success', output: { modelOutput: 'test output' } },
|
|
@@ -3299,7 +3485,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3299
3485
|
});
|
|
3300
3486
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
3301
3487
|
|
|
3302
|
-
const run =
|
|
3488
|
+
const run = workflow.createRun();
|
|
3303
3489
|
const started = run.start({ inputData: { input: 'test' } });
|
|
3304
3490
|
let improvedResponseResultPromise: Promise<any | undefined>;
|
|
3305
3491
|
|
|
@@ -3493,15 +3679,15 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3493
3679
|
});
|
|
3494
3680
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
3495
3681
|
|
|
3496
|
-
const run =
|
|
3682
|
+
const run = promptEvalWorkflow.createRun();
|
|
3497
3683
|
|
|
3498
3684
|
const initialResult = await run.start({ inputData: { input: 'test' } });
|
|
3499
3685
|
expect(initialResult.steps.promptAgent.status).toBe('suspended');
|
|
3500
3686
|
expect(promptAgentAction).toHaveBeenCalledTimes(1);
|
|
3501
3687
|
// expect(initialResult.activePaths.size).toBe(1);
|
|
3502
3688
|
// expect(initialResult.activePaths.get('promptAgent')?.status).toBe('suspended');
|
|
3503
|
-
// expect(initialResult.activePaths.get('promptAgent')?.suspendPayload).
|
|
3504
|
-
expect(initialResult.steps).
|
|
3689
|
+
// expect(initialResult.activePaths.get('promptAgent')?.suspendPayload).toMatchObject({ testPayload: 'hello' });
|
|
3690
|
+
expect(initialResult.steps).toMatchObject({
|
|
3505
3691
|
input: { input: 'test' },
|
|
3506
3692
|
getUserInput: { status: 'success', output: { userInput: 'test input' } },
|
|
3507
3693
|
promptAgent: { status: 'suspended', payload: { testPayload: 'hello' } },
|
|
@@ -3521,7 +3707,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3521
3707
|
|
|
3522
3708
|
// expect(firstResumeResult.activePaths.size).toBe(1);
|
|
3523
3709
|
// expect(firstResumeResult.activePaths.get('improveResponse')?.status).toBe('suspended');
|
|
3524
|
-
expect(firstResumeResult.steps).
|
|
3710
|
+
expect(firstResumeResult.steps).toMatchObject({
|
|
3525
3711
|
input: { input: 'test' },
|
|
3526
3712
|
getUserInput: { status: 'success', output: { userInput: 'test input' } },
|
|
3527
3713
|
promptAgent: { status: 'success', output: { modelOutput: 'test output' } },
|
|
@@ -3548,7 +3734,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3548
3734
|
|
|
3549
3735
|
expect(promptAgentAction).toHaveBeenCalledTimes(2);
|
|
3550
3736
|
|
|
3551
|
-
expect(secondResumeResult.steps).
|
|
3737
|
+
expect(secondResumeResult.steps).toMatchObject({
|
|
3552
3738
|
input: { input: 'test' },
|
|
3553
3739
|
getUserInput: { status: 'success', output: { userInput: 'test input' } },
|
|
3554
3740
|
promptAgent: { status: 'success', output: { modelOutput: 'test output' } },
|
|
@@ -3618,7 +3804,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3618
3804
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
3619
3805
|
|
|
3620
3806
|
// Access new instance properties directly - should work without warning
|
|
3621
|
-
const run =
|
|
3807
|
+
const run = workflow.createRun();
|
|
3622
3808
|
await run.start({ inputData: {} });
|
|
3623
3809
|
|
|
3624
3810
|
expect(telemetry).toBeDefined();
|
|
@@ -3633,6 +3819,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3633
3819
|
const inngest = new Inngest({
|
|
3634
3820
|
id: 'mastra',
|
|
3635
3821
|
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
3822
|
+
middleware: [realtimeMiddleware()],
|
|
3636
3823
|
});
|
|
3637
3824
|
|
|
3638
3825
|
const { createWorkflow, createStep } = init(inngest);
|
|
@@ -3720,28 +3907,29 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3720
3907
|
});
|
|
3721
3908
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
3722
3909
|
|
|
3723
|
-
const run =
|
|
3910
|
+
const run = workflow.createRun();
|
|
3724
3911
|
const result = await run.start({
|
|
3725
3912
|
inputData: { prompt1: 'Capital of France, just the name', prompt2: 'Capital of UK, just the name' },
|
|
3726
3913
|
});
|
|
3727
3914
|
|
|
3728
|
-
|
|
3915
|
+
srv.close();
|
|
3916
|
+
|
|
3917
|
+
expect(result.steps['test-agent-1']).toMatchObject({
|
|
3729
3918
|
status: 'success',
|
|
3730
3919
|
output: { text: 'Paris' },
|
|
3731
3920
|
});
|
|
3732
3921
|
|
|
3733
|
-
expect(result.steps['test-agent-2']).
|
|
3922
|
+
expect(result.steps['test-agent-2']).toMatchObject({
|
|
3734
3923
|
status: 'success',
|
|
3735
3924
|
output: { text: 'London' },
|
|
3736
3925
|
});
|
|
3737
|
-
|
|
3738
|
-
srv.close();
|
|
3739
3926
|
});
|
|
3740
3927
|
|
|
3741
3928
|
it('should be able to use an agent in parallel', async ctx => {
|
|
3742
3929
|
const inngest = new Inngest({
|
|
3743
3930
|
id: 'mastra',
|
|
3744
3931
|
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
3932
|
+
middleware: [realtimeMiddleware()],
|
|
3745
3933
|
});
|
|
3746
3934
|
|
|
3747
3935
|
const { createWorkflow, createStep } = init(inngest);
|
|
@@ -3856,23 +4044,23 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3856
4044
|
});
|
|
3857
4045
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
3858
4046
|
|
|
3859
|
-
const run =
|
|
4047
|
+
const run = workflow.createRun();
|
|
3860
4048
|
const result = await run.start({
|
|
3861
4049
|
inputData: { prompt1: 'Capital of France, just the name', prompt2: 'Capital of UK, just the name' },
|
|
3862
4050
|
});
|
|
3863
4051
|
|
|
3864
4052
|
expect(execute).toHaveBeenCalledTimes(1);
|
|
3865
|
-
expect(result.steps['finalStep']).
|
|
4053
|
+
expect(result.steps['finalStep']).toMatchObject({
|
|
3866
4054
|
status: 'success',
|
|
3867
4055
|
output: { result: 'success' },
|
|
3868
4056
|
});
|
|
3869
4057
|
|
|
3870
|
-
expect(result.steps['nested-workflow']).
|
|
4058
|
+
expect(result.steps['nested-workflow']).toMatchObject({
|
|
3871
4059
|
status: 'success',
|
|
3872
4060
|
output: { text: 'Paris' },
|
|
3873
4061
|
});
|
|
3874
4062
|
|
|
3875
|
-
expect(result.steps['nested-workflow-2']).
|
|
4063
|
+
expect(result.steps['nested-workflow-2']).toMatchObject({
|
|
3876
4064
|
status: 'success',
|
|
3877
4065
|
output: { text: 'London' },
|
|
3878
4066
|
});
|
|
@@ -3999,7 +4187,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
3999
4187
|
});
|
|
4000
4188
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
4001
4189
|
|
|
4002
|
-
const run =
|
|
4190
|
+
const run = counterWorkflow.createRun();
|
|
4003
4191
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
4004
4192
|
|
|
4005
4193
|
srv.close();
|
|
@@ -4009,16 +4197,16 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4009
4197
|
expect(final).toHaveBeenCalledTimes(2);
|
|
4010
4198
|
expect(last).toHaveBeenCalledTimes(1);
|
|
4011
4199
|
// @ts-ignore
|
|
4012
|
-
expect(result.steps['nested-workflow-a'].output).
|
|
4200
|
+
expect(result.steps['nested-workflow-a'].output).toMatchObject({
|
|
4013
4201
|
finalValue: 26 + 1,
|
|
4014
4202
|
});
|
|
4015
4203
|
|
|
4016
4204
|
// @ts-ignore
|
|
4017
|
-
expect(result.steps['nested-workflow-b'].output).
|
|
4205
|
+
expect(result.steps['nested-workflow-b'].output).toMatchObject({
|
|
4018
4206
|
finalValue: 1,
|
|
4019
4207
|
});
|
|
4020
4208
|
|
|
4021
|
-
expect(result.steps['last-step']).
|
|
4209
|
+
expect(result.steps['last-step']).toMatchObject({
|
|
4022
4210
|
output: { success: true },
|
|
4023
4211
|
status: 'success',
|
|
4024
4212
|
});
|
|
@@ -4151,7 +4339,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4151
4339
|
});
|
|
4152
4340
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
4153
4341
|
|
|
4154
|
-
const run =
|
|
4342
|
+
const run = counterWorkflow.createRun();
|
|
4155
4343
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
4156
4344
|
|
|
4157
4345
|
srv.close();
|
|
@@ -4161,16 +4349,16 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4161
4349
|
expect(final).toHaveBeenCalledTimes(2);
|
|
4162
4350
|
expect(last).toHaveBeenCalledTimes(1);
|
|
4163
4351
|
// @ts-ignore
|
|
4164
|
-
expect(result.steps['nested-workflow-a'].output).
|
|
4352
|
+
expect(result.steps['nested-workflow-a'].output).toMatchObject({
|
|
4165
4353
|
finalValue: 26 + 1,
|
|
4166
4354
|
});
|
|
4167
4355
|
|
|
4168
4356
|
// @ts-ignore
|
|
4169
|
-
expect(result.steps['nested-workflow-b'].output).
|
|
4357
|
+
expect(result.steps['nested-workflow-b'].output).toMatchObject({
|
|
4170
4358
|
finalValue: 1,
|
|
4171
4359
|
});
|
|
4172
4360
|
|
|
4173
|
-
expect(result.steps['last-step']).
|
|
4361
|
+
expect(result.steps['last-step']).toMatchObject({
|
|
4174
4362
|
output: { success: true },
|
|
4175
4363
|
status: 'success',
|
|
4176
4364
|
});
|
|
@@ -4310,7 +4498,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4310
4498
|
port: (ctx as any).handlerPort,
|
|
4311
4499
|
});
|
|
4312
4500
|
|
|
4313
|
-
const run =
|
|
4501
|
+
const run = counterWorkflow.createRun();
|
|
4314
4502
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
4315
4503
|
|
|
4316
4504
|
srv.close();
|
|
@@ -4321,16 +4509,16 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4321
4509
|
expect(first).toHaveBeenCalledTimes(1);
|
|
4322
4510
|
expect(last).toHaveBeenCalledTimes(1);
|
|
4323
4511
|
// @ts-ignore
|
|
4324
|
-
expect(result.steps['nested-workflow-a'].output).
|
|
4512
|
+
expect(result.steps['nested-workflow-a'].output).toMatchObject({
|
|
4325
4513
|
finalValue: 26 + 1,
|
|
4326
4514
|
});
|
|
4327
4515
|
|
|
4328
|
-
expect(result.steps['first-step']).
|
|
4516
|
+
expect(result.steps['first-step']).toMatchObject({
|
|
4329
4517
|
output: { success: true },
|
|
4330
4518
|
status: 'success',
|
|
4331
4519
|
});
|
|
4332
4520
|
|
|
4333
|
-
expect(result.steps['last-step']).
|
|
4521
|
+
expect(result.steps['last-step']).toMatchObject({
|
|
4334
4522
|
output: { success: true },
|
|
4335
4523
|
status: 'success',
|
|
4336
4524
|
});
|
|
@@ -4469,7 +4657,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4469
4657
|
port: (ctx as any).handlerPort,
|
|
4470
4658
|
});
|
|
4471
4659
|
|
|
4472
|
-
const run =
|
|
4660
|
+
const run = counterWorkflow.createRun();
|
|
4473
4661
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
4474
4662
|
|
|
4475
4663
|
srv.close();
|
|
@@ -4481,16 +4669,16 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4481
4669
|
expect(last).toHaveBeenCalledTimes(1);
|
|
4482
4670
|
|
|
4483
4671
|
// @ts-ignore
|
|
4484
|
-
expect(result.steps['nested-workflow-b'].output).
|
|
4672
|
+
expect(result.steps['nested-workflow-b'].output).toMatchObject({
|
|
4485
4673
|
finalValue: 1,
|
|
4486
4674
|
});
|
|
4487
4675
|
|
|
4488
|
-
expect(result.steps['first-step']).
|
|
4676
|
+
expect(result.steps['first-step']).toMatchObject({
|
|
4489
4677
|
output: { success: true },
|
|
4490
4678
|
status: 'success',
|
|
4491
4679
|
});
|
|
4492
4680
|
|
|
4493
|
-
expect(result.steps['last-step']).
|
|
4681
|
+
expect(result.steps['last-step']).toMatchObject({
|
|
4494
4682
|
output: { success: true },
|
|
4495
4683
|
status: 'success',
|
|
4496
4684
|
});
|
|
@@ -4666,7 +4854,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4666
4854
|
port: (ctx as any).handlerPort,
|
|
4667
4855
|
});
|
|
4668
4856
|
|
|
4669
|
-
const run =
|
|
4857
|
+
const run = counterWorkflow.createRun();
|
|
4670
4858
|
const result = await run.start({ inputData: { startValue: 1 } });
|
|
4671
4859
|
|
|
4672
4860
|
srv.close();
|
|
@@ -4678,16 +4866,16 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4678
4866
|
// expect(last).toHaveBeenCalledTimes(1);
|
|
4679
4867
|
|
|
4680
4868
|
// @ts-ignore
|
|
4681
|
-
expect(result.steps['nested-workflow-b'].output).
|
|
4869
|
+
expect(result.steps['nested-workflow-b'].output).toMatchObject({
|
|
4682
4870
|
finalValue: 1,
|
|
4683
4871
|
});
|
|
4684
4872
|
|
|
4685
|
-
expect(result.steps['first-step']).
|
|
4873
|
+
expect(result.steps['first-step']).toMatchObject({
|
|
4686
4874
|
output: { success: true },
|
|
4687
4875
|
status: 'success',
|
|
4688
4876
|
});
|
|
4689
4877
|
|
|
4690
|
-
expect(result.steps['last-step']).
|
|
4878
|
+
expect(result.steps['last-step']).toMatchObject({
|
|
4691
4879
|
output: { success: true },
|
|
4692
4880
|
status: 'success',
|
|
4693
4881
|
});
|
|
@@ -4820,7 +5008,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4820
5008
|
});
|
|
4821
5009
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
4822
5010
|
|
|
4823
|
-
const run =
|
|
5011
|
+
const run = counterWorkflow.createRun();
|
|
4824
5012
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
4825
5013
|
|
|
4826
5014
|
expect(begin).toHaveBeenCalledTimes(1);
|
|
@@ -4833,12 +5021,12 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4833
5021
|
});
|
|
4834
5022
|
|
|
4835
5023
|
// @ts-ignore
|
|
4836
|
-
expect(result.steps['last-step']).
|
|
5024
|
+
expect(result.steps['last-step']).toMatchObject(undefined);
|
|
4837
5025
|
|
|
4838
5026
|
const resumedResults = await run.resume({ step: [wfA, otherStep], resumeData: { newValue: 0 } });
|
|
4839
5027
|
|
|
4840
5028
|
// @ts-ignore
|
|
4841
|
-
expect(resumedResults.steps['nested-workflow-a'].output).
|
|
5029
|
+
expect(resumedResults.steps['nested-workflow-a'].output).toMatchObject({
|
|
4842
5030
|
finalValue: 26 + 1,
|
|
4843
5031
|
});
|
|
4844
5032
|
|
|
@@ -4970,7 +5158,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4970
5158
|
port: (ctx as any).handlerPort,
|
|
4971
5159
|
});
|
|
4972
5160
|
|
|
4973
|
-
const run =
|
|
5161
|
+
const run = counterWorkflow.createRun();
|
|
4974
5162
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
4975
5163
|
const results = result.steps;
|
|
4976
5164
|
|
|
@@ -4989,7 +5177,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
4989
5177
|
},
|
|
4990
5178
|
});
|
|
4991
5179
|
|
|
4992
|
-
expect(result.steps['last-step']).
|
|
5180
|
+
expect(result.steps['last-step']).toMatchObject({
|
|
4993
5181
|
status: 'success',
|
|
4994
5182
|
output: { success: true },
|
|
4995
5183
|
});
|
|
@@ -5152,7 +5340,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5152
5340
|
});
|
|
5153
5341
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
5154
5342
|
|
|
5155
|
-
const run =
|
|
5343
|
+
const run = counterWorkflow.createRun();
|
|
5156
5344
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
5157
5345
|
|
|
5158
5346
|
expect(passthroughStep.execute).toHaveBeenCalledTimes(2);
|
|
@@ -5166,18 +5354,23 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5166
5354
|
});
|
|
5167
5355
|
|
|
5168
5356
|
// @ts-ignore
|
|
5169
|
-
expect(result.steps['last-step']).
|
|
5357
|
+
expect(result.steps['last-step']).toMatchObject(undefined);
|
|
5170
5358
|
|
|
5171
5359
|
if (result.status !== 'suspended') {
|
|
5172
5360
|
expect.fail('Workflow should be suspended');
|
|
5173
5361
|
}
|
|
5174
|
-
expect(result.suspended[0]).
|
|
5362
|
+
expect(result.suspended[0]).toMatchObject([
|
|
5363
|
+
'nested-workflow-c',
|
|
5364
|
+
'nested-workflow-b',
|
|
5365
|
+
'nested-workflow-a',
|
|
5366
|
+
'other',
|
|
5367
|
+
]);
|
|
5175
5368
|
const resumedResults = await run.resume({ step: result.suspended[0], resumeData: { newValue: 0 } });
|
|
5176
5369
|
|
|
5177
5370
|
srv.close();
|
|
5178
5371
|
|
|
5179
5372
|
// @ts-ignore
|
|
5180
|
-
expect(resumedResults.steps['nested-workflow-c'].output).
|
|
5373
|
+
expect(resumedResults.steps['nested-workflow-c'].output).toMatchObject({
|
|
5181
5374
|
finalValue: 26 + 1,
|
|
5182
5375
|
});
|
|
5183
5376
|
|
|
@@ -5309,7 +5502,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5309
5502
|
});
|
|
5310
5503
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
5311
5504
|
|
|
5312
|
-
const run =
|
|
5505
|
+
const run = counterWorkflow.createRun();
|
|
5313
5506
|
const result = await run.start({ inputData: { startValue: 0 } });
|
|
5314
5507
|
|
|
5315
5508
|
srv.close();
|
|
@@ -5319,16 +5512,16 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5319
5512
|
expect(final).toHaveBeenCalledTimes(2);
|
|
5320
5513
|
expect(last).toHaveBeenCalledTimes(1);
|
|
5321
5514
|
// @ts-ignore
|
|
5322
|
-
expect(result.steps['nested-workflow-a-clone'].output).
|
|
5515
|
+
expect(result.steps['nested-workflow-a-clone'].output).toMatchObject({
|
|
5323
5516
|
finalValue: 26 + 1,
|
|
5324
5517
|
});
|
|
5325
5518
|
|
|
5326
5519
|
// @ts-ignore
|
|
5327
|
-
expect(result.steps['nested-workflow-b'].output).
|
|
5520
|
+
expect(result.steps['nested-workflow-b'].output).toMatchObject({
|
|
5328
5521
|
finalValue: 1,
|
|
5329
5522
|
});
|
|
5330
5523
|
|
|
5331
|
-
expect(result.steps['last-step']).
|
|
5524
|
+
expect(result.steps['last-step']).toMatchObject({
|
|
5332
5525
|
output: { success: true },
|
|
5333
5526
|
status: 'success',
|
|
5334
5527
|
});
|
|
@@ -5385,7 +5578,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5385
5578
|
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
5386
5579
|
|
|
5387
5580
|
// Access new instance properties directly - should work without warning
|
|
5388
|
-
const run =
|
|
5581
|
+
const run = workflow.createRun();
|
|
5389
5582
|
await run.start({ inputData: {} });
|
|
5390
5583
|
|
|
5391
5584
|
srv.close();
|
|
@@ -5446,7 +5639,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5446
5639
|
port: (ctx as any).handlerPort,
|
|
5447
5640
|
});
|
|
5448
5641
|
|
|
5449
|
-
const run =
|
|
5642
|
+
const run = workflow.createRun();
|
|
5450
5643
|
const result = await run.start({ runtimeContext });
|
|
5451
5644
|
|
|
5452
5645
|
srv.close();
|
|
@@ -5499,7 +5692,7 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5499
5692
|
});
|
|
5500
5693
|
workflow.then(step).commit();
|
|
5501
5694
|
|
|
5502
|
-
const run =
|
|
5695
|
+
const run = workflow.createRun();
|
|
5503
5696
|
await run.start({ runtimeContext });
|
|
5504
5697
|
|
|
5505
5698
|
const resumeruntimeContext = new RuntimeContext();
|
|
@@ -5518,5 +5711,1049 @@ describe('MastraInngestWorkflow', () => {
|
|
|
5518
5711
|
});
|
|
5519
5712
|
});
|
|
5520
5713
|
|
|
5521
|
-
describe('Access to inngest step primitives', () => {
|
|
5714
|
+
describe('Access to inngest step primitives', () => {
|
|
5715
|
+
it('should inject inngest step primitives into steps during run', async ctx => {
|
|
5716
|
+
const inngest = new Inngest({
|
|
5717
|
+
id: 'mastra',
|
|
5718
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
5719
|
+
});
|
|
5720
|
+
|
|
5721
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
5722
|
+
|
|
5723
|
+
const step = createStep({
|
|
5724
|
+
id: 'step1',
|
|
5725
|
+
execute: async ({ engine }) => {
|
|
5726
|
+
return {
|
|
5727
|
+
hasEngine: !!engine.step,
|
|
5728
|
+
};
|
|
5729
|
+
},
|
|
5730
|
+
inputSchema: z.object({}),
|
|
5731
|
+
outputSchema: z.object({}),
|
|
5732
|
+
});
|
|
5733
|
+
const workflow = createWorkflow({
|
|
5734
|
+
id: 'test-workflow',
|
|
5735
|
+
inputSchema: z.object({}),
|
|
5736
|
+
outputSchema: z.object({
|
|
5737
|
+
hasEngine: z.boolean(),
|
|
5738
|
+
}),
|
|
5739
|
+
});
|
|
5740
|
+
workflow.then(step).commit();
|
|
5741
|
+
|
|
5742
|
+
const mastra = new Mastra({
|
|
5743
|
+
storage: new DefaultStorage({
|
|
5744
|
+
url: ':memory:',
|
|
5745
|
+
}),
|
|
5746
|
+
workflows: {
|
|
5747
|
+
'test-workflow': workflow,
|
|
5748
|
+
},
|
|
5749
|
+
server: {
|
|
5750
|
+
apiRoutes: [
|
|
5751
|
+
{
|
|
5752
|
+
path: '/inngest/api',
|
|
5753
|
+
method: 'ALL',
|
|
5754
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
5755
|
+
},
|
|
5756
|
+
],
|
|
5757
|
+
},
|
|
5758
|
+
});
|
|
5759
|
+
|
|
5760
|
+
const app = await createHonoServer(mastra);
|
|
5761
|
+
|
|
5762
|
+
const srv = serve({
|
|
5763
|
+
fetch: app.fetch,
|
|
5764
|
+
port: (ctx as any).handlerPort,
|
|
5765
|
+
});
|
|
5766
|
+
|
|
5767
|
+
const run = workflow.createRun();
|
|
5768
|
+
const result = await run.start({});
|
|
5769
|
+
|
|
5770
|
+
srv.close();
|
|
5771
|
+
|
|
5772
|
+
// @ts-ignore
|
|
5773
|
+
expect(result?.steps.step1.output.hasEngine).toBe(true);
|
|
5774
|
+
});
|
|
5775
|
+
});
|
|
5776
|
+
|
|
5777
|
+
describe('Streaming', () => {
|
|
5778
|
+
it('should generate a stream', async ctx => {
|
|
5779
|
+
const inngest = new Inngest({
|
|
5780
|
+
id: 'mastra',
|
|
5781
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
5782
|
+
middleware: [realtimeMiddleware()],
|
|
5783
|
+
});
|
|
5784
|
+
|
|
5785
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
5786
|
+
|
|
5787
|
+
const step1Action = vi.fn<any>().mockResolvedValue({ result: 'success1' });
|
|
5788
|
+
const step2Action = vi.fn<any>().mockResolvedValue({ result: 'success2' });
|
|
5789
|
+
|
|
5790
|
+
const step1 = createStep({
|
|
5791
|
+
id: 'step1',
|
|
5792
|
+
execute: step1Action,
|
|
5793
|
+
inputSchema: z.object({}),
|
|
5794
|
+
outputSchema: z.object({ value: z.string() }),
|
|
5795
|
+
});
|
|
5796
|
+
const step2 = createStep({
|
|
5797
|
+
id: 'step2',
|
|
5798
|
+
execute: step2Action,
|
|
5799
|
+
inputSchema: z.object({ value: z.string() }),
|
|
5800
|
+
outputSchema: z.object({}),
|
|
5801
|
+
});
|
|
5802
|
+
|
|
5803
|
+
const workflow = createWorkflow({
|
|
5804
|
+
id: 'test-workflow',
|
|
5805
|
+
inputSchema: z.object({}),
|
|
5806
|
+
outputSchema: z.object({}),
|
|
5807
|
+
steps: [step1, step2],
|
|
5808
|
+
});
|
|
5809
|
+
workflow.then(step1).then(step2).commit();
|
|
5810
|
+
|
|
5811
|
+
const mastra = new Mastra({
|
|
5812
|
+
storage: new DefaultStorage({
|
|
5813
|
+
url: ':memory:',
|
|
5814
|
+
}),
|
|
5815
|
+
workflows: {
|
|
5816
|
+
'test-workflow': workflow,
|
|
5817
|
+
},
|
|
5818
|
+
server: {
|
|
5819
|
+
apiRoutes: [
|
|
5820
|
+
{
|
|
5821
|
+
path: '/inngest/api',
|
|
5822
|
+
method: 'ALL',
|
|
5823
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
5824
|
+
},
|
|
5825
|
+
],
|
|
5826
|
+
},
|
|
5827
|
+
});
|
|
5828
|
+
|
|
5829
|
+
const app = await createHonoServer(mastra);
|
|
5830
|
+
|
|
5831
|
+
const srv = serve({
|
|
5832
|
+
fetch: app.fetch,
|
|
5833
|
+
port: (ctx as any).handlerPort,
|
|
5834
|
+
});
|
|
5835
|
+
|
|
5836
|
+
const runId = 'test-run-id';
|
|
5837
|
+
let watchData: StreamEvent[] = [];
|
|
5838
|
+
const run = workflow.createRun({
|
|
5839
|
+
runId,
|
|
5840
|
+
});
|
|
5841
|
+
|
|
5842
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
5843
|
+
|
|
5844
|
+
const { stream, getWorkflowState } = run.stream({ inputData: {} });
|
|
5845
|
+
|
|
5846
|
+
// Start watching the workflow
|
|
5847
|
+
const collectedStreamData: StreamEvent[] = [];
|
|
5848
|
+
for await (const data of stream) {
|
|
5849
|
+
collectedStreamData.push(JSON.parse(JSON.stringify(data)));
|
|
5850
|
+
}
|
|
5851
|
+
watchData = collectedStreamData;
|
|
5852
|
+
|
|
5853
|
+
const executionResult = await getWorkflowState();
|
|
5854
|
+
|
|
5855
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
5856
|
+
|
|
5857
|
+
srv.close();
|
|
5858
|
+
|
|
5859
|
+
expect(watchData.length).toBe(8);
|
|
5860
|
+
expect(watchData).toMatchInlineSnapshot(`
|
|
5861
|
+
[
|
|
5862
|
+
{
|
|
5863
|
+
"payload": {
|
|
5864
|
+
"runId": "test-run-id",
|
|
5865
|
+
},
|
|
5866
|
+
"type": "start",
|
|
5867
|
+
},
|
|
5868
|
+
{
|
|
5869
|
+
"payload": {
|
|
5870
|
+
"id": "step1",
|
|
5871
|
+
},
|
|
5872
|
+
"type": "step-start",
|
|
5873
|
+
},
|
|
5874
|
+
{
|
|
5875
|
+
"payload": {
|
|
5876
|
+
"id": "step1",
|
|
5877
|
+
"output": {
|
|
5878
|
+
"result": "success1",
|
|
5879
|
+
},
|
|
5880
|
+
"status": "success",
|
|
5881
|
+
},
|
|
5882
|
+
"type": "step-result",
|
|
5883
|
+
},
|
|
5884
|
+
{
|
|
5885
|
+
"payload": {
|
|
5886
|
+
"id": "step1",
|
|
5887
|
+
"metadata": {},
|
|
5888
|
+
},
|
|
5889
|
+
"type": "step-finish",
|
|
5890
|
+
},
|
|
5891
|
+
{
|
|
5892
|
+
"payload": {
|
|
5893
|
+
"id": "step2",
|
|
5894
|
+
},
|
|
5895
|
+
"type": "step-start",
|
|
5896
|
+
},
|
|
5897
|
+
{
|
|
5898
|
+
"payload": {
|
|
5899
|
+
"id": "step2",
|
|
5900
|
+
"output": {
|
|
5901
|
+
"result": "success2",
|
|
5902
|
+
},
|
|
5903
|
+
"status": "success",
|
|
5904
|
+
},
|
|
5905
|
+
"type": "step-result",
|
|
5906
|
+
},
|
|
5907
|
+
{
|
|
5908
|
+
"payload": {
|
|
5909
|
+
"id": "step2",
|
|
5910
|
+
"metadata": {},
|
|
5911
|
+
},
|
|
5912
|
+
"type": "step-finish",
|
|
5913
|
+
},
|
|
5914
|
+
{
|
|
5915
|
+
"payload": {
|
|
5916
|
+
"runId": "test-run-id",
|
|
5917
|
+
},
|
|
5918
|
+
"type": "finish",
|
|
5919
|
+
},
|
|
5920
|
+
]
|
|
5921
|
+
`);
|
|
5922
|
+
// Verify execution completed successfully
|
|
5923
|
+
expect(executionResult.steps.step1).toMatchObject({
|
|
5924
|
+
status: 'success',
|
|
5925
|
+
output: { result: 'success1' },
|
|
5926
|
+
payload: {},
|
|
5927
|
+
startedAt: expect.any(Number),
|
|
5928
|
+
endedAt: expect.any(Number),
|
|
5929
|
+
});
|
|
5930
|
+
expect(executionResult.steps.step2).toMatchObject({
|
|
5931
|
+
status: 'success',
|
|
5932
|
+
output: { result: 'success2' },
|
|
5933
|
+
payload: {
|
|
5934
|
+
result: 'success1',
|
|
5935
|
+
},
|
|
5936
|
+
startedAt: expect.any(Number),
|
|
5937
|
+
endedAt: expect.any(Number),
|
|
5938
|
+
});
|
|
5939
|
+
});
|
|
5940
|
+
|
|
5941
|
+
it('should handle basic sleep waiting flow', async ctx => {
|
|
5942
|
+
const inngest = new Inngest({
|
|
5943
|
+
id: 'mastra',
|
|
5944
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
5945
|
+
middleware: [realtimeMiddleware()],
|
|
5946
|
+
});
|
|
5947
|
+
|
|
5948
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
5949
|
+
|
|
5950
|
+
const step1Action = vi.fn<any>().mockResolvedValue({ result: 'success1' });
|
|
5951
|
+
const step2Action = vi.fn<any>().mockResolvedValue({ result: 'success2' });
|
|
5952
|
+
|
|
5953
|
+
const step1 = createStep({
|
|
5954
|
+
id: 'step1',
|
|
5955
|
+
execute: step1Action,
|
|
5956
|
+
inputSchema: z.object({}),
|
|
5957
|
+
outputSchema: z.object({ value: z.string() }),
|
|
5958
|
+
});
|
|
5959
|
+
const step2 = createStep({
|
|
5960
|
+
id: 'step2',
|
|
5961
|
+
execute: step2Action,
|
|
5962
|
+
inputSchema: z.object({ value: z.string() }),
|
|
5963
|
+
outputSchema: z.object({}),
|
|
5964
|
+
});
|
|
5965
|
+
|
|
5966
|
+
const workflow = createWorkflow({
|
|
5967
|
+
id: 'test-workflow',
|
|
5968
|
+
inputSchema: z.object({}),
|
|
5969
|
+
outputSchema: z.object({}),
|
|
5970
|
+
steps: [step1, step2],
|
|
5971
|
+
});
|
|
5972
|
+
workflow.then(step1).sleep(1000).then(step2).commit();
|
|
5973
|
+
|
|
5974
|
+
const mastra = new Mastra({
|
|
5975
|
+
storage: new DefaultStorage({
|
|
5976
|
+
url: ':memory:',
|
|
5977
|
+
}),
|
|
5978
|
+
workflows: {
|
|
5979
|
+
'test-workflow': workflow,
|
|
5980
|
+
},
|
|
5981
|
+
server: {
|
|
5982
|
+
apiRoutes: [
|
|
5983
|
+
{
|
|
5984
|
+
path: '/inngest/api',
|
|
5985
|
+
method: 'ALL',
|
|
5986
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
5987
|
+
},
|
|
5988
|
+
],
|
|
5989
|
+
},
|
|
5990
|
+
});
|
|
5991
|
+
|
|
5992
|
+
const app = await createHonoServer(mastra);
|
|
5993
|
+
|
|
5994
|
+
const srv = serve({
|
|
5995
|
+
fetch: app.fetch,
|
|
5996
|
+
port: (ctx as any).handlerPort,
|
|
5997
|
+
});
|
|
5998
|
+
|
|
5999
|
+
const runId = 'test-run-id';
|
|
6000
|
+
let watchData: StreamEvent[] = [];
|
|
6001
|
+
const run = workflow.createRun({
|
|
6002
|
+
runId,
|
|
6003
|
+
});
|
|
6004
|
+
|
|
6005
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
6006
|
+
|
|
6007
|
+
const { stream, getWorkflowState } = run.stream({ inputData: {} });
|
|
6008
|
+
|
|
6009
|
+
// Start watching the workflow
|
|
6010
|
+
const collectedStreamData: StreamEvent[] = [];
|
|
6011
|
+
for await (const data of stream) {
|
|
6012
|
+
collectedStreamData.push(JSON.parse(JSON.stringify(data)));
|
|
6013
|
+
}
|
|
6014
|
+
watchData = collectedStreamData;
|
|
6015
|
+
|
|
6016
|
+
const executionResult = await getWorkflowState();
|
|
6017
|
+
|
|
6018
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
6019
|
+
|
|
6020
|
+
srv.close();
|
|
6021
|
+
|
|
6022
|
+
expect(watchData.length).toBe(9);
|
|
6023
|
+
expect(watchData).toMatchObject([
|
|
6024
|
+
{
|
|
6025
|
+
payload: {
|
|
6026
|
+
runId: 'test-run-id',
|
|
6027
|
+
},
|
|
6028
|
+
type: 'start',
|
|
6029
|
+
},
|
|
6030
|
+
{
|
|
6031
|
+
payload: {
|
|
6032
|
+
id: 'step1',
|
|
6033
|
+
},
|
|
6034
|
+
type: 'step-start',
|
|
6035
|
+
},
|
|
6036
|
+
{
|
|
6037
|
+
payload: {
|
|
6038
|
+
id: 'step1',
|
|
6039
|
+
output: {
|
|
6040
|
+
result: 'success1',
|
|
6041
|
+
},
|
|
6042
|
+
status: 'success',
|
|
6043
|
+
},
|
|
6044
|
+
type: 'step-result',
|
|
6045
|
+
},
|
|
6046
|
+
{
|
|
6047
|
+
payload: {
|
|
6048
|
+
id: 'step1',
|
|
6049
|
+
metadata: {},
|
|
6050
|
+
},
|
|
6051
|
+
type: 'step-finish',
|
|
6052
|
+
},
|
|
6053
|
+
{
|
|
6054
|
+
payload: {},
|
|
6055
|
+
type: 'step-waiting',
|
|
6056
|
+
},
|
|
6057
|
+
{
|
|
6058
|
+
payload: {
|
|
6059
|
+
id: 'step2',
|
|
6060
|
+
},
|
|
6061
|
+
type: 'step-start',
|
|
6062
|
+
},
|
|
6063
|
+
{
|
|
6064
|
+
payload: {
|
|
6065
|
+
id: 'step2',
|
|
6066
|
+
output: {
|
|
6067
|
+
result: 'success2',
|
|
6068
|
+
},
|
|
6069
|
+
status: 'success',
|
|
6070
|
+
},
|
|
6071
|
+
type: 'step-result',
|
|
6072
|
+
},
|
|
6073
|
+
{
|
|
6074
|
+
payload: {
|
|
6075
|
+
id: 'step2',
|
|
6076
|
+
metadata: {},
|
|
6077
|
+
},
|
|
6078
|
+
type: 'step-finish',
|
|
6079
|
+
},
|
|
6080
|
+
{
|
|
6081
|
+
payload: {
|
|
6082
|
+
runId: 'test-run-id',
|
|
6083
|
+
},
|
|
6084
|
+
type: 'finish',
|
|
6085
|
+
},
|
|
6086
|
+
]);
|
|
6087
|
+
// Verify execution completed successfully
|
|
6088
|
+
expect(executionResult.steps.step1).toMatchObject({
|
|
6089
|
+
status: 'success',
|
|
6090
|
+
output: { result: 'success1' },
|
|
6091
|
+
payload: {},
|
|
6092
|
+
startedAt: expect.any(Number),
|
|
6093
|
+
endedAt: expect.any(Number),
|
|
6094
|
+
});
|
|
6095
|
+
expect(executionResult.steps.step2).toMatchObject({
|
|
6096
|
+
status: 'success',
|
|
6097
|
+
output: { result: 'success2' },
|
|
6098
|
+
payload: {
|
|
6099
|
+
result: 'success1',
|
|
6100
|
+
},
|
|
6101
|
+
startedAt: expect.any(Number),
|
|
6102
|
+
endedAt: expect.any(Number),
|
|
6103
|
+
});
|
|
6104
|
+
});
|
|
6105
|
+
|
|
6106
|
+
it('should handle waitForEvent waiting flow', async ctx => {
|
|
6107
|
+
const inngest = new Inngest({
|
|
6108
|
+
id: 'mastra',
|
|
6109
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
6110
|
+
middleware: [realtimeMiddleware()],
|
|
6111
|
+
});
|
|
6112
|
+
|
|
6113
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
6114
|
+
|
|
6115
|
+
const step1Action = vi.fn<any>().mockResolvedValue({ result: 'success1' });
|
|
6116
|
+
const step2Action = vi.fn<any>().mockResolvedValue({ result: 'success2' });
|
|
6117
|
+
|
|
6118
|
+
const step1 = createStep({
|
|
6119
|
+
id: 'step1',
|
|
6120
|
+
execute: step1Action,
|
|
6121
|
+
inputSchema: z.object({}),
|
|
6122
|
+
outputSchema: z.object({ value: z.string() }),
|
|
6123
|
+
});
|
|
6124
|
+
const step2 = createStep({
|
|
6125
|
+
id: 'step2',
|
|
6126
|
+
execute: step2Action,
|
|
6127
|
+
inputSchema: z.object({ value: z.string() }),
|
|
6128
|
+
outputSchema: z.object({}),
|
|
6129
|
+
});
|
|
6130
|
+
|
|
6131
|
+
const workflow = createWorkflow({
|
|
6132
|
+
id: 'test-workflow',
|
|
6133
|
+
inputSchema: z.object({}),
|
|
6134
|
+
outputSchema: z.object({}),
|
|
6135
|
+
steps: [step1, step2],
|
|
6136
|
+
});
|
|
6137
|
+
workflow.then(step1).waitForEvent('user-event-test', step2).commit();
|
|
6138
|
+
|
|
6139
|
+
const mastra = new Mastra({
|
|
6140
|
+
storage: new DefaultStorage({
|
|
6141
|
+
url: ':memory:',
|
|
6142
|
+
}),
|
|
6143
|
+
workflows: {
|
|
6144
|
+
'test-workflow': workflow,
|
|
6145
|
+
},
|
|
6146
|
+
server: {
|
|
6147
|
+
apiRoutes: [
|
|
6148
|
+
{
|
|
6149
|
+
path: '/inngest/api',
|
|
6150
|
+
method: 'ALL',
|
|
6151
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
6152
|
+
},
|
|
6153
|
+
],
|
|
6154
|
+
},
|
|
6155
|
+
});
|
|
6156
|
+
|
|
6157
|
+
const app = await createHonoServer(mastra);
|
|
6158
|
+
|
|
6159
|
+
const srv = serve({
|
|
6160
|
+
fetch: app.fetch,
|
|
6161
|
+
port: (ctx as any).handlerPort,
|
|
6162
|
+
});
|
|
6163
|
+
|
|
6164
|
+
const runId = 'test-run-id';
|
|
6165
|
+
let watchData: StreamEvent[] = [];
|
|
6166
|
+
const run = workflow.createRun({
|
|
6167
|
+
runId,
|
|
6168
|
+
});
|
|
6169
|
+
|
|
6170
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
6171
|
+
|
|
6172
|
+
const { stream, getWorkflowState } = run.stream({ inputData: {} });
|
|
6173
|
+
|
|
6174
|
+
setTimeout(() => {
|
|
6175
|
+
run.sendEvent('user-event-test', {
|
|
6176
|
+
value: 'eventdata',
|
|
6177
|
+
});
|
|
6178
|
+
}, 3000);
|
|
6179
|
+
|
|
6180
|
+
// Start watching the workflow
|
|
6181
|
+
const collectedStreamData: StreamEvent[] = [];
|
|
6182
|
+
for await (const data of stream) {
|
|
6183
|
+
collectedStreamData.push(JSON.parse(JSON.stringify(data)));
|
|
6184
|
+
}
|
|
6185
|
+
watchData = collectedStreamData;
|
|
6186
|
+
console.dir({ watchData }, { depth: null });
|
|
6187
|
+
|
|
6188
|
+
const executionResult = await getWorkflowState();
|
|
6189
|
+
|
|
6190
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
6191
|
+
|
|
6192
|
+
srv.close();
|
|
6193
|
+
|
|
6194
|
+
expect(watchData.length).toBe(9);
|
|
6195
|
+
expect(watchData).toMatchObject([
|
|
6196
|
+
{
|
|
6197
|
+
payload: {
|
|
6198
|
+
runId: 'test-run-id',
|
|
6199
|
+
},
|
|
6200
|
+
type: 'start',
|
|
6201
|
+
},
|
|
6202
|
+
{
|
|
6203
|
+
payload: {
|
|
6204
|
+
id: 'step1',
|
|
6205
|
+
},
|
|
6206
|
+
type: 'step-start',
|
|
6207
|
+
},
|
|
6208
|
+
{
|
|
6209
|
+
payload: {
|
|
6210
|
+
id: 'step1',
|
|
6211
|
+
output: {
|
|
6212
|
+
result: 'success1',
|
|
6213
|
+
},
|
|
6214
|
+
status: 'success',
|
|
6215
|
+
},
|
|
6216
|
+
type: 'step-result',
|
|
6217
|
+
},
|
|
6218
|
+
{
|
|
6219
|
+
payload: {
|
|
6220
|
+
id: 'step1',
|
|
6221
|
+
metadata: {},
|
|
6222
|
+
},
|
|
6223
|
+
type: 'step-finish',
|
|
6224
|
+
},
|
|
6225
|
+
{
|
|
6226
|
+
payload: {
|
|
6227
|
+
id: 'step2',
|
|
6228
|
+
},
|
|
6229
|
+
type: 'step-waiting',
|
|
6230
|
+
},
|
|
6231
|
+
{
|
|
6232
|
+
payload: {
|
|
6233
|
+
id: 'step2',
|
|
6234
|
+
},
|
|
6235
|
+
type: 'step-start',
|
|
6236
|
+
},
|
|
6237
|
+
{
|
|
6238
|
+
payload: {
|
|
6239
|
+
id: 'step2',
|
|
6240
|
+
output: {
|
|
6241
|
+
result: 'success2',
|
|
6242
|
+
},
|
|
6243
|
+
status: 'success',
|
|
6244
|
+
},
|
|
6245
|
+
type: 'step-result',
|
|
6246
|
+
},
|
|
6247
|
+
{
|
|
6248
|
+
payload: {
|
|
6249
|
+
id: 'step2',
|
|
6250
|
+
metadata: {},
|
|
6251
|
+
},
|
|
6252
|
+
type: 'step-finish',
|
|
6253
|
+
},
|
|
6254
|
+
{
|
|
6255
|
+
payload: {
|
|
6256
|
+
runId: 'test-run-id',
|
|
6257
|
+
},
|
|
6258
|
+
type: 'finish',
|
|
6259
|
+
},
|
|
6260
|
+
]);
|
|
6261
|
+
// Verify execution completed successfully
|
|
6262
|
+
expect(executionResult.steps.step1).toMatchObject({
|
|
6263
|
+
status: 'success',
|
|
6264
|
+
output: { result: 'success1' },
|
|
6265
|
+
payload: {},
|
|
6266
|
+
startedAt: expect.any(Number),
|
|
6267
|
+
endedAt: expect.any(Number),
|
|
6268
|
+
});
|
|
6269
|
+
expect(executionResult.steps.step2).toMatchObject({
|
|
6270
|
+
status: 'success',
|
|
6271
|
+
output: { result: 'success2' },
|
|
6272
|
+
payload: {
|
|
6273
|
+
result: 'success1',
|
|
6274
|
+
},
|
|
6275
|
+
resumePayload: {
|
|
6276
|
+
value: 'eventdata',
|
|
6277
|
+
},
|
|
6278
|
+
startedAt: expect.any(Number),
|
|
6279
|
+
resumedAt: expect.any(Number),
|
|
6280
|
+
endedAt: expect.any(Number),
|
|
6281
|
+
});
|
|
6282
|
+
});
|
|
6283
|
+
|
|
6284
|
+
it('should handle basic suspend and resume flow', async ctx => {
|
|
6285
|
+
const inngest = new Inngest({
|
|
6286
|
+
id: 'mastra',
|
|
6287
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
6288
|
+
middleware: [realtimeMiddleware()],
|
|
6289
|
+
});
|
|
6290
|
+
|
|
6291
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
6292
|
+
|
|
6293
|
+
const getUserInputAction = vi.fn().mockResolvedValue({ userInput: 'test input' });
|
|
6294
|
+
const promptAgentAction = vi
|
|
6295
|
+
.fn()
|
|
6296
|
+
.mockImplementationOnce(async ({ suspend }) => {
|
|
6297
|
+
console.log('suspend');
|
|
6298
|
+
await suspend();
|
|
6299
|
+
return undefined;
|
|
6300
|
+
})
|
|
6301
|
+
.mockImplementationOnce(() => ({ modelOutput: 'test output' }));
|
|
6302
|
+
const evaluateToneAction = vi.fn().mockResolvedValue({
|
|
6303
|
+
toneScore: { score: 0.8 },
|
|
6304
|
+
completenessScore: { score: 0.7 },
|
|
6305
|
+
});
|
|
6306
|
+
const improveResponseAction = vi.fn().mockResolvedValue({ improvedOutput: 'improved output' });
|
|
6307
|
+
const evaluateImprovedAction = vi.fn().mockResolvedValue({
|
|
6308
|
+
toneScore: { score: 0.9 },
|
|
6309
|
+
completenessScore: { score: 0.8 },
|
|
6310
|
+
});
|
|
6311
|
+
|
|
6312
|
+
const getUserInput = createStep({
|
|
6313
|
+
id: 'getUserInput',
|
|
6314
|
+
execute: getUserInputAction,
|
|
6315
|
+
inputSchema: z.object({ input: z.string() }),
|
|
6316
|
+
outputSchema: z.object({ userInput: z.string() }),
|
|
6317
|
+
});
|
|
6318
|
+
const promptAgent = createStep({
|
|
6319
|
+
id: 'promptAgent',
|
|
6320
|
+
execute: promptAgentAction,
|
|
6321
|
+
inputSchema: z.object({ userInput: z.string() }),
|
|
6322
|
+
outputSchema: z.object({ modelOutput: z.string() }),
|
|
6323
|
+
});
|
|
6324
|
+
const evaluateTone = createStep({
|
|
6325
|
+
id: 'evaluateToneConsistency',
|
|
6326
|
+
execute: evaluateToneAction,
|
|
6327
|
+
inputSchema: z.object({ modelOutput: z.string() }),
|
|
6328
|
+
outputSchema: z.object({
|
|
6329
|
+
toneScore: z.any(),
|
|
6330
|
+
completenessScore: z.any(),
|
|
6331
|
+
}),
|
|
6332
|
+
});
|
|
6333
|
+
const improveResponse = createStep({
|
|
6334
|
+
id: 'improveResponse',
|
|
6335
|
+
execute: improveResponseAction,
|
|
6336
|
+
inputSchema: z.object({ toneScore: z.any(), completenessScore: z.any() }),
|
|
6337
|
+
outputSchema: z.object({ improvedOutput: z.string() }),
|
|
6338
|
+
});
|
|
6339
|
+
const evaluateImproved = createStep({
|
|
6340
|
+
id: 'evaluateImprovedResponse',
|
|
6341
|
+
execute: evaluateImprovedAction,
|
|
6342
|
+
inputSchema: z.object({ improvedOutput: z.string() }),
|
|
6343
|
+
outputSchema: z.object({
|
|
6344
|
+
toneScore: z.any(),
|
|
6345
|
+
completenessScore: z.any(),
|
|
6346
|
+
}),
|
|
6347
|
+
});
|
|
6348
|
+
|
|
6349
|
+
const promptEvalWorkflow = createWorkflow({
|
|
6350
|
+
id: 'test-workflow',
|
|
6351
|
+
inputSchema: z.object({ input: z.string() }),
|
|
6352
|
+
outputSchema: z.object({}),
|
|
6353
|
+
steps: [getUserInput, promptAgent, evaluateTone, improveResponse, evaluateImproved],
|
|
6354
|
+
});
|
|
6355
|
+
|
|
6356
|
+
promptEvalWorkflow
|
|
6357
|
+
.then(getUserInput)
|
|
6358
|
+
.then(promptAgent)
|
|
6359
|
+
.then(evaluateTone)
|
|
6360
|
+
.then(improveResponse)
|
|
6361
|
+
.then(evaluateImproved)
|
|
6362
|
+
.commit();
|
|
6363
|
+
|
|
6364
|
+
const mastra = new Mastra({
|
|
6365
|
+
storage: new DefaultStorage({
|
|
6366
|
+
url: ':memory:',
|
|
6367
|
+
}),
|
|
6368
|
+
workflows: {
|
|
6369
|
+
'test-workflow': promptEvalWorkflow,
|
|
6370
|
+
},
|
|
6371
|
+
server: {
|
|
6372
|
+
apiRoutes: [
|
|
6373
|
+
{
|
|
6374
|
+
path: '/inngest/api',
|
|
6375
|
+
method: 'ALL',
|
|
6376
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
6377
|
+
},
|
|
6378
|
+
],
|
|
6379
|
+
},
|
|
6380
|
+
});
|
|
6381
|
+
|
|
6382
|
+
const app = await createHonoServer(mastra);
|
|
6383
|
+
|
|
6384
|
+
const srv = serve({
|
|
6385
|
+
fetch: app.fetch,
|
|
6386
|
+
port: (ctx as any).handlerPort,
|
|
6387
|
+
});
|
|
6388
|
+
|
|
6389
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
6390
|
+
|
|
6391
|
+
const run = promptEvalWorkflow.createRun();
|
|
6392
|
+
|
|
6393
|
+
const { stream, getWorkflowState } = run.stream({ inputData: { input: 'test' } });
|
|
6394
|
+
|
|
6395
|
+
for await (const data of stream) {
|
|
6396
|
+
if (data.type === 'step-suspended') {
|
|
6397
|
+
expect(promptAgentAction).toHaveBeenCalledTimes(1);
|
|
6398
|
+
|
|
6399
|
+
// make it async to show that execution is not blocked
|
|
6400
|
+
setImmediate(() => {
|
|
6401
|
+
const resumeData = { stepId: 'promptAgent', context: { userInput: 'test input for resumption' } };
|
|
6402
|
+
run.resume({ resumeData: resumeData as any, step: promptAgent });
|
|
6403
|
+
});
|
|
6404
|
+
expect(evaluateToneAction).not.toHaveBeenCalledTimes(1);
|
|
6405
|
+
}
|
|
6406
|
+
}
|
|
6407
|
+
|
|
6408
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
6409
|
+
const resumeResult = await getWorkflowState();
|
|
6410
|
+
|
|
6411
|
+
srv.close();
|
|
6412
|
+
|
|
6413
|
+
expect(evaluateToneAction).toHaveBeenCalledTimes(1);
|
|
6414
|
+
expect(resumeResult.steps).toMatchObject({
|
|
6415
|
+
input: { input: 'test' },
|
|
6416
|
+
getUserInput: {
|
|
6417
|
+
status: 'success',
|
|
6418
|
+
output: { userInput: 'test input' },
|
|
6419
|
+
payload: { input: 'test' },
|
|
6420
|
+
startedAt: expect.any(Number),
|
|
6421
|
+
endedAt: expect.any(Number),
|
|
6422
|
+
},
|
|
6423
|
+
promptAgent: {
|
|
6424
|
+
status: 'success',
|
|
6425
|
+
output: { modelOutput: 'test output' },
|
|
6426
|
+
payload: { userInput: 'test input' },
|
|
6427
|
+
startedAt: expect.any(Number),
|
|
6428
|
+
endedAt: expect.any(Number),
|
|
6429
|
+
resumePayload: { stepId: 'promptAgent', context: { userInput: 'test input for resumption' } },
|
|
6430
|
+
resumedAt: expect.any(Number),
|
|
6431
|
+
// suspendedAt: expect.any(Number),
|
|
6432
|
+
},
|
|
6433
|
+
evaluateToneConsistency: {
|
|
6434
|
+
status: 'success',
|
|
6435
|
+
output: { toneScore: { score: 0.8 }, completenessScore: { score: 0.7 } },
|
|
6436
|
+
payload: { modelOutput: 'test output' },
|
|
6437
|
+
startedAt: expect.any(Number),
|
|
6438
|
+
endedAt: expect.any(Number),
|
|
6439
|
+
},
|
|
6440
|
+
improveResponse: {
|
|
6441
|
+
status: 'success',
|
|
6442
|
+
output: { improvedOutput: 'improved output' },
|
|
6443
|
+
payload: { toneScore: { score: 0.8 }, completenessScore: { score: 0.7 } },
|
|
6444
|
+
startedAt: expect.any(Number),
|
|
6445
|
+
endedAt: expect.any(Number),
|
|
6446
|
+
},
|
|
6447
|
+
evaluateImprovedResponse: {
|
|
6448
|
+
status: 'success',
|
|
6449
|
+
output: { toneScore: { score: 0.9 }, completenessScore: { score: 0.8 } },
|
|
6450
|
+
payload: { improvedOutput: 'improved output' },
|
|
6451
|
+
startedAt: expect.any(Number),
|
|
6452
|
+
endedAt: expect.any(Number),
|
|
6453
|
+
},
|
|
6454
|
+
});
|
|
6455
|
+
});
|
|
6456
|
+
|
|
6457
|
+
it('should be able to use an agent as a step', async ctx => {
|
|
6458
|
+
const inngest = new Inngest({
|
|
6459
|
+
id: 'mastra',
|
|
6460
|
+
baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
|
|
6461
|
+
middleware: [realtimeMiddleware()],
|
|
6462
|
+
});
|
|
6463
|
+
|
|
6464
|
+
const { createWorkflow, createStep } = init(inngest);
|
|
6465
|
+
|
|
6466
|
+
const workflow = createWorkflow({
|
|
6467
|
+
id: 'test-workflow',
|
|
6468
|
+
inputSchema: z.object({
|
|
6469
|
+
prompt1: z.string(),
|
|
6470
|
+
prompt2: z.string(),
|
|
6471
|
+
}),
|
|
6472
|
+
outputSchema: z.object({}),
|
|
6473
|
+
});
|
|
6474
|
+
|
|
6475
|
+
const agent = new Agent({
|
|
6476
|
+
name: 'test-agent-1',
|
|
6477
|
+
instructions: 'test agent instructions"',
|
|
6478
|
+
model: new MockLanguageModelV1({
|
|
6479
|
+
doStream: async () => ({
|
|
6480
|
+
stream: simulateReadableStream({
|
|
6481
|
+
chunks: [
|
|
6482
|
+
{ type: 'text-delta', textDelta: 'Paris' },
|
|
6483
|
+
{
|
|
6484
|
+
type: 'finish',
|
|
6485
|
+
finishReason: 'stop',
|
|
6486
|
+
logprobs: undefined,
|
|
6487
|
+
usage: { completionTokens: 10, promptTokens: 3 },
|
|
6488
|
+
},
|
|
6489
|
+
],
|
|
6490
|
+
}),
|
|
6491
|
+
rawCall: { rawPrompt: null, rawSettings: {} },
|
|
6492
|
+
}),
|
|
6493
|
+
}),
|
|
6494
|
+
});
|
|
6495
|
+
|
|
6496
|
+
const agent2 = new Agent({
|
|
6497
|
+
name: 'test-agent-2',
|
|
6498
|
+
instructions: 'test agent instructions',
|
|
6499
|
+
model: new MockLanguageModelV1({
|
|
6500
|
+
doStream: async () => ({
|
|
6501
|
+
stream: simulateReadableStream({
|
|
6502
|
+
chunks: [
|
|
6503
|
+
{ type: 'text-delta', textDelta: 'London' },
|
|
6504
|
+
{
|
|
6505
|
+
type: 'finish',
|
|
6506
|
+
finishReason: 'stop',
|
|
6507
|
+
logprobs: undefined,
|
|
6508
|
+
usage: { completionTokens: 10, promptTokens: 3 },
|
|
6509
|
+
},
|
|
6510
|
+
],
|
|
6511
|
+
}),
|
|
6512
|
+
rawCall: { rawPrompt: null, rawSettings: {} },
|
|
6513
|
+
}),
|
|
6514
|
+
}),
|
|
6515
|
+
});
|
|
6516
|
+
|
|
6517
|
+
const startStep = createStep({
|
|
6518
|
+
id: 'start',
|
|
6519
|
+
inputSchema: z.object({
|
|
6520
|
+
prompt1: z.string(),
|
|
6521
|
+
prompt2: z.string(),
|
|
6522
|
+
}),
|
|
6523
|
+
outputSchema: z.object({ prompt1: z.string(), prompt2: z.string() }),
|
|
6524
|
+
execute: async ({ inputData }) => {
|
|
6525
|
+
return {
|
|
6526
|
+
prompt1: inputData.prompt1,
|
|
6527
|
+
prompt2: inputData.prompt2,
|
|
6528
|
+
};
|
|
6529
|
+
},
|
|
6530
|
+
});
|
|
6531
|
+
|
|
6532
|
+
const agentStep1 = createStep(agent);
|
|
6533
|
+
const agentStep2 = createStep(agent2);
|
|
6534
|
+
|
|
6535
|
+
workflow
|
|
6536
|
+
.then(startStep)
|
|
6537
|
+
.map({
|
|
6538
|
+
prompt: {
|
|
6539
|
+
step: startStep,
|
|
6540
|
+
path: 'prompt1',
|
|
6541
|
+
},
|
|
6542
|
+
})
|
|
6543
|
+
.then(agentStep1)
|
|
6544
|
+
.map({
|
|
6545
|
+
prompt: {
|
|
6546
|
+
step: startStep,
|
|
6547
|
+
path: 'prompt2',
|
|
6548
|
+
},
|
|
6549
|
+
})
|
|
6550
|
+
.then(agentStep2)
|
|
6551
|
+
.commit();
|
|
6552
|
+
|
|
6553
|
+
const mastra = new Mastra({
|
|
6554
|
+
storage: new DefaultStorage({
|
|
6555
|
+
url: ':memory:',
|
|
6556
|
+
}),
|
|
6557
|
+
workflows: {
|
|
6558
|
+
'test-workflow': workflow,
|
|
6559
|
+
},
|
|
6560
|
+
server: {
|
|
6561
|
+
apiRoutes: [
|
|
6562
|
+
{
|
|
6563
|
+
path: '/inngest/api',
|
|
6564
|
+
method: 'ALL',
|
|
6565
|
+
createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
|
|
6566
|
+
},
|
|
6567
|
+
],
|
|
6568
|
+
},
|
|
6569
|
+
});
|
|
6570
|
+
|
|
6571
|
+
const app = await createHonoServer(mastra);
|
|
6572
|
+
|
|
6573
|
+
const srv = serve({
|
|
6574
|
+
fetch: app.fetch,
|
|
6575
|
+
port: (ctx as any).handlerPort,
|
|
6576
|
+
});
|
|
6577
|
+
|
|
6578
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
6579
|
+
|
|
6580
|
+
const run = workflow.createRun({
|
|
6581
|
+
runId: 'test-run-id',
|
|
6582
|
+
});
|
|
6583
|
+
const { stream } = await run.stream({
|
|
6584
|
+
inputData: {
|
|
6585
|
+
prompt1: 'Capital of France, just the name',
|
|
6586
|
+
prompt2: 'Capital of UK, just the name',
|
|
6587
|
+
},
|
|
6588
|
+
});
|
|
6589
|
+
|
|
6590
|
+
const values: StreamEvent[] = [];
|
|
6591
|
+
for await (const value of stream.values()) {
|
|
6592
|
+
values.push(value);
|
|
6593
|
+
}
|
|
6594
|
+
|
|
6595
|
+
srv.close();
|
|
6596
|
+
|
|
6597
|
+
expect(values).toMatchObject([
|
|
6598
|
+
{
|
|
6599
|
+
payload: {
|
|
6600
|
+
runId: 'test-run-id',
|
|
6601
|
+
},
|
|
6602
|
+
type: 'start',
|
|
6603
|
+
},
|
|
6604
|
+
{
|
|
6605
|
+
payload: {
|
|
6606
|
+
id: 'start',
|
|
6607
|
+
},
|
|
6608
|
+
type: 'step-start',
|
|
6609
|
+
},
|
|
6610
|
+
{
|
|
6611
|
+
payload: {
|
|
6612
|
+
id: 'start',
|
|
6613
|
+
output: {
|
|
6614
|
+
prompt1: 'Capital of France, just the name',
|
|
6615
|
+
prompt2: 'Capital of UK, just the name',
|
|
6616
|
+
},
|
|
6617
|
+
status: 'success',
|
|
6618
|
+
},
|
|
6619
|
+
type: 'step-result',
|
|
6620
|
+
},
|
|
6621
|
+
{
|
|
6622
|
+
payload: {
|
|
6623
|
+
id: 'start',
|
|
6624
|
+
metadata: {},
|
|
6625
|
+
},
|
|
6626
|
+
type: 'step-finish',
|
|
6627
|
+
},
|
|
6628
|
+
{
|
|
6629
|
+
payload: {
|
|
6630
|
+
id: expect.any(String),
|
|
6631
|
+
},
|
|
6632
|
+
type: 'step-start',
|
|
6633
|
+
},
|
|
6634
|
+
{
|
|
6635
|
+
payload: {
|
|
6636
|
+
id: expect.any(String),
|
|
6637
|
+
output: {
|
|
6638
|
+
prompt: 'Capital of France, just the name',
|
|
6639
|
+
},
|
|
6640
|
+
status: 'success',
|
|
6641
|
+
},
|
|
6642
|
+
type: 'step-result',
|
|
6643
|
+
},
|
|
6644
|
+
{
|
|
6645
|
+
payload: {
|
|
6646
|
+
id: expect.any(String),
|
|
6647
|
+
metadata: {},
|
|
6648
|
+
},
|
|
6649
|
+
type: 'step-finish',
|
|
6650
|
+
},
|
|
6651
|
+
{
|
|
6652
|
+
payload: {
|
|
6653
|
+
id: 'test-agent-1',
|
|
6654
|
+
},
|
|
6655
|
+
type: 'step-start',
|
|
6656
|
+
},
|
|
6657
|
+
{
|
|
6658
|
+
args: {
|
|
6659
|
+
prompt: 'Capital of France, just the name',
|
|
6660
|
+
},
|
|
6661
|
+
name: 'test-agent-1',
|
|
6662
|
+
type: 'tool-call-streaming-start',
|
|
6663
|
+
},
|
|
6664
|
+
{
|
|
6665
|
+
args: {
|
|
6666
|
+
prompt: 'Capital of France, just the name',
|
|
6667
|
+
},
|
|
6668
|
+
argsTextDelta: 'Paris',
|
|
6669
|
+
name: 'test-agent-1',
|
|
6670
|
+
type: 'tool-call-delta',
|
|
6671
|
+
},
|
|
6672
|
+
{
|
|
6673
|
+
payload: {
|
|
6674
|
+
id: 'test-agent-1',
|
|
6675
|
+
output: {
|
|
6676
|
+
text: 'Paris',
|
|
6677
|
+
},
|
|
6678
|
+
status: 'success',
|
|
6679
|
+
},
|
|
6680
|
+
type: 'step-result',
|
|
6681
|
+
},
|
|
6682
|
+
{
|
|
6683
|
+
payload: {
|
|
6684
|
+
id: expect.any(String),
|
|
6685
|
+
metadata: {},
|
|
6686
|
+
},
|
|
6687
|
+
type: 'step-finish',
|
|
6688
|
+
},
|
|
6689
|
+
{
|
|
6690
|
+
payload: {
|
|
6691
|
+
id: expect.any(String),
|
|
6692
|
+
},
|
|
6693
|
+
type: 'step-start',
|
|
6694
|
+
},
|
|
6695
|
+
{
|
|
6696
|
+
payload: {
|
|
6697
|
+
id: expect.any(String),
|
|
6698
|
+
output: {
|
|
6699
|
+
prompt: 'Capital of UK, just the name',
|
|
6700
|
+
},
|
|
6701
|
+
status: 'success',
|
|
6702
|
+
},
|
|
6703
|
+
type: 'step-result',
|
|
6704
|
+
},
|
|
6705
|
+
{
|
|
6706
|
+
payload: {
|
|
6707
|
+
id: expect.any(String),
|
|
6708
|
+
metadata: {},
|
|
6709
|
+
},
|
|
6710
|
+
type: 'step-finish',
|
|
6711
|
+
},
|
|
6712
|
+
{
|
|
6713
|
+
payload: {
|
|
6714
|
+
id: expect.any(String),
|
|
6715
|
+
},
|
|
6716
|
+
type: 'step-start',
|
|
6717
|
+
},
|
|
6718
|
+
{
|
|
6719
|
+
args: {
|
|
6720
|
+
prompt: 'Capital of UK, just the name',
|
|
6721
|
+
},
|
|
6722
|
+
name: 'test-agent-2',
|
|
6723
|
+
type: 'tool-call-streaming-start',
|
|
6724
|
+
},
|
|
6725
|
+
{
|
|
6726
|
+
args: {
|
|
6727
|
+
prompt: 'Capital of UK, just the name',
|
|
6728
|
+
},
|
|
6729
|
+
argsTextDelta: 'London',
|
|
6730
|
+
name: 'test-agent-2',
|
|
6731
|
+
type: 'tool-call-delta',
|
|
6732
|
+
},
|
|
6733
|
+
{
|
|
6734
|
+
payload: {
|
|
6735
|
+
id: expect.any(String),
|
|
6736
|
+
output: {
|
|
6737
|
+
text: 'London',
|
|
6738
|
+
},
|
|
6739
|
+
status: 'success',
|
|
6740
|
+
},
|
|
6741
|
+
type: 'step-result',
|
|
6742
|
+
},
|
|
6743
|
+
{
|
|
6744
|
+
payload: {
|
|
6745
|
+
id: expect.any(String),
|
|
6746
|
+
metadata: {},
|
|
6747
|
+
},
|
|
6748
|
+
type: 'step-finish',
|
|
6749
|
+
},
|
|
6750
|
+
{
|
|
6751
|
+
payload: {
|
|
6752
|
+
runId: 'test-run-id',
|
|
6753
|
+
},
|
|
6754
|
+
type: 'finish',
|
|
6755
|
+
},
|
|
6756
|
+
]);
|
|
6757
|
+
});
|
|
6758
|
+
});
|
|
5522
6759
|
}, 40e3);
|