@mastra/inngest 0.0.0-taofeeqInngest-20250603090617 → 0.0.0-tsconfig-compile-20250703214351

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/dist/index.js CHANGED
@@ -1,20 +1,26 @@
1
1
  import { randomUUID } from 'crypto';
2
2
  import { subscribe } from '@inngest/realtime';
3
3
  import { RuntimeContext } from '@mastra/core/di';
4
- import { Run, Workflow, cloneStep, createStep, DefaultExecutionEngine } from '@mastra/core/workflows';
4
+ import { Tool } from '@mastra/core/tools';
5
+ import { Run, Workflow, DefaultExecutionEngine } from '@mastra/core/workflows';
5
6
  import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
6
7
  import { serve as serve$1 } from 'inngest/hono';
8
+ import { z } from 'zod';
7
9
 
8
10
  // src/index.ts
9
11
  function serve({ mastra, inngest }) {
10
12
  const wfs = mastra.getWorkflows();
11
- const functions = Object.values(wfs).flatMap((wf) => {
12
- if (wf instanceof InngestWorkflow) {
13
- wf.__registerMastra(mastra);
14
- return wf.getFunctions();
15
- }
16
- return [];
17
- });
13
+ const functions = Array.from(
14
+ new Set(
15
+ Object.values(wfs).flatMap((wf) => {
16
+ if (wf instanceof InngestWorkflow) {
17
+ wf.__registerMastra(mastra);
18
+ return wf.getFunctions();
19
+ }
20
+ return [];
21
+ })
22
+ )
23
+ );
18
24
  return serve$1({
19
25
  client: inngest,
20
26
  functions
@@ -41,15 +47,50 @@ var InngestRun = class extends Run {
41
47
  }
42
48
  async getRunOutput(eventId) {
43
49
  let runs = await this.getRuns(eventId);
44
- while (runs?.[0]?.status !== "Completed") {
50
+ while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
45
51
  await new Promise((resolve) => setTimeout(resolve, 1e3));
46
52
  runs = await this.getRuns(eventId);
47
- if (runs?.[0]?.status === "Failed" || runs?.[0]?.status === "Cancelled") {
53
+ if (runs?.[0]?.status === "Failed") {
54
+ console.log("run", runs?.[0]);
48
55
  throw new Error(`Function run ${runs?.[0]?.status}`);
56
+ } else if (runs?.[0]?.status === "Cancelled") {
57
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
58
+ workflowName: this.workflowId,
59
+ runId: this.runId
60
+ });
61
+ return { output: { result: { steps: snapshot?.context, status: "canceled" } } };
49
62
  }
50
63
  }
51
64
  return runs?.[0];
52
65
  }
66
+ async sendEvent(event, data) {
67
+ await this.inngest.send({
68
+ name: `user-event-${event}`,
69
+ data
70
+ });
71
+ }
72
+ async cancel() {
73
+ await this.inngest.send({
74
+ name: `cancel.workflow.${this.workflowId}`,
75
+ data: {
76
+ runId: this.runId
77
+ }
78
+ });
79
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
80
+ workflowName: this.workflowId,
81
+ runId: this.runId
82
+ });
83
+ if (snapshot) {
84
+ await this.#mastra?.storage?.persistWorkflowSnapshot({
85
+ workflowName: this.workflowId,
86
+ runId: this.runId,
87
+ snapshot: {
88
+ ...snapshot,
89
+ status: "canceled"
90
+ }
91
+ });
92
+ }
93
+ }
53
94
  async start({
54
95
  inputData
55
96
  }) {
@@ -63,7 +104,8 @@ var InngestRun = class extends Run {
63
104
  context: {},
64
105
  activePaths: [],
65
106
  suspendedPaths: {},
66
- timestamp: Date.now()
107
+ timestamp: Date.now(),
108
+ status: "running"
67
109
  }
68
110
  });
