@mastra/inngest 0.0.0-redis-cloud-transporter-20250508203756 → 0.0.0-support-d1-client-20250701191943

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.ts CHANGED
@@ -1,34 +1,49 @@
1
1
  import { randomUUID } from 'crypto';
2
+ import type { ReadableStream } from 'node:stream/web';
2
3
  import { subscribe } from '@inngest/realtime';
3
- import type { Mastra, WorkflowRun } from '@mastra/core';
4
+ import type { Agent, Mastra, ToolExecutionContext, WorkflowRun, WorkflowRuns } from '@mastra/core';
4
5
  import { RuntimeContext } from '@mastra/core/di';
5
- import { NewWorkflow, createStep, Run, DefaultExecutionEngine, cloneStep } from '@mastra/core/workflows/vNext';
6
+ import { Tool } from '@mastra/core/tools';
7
+ import { Workflow, Run, DefaultExecutionEngine } from '@mastra/core/workflows';
6
8
  import type {
7
9
  ExecuteFunction,
8
10
  ExecutionContext,
9
11
  ExecutionEngine,
10
12
  ExecutionGraph,
11
- NewStep,
12
- NewStep as Step,
13
- NewWorkflowConfig,
13
+ Step,
14
+ WorkflowConfig,
14
15
  StepFlowEntry,
15
16
  StepResult,
16
17
  WorkflowResult,
17
- } from '@mastra/core/workflows/vNext';
18
+ SerializedStepFlowEntry,
19
+ StepFailure,
20
+ Emitter,
21
+ WatchEvent,
22
+ StreamEvent,
23
+ } from '@mastra/core/workflows';
24
+ import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
18
25
  import type { Span } from '@opentelemetry/api';
19
26
  import type { Inngest, BaseContext } from 'inngest';
20
27
  import { serve as inngestServe } from 'inngest/hono';
21
- import type { z } from 'zod';
28
+ import { z } from 'zod';
29
+
30
+ export type InngestEngineType = {
31
+ step: any;
32
+ };
22
33
 
