@mastra/inngest 0.0.0-redis-cloud-transporter-20250508194049 → 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/dist/index.cjs CHANGED
@@ -3,34 +3,43 @@
3
3
  var crypto = require('crypto');
4
4
  var realtime = require('@inngest/realtime');
5
5
  var di = require('@mastra/core/di');
6
- var vNext = require('@mastra/core/workflows/vNext');
6
+ var tools = require('@mastra/core/tools');
7
+ var workflows = require('@mastra/core/workflows');
8
+ var _constants = require('@mastra/core/workflows/_constants');
7
9
  var hono = require('inngest/hono');
10
+ var zod = require('zod');
8
11
 
9
12
  // src/index.ts
10
13
  function serve({ mastra, inngest }) {
11
- const wfs = mastra.vnext_getWorkflows();
12
- const functions = Object.values(wfs).flatMap((wf) => {
13
- if (wf instanceof InngestWorkflow) {
14
- wf.__registerMastra(mastra);
15
- return wf.getFunctions();
16
- }
17
- return [];
18
- });
14
+ const wfs = mastra.getWorkflows();
15
+ const functions = Array.from(
16
+ new Set(
17
+ Object.values(wfs).flatMap((wf) => {
18
+ if (wf instanceof InngestWorkflow) {
19
+ wf.__registerMastra(mastra);
20
+ return wf.getFunctions();
21
+ }
22
+ return [];
23
+ })
24
+ )
25
+ );
19
26
  return hono.serve({
20
27
  client: inngest,
21
28
  functions
22
29
  });
23
30
  }
