@mastra/inngest 0.0.0-taofeeqInngest-20250603090617 → 0.0.0-transpile-packages-20250724123433

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