23
34
  export function serve({ mastra, inngest }: { mastra: Mastra; inngest: Inngest }): ReturnType<typeof inngestServe> {
24
- const wfs = mastra.vnext_getWorkflows();
25
- const functions = Object.values(wfs).flatMap(wf => {
26
- if (wf instanceof InngestWorkflow) {
27
- wf.__registerMastra(mastra);
28
- return wf.getFunctions();
29
- }
30
- return [];
31
- });
35
+ const wfs = mastra.getWorkflows();
36
+ const functions = Array.from(
37
+ new Set(
38
+ Object.values(wfs).flatMap(wf => {
39
+ if (wf instanceof InngestWorkflow) {
40
+ wf.__registerMastra(mastra);
41
+ return wf.getFunctions();
42
+ }
43
+ return [];
44
+ }),
45
+ ),
46
+ );
32
47
  return inngestServe({
33
48
  client: inngest,
34
49
  functions,
@@ -36,11 +51,13 @@ export function serve({ mastra, inngest }: { mastra: Mastra; inngest: Inngest })
36
51
  }
37
52
 
38
53
  export class InngestRun<
39
- TSteps extends NewStep<string, any, any>[] = NewStep<string, any, any>[],
54
+ TEngineType = InngestEngineType,
55
+ TSteps extends Step<string, any, any>[] = Step<string, any, any>[],
40
56
  TInput extends z.ZodType<any> = z.ZodType<any>,
41
57
  TOutput extends z.ZodType<any> = z.ZodType<any>,
42
- > extends Run<TSteps, TInput, TOutput> {
58
+ > extends Run<TEngineType, TSteps, TInput, TOutput> {
43
59
  private inngest: Inngest;
60
+ serializedStepGraph: SerializedStepFlowEntry[];
44
61
  #mastra: Mastra;
45
62
 
46
63
  constructor(
@@ -49,6 +66,7 @@ export class InngestRun<
49
66
  runId: string;
50
67
  executionEngine: ExecutionEngine;
51
68
  executionGraph: ExecutionGraph;
69
+ serializedStepGraph: SerializedStepFlowEntry[];
52
70
  mastra?: Mastra;
53
71
  retryConfig?: {
54
72
  attempts?: number;
@@ -60,11 +78,12 @@ export class InngestRun<
60
78
  ) {
61
79
  super(params);
62
80
  this.inngest = inngest;
81
+ this.serializedStepGraph = params.serializedStepGraph;
63
82
  this.#mastra = params.mastra!;
64
83
  }
65
84
 
66
85
  async getRuns(eventId: string) {
67
- const response = await fetch(`${this.inngest.apiBaseUrl}/v1/events/${eventId}/runs`, {
86
+ const response = await fetch(`${this.inngest.apiBaseUrl ?? 'https://api.inngest.com'}/v1/events/${eventId}/runs`, {
68
87
  headers: {
69
88
  Authorization: `Bearer ${process.env.INNGEST_SIGNING_KEY}`,
70
89
  },
@@ -75,16 +94,54 @@ export class InngestRun<
75
94
 
76
95
  async getRunOutput(eventId: string) {
77
96
  let runs = await this.getRuns(eventId);
78
- while (runs?.[0]?.status !== 'Completed') {
97
+
98
+ while (runs?.[0]?.status !== 'Completed' || runs?.[0]?.event_id !== eventId) {
79
99
  await new Promise(resolve => setTimeout(resolve, 1000));
80
100
  runs = await this.getRuns(eventId);
81
- if (runs?.[0]?.status === 'Failed' || runs?.[0]?.status === 'Cancelled') {
101
+ if (runs?.[0]?.status === 'Failed') {
82
102
  throw new Error(`Function run ${runs?.[0]?.status}`);
103
+ } else if (runs?.[0]?.status === 'Cancelled') {
104
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
105
+ workflowName: this.workflowId,
106
+ runId: this.runId,
107
+ });
108
+ return { output: { result: { steps: snapshot?.context, status: 'canceled' } } };
83
109
  }
84
110
  }
85
111
  return runs?.[0];
86
112
  }
87
113
 
114
+ async sendEvent(event: string, data: any) {
115
+ await this.inngest.send({
116
+ name: `user-event-${event}`,
117
+ data,
118
+ });
119
+ }
120
+
121
+ async cancel() {
122
+ await this.inngest.send({
123
+ name: `cancel.workflow.${this.workflowId}`,
124
+ data: {
125
+ runId: this.runId,
126
+ },
127
+ });
128
+
129
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
130
+ workflowName: this.workflowId,
131
+ runId: this.runId,
132
+ });
133
+ if (snapshot) {
134
+ await this.#mastra?.storage?.persistWorkflowSnapshot({
135
+ workflowName: this.workflowId,
136
+ runId: this.runId,
137
+ snapshot: {
138
+ ...snapshot,
139
+ status: 'canceled' as any,
140
+ },
141
+ });
142
+ }
143
+ }
144
+
88
145
  async start({
89
146
  inputData,
90
147
  }: {
@@ -96,11 +153,13 @@ export class InngestRun<
96
153
  runId: this.runId,
97
154
  snapshot: {
98
155
  runId: this.runId,
156
+ serializedStepGraph: this.serializedStepGraph,
99
157
  value: {},
100
158
  context: {} as any,
101
159
  activePaths: [],
102
160
  suspendedPaths: {},
103
161
  timestamp: Date.now(),
162
+ status: 'running',
104
163
  },
105
164
  });
106
165
 
@@ -122,7 +181,9 @@ export class InngestRun<
122
181
  result.error = new Error(result.error);
123
182
  }
124
183
 
125
- this.cleanup?.();
184
+ if (result.status !== 'suspended') {
185
+ this.cleanup?.();
186
+ }
126
187
  return result;
127
188
  }
128
189
 
@@ -134,6 +195,27 @@ export class InngestRun<
134
195
  | string
135
196
  | string[];
136
197
  runtimeContext?: RuntimeContext;
198
+ }): Promise<WorkflowResult<TOutput, TSteps>> {
199
+ const p = this._resume(params).then(result => {
200
+ if (result.status !== 'suspended') {
201
+ this.closeStreamAction?.().catch(() => {});
202
+ }
203
+
204
+ return result;
205
+ });
206
+
207
+ this.executionResults = p;
208
+ return p;
209
+ }
210
+
211
+ async _resume<TResumeSchema extends z.ZodType<any>>(params: {
212
+ resumeData?: z.infer<TResumeSchema>;
213
+ step:
214
+ | Step<string, any, any, TResumeSchema, any>
215
+ | [...Step<string, any, any, any, any>[], Step<string, any, any, TResumeSchema, any>]
216
+ | string
217
+ | string[];
218
+ runtimeContext?: RuntimeContext;
137
219
  }): Promise<WorkflowResult<TOutput, TSteps>> {
138
220
  const steps: string[] = (Array.isArray(params.step) ? params.step : [params.step]).map(step =>
139
221
  typeof step === 'string' ? step : step?.id,
@@ -171,43 +253,88 @@ export class InngestRun<
171
253
  return result;
172
254
  }
173
255
 
174
- watch(cb: (event: any) => void): () => void {
256
+ watch(cb: (event: WatchEvent) => void, type: 'watch' | 'watch-v2' = 'watch'): () => void {
257
+ let active = true;
175
258
  const streamPromise = subscribe(
176
259
  {
177
260
  channel: `workflow:${this.workflowId}:${this.runId}`,
178
- topics: ['watch'],
261
+ topics: [type],
179
262
  app: this.inngest,
180
263
  },
181
264
  (message: any) => {
182
- cb(message.data);
265
+ if (active) {
266
+ cb(message.data);
267
+ }
183
268
  },
184
269
  );
185
270
 
186
271
  return () => {
272
+ active = false;
187
273
  streamPromise
188
- .then((stream: any) => {
189
- stream.cancel();
274
+ .then(async (stream: Awaited<typeof streamPromise>) => {
275
+ return stream.cancel();
190
276
  })
191
277
  .catch(err => {
192
278
  console.error(err);
193
279
  });
194
280
  };
195
281
  }
282
+
283
+ stream({ inputData, runtimeContext }: { inputData?: z.infer<TInput>; runtimeContext?: RuntimeContext } = {}): {
284
+ stream: ReadableStream<StreamEvent>;
285
+ getWorkflowState: () => Promise<WorkflowResult<TOutput, TSteps>>;
286
+ } {
287
+ const { readable, writable } = new TransformStream<StreamEvent, StreamEvent>();
288
+
289
+ const writer = writable.getWriter();
290
+ const unwatch = this.watch(async event => {
291
+ try {
292
+ // watch-v2 events are data stream events, so we need to cast them to the correct type
293
+ await writer.write(event as any);
294
+ } catch {}
295
+ }, 'watch-v2');
296
+
297
+ this.closeStreamAction = async () => {
298
+ unwatch();
299
+
300
+ try {
301
+ await writer.close();
302
+ } catch (err) {
303
+ console.error('Error closing stream:', err);
304
+ } finally {
305
+ writer.releaseLock();
306
+ }
307
+ };
308
+
309
+ this.executionResults = this.start({ inputData, runtimeContext }).then(result => {
310
+ if (result.status !== 'suspended') {
311
+ this.closeStreamAction?.().catch(() => {});
312
+ }
313
+
314
+ return result;
315
+ });
316
+
317
+ return {
318
+ stream: readable as ReadableStream<StreamEvent>,
319
+ getWorkflowState: () => this.executionResults!,
320
+ };
321
+ }
196
322
  }
197
323
 
198
324
  export class InngestWorkflow<
199
- TSteps extends NewStep<string, any, any>[] = NewStep<string, any, any>[],
325
+ TEngineType = InngestEngineType,
326
+ TSteps extends Step<string, any, any>[] = Step<string, any, any>[],
200
327
  TWorkflowId extends string = string,
201
328
  TInput extends z.ZodType<any> = z.ZodType<any>,
202
329
  TOutput extends z.ZodType<any> = z.ZodType<any>,
203
330
  TPrevSchema extends z.ZodType<any> = TInput,
204
- > extends NewWorkflow<TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> {
331
+ > extends Workflow<TEngineType, TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> {
205
332
  #mastra: Mastra;
206
333
  public inngest: Inngest;
207
334
 
208
335
  private function: ReturnType<Inngest['createFunction']> | undefined;
209
336
 
210
- constructor(params: NewWorkflowConfig<TWorkflowId, TInput, TOutput, TSteps>, inngest: Inngest) {
337
+ constructor(params: WorkflowConfig<TWorkflowId, TInput, TOutput, TSteps>, inngest: Inngest) {
211
338
  super(params);
212
339
  this.#mastra = params.mastra!;
213
340
  this.inngest = inngest;
@@ -226,16 +353,19 @@ export class InngestWorkflow<
226
353
  return { runs: [], total: 0 };
227
354
  }
228
355
 
229
- return storage.getWorkflowRuns({ workflowName: this.id, ...(args ?? {}) });
356
+ return storage.getWorkflowRuns({ workflowName: this.id, ...(args ?? {}) }) as unknown as WorkflowRuns;
230
357
  }
231
358
 
232
359
  async getWorkflowRunById(runId: string): Promise<WorkflowRun | null> {
233
360
  const storage = this.#mastra?.getStorage();
234
361
  if (!storage) {
235
362
  this.logger.debug('Cannot get workflow runs. Mastra engine is not initialized');
236
- return null;
363
+ //returning in memory run if no storage is initialized
364
+ return this.runs.get(runId)
365
+ ? ({ ...this.runs.get(runId), workflowName: this.id } as unknown as WorkflowRun)
366
+ : null;
237
367
  }
238
- const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
368
+ const run = (await storage.getWorkflowRunById({ runId, workflowName: this.id })) as unknown as WorkflowRun;
239
369
 
240
370
  return (
241
371
  run ??
@@ -243,6 +373,32 @@ export class InngestWorkflow<
243
373
  );
244
374
  }
245
375
 
376
+ async getWorkflowRunExecutionResult(runId: string): Promise<WatchEvent['payload']['workflowState'] | null> {
377
+ const storage = this.#mastra?.getStorage();
378
+ if (!storage) {
379
+ this.logger.debug('Cannot get workflow run execution result. Mastra storage is not initialized');
380
+ return null;
381
+ }
382
+
383
+ const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
384
+
385
+ if (!run?.snapshot) {
386
+ return null;
387
+ }
388
+
389
+ if (typeof run.snapshot === 'string') {
390
+ return null;
391
+ }
392
+
393
+ return {
394
+ status: run.snapshot.status,
395
+ result: run.snapshot.result,
396
+ error: run.snapshot.error,
397
+ payload: run.snapshot.context?.input,
398
+ steps: run.snapshot.context as any,
399
+ };
400
+ }
401
+
246
402
  __registerMastra(mastra: Mastra) {
247
403
  this.#mastra = mastra;
248
404
  this.executionEngine.__registerMastra(mastra);
@@ -266,11 +422,11 @@ export class InngestWorkflow<
266
422
  }
267
423
  }
268
424
 
269
- createRun(options?: { runId?: string }): Run<TSteps, TInput, TOutput> {
425
+ createRun(options?: { runId?: string }): Run<TEngineType, TSteps, TInput, TOutput> {
270
426
  const runIdToUse = options?.runId || randomUUID();
271
427
 
272
428
  // Return a new Run instance with object parameters
273
- const run: Run<TSteps, TInput, TOutput> =
429
+ const run: Run<TEngineType, TSteps, TInput, TOutput> =
274
430
  this.runs.get(runIdToUse) ??
275
431
  new InngestRun(
276
432
  {
@@ -278,6 +434,7 @@ export class InngestWorkflow<
278
434
  runId: runIdToUse,
279
435
  executionEngine: this.executionEngine,
280
436
  executionGraph: this.executionGraph,
437
+ serializedStepGraph: this.serializedStepGraph,
281
438
  mastra: this.#mastra,
282
439
  retryConfig: this.retryConfig,
283
440
  cleanup: () => this.runs.delete(runIdToUse),
@@ -289,13 +446,64 @@ export class InngestWorkflow<
289
446
  return run;
290
447
  }
291
448
 
449
+ async createRunAsync(options?: { runId?: string }): Promise<Run<TEngineType, TSteps, TInput, TOutput>> {
450
+ const runIdToUse = options?.runId || randomUUID();
451
+
452
+ // Return a new Run instance with object parameters
453
+ const run: Run<TEngineType, TSteps, TInput, TOutput> =
454
+ this.runs.get(runIdToUse) ??
455
+ new InngestRun(
456
+ {
457
+ workflowId: this.id,
458
+ runId: runIdToUse,
459
+ executionEngine: this.executionEngine,
460
+ executionGraph: this.executionGraph,
461
+ serializedStepGraph: this.serializedStepGraph,
462
+ mastra: this.#mastra,
463
+ retryConfig: this.retryConfig,
464
+ cleanup: () => this.runs.delete(runIdToUse),
465
+ },
466
+ this.inngest,
467
+ );
468
+
469
+ this.runs.set(runIdToUse, run);
470
+
471
+ const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
472
+
473
+ if (!workflowSnapshotInStorage) {
474
+ await this.mastra?.getStorage()?.persistWorkflowSnapshot({
475
+ workflowName: this.id,
476
+ runId: runIdToUse,
477
+ snapshot: {
478
+ runId: runIdToUse,
479
+ status: 'pending',
480
+ value: {},
481
+ context: {},
482
+ activePaths: [],
483
+ serializedStepGraph: this.serializedStepGraph,
484
+ suspendedPaths: {},
485
+ result: undefined,
486
+ error: undefined,
487
+ // @ts-ignore
488
+ timestamp: Date.now(),
489
+ },
490
+ });
491
+ }
492
+
493
+ return run;
494
+ }
495
+
292
496
  getFunction() {
293
497
  if (this.function) {
294
498
  return this.function;
295
499
  }
296
500
  this.function = this.inngest.createFunction(
297
- // @ts-ignore
298
- { id: `workflow.${this.id}`, retries: this.retryConfig?.attempts ?? 0 },
501
+ {
502
+ id: `workflow.${this.id}`,
503
+ // @ts-ignore
504
+ retries: this.retryConfig?.attempts ?? 0,
505
+ cancelOn: [{ event: `cancel.workflow.${this.id}` }],
506
+ },
299
507
  { event: `workflow.${this.id}` },
300
508
  async ({ event, step, attempt, publish }) => {
301
509
  let { inputData, runId, resume } = event.data;
@@ -315,13 +523,22 @@ export class InngestWorkflow<
315
523
  try {
316
524
  await publish({
317
525
  channel: `workflow:${this.id}:${runId}`,
318
- topic: 'watch',
526
+ topic: event,
319
527
  data,
320
528
  });
321
529
  } catch (err: any) {
322
530
  this.logger.error('Error emitting event: ' + (err?.stack ?? err?.message ?? err));
323
531
  }
324
532
  },
533
+ on: (_event: string, _callback: (data: any) => void) => {
534
+ // no-op
535
+ },
536
+ off: (_event: string, _callback: (data: any) => void) => {
537
+ // no-op
538
+ },
539
+ once: (_event: string, _callback: (data: any) => void) => {
540
+ // no-op
541
+ },
325
542
  };
326
543
 
327
544
  const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
@@ -329,11 +546,13 @@ export class InngestWorkflow<
329
546
  workflowId: this.id,
330
547
  runId,
331
548
  graph: this.executionGraph,
549
+ serializedStepGraph: this.serializedStepGraph,
332
550
  input: inputData,
333
551
  emitter,
334
552
  retryConfig: this.retryConfig,
335
553
  runtimeContext: new RuntimeContext(), // TODO
336
554
  resume,
555
+ abortController: new AbortController(),
337
556
  });
338
557
 
339
558
  return { result, runId };
@@ -362,29 +581,197 @@ export class InngestWorkflow<
362
581
  }
363
582
  }
364
583
 
365
- function cloneWorkflow<
366
- TWorkflowId extends string = string,
367
- TInput extends z.ZodType<any> = z.ZodType<any>,
368
- TOutput extends z.ZodType<any> = z.ZodType<any>,
369
- TSteps extends Step<string, any, any, any, any>[] = Step<string, any, any, any, any>[],
584
+ function isAgent(params: any): params is Agent<any, any, any> {
585
+ return params?.component === 'AGENT';
586
+ }
587
+
588
+ function isTool(params: any): params is Tool<any, any, any> {
589
+ return params instanceof Tool;
590
+ }
591
+
592
+ export function createStep<
593
+ TStepId extends string,
594
+ TStepInput extends z.ZodType<any>,
595
+ TStepOutput extends z.ZodType<any>,
596
+ TResumeSchema extends z.ZodType<any>,
597
+ TSuspendSchema extends z.ZodType<any>,
598
+ >(params: {
599
+ id: TStepId;
600
+ description?: string;
601
+ inputSchema: TStepInput;
602
+ outputSchema: TStepOutput;
603
+ resumeSchema?: TResumeSchema;
604
+ suspendSchema?: TSuspendSchema;
605
+ execute: ExecuteFunction<
606
+ z.infer<TStepInput>,
607
+ z.infer<TStepOutput>,
608
+ z.infer<TResumeSchema>,
609
+ z.infer<TSuspendSchema>,
610
+ InngestEngineType
611
+ >;
612
+ }): Step<TStepId, TStepInput, TStepOutput, TResumeSchema, TSuspendSchema, InngestEngineType>;
613
+
614
+ export function createStep<
615
+ TStepId extends string,
616
+ TStepInput extends z.ZodObject<{ prompt: z.ZodString }>,
617
+ TStepOutput extends z.ZodObject<{ text: z.ZodString }>,
618
+ TResumeSchema extends z.ZodType<any>,
619
+ TSuspendSchema extends z.ZodType<any>,
370
620
  >(
371
- workflow: InngestWorkflow<TSteps, string, TInput, TOutput>,
372
- opts: { id: TWorkflowId },
373
- ): InngestWorkflow<TSteps, TWorkflowId, TInput, TOutput> {
374
- const wf = new InngestWorkflow(
375
- {
376
- id: opts.id,
377
- inputSchema: workflow.inputSchema,
378
- outputSchema: workflow.outputSchema,
379
- steps: workflow.stepDefs,
380
- mastra: workflow.mastra,
381
- },
382
- workflow.inngest,
383
- );
621
+ agent: Agent<TStepId, any, any>,
622
+ ): Step<TStepId, TStepInput, TStepOutput, TResumeSchema, TSuspendSchema, InngestEngineType>;
384
623
 
385
- wf.setStepFlow(workflow.stepGraph);
386
- wf.commit();
387
- return wf;
624
+ export function createStep<
625
+ TSchemaIn extends z.ZodType<any>,
626
+ TSchemaOut extends z.ZodType<any>,
627
+ TContext extends ToolExecutionContext<TSchemaIn>,
628
+ >(
629
+ tool: Tool<TSchemaIn, TSchemaOut, TContext> & {
630
+ inputSchema: TSchemaIn;
631
+ outputSchema: TSchemaOut;
632
+ execute: (context: TContext) => Promise<any>;
633
+ },
634
+ ): Step<string, TSchemaIn, TSchemaOut, z.ZodType<any>, z.ZodType<any>, InngestEngineType>;
635
+ export function createStep<
636
+ TStepId extends string,
637
+ TStepInput extends z.ZodType<any>,
638
+ TStepOutput extends z.ZodType<any>,
639
+ TResumeSchema extends z.ZodType<any>,
640
+ TSuspendSchema extends z.ZodType<any>,
641
+ >(
642
+ params:
643
+ | {
644
+ id: TStepId;
645
+ description?: string;
646
+ inputSchema: TStepInput;
647
+ outputSchema: TStepOutput;
648
+ resumeSchema?: TResumeSchema;
649
+ suspendSchema?: TSuspendSchema;
650
+ execute: ExecuteFunction<
651
+ z.infer<TStepInput>,
652
+ z.infer<TStepOutput>,
653
+ z.infer<TResumeSchema>,
654
+ z.infer<TSuspendSchema>,
655
+ InngestEngineType
656
+ >;
657
+ }
658
+ | Agent<any, any, any>
659
+ | (Tool<TStepInput, TStepOutput, any> & {
660
+ inputSchema: TStepInput;
661
+ outputSchema: TStepOutput;
662
+ execute: (context: ToolExecutionContext<TStepInput>) => Promise<any>;
663
+ }),
664
+ ): Step<TStepId, TStepInput, TStepOutput, TResumeSchema, TSuspendSchema, InngestEngineType> {
665
+ if (isAgent(params)) {
666
+ return {
667
+ id: params.name,
668
+ // @ts-ignore
669
+ inputSchema: z.object({
670
+ prompt: z.string(),
671
+ // resourceId: z.string().optional(),
672
+ // threadId: z.string().optional(),
673
+ }),
674
+ // @ts-ignore
675
+ outputSchema: z.object({
676
+ text: z.string(),
677
+ }),
678
+ execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
679
+ let streamPromise = {} as {
680
+ promise: Promise<string>;
681
+ resolve: (value: string) => void;
682
+ reject: (reason?: any) => void;
683
+ };
684
+
685
+ streamPromise.promise = new Promise((resolve, reject) => {
686
+ streamPromise.resolve = resolve;
687
+ streamPromise.reject = reject;
688
+ });
689
+ const toolData = {
690
+ name: params.name,
691
+ args: inputData,
692
+ };
693
+ await emitter.emit('watch-v2', {
694
+ type: 'tool-call-streaming-start',
695
+ ...toolData,
696
+ });
697
+ const { fullStream } = await params.stream(inputData.prompt, {
698
+ // resourceId: inputData.resourceId,
699
+ // threadId: inputData.threadId,
700
+ runtimeContext,
701
+ onFinish: result => {
702
+ streamPromise.resolve(result.text);
703
+ },
704
+ abortSignal,
705
+ });
706
+
707
+ if (abortSignal.aborted) {
708
+ return abort();
709
+ }
710
+
711
+ for await (const chunk of fullStream) {
712
+ switch (chunk.type) {
713
+ case 'text-delta':
714
+ await emitter.emit('watch-v2', {
715
+ type: 'tool-call-delta',
716
+ ...toolData,
717
+ argsTextDelta: chunk.textDelta,
718
+ });
719
+ break;
720
+
721
+ case 'step-start':
722
+ case 'step-finish':
723
+ case 'finish':
724
+ break;
725
+
726
+ case 'tool-call':
727
+ case 'tool-result':
728
+ case 'tool-call-streaming-start':
729
+ case 'tool-call-delta':
730
+ case 'source':
731
+ case 'file':
732
+ default:
733
+ await emitter.emit('watch-v2', chunk);
734
+ break;
735
+ }
736
+ }
737
+
738
+ return {
739
+ text: await streamPromise.promise,
740
+ };
741
+ },
742
+ };
743
+ }
744
+
745
+ if (isTool(params)) {
746
+ if (!params.inputSchema || !params.outputSchema) {
747
+ throw new Error('Tool must have input and output schemas defined');
748
+ }
749
+
750
+ return {
751
+ // TODO: tool probably should have strong id type
752
+ // @ts-ignore
753
+ id: params.id,
754
+ inputSchema: params.inputSchema,
755
+ outputSchema: params.outputSchema,
756
+ execute: async ({ inputData, mastra, runtimeContext }) => {
757
+ return params.execute({
758
+ context: inputData,
759
+ mastra,
760
+ runtimeContext,
761
+ });
762
+ },
763
+ };
764
+ }
765
+
766
+ return {
767
+ id: params.id,
768
+ description: params.description,
769
+ inputSchema: params.inputSchema,
770
+ outputSchema: params.outputSchema,
771
+ resumeSchema: params.resumeSchema,
772
+ suspendSchema: params.suspendSchema,
773
+ execute: params.execute,
774
+ };
388
775
  }
389
776
 
390
777
  export function init(inngest: Inngest) {
@@ -393,13 +780,59 @@ export function init(inngest: Inngest) {
393
780
  TWorkflowId extends string = string,
394
781
  TInput extends z.ZodType<any> = z.ZodType<any>,
395
782
  TOutput extends z.ZodType<any> = z.ZodType<any>,
396
- TSteps extends Step<string, any, any>[] = Step<string, any, any>[],
397
- >(params: NewWorkflowConfig<TWorkflowId, TInput, TOutput, TSteps>) {
398
- return new InngestWorkflow(params, inngest);
783
+ TSteps extends Step<string, any, any, any, any, InngestEngineType>[] = Step<
784
+ string,
785
+ any,
786
+ any,
787
+ any,
788
+ any,
789
+ InngestEngineType
790
+ >[],
791
+ >(params: WorkflowConfig<TWorkflowId, TInput, TOutput, TSteps>) {
792
+ return new InngestWorkflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput, TInput>(params, inngest);
399
793
  },
400
794
  createStep,
401
- cloneStep,
402
- cloneWorkflow,
795
+ cloneStep<TStepId extends string>(
796
+ step: Step<string, any, any, any, any, InngestEngineType>,
797
+ opts: { id: TStepId },
798
+ ): Step<TStepId, any, any, any, any, InngestEngineType> {
799
+ return {
800
+ id: opts.id,
801
+ description: step.description,
802
+ inputSchema: step.inputSchema,
803
+ outputSchema: step.outputSchema,
804
+ execute: step.execute,
805
+ };
806
+ },
807
+ cloneWorkflow<
808
+ TWorkflowId extends string = string,
809
+ TInput extends z.ZodType<any> = z.ZodType<any>,
810
+ TOutput extends z.ZodType<any> = z.ZodType<any>,
811
+ TSteps extends Step<string, any, any, any, any, InngestEngineType>[] = Step<
812
+ string,
813
+ any,
814
+ any,
815
+ any,
816
+ any,
817
+ InngestEngineType
818
+ >[],
819
+ TPrevSchema extends z.ZodType<any> = TInput,
820
+ >(
821
+ workflow: Workflow<InngestEngineType, TSteps, string, TInput, TOutput, TPrevSchema>,
822
+ opts: { id: TWorkflowId },
823
+ ): Workflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> {
824
+ const wf: Workflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> = new Workflow({
825
+ id: opts.id,
826
+ inputSchema: workflow.inputSchema,
827
+ outputSchema: workflow.outputSchema,
828
+ steps: workflow.stepDefs,
829
+ mastra: workflow.mastra,
830
+ });
831
+
832
+ wf.setStepFlow(workflow.stepGraph);
833
+ wf.commit();
834
+ return wf;
835
+ },
403
836
  };
404
837
  }
405
838
 
@@ -413,11 +846,47 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
413
846
  this.inngestAttempts = inngestAttempts;
414
847
  }
415
848
 
849
+ async execute<TInput, TOutput>(params: {
850
+ workflowId: string;
851
+ runId: string;
852
+ graph: ExecutionGraph;
853
+ serializedStepGraph: SerializedStepFlowEntry[];
854
+ input?: TInput;
855
+ resume?: {
856
+ // TODO: add execute path
857
+ steps: string[];
858
+ stepResults: Record<string, StepResult<any, any, any, any>>;
859
+ resumePayload: any;
860
+ resumePath: number[];
861
+ };
862
+ emitter: Emitter;
863
+ retryConfig?: {
864
+ attempts?: number;
865
+ delay?: number;
866
+ };
867
+ runtimeContext: RuntimeContext;
868
+ abortController: AbortController;
869
+ }): Promise<TOutput> {
870
+ await params.emitter.emit('watch-v2', {
871
+ type: 'start',
872
+ payload: { runId: params.runId },
873
+ });
874
+
875
+ const result = await super.execute<TInput, TOutput>(params);
876
+
877
+ await params.emitter.emit('watch-v2', {
878
+ type: 'finish',
879
+ payload: { runId: params.runId },
880
+ });
881
+
882
+ return result;
883
+ }
884
+
416
885
  protected async fmtReturnValue<TOutput>(
417
886
  executionSpan: Span | undefined,
418
- emitter: { emit: (event: string, data: any) => Promise<void> },
419
- stepResults: Record<string, StepResult<any>>,
420
- lastOutput: StepResult<any>,
887
+ emitter: Emitter,
888
+ stepResults: Record<string, StepResult<any, any, any, any>>,
889
+ lastOutput: StepResult<any, any, any, any>,
421
890
  error?: Error | string,
422
891
  ): Promise<TOutput> {
423
892
  const base: any = {
@@ -496,21 +965,23 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
496
965
  resume,
497
966
  prevOutput,
498
967
  emitter,
968
+ abortController,
499
969
  runtimeContext,
500
970
  }: {
501
971
  workflowId: string;
502
972
  runId: string;
503
973
  step: Step<string, any, any>;
504
- stepResults: Record<string, StepResult<any>>;
974
+ stepResults: Record<string, StepResult<any, any, any, any>>;
505
975
  executionContext: ExecutionContext;
506
976
  resume?: {
507
977
  steps: string[];
508
978
  resumePayload: any;
509
979
  };
510
980
  prevOutput: any;
511
- emitter: { emit: (event: string, data: any) => Promise<void> };
981
+ emitter: Emitter;
982
+ abortController: AbortController;
512
983
  runtimeContext: RuntimeContext;
513
- }): Promise<StepResult<any>> {
984
+ }): Promise<StepResult<any, any, any, any>> {
514
985
  return super.executeStep({
515
986
  workflowId,
516
987
  runId,
@@ -520,10 +991,28 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
520
991
  resume,
521
992
  prevOutput,
522
993
  emitter,
994
+ abortController,
523
995
  runtimeContext,
524
996
  });
525
997
  }
526
998
 
999
+ async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
1000
+ await this.inngestStep.sleep(id, duration);
1001
+ }
1002
+
1003
+ async executeWaitForEvent({ event, timeout }: { event: string; timeout?: number }): Promise<any> {
1004
+ const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
1005
+ event: `user-event-${event}`,
1006
+ timeout: timeout ?? 5e3,
1007
+ });
1008
+
1009
+ if (eventData === null) {
1010
+ throw 'Timeout waiting for event';
1011
+ }
1012
+
1013
+ return eventData?.data;
1014
+ }
1015
+
527
1016
  async executeStep({
528
1017
  step,
529
1018
  stepResults,
@@ -531,29 +1020,26 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
531
1020
  resume,
532
1021
  prevOutput,
533
1022
  emitter,
1023
+ abortController,
534
1024
  runtimeContext,
535
1025
  }: {
536
1026
  step: Step<string, any, any>;
537
- stepResults: Record<string, StepResult<any>>;
538
- executionContext: {
539
- workflowId: string;
540
- runId: string;
541
- executionPath: number[];
542
- suspendedPaths: Record<string, number[]>;
543
- retryConfig: { attempts: number; delay: number };
544
- };
1027
+ stepResults: Record<string, StepResult<any, any, any, any>>;
1028
+ executionContext: ExecutionContext;
545
1029
  resume?: {
546
1030
  steps: string[];
547
1031
  resumePayload: any;
548
1032
  runId?: string;
549
1033
  };
550
1034
  prevOutput: any;
551
- emitter: { emit: (event: string, data: any) => Promise<void> };
1035
+ emitter: Emitter;
1036
+ abortController: AbortController;
552
1037
  runtimeContext: RuntimeContext;
553
- }): Promise<StepResult<any>> {
554
- await this.inngestStep.run(
1038
+ }): Promise<StepResult<any, any, any, any>> {
1039
+ const startedAt = await this.inngestStep.run(
555
1040
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
556
1041
  async () => {
1042
+ const startedAt = Date.now();
557
1043
  await emitter.emit('watch', {
558
1044
  type: 'watch',
559
1045
  payload: {
@@ -575,6 +1061,16 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
575
1061
  },
576
1062
  eventTimestamp: Date.now(),
577
1063
  });
1064
+
1065
+ await emitter.emit('watch-v2', {
1066
+ type: 'step-start',
1067
+ payload: {
1068
+ id: step.id,
1069
+ status: 'running',
1070
+ },
1071
+ });
1072
+
1073
+ return startedAt;
578
1074
  },
579
1075
  );
580
1076
 
@@ -641,10 +1137,20 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
641
1137
  eventTimestamp: Date.now(),
642
1138
  });