24
- var InngestRun = class extends vNext.Run {
31
+ var InngestRun = class extends workflows.Run {
25
32
  inngest;
33
+ serializedStepGraph;
26
34
  #mastra;
27
35
  constructor(params, inngest) {
28
36
  super(params);
29
37
  this.inngest = inngest;
38
+ this.serializedStepGraph = params.serializedStepGraph;
30
39
  this.#mastra = params.mastra;
31
40
  }
32
41
  async getRuns(eventId) {
33
- const response = await fetch(`${this.inngest.apiBaseUrl}/v1/events/${eventId}/runs`, {
42
+ const response = await fetch(`${this.inngest.apiBaseUrl ?? "https://api.inngest.com"}/v1/events/${eventId}/runs`, {
34
43
  headers: {
35
44
  Authorization: `Bearer ${process.env.INNGEST_SIGNING_KEY}`
36
45
  }
@@ -40,15 +49,49 @@ var InngestRun = class extends vNext.Run {
40
49
  }
41
50
  async getRunOutput(eventId) {
42
51
  let runs = await this.getRuns(eventId);
43
- while (runs?.[0]?.status !== "Completed") {
52
+ while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
44
53
  await new Promise((resolve) => setTimeout(resolve, 1e3));
45
54
  runs = await this.getRuns(eventId);
46
- if (runs?.[0]?.status === "Failed" || runs?.[0]?.status === "Cancelled") {
55
+ if (runs?.[0]?.status === "Failed") {
47
56
  throw new Error(`Function run ${runs?.[0]?.status}`);
57
+ } else if (runs?.[0]?.status === "Cancelled") {
58
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
59
+ workflowName: this.workflowId,
60
+ runId: this.runId
61
+ });
62
+ return { output: { result: { steps: snapshot?.context, status: "canceled" } } };
48
63
  }
49
64
  }
50
65
  return runs?.[0];
51
66
  }
67
+ async sendEvent(event, data) {
68
+ await this.inngest.send({
69
+ name: `user-event-${event}`,
70
+ data
71
+ });
72
+ }
73
+ async cancel() {
74
+ await this.inngest.send({
75
+ name: `cancel.workflow.${this.workflowId}`,
76
+ data: {
77
+ runId: this.runId
78
+ }
79
+ });
80
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
81
+ workflowName: this.workflowId,
82
+ runId: this.runId
83
+ });
84
+ if (snapshot) {
85
+ await this.#mastra?.storage?.persistWorkflowSnapshot({
86
+ workflowName: this.workflowId,
87
+ runId: this.runId,
88
+ snapshot: {
89
+ ...snapshot,
90
+ status: "canceled"
91
+ }
92
+ });
93
+ }
94
+ }
52
95
  async start({
53
96
  inputData
54
97
  }) {
@@ -57,11 +100,13 @@ var InngestRun = class extends vNext.Run {
57
100
  runId: this.runId,
58
101
  snapshot: {
59
102
  runId: this.runId,
103
+ serializedStepGraph: this.serializedStepGraph,
60
104
  value: {},
61
105
  context: {},
62
106
  activePaths: [],
63
107
  suspendedPaths: {},
64
- timestamp: Date.now()
108
+ timestamp: Date.now(),
109
+ status: "running"
65
110
  }
66
111
  });
67
112
  const eventOutput = await this.inngest.send({
@@ -80,10 +125,23 @@ var InngestRun = class extends vNext.Run {
80
125
  if (result.status === "failed") {
81
126
  result.error = new Error(result.error);
82
127
  }
83
- this.cleanup?.();
128
+ if (result.status !== "suspended") {
129
+ this.cleanup?.();
130
+ }
84
131
  return result;
85
132
  }
86
133
  async resume(params) {
134
+ const p = this._resume(params).then((result) => {
135
+ if (result.status !== "suspended") {
136
+ this.closeStreamAction?.().catch(() => {
137
+ });
138
+ }
139
+ return result;
140
+ });
141
+ this.executionResults = p;
142
+ return p;
143
+ }
144
+ async _resume(params) {
87
145
  const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
88
146
  (step) => typeof step === "string" ? step : step?.id
89
147
  );
@@ -117,27 +175,62 @@ var InngestRun = class extends vNext.Run {
117
175
  }
118
176
  return result;
119
177
  }
120
- watch(cb) {
178
+ watch(cb, type = "watch") {
179
+ let active = true;
121
180
  const streamPromise = realtime.subscribe(
122
181
  {
123
182
  channel: `workflow:${this.workflowId}:${this.runId}`,
124
- topics: ["watch"],
183
+ topics: [type],
125
184
  app: this.inngest
126
185
  },
127
186
  (message) => {
128
- cb(message.data);
187
+ if (active) {
188
+ cb(message.data);
189
+ }
129
190
  }
130
191
  );
131
192
  return () => {
132
- streamPromise.then((stream) => {
133
- stream.cancel();
193
+ active = false;
194
+ streamPromise.then(async (stream) => {
195
+ return stream.cancel();
134
196
  }).catch((err) => {
135
197
  console.error(err);
136
198
  });
137
199
  };
138
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
+ }
139
232
  };
140
- var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
233
+ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
141
234
  #mastra;
142
235
  inngest;
143
236
  function;
@@ -158,11 +251,32 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
158
251
  const storage = this.#mastra?.getStorage();
159
252
  if (!storage) {
160
253
  this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
161
- return null;
254
+ return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
162
255
  }
163
256
  const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
164
257
  return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
165
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
+ }
166
280
  __registerMastra(mastra) {
167
281
  this.#mastra = mastra;
168
282
  this.executionEngine.__registerMastra(mastra);
@@ -189,6 +303,7 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
189
303
  runId: runIdToUse,
190
304
  executionEngine: this.executionEngine,
191
305
  executionGraph: this.executionGraph,
306
+ serializedStepGraph: this.serializedStepGraph,
192
307
  mastra: this.#mastra,
193
308
  retryConfig: this.retryConfig,
194
309
  cleanup: () => this.runs.delete(runIdToUse)
@@ -198,13 +313,55 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
198
313
  this.runs.set(runIdToUse, run);
199
314
  return run;
200
315
  }
316
+ async createRunAsync(options) {
317
+ const runIdToUse = options?.runId || crypto.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
+ }
201
354
  getFunction() {
202
355
  if (this.function) {
203
356
  return this.function;
204
357
  }
205
358
  this.function = this.inngest.createFunction(
206
- // @ts-ignore
207
- { 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
+ },
208
365
  { event: `workflow.${this.id}` },
209
366
  async ({ event, step, attempt, publish }) => {
210
367
  let { inputData, runId, resume } = event.data;
@@ -221,12 +378,18 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
221
378
  try {
222
379
  await publish({
223
380
  channel: `workflow:${this.id}:${runId}`,
224
- topic: "watch",
381
+ topic: event2,
225
382
  data
226
383
  });
227
384
  } catch (err) {
228
385
  this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
229
386
  }
387
+ },
388
+ on: (_event, _callback) => {
389
+ },
390
+ off: (_event, _callback) => {
391
+ },
392
+ once: (_event, _callback) => {
230
393
  }
231
394
  };
232
395
  const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
@@ -234,12 +397,14 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
234
397
  workflowId: this.id,
235
398
  runId,
236
399
  graph: this.executionGraph,
400
+ serializedStepGraph: this.serializedStepGraph,
237
401
  input: inputData,
238
402
  emitter,
239
403
  retryConfig: this.retryConfig,
240
404
  runtimeContext: new di.RuntimeContext(),
241
405
  // TODO
242
- resume
406
+ resume,
407
+ abortController: new AbortController()
243
408
  });
244
409
  return { result, runId };
245
410
  }
@@ -263,32 +428,141 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
263
428
  return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
264
429
  }
265
430
  };