69
111
  const eventOutput = await this.inngest.send({
@@ -82,10 +124,23 @@ var InngestRun = class extends Run {
82
124
  if (result.status === "failed") {
83
125
  result.error = new Error(result.error);
84
126
  }
85
- this.cleanup?.();
127
+ if (result.status !== "suspended") {
128
+ this.cleanup?.();
129
+ }
86
130
  return result;
87
131
  }
88
132
  async resume(params) {
133
+ const p = this._resume(params).then((result) => {
134
+ if (result.status !== "suspended") {
135
+ this.closeStreamAction?.().catch(() => {
136
+ });
137
+ }
138
+ return result;
139
+ });
140
+ this.executionResults = p;
141
+ return p;
142
+ }
143
+ async _resume(params) {
89
144
  const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
90
145
  (step) => typeof step === "string" ? step : step?.id
91
146
  );
@@ -119,25 +174,60 @@ var InngestRun = class extends Run {
119
174
  }
120
175
  return result;
121
176
  }
122
- watch(cb) {
177
+ watch(cb, type = "watch") {
178
+ let active = true;
123
179
  const streamPromise = subscribe(
124
180
  {
125
181
  channel: `workflow:${this.workflowId}:${this.runId}`,
126
- topics: ["watch"],
182
+ topics: [type],
127
183
  app: this.inngest
128
184
  },
129
185
  (message) => {
130
- cb(message.data);
186
+ if (active) {
187
+ cb(message.data);
188
+ }
131
189
  }
132
190
  );
133
191
  return () => {
134
- streamPromise.then((stream) => {
135
- stream.cancel();
192
+ active = false;
193
+ streamPromise.then(async (stream) => {
194
+ return stream.cancel();
136
195
  }).catch((err) => {
137
196
  console.error(err);
138
197
  });
139
198
  };
140
199
  }
200
+ stream({ inputData, runtimeContext } = {}) {
201
+ const { readable, writable } = new TransformStream();
202
+ const writer = writable.getWriter();
203
+ const unwatch = this.watch(async (event) => {
204
+ try {
205
+ await writer.write(event);
206
+ } catch {
207
+ }
208
+ }, "watch-v2");
209
+ this.closeStreamAction = async () => {
210
+ unwatch();
211
+ try {
212
+ await writer.close();
213
+ } catch (err) {
214
+ console.error("Error closing stream:", err);
215
+ } finally {
216
+ writer.releaseLock();
217
+ }
218
+ };
219
+ this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
220
+ if (result.status !== "suspended") {
221
+ this.closeStreamAction?.().catch(() => {
222
+ });
223
+ }
224
+ return result;
225
+ });
226
+ return {
227
+ stream: readable,
228
+ getWorkflowState: () => this.executionResults
229
+ };
230
+ }
141
231
  };
142
232
  var InngestWorkflow = class _InngestWorkflow extends Workflow {
143
233
  #mastra;
@@ -160,11 +250,32 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
160
250
  const storage = this.#mastra?.getStorage();
161
251
  if (!storage) {
162
252
  this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
163
- return null;
253
+ return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
164
254
  }
165
255
  const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
166
256
  return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
167
257
  }
258
+ async getWorkflowRunExecutionResult(runId) {
259
+ const storage = this.#mastra?.getStorage();
260
+ if (!storage) {
261
+ this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
262
+ return null;
263
+ }
264
+ const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
265
+ if (!run?.snapshot) {
266
+ return null;
267
+ }
268
+ if (typeof run.snapshot === "string") {
269
+ return null;
270
+ }
271
+ return {
272
+ status: run.snapshot.status,
273
+ result: run.snapshot.result,
274
+ error: run.snapshot.error,
275
+ payload: run.snapshot.context?.input,
276
+ steps: run.snapshot.context
277
+ };
278
+ }
168
279
  __registerMastra(mastra) {
169
280
  this.#mastra = mastra;
170
281
  this.executionEngine.__registerMastra(mastra);
@@ -201,13 +312,55 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
201
312
  this.runs.set(runIdToUse, run);
202
313
  return run;
203
314
  }
315
+ async createRunAsync(options) {
316
+ const runIdToUse = options?.runId || randomUUID();
317
+ const run = this.runs.get(runIdToUse) ?? new InngestRun(
318
+ {
319
+ workflowId: this.id,
320
+ runId: runIdToUse,
321
+ executionEngine: this.executionEngine,
322
+ executionGraph: this.executionGraph,
323
+ serializedStepGraph: this.serializedStepGraph,
324
+ mastra: this.#mastra,
325
+ retryConfig: this.retryConfig,
326
+ cleanup: () => this.runs.delete(runIdToUse)
327
+ },
328
+ this.inngest
329
+ );
330
+ this.runs.set(runIdToUse, run);
331
+ const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
332
+ if (!workflowSnapshotInStorage) {
333
+ await this.mastra?.getStorage()?.persistWorkflowSnapshot({
334
+ workflowName: this.id,
335
+ runId: runIdToUse,
336
+ snapshot: {
337
+ runId: runIdToUse,
338
+ status: "pending",
339
+ value: {},
340
+ context: {},
341
+ activePaths: [],
342
+ serializedStepGraph: this.serializedStepGraph,
343
+ suspendedPaths: {},
344
+ result: void 0,
345
+ error: void 0,
346
+ // @ts-ignore
347
+ timestamp: Date.now()
348
+ }
349
+ });
350
+ }
351
+ return run;
352
+ }
204
353
  getFunction() {
205
354
  if (this.function) {
206
355
  return this.function;
207
356
  }
208
357
  this.function = this.inngest.createFunction(
209
- // @ts-ignore
210
- { id: `workflow.${this.id}`, retries: this.retryConfig?.attempts ?? 0 },
358
+ {
359
+ id: `workflow.${this.id}`,
360
+ // @ts-ignore
361
+ retries: this.retryConfig?.attempts ?? 0,
362
+ cancelOn: [{ event: `cancel.workflow.${this.id}` }]
363
+ },
211
364
  { event: `workflow.${this.id}` },
212
365
  async ({ event, step, attempt, publish }) => {
213
366
  let { inputData, runId, resume } = event.data;
@@ -224,12 +377,18 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
224
377
  try {
225
378
  await publish({
226
379
  channel: `workflow:${this.id}:${runId}`,
227
- topic: "watch",
380
+ topic: event2,
228
381
  data
229
382
  });
230
383
  } catch (err) {
231
384
  this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
232
385
  }
386
+ },
387
+ on: (_event, _callback) => {
388
+ },
389
+ off: (_event, _callback) => {
390
+ },
391
+ once: (_event, _callback) => {
233
392
  }
234
393
  };
235
394
  const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
@@ -243,7 +402,8 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
243
402
  retryConfig: this.retryConfig,
244
403
  runtimeContext: new RuntimeContext(),
245
404
  // TODO
246
- resume
405
+ resume,
406
+ abortController: new AbortController()
247
407
  });