643
1139
 
1140
+ await emitter.emit('watch-v2', {
1141
+ type: 'step-result',
1142
+ payload: {
1143
+ id: step.id,
1144
+ status: 'failed',
1145
+ error: result?.error,
1146
+ payload: prevOutput,
1147
+ },
1148
+ });
1149
+
644
1150
  return { executionContext, result: { status: 'failed', error: result?.error } };
645
1151
  } else if (result.status === 'suspended') {
646
1152
  const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
647
- const stepRes: StepResult<any> = stepResult as StepResult<any>;
1153
+ const stepRes: StepResult<any, any, any, any> = stepResult as StepResult<any, any, any, any>;
648
1154
  return stepRes?.status === 'suspended';
649
1155
  });
650
1156
 
@@ -671,6 +1177,14 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
671
1177
  eventTimestamp: Date.now(),
672
1178
  });
673
1179
 
1180
+ await emitter.emit('watch-v2', {
1181
+ type: 'step-suspended',
1182
+ payload: {
1183
+ id: step.id,
1184
+ status: 'suspended',
1185
+ },
1186
+ });
1187
+
674
1188
  return {
675
1189
  executionContext,
676
1190
  result: {
@@ -727,19 +1241,39 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
727
1241
  eventTimestamp: Date.now(),
728
1242
  });