266
- function cloneWorkflow(workflow, opts) {
267
- const wf = new InngestWorkflow(
268
- {
269
- id: opts.id,
270
- inputSchema: workflow.inputSchema,
271
- outputSchema: workflow.outputSchema,
272
- steps: workflow.stepDefs,
273
- mastra: workflow.mastra
274
- },
275
- workflow.inngest
276
- );
277
- wf.setStepFlow(workflow.stepGraph);
278
- wf.commit();
279
- return wf;
431
+ function isAgent(params) {
432
+ return params?.component === "AGENT";
433
+ }
434
+ function isTool(params) {
435
+ return params instanceof tools.Tool;
436
+ }
437
+ function createStep(params) {
438
+ if (isAgent(params)) {
439
+ return {
440
+ id: params.name,
441
+ // @ts-ignore
442
+ inputSchema: zod.z.object({
443
+ prompt: zod.z.string()
444
+ // resourceId: z.string().optional(),
445
+ // threadId: z.string().optional(),
446
+ }),
447
+ // @ts-ignore
448
+ outputSchema: zod.z.object({
449
+ text: zod.z.string()
450
+ }),
451
+ execute: async ({ inputData, [_constants.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
+ };
280
535
  }
281
536
  function init(inngest) {
282
537
  return {
283
538
  createWorkflow(params) {
284
539
  return new InngestWorkflow(params, inngest);
285
540
  },
286
- createStep: vNext.createStep,
287
- cloneStep: vNext.cloneStep,
288
- cloneWorkflow
541
+ createStep,
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 workflows.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
+ }
289
563
  };
290
564
  }
291
- var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
565
+ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
292
566
  inngestStep;
293
567
  inngestAttempts;
294
568
  constructor(mastra, inngestStep, inngestAttempts = 0) {
@@ -296,6 +570,18 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
296
570
  this.inngestStep = inngestStep;
297
571
  this.inngestAttempts = inngestAttempts;
298
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
+ }
299
585
  async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
300
586
  const base = {
301
587
  status: lastOutput.status,
@@ -362,6 +648,7 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
362
648
  resume,
363
649
  prevOutput,
364
650
  emitter,
651
+ abortController,
365
652
  runtimeContext
366
653
  }) {
367
654
  return super.executeStep({
@@ -373,9 +660,23 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
373
660
  resume,
374
661
  prevOutput,
375
662
  emitter,
663
+ abortController,
376
664
  runtimeContext
377
665
  });
378
666
  }
667
+ async executeSleep({ id, duration }) {
668
+ await this.inngestStep.sleep(id, duration);
669
+ }
670
+ async executeWaitForEvent({ event, timeout }) {
671
+ const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
672
+ event: `user-event-${event}`,
673
+ timeout: timeout ?? 5e3
674
+ });
675
+ if (eventData === null) {
676
+ throw "Timeout waiting for event";
677
+ }
678
+ return eventData?.data;
679
+ }
379
680
  async executeStep({
380
681
  step,
381
682
  stepResults,
@@ -383,11 +684,13 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
383
684
  resume,
384
685
  prevOutput,
385
686
  emitter,
687
+ abortController,
386
688
  runtimeContext
387
689
  }) {
388
- await this.inngestStep.run(
690
+ const startedAt = await this.inngestStep.run(
389
691
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
390
692
  async () => {
693
+ const startedAt2 = Date.now();
391
694
  await emitter.emit("watch", {
392
695
  type: "watch",
393
696
  payload: {
@@ -409,6 +712,14 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
409
712
  },
410
713
  eventTimestamp: Date.now()
411
714
  });
715
+ await emitter.emit("watch-v2", {
716
+ type: "step-start",
717
+ payload: {
718
+ id: step.id,
719
+ status: "running"
720
+ }
721
+ });
722
+ return startedAt2;
412
723
  }
413
724
  );
414
725
  if (step instanceof InngestWorkflow) {
@@ -469,6 +780,15 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
469
780
  },
470
781
  eventTimestamp: Date.now()
471
782
  });
783
+ await emitter.emit("watch-v2", {
784
+ type: "step-result",
785
+ payload: {
786
+ id: step.id,
787
+ status: "failed",
788
+ error: result?.error,
789
+ payload: prevOutput
790
+ }
791
+ });
472
792
  return { executionContext, result: { status: "failed", error: result?.error } };
473
793
  } else if (result.status === "suspended") {
474
794
  const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
@@ -495,6 +815,13 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
495
815
  },