248
408
  return { result, runId };
249
409
  }
@@ -267,20 +427,110 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
267
427
  return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
268
428
  }
269
429
  };
270
- function cloneWorkflow(workflow, opts) {
271
- const wf = new InngestWorkflow(
272
- {
273
- id: opts.id,
274
- inputSchema: workflow.inputSchema,
275
- outputSchema: workflow.outputSchema,
276
- steps: workflow.stepDefs,
277
- mastra: workflow.mastra
278
- },
279
- workflow.inngest
280
- );
281
- wf.setStepFlow(workflow.stepGraph);
282
- wf.commit();
283
- return wf;
430
+ function isAgent(params) {
431
+ return params?.component === "AGENT";
432
+ }
433
+ function isTool(params) {
434
+ return params instanceof Tool;
435
+ }
436
+ function createStep(params) {
437
+ if (isAgent(params)) {
438
+ return {
439
+ id: params.name,
440
+ // @ts-ignore
441
+ inputSchema: z.object({
442
+ prompt: z.string()
443
+ // resourceId: z.string().optional(),
444
+ // threadId: z.string().optional(),
445
+ }),
446
+ // @ts-ignore
447
+ outputSchema: z.object({
448
+ text: z.string()
449
+ }),
450
+ execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
451
+ let streamPromise = {};
452
+ streamPromise.promise = new Promise((resolve, reject) => {
453
+ streamPromise.resolve = resolve;
454
+ streamPromise.reject = reject;
455
+ });
456
+ const toolData = {
457
+ name: params.name,
458
+ args: inputData
459
+ };
460
+ await emitter.emit("watch-v2", {
461
+ type: "tool-call-streaming-start",
462
+ ...toolData
463
+ });
464
+ const { fullStream } = await params.stream(inputData.prompt, {
465
+ // resourceId: inputData.resourceId,
466
+ // threadId: inputData.threadId,
467
+ runtimeContext,
468
+ onFinish: (result) => {
469
+ streamPromise.resolve(result.text);
470
+ },
471
+ abortSignal
472
+ });
473
+ if (abortSignal.aborted) {
474
+ return abort();
475
+ }
476
+ for await (const chunk of fullStream) {
477
+ switch (chunk.type) {
478
+ case "text-delta":
479
+ await emitter.emit("watch-v2", {
480
+ type: "tool-call-delta",
481
+ ...toolData,
482
+ argsTextDelta: chunk.textDelta
483
+ });
484
+ break;
485
+ case "step-start":
486
+ case "step-finish":
487
+ case "finish":
488
+ break;
489
+ case "tool-call":
490
+ case "tool-result":
491
+ case "tool-call-streaming-start":
492
+ case "tool-call-delta":
493
+ case "source":
494
+ case "file":
495
+ default:
496
+ await emitter.emit("watch-v2", chunk);
497
+ break;
498
+ }
499
+ }
500
+ return {
501
+ text: await streamPromise.promise
502
+ };
503
+ }
504
+ };
505
+ }
506
+ if (isTool(params)) {
507
+ if (!params.inputSchema || !params.outputSchema) {
508
+ throw new Error("Tool must have input and output schemas defined");
509
+ }
510
+ return {
511
+ // TODO: tool probably should have strong id type
512
+ // @ts-ignore
513
+ id: params.id,
514
+ inputSchema: params.inputSchema,
515
+ outputSchema: params.outputSchema,
516
+ execute: async ({ inputData, mastra, runtimeContext }) => {
517
+ return params.execute({
518
+ context: inputData,
519
+ mastra,
520
+ runtimeContext
521
+ });
522
+ }
523
+ };
524
+ }
525
+ return {
526
+ id: params.id,
527
+ description: params.description,
528
+ inputSchema: params.inputSchema,
529
+ outputSchema: params.outputSchema,
530
+ resumeSchema: params.resumeSchema,
531
+ suspendSchema: params.suspendSchema,
532
+ execute: params.execute
533
+ };
284
534
  }