729
1243
 
1244
+ await emitter.emit('watch-v2', {
1245
+ type: 'step-result',
1246
+ payload: {
1247
+ id: step.id,
1248
+ status: 'success',
1249
+ output: result?.result,
1250
+ },
1251
+ });
1252
+
1253
+ await emitter.emit('watch-v2', {
1254
+ type: 'step-finish',
1255
+ payload: {
1256
+ id: step.id,
1257
+ metadata: {},
1258
+ },
1259
+ });
1260
+
730
1261
  return { executionContext, result: { status: 'success', output: result?.result } };
731
1262
  },
732
1263
  );
733
1264
 
734
1265
  Object.assign(executionContext, res.executionContext);
735
- return res.result as StepResult<any>;
1266
+ return res.result as StepResult<any, any, any, any>;
736
1267
  }
737
1268
 
738
1269
  const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
739
1270
  let execResults: any;
740
1271
  let suspended: { payload: any } | undefined;
1272
+ let bailed: { payload: any } | undefined;
1273
+
741
1274
  try {
742
1275
  const result = await step.execute({
1276
+ runId: executionContext.runId,
743
1277
  mastra: this.mastra!,
744
1278
  runtimeContext,
745
1279
  inputData: prevOutput,
@@ -757,22 +1291,56 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
757
1291
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
758
1292
  suspended = { payload: suspendPayload };
759
1293
  },
1294
+ bail: (result: any) => {
1295
+ bailed = { payload: result };
1296
+ },
760
1297
  resume: {
761
1298
  steps: resume?.steps?.slice(1) || [],
762
1299
  resumePayload: resume?.resumePayload,
763
1300
  // @ts-ignore
764
1301
  runId: stepResults[step.id]?.payload?.__workflow_meta?.runId,
765
1302
  },
766
- emitter,
1303
+ [EMITTER_SYMBOL]: emitter,
1304
+ engine: {
1305
+ step: this.inngestStep,
1306
+ },
1307
+ abortSignal: abortController.signal,
767
1308
  });