496
816
  eventTimestamp: Date.now()
497
817
  });
818
+ await emitter.emit("watch-v2", {
819
+ type: "step-suspended",
820
+ payload: {
821
+ id: step.id,
822
+ status: "suspended"
823
+ }
824
+ });
498
825
  return {
499
826
  executionContext,
500
827
  result: {
@@ -545,6 +872,21 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
545
872
  },
546
873
  eventTimestamp: Date.now()
547
874
  });
875
+ await emitter.emit("watch-v2", {
876
+ type: "step-result",
877
+ payload: {
878
+ id: step.id,
879
+ status: "success",
880
+ output: result?.result
881
+ }
882
+ });
883
+ await emitter.emit("watch-v2", {
884
+ type: "step-finish",
885
+ payload: {
886
+ id: step.id,
887
+ metadata: {}
888
+ }
889
+ });
548
890
  return { executionContext, result: { status: "success", output: result?.result } };
549
891
  }
550
892
  );
@@ -554,8 +896,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
554
896
  const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
555
897
  let execResults;
556
898
  let suspended;
899
+ let bailed;
557
900
  try {
558
901
  const result = await step.execute({
902
+ runId: executionContext.runId,
559
903
  mastra: this.mastra,
560
904
  runtimeContext,
561
905
  inputData: prevOutput,
@@ -572,20 +916,54 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
572
916
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
573
917
  suspended = { payload: suspendPayload };
574
918
  },
919
+ bail: (result2) => {
920
+ bailed = { payload: result2 };
921
+ },
575
922
  resume: {
576
923
  steps: resume?.steps?.slice(1) || [],
577
924
  resumePayload: resume?.resumePayload,
578
925
  // @ts-ignore
579
926
  runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
580
927
  },
581
- emitter
928
+ [_constants.EMITTER_SYMBOL]: emitter,
929
+ engine: {
930
+ step: this.inngestStep
931
+ },
932
+ abortSignal: abortController.signal
582
933
  });
583
- execResults = { status: "success", output: result };
934
+ const endedAt = Date.now();
935
+ execResults = {
936
+ status: "success",
937
+ output: result,
938
+ startedAt,
939
+ endedAt,
940
+ payload: prevOutput,
941
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
942
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
943
+ };
584
944
  } catch (e) {
585
- execResults = { status: "failed", error: e instanceof Error ? e.message : String(e) };
945
+ execResults = {
946
+ status: "failed",
947
+ payload: prevOutput,
948
+ error: e instanceof Error ? e.message : String(e),
949
+ endedAt: Date.now(),
950
+ startedAt,
951
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
952
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
953
+ };
586
954
  }
587
955
  if (suspended) {
588
- execResults = { status: "suspended", payload: suspended.payload };
956
+ execResults = {
957
+ status: "suspended",
958
+ suspendedPayload: suspended.payload,
959
+ payload: prevOutput,
960
+ suspendedAt: Date.now(),
961
+ startedAt,
962
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
963
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
964
+ };
965
+ } else if (bailed) {
966
+ execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
589
967
  }
590
968
  if (execResults.status === "failed") {
591
969
  if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
@@ -597,18 +975,41 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
597
975
  payload: {
598
976
  currentStep: {
599
977
  id: step.id,
600
- status: execResults.status,
601
- output: execResults.output
978
+ ...execResults
602
979
  },
603
980
  workflowState: {
604
981
  status: "running",
605
- steps: stepResults,
982
+ steps: { ...stepResults, [step.id]: execResults },
606
983
  result: null,
607
984
  error: null
608
985
  }
609
986
  },
610
987
  eventTimestamp: Date.now()
611
988
  });