285
535
  function init(inngest) {
286
536
  return {
@@ -288,8 +538,27 @@ function init(inngest) {
288
538
  return new InngestWorkflow(params, inngest);
289
539
  },
290
540
  createStep,
291
- cloneStep,
292
- cloneWorkflow
541
+ cloneStep(step, opts) {
542
+ return {
543
+ id: opts.id,
544
+ description: step.description,
545
+ inputSchema: step.inputSchema,
546
+ outputSchema: step.outputSchema,
547
+ execute: step.execute
548
+ };
549
+ },
550
+ cloneWorkflow(workflow, opts) {
551
+ const wf = new Workflow({
552
+ id: opts.id,
553
+ inputSchema: workflow.inputSchema,
554
+ outputSchema: workflow.outputSchema,
555
+ steps: workflow.stepDefs,
556
+ mastra: workflow.mastra
557
+ });
558
+ wf.setStepFlow(workflow.stepGraph);
559
+ wf.commit();
560
+ return wf;
561
+ }
293
562
  };
294
563
  }
295
564
  var InngestExecutionEngine = class extends DefaultExecutionEngine {
@@ -300,6 +569,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
300
569
  this.inngestStep = inngestStep;
301
570
  this.inngestAttempts = inngestAttempts;
302
571
  }
572
+ async execute(params) {
573
+ await params.emitter.emit("watch-v2", {
574
+ type: "start",
575
+ payload: { runId: params.runId }
576
+ });
577
+ const result = await super.execute(params);
578
+ await params.emitter.emit("watch-v2", {
579
+ type: "finish",
580
+ payload: { runId: params.runId }
581
+ });
582
+ return result;
583
+ }
303
584
  async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
304
585
  const base = {
305
586
  status: lastOutput.status,
@@ -366,6 +647,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
366
647
  resume,
367
648
  prevOutput,
368
649
  emitter,
650
+ abortController,
369
651
  runtimeContext
370
652
  }) {
371
653
  return super.executeStep({
@@ -377,9 +659,118 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
377
659
  resume,
378
660
  prevOutput,
379
661
  emitter,
662
+ abortController,
380
663
  runtimeContext
381
664
  });
382
665
  }
