@mastra/inngest 0.10.6-alpha.2 → 0.11.0

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.
@@ -1,23 +1,23 @@
1
1
 
2
- > @mastra/inngest@0.10.6-alpha.2 build /home/runner/work/mastra/mastra/workflows/inngest
2
+ > @mastra/inngest@0.11.0-alpha.3 build /home/runner/work/mastra/mastra/workflows/inngest
3
3
  > tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting
4
4
 
5
5
  CLI Building entry: src/index.ts
6
6
  CLI Using tsconfig: tsconfig.json
7
7
  CLI tsup v8.5.0
8
8
  TSC Build start
9
- TSC ⚡️ Build success in 9138ms
9
+ TSC ⚡️ Build success in 9007ms
10
10
  DTS Build start
11
11
  CLI Target: es2022
12
12
  Analysis will use the bundled TypeScript version 5.8.3
13
13
  Writing package typings: /home/runner/work/mastra/mastra/workflows/inngest/dist/_tsup-dts-rollup.d.ts
14
14
  Analysis will use the bundled TypeScript version 5.8.3
15
15
  Writing package typings: /home/runner/work/mastra/mastra/workflows/inngest/dist/_tsup-dts-rollup.d.cts
16
- DTS ⚡️ Build success in 5865ms
16
+ DTS ⚡️ Build success in 6069ms
17
17
  CLI Cleaning output folder
18
18
  ESM Build start
19
19
  CJS Build start
20
- CJS dist/index.cjs 31.43 KB
21
- CJS ⚡️ Build success in 236ms
22
- ESM dist/index.js 31.23 KB
23
- ESM ⚡️ Build success in 237ms
20
+ ESM dist/index.js 32.52 KB
21
+ ESM ⚡️ Build success in 218ms
22
+ CJS dist/index.cjs 32.72 KB
23
+ CJS ⚡️ Build success in 287ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # @mastra/inngest
2
2
 
