@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/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 = await workflow.createRun();
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']).toEqual({
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 = await workflow.createRun();
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).toEqual({
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 = await workflow.createRun();
254
+ const run = workflow.createRun();
251
255
  const result = await run.start({ inputData: {} });
252
256
 
253
- expect(executionOrder).toEqual(['step1', 'step2']);
254
- expect(result.steps).toEqual({
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 = await workflow.createRun();
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']).toEqual({
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']).toEqual({
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 = await workflow.createRun();
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']).toEqual({
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']).toEqual({
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 = await workflow.createRun();
689
+ const run = workflow.createRun();
502
690
  const result = await run.start({ inputData: { inputData: 'test-input' } });
503
691
 
504
- expect(result.steps.step1).toEqual({ status: 'success', output: { result: 'success' } });
505
- expect(result.steps.step2).toEqual({ status: 'success', output: { result: 'success' } });
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).toEqual({ inputValue: 'test-input' });
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).toEqual({ value: 'step1-result' });
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 = await workflow.createRun();
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).toEqual({
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 = await workflow.createRun();
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 = await workflow.createRun();
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).toEqual({ status: 'success', output: { result: { cool: 'test-input' } } });
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 = await workflow.createRun();
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 = await workflow.createRun();
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).toEqual({
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 = await workflow.createRun();
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).toEqual({
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 = await workflow.createRun();
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 = await workflow.createRun();
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).toEqual({
1372
+ expect(result.steps.step1).toMatchObject({
1185
1373
  status: 'success',
1186
1374
  output: { count: 5 },
1187
1375
  });
1188
- expect(result.steps.step2).toEqual({
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 = await workflow.createRun();
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 = await workflow.createRun();
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 = await mainWorkflow.createRun();
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 = await workflow.createRun();
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).toEqual({ status: 'success', output: { result: '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 = await counterWorkflow.createRun();
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).toEqual({ finalValue: 12 });
1849
+ expect(result.result).toMatchObject({ finalValue: 12 });
1663
1850
  // @ts-ignore
1664
- expect(result.steps.increment.output).toEqual({ value: 12 });
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 = await counterWorkflow.createRun();
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).toEqual({ finalValue: 12 });
1952
+ expect(result.result).toMatchObject({ finalValue: 12 });
1766
1953
  // @ts-ignore
1767
- expect(result.steps.increment.output).toEqual({ value: 12 });
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 = await counterWorkflow.createRun();
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).toEqual({
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 = await counterWorkflow.createRun();
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).toEqual({ finalValue: 2 });
2195
+ expect(result.steps.finalIf.output).toMatchObject({ finalValue: 2 });
2009
2196
  // @ts-ignore
2010
- expect(result.steps.start.output).toEqual({ newValue: 2 });
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 = await counterWorkflow.createRun();
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).toEqual({ finalValue: 26 + 6 + 1 });
2344
+ expect(result.steps['else-branch'].output).toMatchObject({ finalValue: 26 + 6 + 1 });
2158
2345
  // @ts-ignore
2159
- expect(result.steps.start.output).toEqual({ newValue: 7 });
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 = await workflow.createRun();
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 = await workflow.createRun();
2509
+ const run = workflow.createRun();
2323
2510
  const result = await run.start({ inputData: {} });
2324
2511
 
2325
- expect(result.steps['nested-a']).toEqual({ status: 'success', output: { result: 'success3' } });
2326
- expect(result.steps['nested-b']).toEqual({ status: 'success', output: { result: 'success5' } });
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 = await workflow.createRun();
2575
+ const run = workflow.createRun();
2389
2576
  const result = await run.start({ inputData: {} });
2390
2577
 
2391
- expect(result.steps.step1).toEqual({ status: 'success', output: { result: 'success' } });
2392
- expect(result.steps.step2).toEqual({ status: 'failed', error: 'Step failed' });
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 = await workflow.createRun();
2632
+ const run = workflow.createRun();
2446
2633
  const result = await run.start({ inputData: {} });
2447
2634
 
2448
- expect(result.steps.step1).toEqual({ status: 'success', output: { result: 'success' } });
2449
- expect(result.steps.step2).toEqual({ status: 'failed', error: 'Step failed' });
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 run = await workflow.createRun();
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).toEqual({ status: 'success', output: { name: 'step1' } });
2528
- expect(result.steps['random-tool']).toEqual({ status: 'success', output: { name: 'step1' } });
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 = await workflow.createRun();
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).toEqual({
2893
+ expect(executionResult.steps.step1).toMatchObject({
2708
2894
  status: 'success',
2709
2895
  output: { result: 'success1' },
2710
2896
  });
2711
- expect(executionResult.steps.step2).toEqual({
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 = await workflow.createRun();
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 = await workflow.createRun();
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 = await workflow.createRun();
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 = await workflow.createRun();
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 = await promptEvalWorkflow.createRun();
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).toEqual({
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 = await workflow.createRun();
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).toEqual({
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 = await workflow.createRun();
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 = await promptEvalWorkflow.createRun();
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).toEqual({ testPayload: 'hello' });
3504
- expect(initialResult.steps).toEqual({
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).toEqual({
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).toEqual({
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 = await workflow.createRun();
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 = await workflow.createRun();
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
- expect(result.steps['test-agent-1']).toEqual({
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']).toEqual({
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 = await workflow.createRun();
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']).toEqual({
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']).toEqual({
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']).toEqual({
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 = await counterWorkflow.createRun();
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).toEqual({
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).toEqual({
4205
+ expect(result.steps['nested-workflow-b'].output).toMatchObject({
4018
4206
  finalValue: 1,
4019
4207
  });
4020
4208
 
4021
- expect(result.steps['last-step']).toEqual({
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 = await counterWorkflow.createRun();
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).toEqual({
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).toEqual({
4357
+ expect(result.steps['nested-workflow-b'].output).toMatchObject({
4170
4358
  finalValue: 1,
4171
4359
  });
4172
4360
 
4173
- expect(result.steps['last-step']).toEqual({
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 = await counterWorkflow.createRun();
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).toEqual({
4512
+ expect(result.steps['nested-workflow-a'].output).toMatchObject({
4325
4513
  finalValue: 26 + 1,
4326
4514
  });
4327
4515
 
4328
- expect(result.steps['first-step']).toEqual({
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']).toEqual({
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 = await counterWorkflow.createRun();
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).toEqual({
4672
+ expect(result.steps['nested-workflow-b'].output).toMatchObject({
4485
4673
  finalValue: 1,
4486
4674
  });
4487
4675
 
4488
- expect(result.steps['first-step']).toEqual({
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']).toEqual({
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 = await counterWorkflow.createRun();
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).toEqual({
4869
+ expect(result.steps['nested-workflow-b'].output).toMatchObject({
4682
4870
  finalValue: 1,
4683
4871
  });
4684
4872
 
4685
- expect(result.steps['first-step']).toEqual({
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']).toEqual({
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 = await counterWorkflow.createRun();
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']).toEqual(undefined);
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).toEqual({
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 = await counterWorkflow.createRun();
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']).toEqual({
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 = await counterWorkflow.createRun();
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']).toEqual(undefined);
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]).toEqual(['nested-workflow-c', 'nested-workflow-b', 'nested-workflow-a', 'other']);
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).toEqual({
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 = await counterWorkflow.createRun();
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).toEqual({
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).toEqual({
5520
+ expect(result.steps['nested-workflow-b'].output).toMatchObject({
5328
5521
  finalValue: 1,
5329
5522
  });
5330
5523
 
5331
- expect(result.steps['last-step']).toEqual({
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 = await workflow.createRun();
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 = await workflow.createRun();
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 = await workflow.createRun();
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);