666
+ // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
667
+ // await this.inngestStep.sleep(id, duration);
668
+ // }
669
+ async executeSleep({
670
+ workflowId,
671
+ runId,
672
+ entry,
673
+ prevOutput,
674
+ stepResults,
675
+ emitter,
676
+ abortController,
677
+ runtimeContext
678
+ }) {
679
+ let { duration, fn } = entry;
680
+ if (fn) {
681
+ duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
682
+ return await fn({
683
+ runId,
684
+ mastra: this.mastra,
685
+ runtimeContext,
686
+ inputData: prevOutput,
687
+ runCount: -1,
688
+ getInitData: () => stepResults?.input,
689
+ getStepResult: (step) => {
690
+ if (!step?.id) {
691
+ return null;
692
+ }
693
+ const result = stepResults[step.id];
694
+ if (result?.status === "success") {
695
+ return result.output;
696
+ }
697
+ return null;
698
+ },
699
+ // TODO: this function shouldn't have suspend probably?
700
+ suspend: async (_suspendPayload) => {
701
+ },
702
+ bail: () => {
703
+ },
704
+ abort: () => {
705
+ abortController?.abort();
706
+ },
707
+ [EMITTER_SYMBOL]: emitter,
708
+ engine: { step: this.inngestStep },
709
+ abortSignal: abortController?.signal
710
+ });
711
+ });
712
+ }
713
+ await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
714
+ }
715
+ async executeSleepUntil({
716
+ workflowId,
717
+ runId,
718
+ entry,
719
+ prevOutput,
720
+ stepResults,
721
+ emitter,
722
+ abortController,
723
+ runtimeContext
724
+ }) {
725
+ let { date, fn } = entry;
726
+ if (fn) {
727
+ date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
728
+ return await fn({
729
+ runId,
730
+ mastra: this.mastra,
731
+ runtimeContext,
732
+ inputData: prevOutput,
733
+ runCount: -1,
734
+ getInitData: () => stepResults?.input,
735
+ getStepResult: (step) => {
736
+ if (!step?.id) {
737
+ return null;
738
+ }
739
+ const result = stepResults[step.id];
740
+ if (result?.status === "success") {
741
+ return result.output;
742
+ }
743
+ return null;
744
+ },
745
+ // TODO: this function shouldn't have suspend probably?
746
+ suspend: async (_suspendPayload) => {
747
+ },
748
+ bail: () => {
749
+ },
750
+ abort: () => {
751
+ abortController?.abort();
752
+ },
753
+ [EMITTER_SYMBOL]: emitter,
754
+ engine: { step: this.inngestStep },
755
+ abortSignal: abortController?.signal
756
+ });
757
+ });
758
+ }
759
+ if (!(date instanceof Date)) {
760
+ return;
761
+ }
762
+ await this.inngestStep.sleepUntil(entry.id, date);
763
+ }
764
+ async executeWaitForEvent({ event, timeout }) {
765
+ const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
766
+ event: `user-event-${event}`,
767
+ timeout: timeout ?? 5e3
768
+ });
769
+ if (eventData === null) {
770
+ throw "Timeout waiting for event";
771
+ }
772
+ return eventData?.data;
773
+ }
383
774
  async executeStep({
384
775
  step,
385
776
  stepResults,
@@ -387,11 +778,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
387
778
  resume,
388
779
  prevOutput,
389
780
  emitter,
781
+ abortController,
390
782
  runtimeContext
391
783
  }) {
392
- await this.inngestStep.run(
784
+ const startedAt = await this.inngestStep.run(
393
785
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
394
786
  async () => {
787
+ const startedAt2 = Date.now();
395
788
  await emitter.emit("watch", {
396
789
  type: "watch",
397
790
  payload: {
@@ -413,6 +806,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
413
806
  },
414
807
  eventTimestamp: Date.now()
415
808
  });
809
+ await emitter.emit("watch-v2", {
810
+ type: "step-start",
811
+ payload: {
812
+ id: step.id,
813
+ status: "running",
814
+ payload: prevOutput,
815
+ startedAt: startedAt2
816
+ }
817
+ });
818
+ return startedAt2;
416
819
  }
417
820
  );
418
821
  if (step instanceof InngestWorkflow) {
@@ -473,6 +876,15 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
473
876
  },
474
877
  eventTimestamp: Date.now()
475
878
  });