3
+ ## 0.11.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 8a3bfd2: Update peerdeps to latest core
8
+
9
+ ### Patch Changes
10
+
11
+ - 8e1b6e9: dependencies updates:
12
+ - Updated dependency [`zod@^3.25.67` ↗︎](https://www.npmjs.com/package/zod/v/3.25.67) (from `^3.25.57`, in `dependencies`)
13
+ - 9d52b17: Fix inngest workflows streaming and add step metadata
14
+ - 4fb0cc2: Type safe variable mapping
15
+ - 502fe05: createRun() -> createRunAsync()
16
+ - 4efcfa0: Added bail() method and more ergonomic suspend function return value
17
+ - Updated dependencies [15e9d26]
18
+ - Updated dependencies [d1baedb]
19
+ - Updated dependencies [d8f2d19]
20
+ - Updated dependencies [4d21bf2]
21
+ - Updated dependencies [07d6d88]
22
+ - Updated dependencies [9d52b17]
23
+ - Updated dependencies [2097952]
24
+ - Updated dependencies [792c4c0]
25
+ - Updated dependencies [5d74aab]
26
+ - Updated dependencies [a8b194f]
27
+ - Updated dependencies [4fb0cc2]
28
+ - Updated dependencies [d2a7a31]
29
+ - Updated dependencies [502fe05]
30
+ - Updated dependencies [144eb0b]
31
+ - Updated dependencies [8ba1b51]
32
+ - Updated dependencies [4efcfa0]
33
+ - Updated dependencies [0e17048]
34
+ - @mastra/core@0.10.7
35
+
36
+ ## 0.11.0-alpha.3
37
+
38
+ ### Minor Changes
39
+
40
+ - 8a3bfd2: Update peerdeps to latest core
41
+
42
+ ### Patch Changes
43
+
44
+ - 502fe05: createRun() -> createRunAsync()
45
+ - 4efcfa0: Added bail() method and more ergonomic suspend function return value
46
+ - Updated dependencies [792c4c0]
47
+ - Updated dependencies [502fe05]
48
+ - Updated dependencies [4efcfa0]
49
+ - @mastra/core@0.10.7-alpha.3
50
+
3
51
  ## 0.10.6-alpha.2
4
52
 
5
53
  ### Patch Changes
@@ -233,6 +233,9 @@ export declare class InngestWorkflow<TEngineType = InngestEngineType, TSteps ext
233
233
  createRun(options?: {
234
234
  runId?: string;
235
235
  }): Run<TEngineType, TSteps, TInput, TOutput>;
236
+ createRunAsync(options?: {
237
+ runId?: string;
238
+ }): Promise<Run<TEngineType, TSteps, TInput, TOutput>>;
236
239
  getFunction(): InngestFunction<Omit<InngestFunction.Options<Inngest<ClientOptions>, InngestMiddleware.Stack, InngestFunction.Trigger<string>[] | [{
237
240
  cron: string;
238
241
  } & Partial<Record<"event" | "if", never>>] | [{
@@ -233,6 +233,9 @@ export declare class InngestWorkflow<TEngineType = InngestEngineType, TSteps ext
233
233
  createRun(options?: {
234
234
  runId?: string;
235
235
  }): Run<TEngineType, TSteps, TInput, TOutput>;
236
+ createRunAsync(options?: {
237
+ runId?: string;
238
+ }): Promise<Run<TEngineType, TSteps, TInput, TOutput>>;
236
239
  getFunction(): InngestFunction<Omit<InngestFunction.Options<Inngest<ClientOptions>, InngestMiddleware.Stack, InngestFunction.Trigger<string>[] | [{
237
240
  cron: string;
238
241
  } & Partial<Record<"event" | "if", never>>] | [{
package/dist/index.cjs CHANGED
@@ -279,6 +279,41 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
279
279
  this.runs.set(runIdToUse, run);
280
280
  return run;
281
281
  }
282
+ async createRunAsync(options) {
283
+ const runIdToUse = options?.runId || crypto.randomUUID();
284
+ const run = this.runs.get(runIdToUse) ?? new InngestRun(
285
+ {
286
+ workflowId: this.id,
287
+ runId: runIdToUse,
288
+ executionEngine: this.executionEngine,
289
+ executionGraph: this.executionGraph,
290
+ serializedStepGraph: this.serializedStepGraph,
291
+ mastra: this.#mastra,
292
+ retryConfig: this.retryConfig,
293
+ cleanup: () => this.runs.delete(runIdToUse)
294
+ },
295
+ this.inngest
296
+ );
297
+ this.runs.set(runIdToUse, run);
298
+ await this.mastra?.getStorage()?.persistWorkflowSnapshot({
299
+ workflowName: this.id,
300
+ runId: runIdToUse,
301
+ snapshot: {
302
+ runId: runIdToUse,
303
+ status: "pending",
304
+ value: {},
305
+ context: {},
306
+ activePaths: [],
307
+ serializedStepGraph: this.serializedStepGraph,
308
+ suspendedPaths: {},
309
+ result: void 0,
310
+ error: void 0,
311
+ // @ts-ignore
312
+ timestamp: Date.now()
313
+ }
314
+ });
315
+ return run;
316
+ }
282
317
  getFunction() {
283
318
  if (this.function) {
284
319
  return this.function;
@@ -800,6 +835,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
800
835
  const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
801
836
  let execResults;
802
837
  let suspended;
838
+ let bailed;
803
839
  try {
804
840
  const result = await step.execute({
805
841
  runId: executionContext.runId,
@@ -819,6 +855,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
819
855
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
820
856
  suspended = { payload: suspendPayload };
821
857
  },
858
+ bail: (result2) => {
859
+ bailed = { payload: result2 };
860
+ },
822
861
  resume: {
823
862
  steps: resume?.steps?.slice(1) || [],
824
863
  resumePayload: resume?.resumePayload,
@@ -861,6 +900,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
861
900
  resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
862
901
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
863
902
  };
903
+ } else if (bailed) {
904
+ execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
864
905
  }
865
906
  if (execResults.status === "failed") {
866
907
  if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
@@ -985,6 +1026,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
985
1026
  // TODO: this function shouldn't have suspend probably?
986
1027
  suspend: async (_suspendPayload) => {
987
1028
  },
1029
+ bail: () => {
1030
+ },
988
1031
  [_constants.EMITTER_SYMBOL]: emitter,
989
1032
  engine: {
990
1033
  step: this.inngestStep
package/dist/index.js CHANGED
@@ -277,6 +277,41 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
277
277
  this.runs.set(runIdToUse, run);
278
278
  return run;
279
279
  }
280
+ async createRunAsync(options) {
281
+ const runIdToUse = options?.runId || randomUUID();
282
+ const run = this.runs.get(runIdToUse) ?? new InngestRun(
283
+ {
284
+ workflowId: this.id,
285
+ runId: runIdToUse,
286
+ executionEngine: this.executionEngine,
287
+ executionGraph: this.executionGraph,
288
+ serializedStepGraph: this.serializedStepGraph,
289
+ mastra: this.#mastra,
290
+ retryConfig: this.retryConfig,
291
+ cleanup: () => this.runs.delete(runIdToUse)
292
+ },
293
+ this.inngest
294
+ );
295
+ this.runs.set(runIdToUse, run);
296
+ await this.mastra?.getStorage()?.persistWorkflowSnapshot({
297
+ workflowName: this.id,
298
+ runId: runIdToUse,
299
+ snapshot: {
300
+ runId: runIdToUse,
301
+ status: "pending",
302
+ value: {},
303
+ context: {},
304
+ activePaths: [],
305
+ serializedStepGraph: this.serializedStepGraph,
306
+ suspendedPaths: {},
307
+ result: void 0,
308
+ error: void 0,
309
+ // @ts-ignore
310
+ timestamp: Date.now()
311
+ }
312
+ });
313
+ return run;
314
+ }
280
315
  getFunction() {
281
316
  if (this.function) {
282
317
  return this.function;
@@ -798,6 +833,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
798
833
  const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
799
834
  let execResults;
800
835
  let suspended;
836
+ let bailed;
801
837
  try {
802
838
  const result = await step.execute({
803
839
  runId: executionContext.runId,
@@ -817,6 +853,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
817
853
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
818
854
  suspended = { payload: suspendPayload };
819
855
  },
856
+ bail: (result2) => {
857
+ bailed = { payload: result2 };
858
+ },
820
859
  resume: {
821
860
  steps: resume?.steps?.slice(1) || [],
822
861
  resumePayload: resume?.resumePayload,
@@ -859,6 +898,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
859
898
  resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
860
899
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
861
900
  };
901
+ } else if (bailed) {
902
+ execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
862
903
  }
863
904
  if (execResults.status === "failed") {
864
905
  if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
@@ -983,6 +1024,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
983
1024
  // TODO: this function shouldn't have suspend probably?
984
1025
  suspend: async (_suspendPayload) => {
985
1026
  },
1027
+ bail: () => {
1028
+ },
986
1029
  [EMITTER_SYMBOL]: emitter,
987
1030
  engine: {
988
1031
  step: this.inngestStep
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mastra/inngest",
3
- "version": "0.10.6-alpha.2",
3
+ "version": "0.11.0",
4
4
  "description": "Mastra Inngest integration",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,13 +37,13 @@
37
37
  "tsup": "^8.5.0",
38
38
  "typescript": "^5.8.3",
39
39
  "vitest": "^2.1.9",
40
- "@mastra/core": "0.10.7-alpha.2",
41
- "@internal/lint": "0.0.13",
42
- "@mastra/libsql": "0.10.4-alpha.2",
43
- "@mastra/deployer": "0.10.7-alpha.2"
40
+ "@internal/lint": "0.0.14",
41
+ "@mastra/core": "0.10.7",
42
+ "@mastra/libsql": "0.11.0",
43
+ "@mastra/deployer": "0.10.7"
44
44
  },
45
45
  "peerDependencies": {
46
- "@mastra/core": "^0.10.2-alpha.0"
46
+ "@mastra/core": ">=0.10.7-0 <0.11.0-0"
47
47
  },
48
48
  "scripts": {
49
49
  "build": "tsup src/index.ts --format esm,cjs --experimental-dts --clean --treeshake=smallest --splitting",
package/src/index.test.ts CHANGED
@@ -44,6 +44,109 @@ describe('MastraInngestWorkflow', () => {
44
44
  });
45
45
 
46
46
  describe.sequential('Basic Workflow Execution', () => {
47
+ it('should be able to bail workflow execution', async ctx => {
48
+ const inngest = new Inngest({
49
+ id: 'mastra',
50
+ baseUrl: `http://localhost:${(ctx as any).inngestPort}`,
51
+ middleware: [realtimeMiddleware()],
52
+ });
53
+
54
+ const { createWorkflow, createStep } = init(inngest);
55
+
56
+ const step1 = createStep({
57
+ id: 'step1',
58
+ execute: async ({ bail, inputData }) => {
59
+ if (inputData.value === 'bail') {
60
+ return bail({ result: 'bailed' });
61
+ }
62
+
63
+ return { result: 'step1: ' + inputData.value };
64
+ },
65
+ inputSchema: z.object({ value: z.string() }),
66
+ outputSchema: z.object({ result: z.string() }),
67
+ });
68
+ const step2 = createStep({
69
+ id: 'step2',
70
+ execute: async ({ inputData }) => {
71
+ return { result: 'step2: ' + inputData.result };
72
+ },
73
+ inputSchema: z.object({ result: z.string() }),
74
+ outputSchema: z.object({ result: z.string() }),
75
+ });
76
+
77
+ const workflow = createWorkflow({
78
+ id: 'test-workflow',
79
+ inputSchema: z.object({ value: z.string() }),
80
+ outputSchema: z.object({
81
+ result: z.string(),
82
+ }),
83
+ steps: [step1, step2],
84
+ });
85
+
86
+ workflow.then(step1).then(step2).commit();
87
+
88
+ const mastra = new Mastra({
89
+ storage: new DefaultStorage({
90
+ url: ':memory:',
91
+ }),
92
+ workflows: {
93
+ 'test-workflow': workflow,
94
+ },
95
+ server: {
96
+ apiRoutes: [
97
+ {
98
+ path: '/inngest/api',
99
+ method: 'ALL',
100
+ createHandler: async ({ mastra }) => inngestServe({ mastra, inngest }),
101
+ },
102
+ ],
103
+ },
104
+ });
105
+
106
+ const app = await createHonoServer(mastra);
107
+
108
+ const srv = serve({
109
+ fetch: app.fetch,
110
+ port: (ctx as any).handlerPort,
111
+ });
112
+
113
+ const run = await workflow.createRunAsync();
114
+ const result = await run.start({ inputData: { value: 'bail' } });
115
+
116
+ await new Promise(resolve => setTimeout(resolve, 2000));
117
+
118
+ expect(result.steps['step1']).toEqual({
119
+ status: 'success',
120
+ output: { result: 'bailed' },
121
+ payload: { value: 'bail' },
122
+ startedAt: expect.any(Number),
123
+ endedAt: expect.any(Number),
124
+ });
125
+
126
+ expect(result.steps['step2']).toBeUndefined();
127
+
128
+ const run2 = await workflow.createRunAsync();
129
+ const result2 = await run2.start({ inputData: { value: 'no-bail' } });
130
+
131
+ srv.close();
132
+
133
+ expect(result2.steps['step1']).toEqual({
134
+ status: 'success',
135
+ output: { result: 'step1: no-bail' },
136
+ payload: { value: 'no-bail' },
137
+ startedAt: expect.any(Number),
138
+ endedAt: expect.any(Number),
139
+ });
140
+
141
+ expect(result2.steps['step2']).toEqual({
142
+ status: 'success',
143
+ output: { result: 'step2: step1: no-bail' },
144
+ payload: { result: 'step1: no-bail' },
145
+ startedAt: expect.any(Number),
146
+ endedAt: expect.any(Number),
147
+ });
148
+ });
149
+
47
150
  it('should execute a single step workflow successfully', async ctx => {
48
151
  const inngest = new Inngest({
49
152
  id: 'mastra',
@@ -95,7 +198,7 @@ describe('MastraInngestWorkflow', () => {
95
198
  });
96
199
  await new Promise(resolve => setTimeout(resolve, 2000));
97
200
 
98
- const run = workflow.createRun();
201
+ const run = await workflow.createRunAsync();
99
202
  const result = await run.start({ inputData: {} });
100
203
 
101
204
  expect(execute).toHaveBeenCalled();
@@ -170,7 +273,7 @@ describe('MastraInngestWorkflow', () => {
170
273
  });
171
274
  await new Promise(resolve => setTimeout(resolve, 2000));
172
275
 
173
- const run = workflow.createRun();
276
+ const run = await workflow.createRunAsync();
174
277
  const result = await run.start({ inputData: {} });
175
278
 
176
279
  expect(step1Action).toHaveBeenCalled();
@@ -251,7 +354,7 @@ describe('MastraInngestWorkflow', () => {
251
354
  });
252
355
  await new Promise(resolve => setTimeout(resolve, 2000));
253
356
 
254
- const run = workflow.createRun();
357
+ const run = await workflow.createRunAsync();
255
358
  const result = await run.start({ inputData: {} });
256
359
 
257
360
  expect(executionOrder).toMatchObject(['step1', 'step2']);
@@ -325,7 +428,7 @@ describe('MastraInngestWorkflow', () => {
325
428
  });
326
429
  await new Promise(resolve => setTimeout(resolve, 2000));
327
430
 
328
- const run = workflow.createRun();
431
+ const run = await workflow.createRunAsync();
329
432
  const startTime = Date.now();
330
433
  const result = await run.start({ inputData: {} });
331
434
  const endTime = Date.now();
@@ -417,7 +520,7 @@ describe('MastraInngestWorkflow', () => {
417
520
  });
418
521
  await new Promise(resolve => setTimeout(resolve, 2000));
419
522
 
420
- const run = workflow.createRun();
523
+ const run = await workflow.createRunAsync();
421
524
  const startTime = Date.now();
422
525
  const result = await run.start({ inputData: {} });
423
526
  const endTime = Date.now();
@@ -507,7 +610,7 @@ describe('MastraInngestWorkflow', () => {
507
610
  });
508
611
  await new Promise(resolve => setTimeout(resolve, 2000));
509
612
 
510
- const run = workflow.createRun();
613
+ const run = await workflow.createRunAsync();
511
614
  const startTime = Date.now();
512
615
  setTimeout(() => {
513
616
  run.sendEvent('hello-event', { data: 'hello' });
@@ -601,7 +704,7 @@ describe('MastraInngestWorkflow', () => {
601
704
  });
602
705
  await new Promise(resolve => setTimeout(resolve, 2000));
603
706
 
604
- const run = workflow.createRun();
707
+ const run = await workflow.createRunAsync();
605
708
  const startTime = Date.now();
606
709
  const result = await run.start({ inputData: {} });
607
710
  const endTime = Date.now();
@@ -686,7 +789,7 @@ describe('MastraInngestWorkflow', () => {
686
789
  port: (ctx as any).handlerPort,
687
790
  });
688
791
 
689
- const run = workflow.createRun();
792
+ const run = await workflow.createRunAsync();
690
793
  const result = await run.start({ inputData: { inputData: 'test-input' } });
691
794
 
692
795
  expect(result.steps.step1).toMatchObject({ status: 'success', output: { result: 'success' } });
@@ -773,7 +876,7 @@ describe('MastraInngestWorkflow', () => {
773
876
  port: (ctx as any).handlerPort,
774
877
  });
775
878
 
776
- const run = workflow.createRun();
879
+ const run = await workflow.createRunAsync();
777
880
  const result = await run.start({ inputData: { inputValue: 'test-input' } });
778
881
 
779
882
  expect(step1Action).toHaveBeenCalled();
@@ -840,7 +943,7 @@ describe('MastraInngestWorkflow', () => {
840
943
  port: (ctx as any).handlerPort,
841
944
  });
842
945
 
843
- const run = workflow.createRun();
946
+ const run = await workflow.createRunAsync();
844
947
  await run.start({ inputData: { inputData: 'test-input' } });
845
948
 
846
949
  expect(execute).toHaveBeenCalledWith(
@@ -915,7 +1018,7 @@ describe('MastraInngestWorkflow', () => {
915
1018
  port: (ctx as any).handlerPort,
916
1019
  });
917
1020
 
918
- const run = workflow.createRun();
1021
+ const run = await workflow.createRunAsync();
919
1022
  const result = await run.start({ inputData: { cool: 'test-input' } });
920
1023
 
921
1024
  expect(execute).toHaveBeenCalledWith(
@@ -997,7 +1100,7 @@ describe('MastraInngestWorkflow', () => {
997
1100
  port: (ctx as any).handlerPort,
998
1101
  });
999
1102
 
1000
- const run = workflow.createRun();
1103
+ const run = await workflow.createRunAsync();
1001
1104
  await run.start({ inputData: {} });
1002
1105
 
1003
1106
  expect(step2Action).toHaveBeenCalledWith(
@@ -1100,7 +1203,7 @@ describe('MastraInngestWorkflow', () => {
1100
1203
  port: (ctx as any).handlerPort,
1101
1204
  });
1102
1205
 
1103
- const run = workflow.createRun();
1206
+ const run = await workflow.createRunAsync();
1104
1207
  const result = await run.start({ inputData: { status: 'success' } });
1105
1208
  srv.close();
1106
1209
 
@@ -1176,7 +1279,7 @@ describe('MastraInngestWorkflow', () => {
1176
1279
  port: (ctx as any).handlerPort,
1177
1280
  });
1178
1281
 
1179
- const run = workflow.createRun();
1282
+ const run = await workflow.createRunAsync();
1180
1283
  let result: Awaited<ReturnType<typeof run.start>> | undefined = undefined;
1181
1284
  try {
1182
1285
  result = await run.start({ inputData: {} });
@@ -1281,7 +1384,7 @@ describe('MastraInngestWorkflow', () => {
1281
1384
  port: (ctx as any).handlerPort,
1282
1385
  });
1283
1386
 
1284
- const run = workflow.createRun();
1387
+ const run = await workflow.createRunAsync();
1285
1388
  const result = await run.start({ inputData: { status: 'success' } });
1286
1389
  srv.close();
1287
1390
 
@@ -1364,7 +1467,7 @@ describe('MastraInngestWorkflow', () => {
1364
1467
  port: (ctx as any).handlerPort,
1365
1468
  });
1366
1469
 
1367
- const run = workflow.createRun();
1470
+ const run = await workflow.createRunAsync();
1368
1471
  const result = await run.start({ inputData: { count: 5 } });
1369
1472
  srv.close();
1370
1473
 
@@ -1432,7 +1535,7 @@ describe('MastraInngestWorkflow', () => {
1432
1535
  });
1433
1536
  await new Promise(resolve => setTimeout(resolve, 2000));
1434
1537
 
1435
- const run = workflow.createRun();
1538
+ const run = await workflow.createRunAsync();
1436
1539
 
1437
1540
  await expect(run.start({ inputData: {} })).resolves.toMatchObject({
1438
1541
  steps: {
@@ -1516,7 +1619,7 @@ describe('MastraInngestWorkflow', () => {
1516
1619
  });
1517
1620
  await new Promise(resolve => setTimeout(resolve, 2000));
1518
1621
 
1519
- const run = workflow.createRun();
1622
+ const run = await workflow.createRunAsync();
1520
1623
  const result = await run.start({ inputData: {} });
1521
1624
 
1522
1625
  expect(result.steps).toMatchObject({
@@ -1610,7 +1713,7 @@ describe('MastraInngestWorkflow', () => {
1610
1713
  });
1611
1714
  await new Promise(resolve => setTimeout(resolve, 2000));
1612
1715
 
1613
- const run = mainWorkflow.createRun();
1716
+ const run = await mainWorkflow.createRunAsync();
1614
1717
  const result = await run.start({ inputData: {} });
1615
1718
 
1616
1719
  expect(result.steps).toMatchObject({
@@ -1738,7 +1841,7 @@ describe('MastraInngestWorkflow', () => {
1738
1841
  });
1739
1842
  await new Promise(resolve => setTimeout(resolve, 2000));
1740
1843
 
1741
- const run = workflow.createRun();
1844
+ const run = await workflow.createRunAsync();
1742
1845
  const result = await run.start({ inputData: {} });
1743
1846
 
1744
1847
  expect(step2Action).toHaveBeenCalled();
@@ -1840,7 +1943,7 @@ describe('MastraInngestWorkflow', () => {
1840
1943
  });
1841
1944
  await new Promise(resolve => setTimeout(resolve, 2000));
1842
1945
 
1843
- const run = counterWorkflow.createRun();
1946
+ const run = await counterWorkflow.createRunAsync();
1844
1947
  const result = await run.start({ inputData: { target: 10, value: 0 } });
1845
1948
 
1846
1949
  expect(increment).toHaveBeenCalledTimes(12);
@@ -1943,7 +2046,7 @@ describe('MastraInngestWorkflow', () => {
1943
2046
  });
1944
2047
  await new Promise(resolve => setTimeout(resolve, 2000));
1945
2048
 
1946
- const run = counterWorkflow.createRun();
2049
+ const run = await counterWorkflow.createRunAsync();
1947
2050
  const result = await run.start({ inputData: { target: 10, value: 0 } });
1948
2051
 
1949
2052
  expect(increment).toHaveBeenCalledTimes(12);
@@ -2032,7 +2135,7 @@ describe('MastraInngestWorkflow', () => {
2032
2135
  });
2033
2136
  await new Promise(resolve => setTimeout(resolve, 2000));
2034
2137
 
2035
- const run = counterWorkflow.createRun();
2138
+ const run = await counterWorkflow.createRunAsync();
2036
2139
  const result = await run.start({ inputData: [{ value: 1 }, { value: 22 }, { value: 333 }] });
2037
2140
 
2038
2141
  const endTime = Date.now();
@@ -2185,7 +2288,7 @@ describe('MastraInngestWorkflow', () => {
2185
2288
  });
2186
2289
  await new Promise(resolve => setTimeout(resolve, 2000));
2187
2290
 
2188
- const run = counterWorkflow.createRun();
2291
+ const run = await counterWorkflow.createRunAsync();
2189
2292
  const result = await run.start({ inputData: { startValue: 1 } });
2190
2293
 
2191
2294
  expect(start).toHaveBeenCalledTimes(1);
@@ -2334,7 +2437,7 @@ describe('MastraInngestWorkflow', () => {
2334
2437
  });
2335
2438
  await new Promise(resolve => setTimeout(resolve, 2000));
2336
2439
 
2337
- const run = counterWorkflow.createRun();
2440
+ const run = await counterWorkflow.createRunAsync();
2338
2441
  const result = await run.start({ inputData: { startValue: 6 } });
2339
2442
 
2340
2443
  expect(start).toHaveBeenCalledTimes(1);
@@ -2400,7 +2503,7 @@ describe('MastraInngestWorkflow', () => {
2400
2503
  ).rejects.toThrow();
2401
2504
 
2402
2505
  // Should pass validation
2403
- const run = workflow.createRun();
2506
+ const run = await workflow.createRunAsync();
2404
2507
  await run.start({
2405
2508
  inputData: {
2406
2509
  required: 'test',
@@ -2506,7 +2609,7 @@ describe('MastraInngestWorkflow', () => {
2506
2609
  });
2507
2610
  await new Promise(resolve => setTimeout(resolve, 2000));
2508
2611
 
2509
- const run = workflow.createRun();
2612
+ const run = await workflow.createRunAsync();
2510
2613
  const result = await run.start({ inputData: {} });
2511
2614
 
2512
2615
  expect(result.steps['nested-a']).toMatchObject({ status: 'success', output: { result: 'success3' } });
@@ -2572,7 +2675,7 @@ describe('MastraInngestWorkflow', () => {
2572
2675
  });
2573
2676
  await new Promise(resolve => setTimeout(resolve, 2000));
2574
2677
 
2575
- const run = workflow.createRun();
2678
+ const run = await workflow.createRunAsync();
2576
2679
  const result = await run.start({ inputData: {} });
2577
2680
 
2578
2681
  expect(result.steps.step1).toMatchObject({ status: 'success', output: { result: 'success' } });
@@ -2629,7 +2732,7 @@ describe('MastraInngestWorkflow', () => {
2629
2732
 
2630
2733
  workflow.then(step1).then(step2).commit();
2631
2734
 
2632
- const run = workflow.createRun();
2735
+ const run = await workflow.createRunAsync();
2633
2736
  const result = await run.start({ inputData: {} });
2634
2737
 
2635
2738
  expect(result.steps.step1).toMatchObject({ status: 'success', output: { result: 'success' } });
@@ -2704,7 +2807,8 @@ describe('MastraInngestWorkflow', () => {
2704
2807
  });
2705
2808
  await new Promise(resolve => setTimeout(resolve, 2000));
2706
2809
 
2707
- const result = await workflow.createRun().start({ inputData: {} });
2810
+ const run = await workflow.createRunAsync();
2811
+ const result = await run.start({ inputData: {} });
2708
2812
 
2709
2813
  srv.close();
2710
2814
 
@@ -2775,7 +2879,7 @@ describe('MastraInngestWorkflow', () => {
2775
2879
  });
2776
2880
  await new Promise(resolve => setTimeout(resolve, 2000));
2777
2881
 
2778
- const run = workflow.createRun();
2882
+ const run = await workflow.createRunAsync();
2779
2883
 
2780
2884
  // Start watching the workflow
2781
2885
  let cnt = 0;
@@ -2964,7 +3068,7 @@ describe('MastraInngestWorkflow', () => {
2964
3068
  const onTransition = vi.fn();
2965
3069
  const onTransition2 = vi.fn();
2966
3070
 
2967
- const run = workflow.createRun();
3071
+ const run = await workflow.createRunAsync();
2968
3072
 
2969
3073
  run.watch(onTransition);
2970
3074
  run.watch(onTransition2);
@@ -2974,7 +3078,7 @@ describe('MastraInngestWorkflow', () => {
2974
3078
  expect(onTransition).toHaveBeenCalledTimes(5);
2975
3079
  expect(onTransition2).toHaveBeenCalledTimes(5);
2976
3080
 
2977
- const run2 = workflow.createRun();
3081
+ const run2 = await workflow.createRunAsync();
2978
3082
 
2979
3083
  run2.watch(onTransition2);
2980
3084
 
@@ -2983,7 +3087,7 @@ describe('MastraInngestWorkflow', () => {
2983
3087
  expect(onTransition).toHaveBeenCalledTimes(5);
2984
3088
  expect(onTransition2).toHaveBeenCalledTimes(10);
2985
3089
 
2986
- const run3 = workflow.createRun();
3090
+ const run3 = await workflow.createRunAsync();
2987
3091
 
2988
3092
  run3.watch(onTransition);
2989
3093
 
@@ -3018,8 +3122,8 @@ describe('MastraInngestWorkflow', () => {
3018
3122
  outputSchema: z.object({}),
3019
3123
  steps: [],
3020
3124
  });
3021
- const run = workflow.createRun();
3022
- const run2 = workflow.createRun({ runId: run.runId });
3125
+ const run = await workflow.createRunAsync();
3126
+ const run2 = await workflow.createRunAsync({ runId: run.runId });
3023
3127
 
3024
3128
  expect(run.runId).toBeDefined();
3025
3129
  expect(run2.runId).toBeDefined();
@@ -3133,7 +3237,7 @@ describe('MastraInngestWorkflow', () => {
3133
3237
  });
3134
3238
  await new Promise(resolve => setTimeout(resolve, 2000));
3135
3239
 
3136
- const run = promptEvalWorkflow.createRun();
3240
+ const run = await promptEvalWorkflow.createRunAsync();
3137
3241
 
3138
3242
  // Create a promise to track when the workflow is ready to resume
3139
3243
  let resolveWorkflowSuspended: (value: unknown) => void;
@@ -3283,7 +3387,7 @@ describe('MastraInngestWorkflow', () => {
3283
3387
  });
3284
3388
  await new Promise(resolve => setTimeout(resolve, 2000));
3285
3389
 
3286
- const run = workflow.createRun();
3390
+ const run = await workflow.createRunAsync();
3287
3391
 
3288
3392
  const started = run.start({ inputData: { input: 'test' } });
3289
3393
 
@@ -3485,7 +3589,7 @@ describe('MastraInngestWorkflow', () => {
3485
3589
  });
3486
3590
  await new Promise(resolve => setTimeout(resolve, 2000));
3487
3591
 
3488
- const run = workflow.createRun();
3592
+ const run = await workflow.createRunAsync();
3489
3593
  const started = run.start({ inputData: { input: 'test' } });
3490
3594
  let improvedResponseResultPromise: Promise<any | undefined>;
3491
3595
 
@@ -3679,7 +3783,7 @@ describe('MastraInngestWorkflow', () => {
3679
3783
  });
3680
3784
  await new Promise(resolve => setTimeout(resolve, 2000));
3681
3785
 
3682
- const run = promptEvalWorkflow.createRun();
3786
+ const run = await promptEvalWorkflow.createRunAsync();
3683
3787
 
3684
3788
  const initialResult = await run.start({ inputData: { input: 'test' } });
3685
3789
  expect(initialResult.steps.promptAgent.status).toBe('suspended');
@@ -3690,7 +3794,11 @@ describe('MastraInngestWorkflow', () => {
3690
3794
  expect(initialResult.steps).toMatchObject({
3691
3795
  input: { input: 'test' },
3692
3796
  getUserInput: { status: 'success', output: { userInput: 'test input' } },
3693
- promptAgent: { status: 'suspended', payload: { testPayload: 'hello' } },
3797
+ promptAgent: {
3798
+ status: 'suspended',
3799
+ suspendedPayload: { testPayload: 'hello' },
3800
+ payload: { userInput: 'test input' },
3801
+ },
3694
3802
  });
3695
3803
 
3696
3804
  const newCtx = {
@@ -3804,7 +3912,7 @@ describe('MastraInngestWorkflow', () => {
3804
3912
  await new Promise(resolve => setTimeout(resolve, 2000));
3805
3913
 
3806
3914
  // Access new instance properties directly - should work without warning
3807
- const run = workflow.createRun();
3915
+ const run = await workflow.createRunAsync();
3808
3916
  await run.start({ inputData: {} });
3809
3917
 
3810
3918
  expect(telemetry).toBeDefined();
@@ -3907,7 +4015,7 @@ describe('MastraInngestWorkflow', () => {
3907
4015
  });
3908
4016
  await new Promise(resolve => setTimeout(resolve, 2000));
3909
4017
 
3910
- const run = workflow.createRun();
4018
+ const run = await workflow.createRunAsync();
3911
4019
  const result = await run.start({
3912
4020
  inputData: { prompt1: 'Capital of France, just the name', prompt2: 'Capital of UK, just the name' },
3913
4021
  });
@@ -4044,7 +4152,7 @@ describe('MastraInngestWorkflow', () => {
4044
4152
  });
4045
4153
  await new Promise(resolve => setTimeout(resolve, 2000));
4046
4154
 
4047
- const run = workflow.createRun();
4155
+ const run = await workflow.createRunAsync();
4048
4156
  const result = await run.start({
4049
4157
  inputData: { prompt1: 'Capital of France, just the name', prompt2: 'Capital of UK, just the name' },
4050
4158
  });
@@ -4187,7 +4295,7 @@ describe('MastraInngestWorkflow', () => {
4187
4295
  });
4188
4296
  await new Promise(resolve => setTimeout(resolve, 2000));
4189
4297
 
4190
- const run = counterWorkflow.createRun();
4298
+ const run = await counterWorkflow.createRunAsync();
4191
4299
  const result = await run.start({ inputData: { startValue: 0 } });
4192
4300
 
4193
4301
  srv.close();
@@ -4339,7 +4447,7 @@ describe('MastraInngestWorkflow', () => {
4339
4447
  });
4340
4448
  await new Promise(resolve => setTimeout(resolve, 2000));
4341
4449
 
4342
- const run = counterWorkflow.createRun();
4450
+ const run = await counterWorkflow.createRunAsync();
4343
4451
  const result = await run.start({ inputData: { startValue: 0 } });
4344
4452
 
4345
4453
  srv.close();
@@ -4498,7 +4606,7 @@ describe('MastraInngestWorkflow', () => {
4498
4606
  port: (ctx as any).handlerPort,
4499
4607
  });
4500
4608
 
4501
- const run = counterWorkflow.createRun();
4609
+ const run = await counterWorkflow.createRunAsync();
4502
4610
  const result = await run.start({ inputData: { startValue: 0 } });
4503
4611
 
4504
4612
  srv.close();
@@ -4657,7 +4765,7 @@ describe('MastraInngestWorkflow', () => {
4657
4765
  port: (ctx as any).handlerPort,
4658
4766
  });
4659
4767
 
4660
- const run = counterWorkflow.createRun();
4768
+ const run = await counterWorkflow.createRunAsync();
4661
4769
  const result = await run.start({ inputData: { startValue: 0 } });
4662
4770
 
4663
4771
  srv.close();
@@ -4854,7 +4962,7 @@ describe('MastraInngestWorkflow', () => {
4854
4962
  port: (ctx as any).handlerPort,
4855
4963
  });
4856
4964
 
4857
- const run = counterWorkflow.createRun();
4965
+ const run = await counterWorkflow.createRunAsync();
4858
4966
  const result = await run.start({ inputData: { startValue: 1 } });
4859
4967
 
4860
4968
  srv.close();
@@ -5008,7 +5116,7 @@ describe('MastraInngestWorkflow', () => {
5008
5116
  });
5009
5117
  await new Promise(resolve => setTimeout(resolve, 2000));
5010
5118
 
5011
- const run = counterWorkflow.createRun();
5119
+ const run = await counterWorkflow.createRunAsync();
5012
5120
  const result = await run.start({ inputData: { startValue: 0 } });
5013
5121
 
5014
5122
  expect(begin).toHaveBeenCalledTimes(1);
@@ -5158,7 +5266,7 @@ describe('MastraInngestWorkflow', () => {
5158
5266
  port: (ctx as any).handlerPort,
5159
5267
  });
5160
5268
 
5161
- const run = counterWorkflow.createRun();
5269
+ const run = await counterWorkflow.createRunAsync();
5162
5270
  const result = await run.start({ inputData: { startValue: 0 } });
5163
5271
  const results = result.steps;
5164
5272
 
@@ -5340,7 +5448,7 @@ describe('MastraInngestWorkflow', () => {
5340
5448
  });
5341
5449
  await new Promise(resolve => setTimeout(resolve, 2000));
5342
5450
 
5343
- const run = counterWorkflow.createRun();
5451
+ const run = await counterWorkflow.createRunAsync();
5344
5452
  const result = await run.start({ inputData: { startValue: 0 } });
5345
5453
 
5346
5454
  expect(passthroughStep.execute).toHaveBeenCalledTimes(2);
@@ -5502,7 +5610,7 @@ describe('MastraInngestWorkflow', () => {
5502
5610
  });
5503
5611
  await new Promise(resolve => setTimeout(resolve, 2000));
5504
5612
 
5505
- const run = counterWorkflow.createRun();
5613
+ const run = await counterWorkflow.createRunAsync();
5506
5614
  const result = await run.start({ inputData: { startValue: 0 } });
5507
5615
 
5508
5616
  srv.close();
@@ -5578,7 +5686,7 @@ describe('MastraInngestWorkflow', () => {
5578
5686
  await new Promise(resolve => setTimeout(resolve, 2000));
5579
5687
 
5580
5688
  // Access new instance properties directly - should work without warning
5581
- const run = workflow.createRun();
5689
+ const run = await workflow.createRunAsync();
5582
5690
  await run.start({ inputData: {} });
5583
5691
 
5584
5692
  srv.close();
@@ -5639,7 +5747,7 @@ describe('MastraInngestWorkflow', () => {
5639
5747
  port: (ctx as any).handlerPort,
5640
5748
  });
5641
5749
 
5642
- const run = workflow.createRun();
5750
+ const run = await workflow.createRunAsync();
5643
5751
  const result = await run.start({ runtimeContext });
5644
5752
 
5645
5753
  srv.close();
@@ -5692,7 +5800,7 @@ describe('MastraInngestWorkflow', () => {
5692
5800
  });
5693
5801
  workflow.then(step).commit();
5694
5802
 
5695
- const run = workflow.createRun();
5803
+ const run = await workflow.createRunAsync();
5696
5804
  await run.start({ runtimeContext });
5697
5805
 
5698
5806
  const resumeruntimeContext = new RuntimeContext();
@@ -5764,7 +5872,7 @@ describe('MastraInngestWorkflow', () => {
5764
5872
  port: (ctx as any).handlerPort,
5765
5873
  });
5766
5874
 
5767
- const run = workflow.createRun();
5875
+ const run = await workflow.createRunAsync();
5768
5876
  const result = await run.start({});
5769
5877
 
5770
5878
  srv.close();
@@ -5835,7 +5943,7 @@ describe('MastraInngestWorkflow', () => {
5835
5943
 
5836
5944
  const runId = 'test-run-id';
5837
5945
  let watchData: StreamEvent[] = [];
5838
- const run = workflow.createRun({
5946
+ const run = await workflow.createRunAsync({
5839
5947
  runId,
5840
5948
  });
5841
5949
 
@@ -5998,7 +6106,7 @@ describe('MastraInngestWorkflow', () => {
5998
6106
 
5999
6107
  const runId = 'test-run-id';
6000
6108
  let watchData: StreamEvent[] = [];
6001
- const run = workflow.createRun({
6109
+ const run = await workflow.createRunAsync({
6002
6110
  runId,
6003
6111
  });
6004
6112
 
@@ -6163,7 +6271,7 @@ describe('MastraInngestWorkflow', () => {
6163
6271
 
6164
6272
  const runId = 'test-run-id';
6165
6273
  let watchData: StreamEvent[] = [];
6166
- const run = workflow.createRun({
6274
+ const run = await workflow.createRunAsync({
6167
6275
  runId,
6168
6276
  });
6169
6277
 
@@ -6388,7 +6496,7 @@ describe('MastraInngestWorkflow', () => {
6388
6496
 
6389
6497
  await new Promise(resolve => setTimeout(resolve, 1000));
6390
6498
 
6391
- const run = promptEvalWorkflow.createRun();
6499
+ const run = await promptEvalWorkflow.createRunAsync();
6392
6500
 
6393
6501
  const { stream, getWorkflowState } = run.stream({ inputData: { input: 'test' } });
6394
6502
 
@@ -6577,10 +6685,10 @@ describe('MastraInngestWorkflow', () => {
6577
6685
 
6578
6686
  await new Promise(resolve => setTimeout(resolve, 1000));
6579
6687
 
6580
- const run = workflow.createRun({
6688
+ const run = await workflow.createRunAsync({
6581
6689
  runId: 'test-run-id',
6582
6690
  });
6583
- const { stream } = await run.stream({
6691
+ const { stream } = run.stream({
6584
6692
  inputData: {
6585
6693
  prompt1: 'Capital of France, just the name',
6586
6694
  prompt2: 'Capital of UK, just the name',
package/src/index.ts CHANGED
@@ -410,6 +410,49 @@ export class InngestWorkflow<
410
410
  return run;
411
411
  }
412
412
 
413
+ async createRunAsync(options?: { runId?: string }): Promise<Run<TEngineType, TSteps, TInput, TOutput>> {
414
+ const runIdToUse = options?.runId || randomUUID();
415
+
416
+ // Return a new Run instance with object parameters
417
+ const run: Run<TEngineType, TSteps, TInput, TOutput> =
418
+ this.runs.get(runIdToUse) ??
419
+ new InngestRun(
420
+ {
421
+ workflowId: this.id,
422
+ runId: runIdToUse,
423
+ executionEngine: this.executionEngine,
424
+ executionGraph: this.executionGraph,
425
+ serializedStepGraph: this.serializedStepGraph,
426
+ mastra: this.#mastra,
427
+ retryConfig: this.retryConfig,
428
+ cleanup: () => this.runs.delete(runIdToUse),
429
+ },
430
+ this.inngest,
431
+ );
432
+
433
+ this.runs.set(runIdToUse, run);
434
+
435
+ await this.mastra?.getStorage()?.persistWorkflowSnapshot({
436
+ workflowName: this.id,
437
+ runId: runIdToUse,
438
+ snapshot: {
439
+ runId: runIdToUse,
440
+ status: 'pending',
441
+ value: {},
442
+ context: {},
443
+ activePaths: [],
444
+ serializedStepGraph: this.serializedStepGraph,
445
+ suspendedPaths: {},
446
+ result: undefined,
447
+ error: undefined,
448
+ // @ts-ignore
449
+ timestamp: Date.now(),
450
+ },
451
+ });
452
+
453
+ return run;
454
+ }
455
+
413
456
  getFunction() {
414
457
  if (this.function) {
415
458
  return this.function;
@@ -1163,6 +1206,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
1163
1206
  const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1164
1207
  let execResults: any;
1165
1208
  let suspended: { payload: any } | undefined;
1209
+ let bailed: { payload: any } | undefined;
1166
1210
 
1167
1211
  try {
1168
1212
  const result = await step.execute({
@@ -1184,6 +1228,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
1184
1228
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1185
1229
  suspended = { payload: suspendPayload };
1186
1230
  },
1231
+ bail: (result: any) => {
1232
+ bailed = { payload: result };
1233
+ },
1187
1234
  resume: {
1188
1235
  steps: resume?.steps?.slice(1) || [],
1189
1236
  resumePayload: resume?.resumePayload,
@@ -1228,6 +1275,8 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
1228
1275
  resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,
1229
1276
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
1230
1277
  };
1278
+ } else if (bailed) {
1279
+ execResults = { status: 'bailed', output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
1231
1280
  }
1232
1281
 
1233
1282
  if (execResults.status === 'failed') {
@@ -1397,6 +1446,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
1397
1446
 
1398
1447
  // TODO: this function shouldn't have suspend probably?
1399
1448
  suspend: async (_suspendPayload: any) => {},
1449
+ bail: () => {},
1400
1450
  [EMITTER_SYMBOL]: emitter,
1401
1451
  engine: {
1402
1452
  step: this.inngestStep,