989
+ if (execResults.status === "suspended") {
990
+ await emitter.emit("watch-v2", {
991
+ type: "step-suspended",
992
+ payload: {
993
+ id: step.id,
994
+ ...execResults
995
+ }
996
+ });
997
+ } else {
998
+ await emitter.emit("watch-v2", {
999
+ type: "step-result",
1000
+ payload: {
1001
+ id: step.id,
1002
+ ...execResults
1003
+ }
1004
+ });
1005
+ await emitter.emit("watch-v2", {
1006
+ type: "step-finish",
1007
+ payload: {
1008
+ id: step.id,
1009
+ metadata: {}
1010
+ }
1011
+ });
1012
+ }
612
1013
  return { result: execResults, executionContext, stepResults };
613
1014
  });
614
1015
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
@@ -619,7 +1020,11 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
619
1020
  workflowId,
620
1021
  runId,
621
1022
  stepResults,
622
- executionContext
1023
+ executionContext,
1024
+ serializedStepGraph,
1025
+ workflowStatus,
1026
+ result,
1027
+ error
623
1028
  }) {
624
1029
  await this.inngestStep.run(
625
1030
  `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
@@ -633,6 +1038,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
633
1038
  context: stepResults,
634
1039
  activePaths: [],
635
1040
  suspendedPaths: executionContext.suspendedPaths,
1041
+ serializedStepGraph,
1042
+ status: workflowStatus,
1043
+ result,
1044
+ error,
636
1045
  // @ts-ignore
637
1046
  timestamp: Date.now()
638
1047
  }
@@ -647,9 +1056,11 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
647
1056
  prevOutput,
648
1057
  prevStep,
649
1058
  stepResults,
1059
+ serializedStepGraph,
650
1060
  resume,
651
1061
  executionContext,
652
1062
  emitter,
1063
+ abortController,
653
1064
  runtimeContext
654
1065
  }) {
655
1066
  let execResults;
@@ -658,8 +1069,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
658
1069
  (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
659
1070
  try {
660
1071
  const result = await cond({
1072
+ runId,
661
1073
  mastra: this.mastra,
662
1074
  runtimeContext,
1075
+ runCount: -1,
663
1076
  inputData: prevOutput,
664
1077
  getInitData: () => stepResults?.input,
665
1078
  getStepResult: (step) => {
@@ -675,7 +1088,16 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
675
1088
  // TODO: this function shouldn't have suspend probably?
676
1089
  suspend: async (_suspendPayload) => {
677
1090
  },
678
- emitter
1091
+ bail: () => {
1092
+ },
1093
+ abort: () => {
1094
+ abortController.abort();
1095
+ },
1096
+ [_constants.EMITTER_SYMBOL]: emitter,
1097
+ engine: {
1098
+ step: this.inngestStep
1099
+ },
1100
+ abortSignal: abortController.signal
679
1101
  });
680
1102
  return result ? index : null;
681
1103
  } catch (e) {
@@ -694,6 +1116,7 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
694
1116
  prevStep,
695
1117
  stepResults,
696
1118
  resume,
1119
+ serializedStepGraph,
697
1120
  executionContext: {
698
1121
  workflowId,
699
1122
  runId,
@@ -703,21 +1126,22 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
703
1126
  executionSpan: executionContext.executionSpan
704
1127
  },
705
1128
  emitter,
1129
+ abortController,
706
1130
  runtimeContext
707
1131
  })
708
1132
  )
709
1133
  );
710
- const hasFailed = results.find((result) => result.status === "failed");
711
- const hasSuspended = results.find((result) => result.status === "suspended");
1134
+ const hasFailed = results.find((result) => result.result.status === "failed");
1135
+ const hasSuspended = results.find((result) => result.result.status === "suspended");
712
1136
  if (hasFailed) {
713
- execResults = { status: "failed", error: hasFailed.error };
1137
+ execResults = { status: "failed", error: hasFailed.result.error };
714
1138
  } else if (hasSuspended) {
715
- execResults = { status: "suspended", payload: hasSuspended.payload };
1139
+ execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
716
1140
  } else {
717
1141
  execResults = {
718
1142
  status: "success",
719
1143
  output: results.reduce((acc, result, index) => {
720
- if (result.status === "success") {
1144
+ if (result.result.status === "success") {
721
1145
  acc[stepsToRun[index].step.id] = result.output;
722
1146
  }
723
1147
  return acc;
@@ -731,5 +1155,6 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
731
1155
  exports.InngestExecutionEngine = InngestExecutionEngine;
732
1156
  exports.InngestRun = InngestRun;
733
1157
  exports.InngestWorkflow = InngestWorkflow;
1158
+ exports.createStep = createStep;
734
1159
  exports.init = init;
735
1160
  exports.serve = serve;