@mastra/inngest 0.0.0-generate-message-id-20250512171942 → 0.0.0-http-transporter-20250702160118

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