768
-
769
- execResults = { status: 'success', output: result };
1309
+ const endedAt = Date.now();
1310
+
1311
+ execResults = {
1312
+ status: 'success',
1313
+ output: result,
1314
+ startedAt,
1315
+ endedAt,
1316
+ payload: prevOutput,
1317
+ resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,
1318
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
1319
+ };
770
1320
  } catch (e) {
771
- execResults = { status: 'failed', error: e instanceof Error ? e.message : String(e) };
1321
+ execResults = {
1322
+ status: 'failed',
1323
+ payload: prevOutput,
1324
+ error: e instanceof Error ? e.message : String(e),
1325
+ endedAt: Date.now(),
1326
+ startedAt,
1327
+ resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,
1328
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
1329
+ };
772
1330
  }
773
1331
 
774
1332
  if (suspended) {
775
- execResults = { status: 'suspended', payload: suspended.payload };
1333
+ execResults = {
1334
+ status: 'suspended',
1335
+ suspendedPayload: suspended.payload,
1336
+ payload: prevOutput,
1337
+ suspendedAt: Date.now(),
1338
+ startedAt,
1339
+ resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,
1340
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
1341
+ };
1342
+ } else if (bailed) {
1343
+ execResults = { status: 'bailed', output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
776
1344
  }
777
1345
 
778
1346
  if (execResults.status === 'failed') {
@@ -786,12 +1354,11 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
786
1354
  payload: {
787
1355
  currentStep: {
788
1356
  id: step.id,
789
- status: execResults.status,
790
- output: execResults.output,
1357
+ ...execResults,
791
1358
  },
792
1359
  workflowState: {
793
1360
  status: 'running',
794
- steps: stepResults,
1361
+ steps: { ...stepResults, [step.id]: execResults },
795
1362
  result: null,
796
1363
  error: null,
797
1364
  },
@@ -799,6 +1366,32 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
799
1366
  eventTimestamp: Date.now(),
800
1367
  });
801
1368
 
1369
+ if (execResults.status === 'suspended') {
1370
+ await emitter.emit('watch-v2', {
1371
+ type: 'step-suspended',
1372
+ payload: {
1373
+ id: step.id,
1374
+ ...execResults,
1375
+ },
1376
+ });
1377
+ } else {
1378
+ await emitter.emit('watch-v2', {
1379
+ type: 'step-result',
1380
+ payload: {
1381
+ id: step.id,
1382
+ ...execResults,
1383
+ },
1384
+ });
1385
+
1386
+ await emitter.emit('watch-v2', {
1387
+ type: 'step-finish',
1388
+ payload: {
1389
+ id: step.id,
1390
+ metadata: {},
1391
+ },
1392
+ });
1393
+ }
1394
+
802
1395
  return { result: execResults, executionContext, stepResults };
803
1396
  });