879
+ await emitter.emit("watch-v2", {
880
+ type: "step-result",
881
+ payload: {
882
+ id: step.id,
883
+ status: "failed",
884
+ error: result?.error,
885
+ payload: prevOutput
886
+ }
887
+ });
476
888
  return { executionContext, result: { status: "failed", error: result?.error } };
477
889
  } else if (result.status === "suspended") {
478
890
  const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
@@ -499,6 +911,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
499
911
  },
500
912
  eventTimestamp: Date.now()
501
913
  });
914
+ await emitter.emit("watch-v2", {
915
+ type: "step-suspended",
916
+ payload: {
917
+ id: step.id,
918
+ status: "suspended"
919
+ }
920
+ });
502
921
  return {
503
922
  executionContext,
504
923
  result: {
@@ -549,6 +968,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
549
968
  },
550
969
  eventTimestamp: Date.now()
551
970
  });
971
+ await emitter.emit("watch-v2", {
972
+ type: "step-result",
973
+ payload: {
974
+ id: step.id,
975
+ status: "success",
976
+ output: result?.result
977
+ }
978
+ });
979
+ await emitter.emit("watch-v2", {
980
+ type: "step-finish",
981
+ payload: {
982
+ id: step.id,
983
+ metadata: {}
984
+ }
985
+ });
552
986
  return { executionContext, result: { status: "success", output: result?.result } };
553
987
  }
554
988
  );
@@ -558,6 +992,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
558
992
  const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
559
993
  let execResults;
560
994
  let suspended;
995
+ let bailed;
561
996
  try {
562
997
  const result = await step.execute({
563
998
  runId: executionContext.runId,
@@ -577,20 +1012,54 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
577
1012
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
578
1013
  suspended = { payload: suspendPayload };
579
1014
  },
1015
+ bail: (result2) => {
1016
+ bailed = { payload: result2 };
1017
+ },
580
1018
  resume: {
581
1019
  steps: resume?.steps?.slice(1) || [],
582
1020
  resumePayload: resume?.resumePayload,
583
1021
  // @ts-ignore
584
1022
  runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
585
1023
  },
586
- emitter
1024
+ [EMITTER_SYMBOL]: emitter,
1025
+ engine: {
1026
+ step: this.inngestStep
1027
+ },
1028
+ abortSignal: abortController.signal
587
1029
  });
588
- execResults = { status: "success", output: result };
1030
+ const endedAt = Date.now();
1031
+ execResults = {
1032
+ status: "success",
1033
+ output: result,
1034
+ startedAt,
1035
+ endedAt,
1036
+ payload: prevOutput,
1037
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1038
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1039
+ };
589
1040
  } catch (e) {
590
- execResults = { status: "failed", error: e instanceof Error ? e.message : String(e) };
1041
+ execResults = {
1042
+ status: "failed",
1043
+ payload: prevOutput,
1044
+ error: e instanceof Error ? e.message : String(e),
1045
+ endedAt: Date.now(),
1046
+ startedAt,
1047
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1048
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1049
+ };
591
1050
  }
592
1051
  if (suspended) {
593
- execResults = { status: "suspended", payload: suspended.payload };
1052
+ execResults = {
1053
+ status: "suspended",
1054
+ suspendedPayload: suspended.payload,
1055
+ payload: prevOutput,
1056
+ suspendedAt: Date.now(),
1057
+ startedAt,
1058
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1059
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1060
+ };
1061
+ } else if (bailed) {
1062
+ execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
594
1063
  }
595
1064
  if (execResults.status === "failed") {
596
1065
  if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
@@ -602,18 +1071,41 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
602
1071
  payload: {
603
1072
  currentStep: {
604
1073
  id: step.id,
605
- status: execResults.status,
606
- output: execResults.output
1074
+ ...execResults
607
1075
  },
608
1076
  workflowState: {
609
1077
  status: "running",
610
- steps: stepResults,
1078
+ steps: { ...stepResults, [step.id]: execResults },
611
1079
  result: null,
612
1080
  error: null
613
1081
  }
614
1082
  },
615
1083
  eventTimestamp: Date.now()
616
1084
  });