804
1397
 
@@ -816,11 +1409,19 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
816
1409
  runId,
817
1410
  stepResults,
818
1411
  executionContext,
1412
+ serializedStepGraph,
1413
+ workflowStatus,
1414
+ result,
1415
+ error,
819
1416
  }: {
820
1417
  workflowId: string;
821
1418
  runId: string;
822
- stepResults: Record<string, StepResult<any>>;
1419
+ stepResults: Record<string, StepResult<any, any, any, any>>;
1420
+ serializedStepGraph: SerializedStepFlowEntry[];
823
1421
  executionContext: ExecutionContext;
1422
+ workflowStatus: 'success' | 'failed' | 'suspended' | 'running';
1423
+ result?: Record<string, any>;
1424
+ error?: string | Error;
824
1425
  }) {
825
1426
  await this.inngestStep.run(
826
1427
  `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
@@ -834,6 +1435,10 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
834
1435
  context: stepResults as any,
835
1436
  activePaths: [],
836
1437
  suspendedPaths: executionContext.suspendedPaths,
1438
+ serializedStepGraph,
1439
+ status: workflowStatus,
1440
+ result,
1441
+ error,
837
1442
  // @ts-ignore
838
1443
  timestamp: Date.now(),
839
1444
  },
@@ -849,27 +1454,35 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
849
1454
  prevOutput,
850
1455
  prevStep,
851
1456
  stepResults,
1457
+ serializedStepGraph,
852
1458
  resume,
853
1459
  executionContext,
854
1460
  emitter,
1461
+ abortController,
855
1462
  runtimeContext,
856
1463
  }: {
857
1464
  workflowId: string;
858
1465
  runId: string;
859
- entry: { type: 'conditional'; steps: StepFlowEntry[]; conditions: ExecuteFunction<any, any, any, any>[] };
1466
+ entry: {
1467
+ type: 'conditional';
1468
+ steps: StepFlowEntry[];
1469
+ conditions: ExecuteFunction<any, any, any, any, InngestEngineType>[];
1470
+ };
860
1471
  prevStep: StepFlowEntry;
1472
+ serializedStepGraph: SerializedStepFlowEntry[];
861
1473
  prevOutput: any;
862
- stepResults: Record<string, StepResult<any>>;
1474
+ stepResults: Record<string, StepResult<any, any, any, any>>;
863
1475
  resume?: {
864
1476
  steps: string[];
865
- stepResults: Record<string, StepResult<any>>;
1477
+ stepResults: Record<string, StepResult<any, any, any, any>>;
866
1478
  resumePayload: any;
867
1479
  resumePath: number[];
868
1480
  };
869
1481
  executionContext: ExecutionContext;
870
- emitter: { emit: (event: string, data: any) => Promise<void> };
1482
+ emitter: Emitter;
1483
+ abortController: AbortController;
871
1484
  runtimeContext: RuntimeContext;
872
- }): Promise<StepResult<any>> {
1485
+ }): Promise<StepResult<any, any, any, any>> {
873
1486
  let execResults: any;
874
1487
  const truthyIndexes = (
875
1488
  await Promise.all(
@@ -877,8 +1490,10 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
877
1490
  this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
878
1491
  try {
879
1492
  const result = await cond({
1493
+ runId,
880
1494
  mastra: this.mastra!,
881
1495
  runtimeContext,
1496
+ runCount: -1,
882
1497
  inputData: prevOutput,
883
1498
  getInitData: () => stepResults?.input as any,
884
1499
  getStepResult: (step: any) => {
@@ -896,7 +1511,15 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
896
1511
 
897
1512
  // TODO: this function shouldn't have suspend probably?
898
1513
  suspend: async (_suspendPayload: any) => {},
899
- emitter,
1514
+ bail: () => {},
1515
+ abort: () => {
1516
+ abortController.abort();
1517
+ },
1518
+ [EMITTER_SYMBOL]: emitter,
1519
+ engine: {
1520
+ step: this.inngestStep,
1521
+ },
1522
+ abortSignal: abortController.signal,
900
1523
  });
901
1524
  return result ? index : null;
902
1525
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -909,7 +1532,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
909
1532
  ).filter((index: any): index is number => index !== null);
910
1533
 
911
1534
  const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
912
- const results: StepResult<any>[] = await Promise.all(
1535
+ const results: { result: StepResult<any, any, any, any> }[] = await Promise.all(
913
1536
  stepsToRun.map((step, index) =>
914
1537
  this.executeEntry({
915
1538
  workflowId,
@@ -918,6 +1541,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
918
1541
  prevStep,
919
1542
  stepResults,
920
1543
  resume,
1544
+ serializedStepGraph,
921
1545
  executionContext: {
922
1546
  workflowId,
923
1547
  runId,
@@ -927,21 +1551,24 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
927
1551
  executionSpan: executionContext.executionSpan,
928
1552
  },
929
1553
  emitter,
1554
+ abortController,
930
1555
  runtimeContext,
931
1556
  }),
932
1557
  ),
933
1558
  );
934
- const hasFailed = results.find(result => result.status === 'failed');
935
- const hasSuspended = results.find(result => result.status === 'suspended');
1559
+ const hasFailed = results.find(result => result.result.status === 'failed') as {
1560
+ result: StepFailure<any, any, any>;
1561
+ };
1562
+ const hasSuspended = results.find(result => result.result.status === 'suspended');
936
1563
  if (hasFailed) {
937
- execResults = { status: 'failed', error: hasFailed.error };
1564
+ execResults = { status: 'failed', error: hasFailed.result.error };
938
1565
  } else if (hasSuspended) {
939
- execResults = { status: 'suspended', payload: hasSuspended.payload };
1566
+ execResults = { status: 'suspended', payload: hasSuspended.result.suspendPayload };
940
1567
  } else {
941
1568
  execResults = {
942
1569
  status: 'success',
943
1570
  output: results.reduce((acc: Record<string, any>, result, index) => {
944
- if (result.status === 'success') {
1571
+ if (result.result.status === 'success') {
945
1572
  // @ts-ignore
946
1573
  acc[stepsToRun[index]!.step.id] = result.output;
947
1574
  }