1085
+ if (execResults.status === "suspended") {
1086
+ await emitter.emit("watch-v2", {
1087
+ type: "step-suspended",
1088
+ payload: {
1089
+ id: step.id,
1090
+ ...execResults
1091
+ }
1092
+ });
1093
+ } else {
1094
+ await emitter.emit("watch-v2", {
1095
+ type: "step-result",
1096
+ payload: {
1097
+ id: step.id,
1098
+ ...execResults
1099
+ }
1100
+ });
1101
+ await emitter.emit("watch-v2", {
1102
+ type: "step-finish",
1103
+ payload: {
1104
+ id: step.id,
1105
+ metadata: {}
1106
+ }
1107
+ });
1108
+ }
617
1109
  return { result: execResults, executionContext, stepResults };
618
1110
  });
619
1111
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
@@ -625,7 +1117,10 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
625
1117
  runId,
626
1118
  stepResults,
627
1119
  executionContext,
628
- serializedStepGraph
1120
+ serializedStepGraph,
1121
+ workflowStatus,
1122
+ result,
1123
+ error
629
1124
  }) {
630
1125
  await this.inngestStep.run(
631
1126
  `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
@@ -640,6 +1135,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
640
1135
  activePaths: [],
641
1136
  suspendedPaths: executionContext.suspendedPaths,
642
1137
  serializedStepGraph,
1138
+ status: workflowStatus,
1139
+ result,
1140
+ error,
643
1141
  // @ts-ignore
644
1142
  timestamp: Date.now()
645
1143
  }
@@ -658,6 +1156,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
658
1156
  resume,
659
1157
  executionContext,
660
1158
  emitter,
1159
+ abortController,
661
1160
  runtimeContext
662
1161
  }) {
663
1162
  let execResults;
@@ -669,6 +1168,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
669
1168
  runId,
670
1169
  mastra: this.mastra,
671
1170
  runtimeContext,
1171
+ runCount: -1,
672
1172
  inputData: prevOutput,
673
1173
  getInitData: () => stepResults?.input,
674
1174
  getStepResult: (step) => {
@@ -684,7 +1184,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
684
1184
  // TODO: this function shouldn't have suspend probably?
685
1185
  suspend: async (_suspendPayload) => {
686
1186
  },
687
- [EMITTER_SYMBOL]: emitter
1187
+ bail: () => {
1188
+ },
1189
+ abort: () => {
1190
+ abortController.abort();
1191
+ },
1192
+ [EMITTER_SYMBOL]: emitter,
1193
+ engine: {
1194
+ step: this.inngestStep
1195
+ },
1196
+ abortSignal: abortController.signal
688
1197
  });
689
1198
  return result ? index : null;
690
1199
  } catch (e) {
@@ -713,21 +1222,22 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
713
1222
  executionSpan: executionContext.executionSpan
714
1223
  },
715
1224
  emitter,
1225
+ abortController,
716
1226
  runtimeContext
717
1227
  })
718
1228
  )
719
1229
  );
720
- const hasFailed = results.find((result) => result.status === "failed");
721
- const hasSuspended = results.find((result) => result.status === "suspended");
1230
+ const hasFailed = results.find((result) => result.result.status === "failed");
1231
+ const hasSuspended = results.find((result) => result.result.status === "suspended");
722
1232
  if (hasFailed) {
723
- execResults = { status: "failed", error: hasFailed.error };
1233
+ execResults = { status: "failed", error: hasFailed.result.error };
724
1234
  } else if (hasSuspended) {
725
- execResults = { status: "suspended", payload: hasSuspended.payload };
1235
+ execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
726
1236
  } else {
727
1237
  execResults = {
728
1238
  status: "success",
729
1239
  output: results.reduce((acc, result, index) => {
730
- if (result.status === "success") {
1240
+ if (result.result.status === "success") {
731
1241
  acc[stepsToRun[index].step.id] = result.output;
732
1242
  }
733
1243
  return acc;
@@ -738,4 +1248,4 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
738
1248
  }
739
1249
  };
740
1250
 
741
- export { InngestExecutionEngine, InngestRun, InngestWorkflow, init, serve };
1251
+ export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };