@mastra/inngest 0.0.0-cloud-deployer-for-core-0.19.1-20251001164939 → 0.0.0-cloud-storage-adapter-20251106204059

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,10 +1,13 @@
1
1
  import { randomUUID } from 'crypto';
2
+ import { ReadableStream } from 'stream/web';
2
3
  import { subscribe } from '@inngest/realtime';
3
- import { wrapMastra, AISpanType } from '@mastra/core/ai-tracing';
4
- import { RuntimeContext } from '@mastra/core/di';
4
+ import { RequestContext } from '@mastra/core/di';
5
+ import { wrapMastra, SpanType } from '@mastra/core/observability';
6
+ import { ChunkFrom, WorkflowRunOutput } from '@mastra/core/stream';
5
7
  import { ToolStream, Tool } from '@mastra/core/tools';
6
- import { Run, Workflow, DefaultExecutionEngine, getStepResult, validateStepInput } from '@mastra/core/workflows';
8
+ import { Run, Workflow, DefaultExecutionEngine, createDeprecationProxy, getStepResult, runCountDeprecationMessage, validateStepInput } from '@mastra/core/workflows';
7
9
  import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
10
+ import { NonRetriableError, RetryAfterError } from 'inngest';
8
11
  import { serve as serve$1 } from 'inngest/hono';
9
12
  import { z } from 'zod';
10
13
 
@@ -15,7 +18,7 @@ function serve({
15
18
  functions: userFunctions = [],
16
19
  registerOptions
17
20
  }) {
18
- const wfs = mastra.getWorkflows();
21
+ const wfs = mastra.listWorkflows();
19
22
  const workflowFunctions = Array.from(
20
23
  new Set(
21
24
  Object.values(wfs).flatMap((wf) => {
@@ -54,13 +57,21 @@ var InngestRun = class extends Run {
54
57
  }
55
58
  async getRunOutput(eventId) {
56
59
  let runs = await this.getRuns(eventId);
60
+ const storage = this.#mastra?.getStorage();
57
61
  while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
58
62
  await new Promise((resolve) => setTimeout(resolve, 1e3));
59
63
  runs = await this.getRuns(eventId);
60
64
  if (runs?.[0]?.status === "Failed") {
61
- throw new Error(`Function run ${runs?.[0]?.status}`);
62
- } else if (runs?.[0]?.status === "Cancelled") {
63
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
65
+ const snapshot = await storage?.loadWorkflowSnapshot({
66
+ workflowName: this.workflowId,
67
+ runId: this.runId
68
+ });
69
+ return {
70
+ output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
71
+ };
72
+ }
73
+ if (runs?.[0]?.status === "Cancelled") {
74
+ const snapshot = await storage?.loadWorkflowSnapshot({
64
75
  workflowName: this.workflowId,
65
76
  runId: this.runId
66
77
  });
@@ -69,25 +80,20 @@ var InngestRun = class extends Run {
69
80
  }
70
81
  return runs?.[0];
71
82
  }
72
- async sendEvent(event, data) {
73
- await this.inngest.send({
74
- name: `user-event-${event}`,
75
- data
76
- });
77
- }
78
83
  async cancel() {
84
+ const storage = this.#mastra?.getStorage();
79
85
  await this.inngest.send({
80
86
  name: `cancel.workflow.${this.workflowId}`,
81
87
  data: {
82
88
  runId: this.runId
83
89
  }
84
90
  });
85
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
91
+ const snapshot = await storage?.loadWorkflowSnapshot({
86
92
  workflowName: this.workflowId,
87
93
  runId: this.runId
88
94
  });
89
95
  if (snapshot) {
90
- await this.#mastra?.storage?.persistWorkflowSnapshot({
96
+ await storage?.persistWorkflowSnapshot({
91
97
  workflowName: this.workflowId,
92
98
  runId: this.runId,
93
99
  resourceId: this.resourceId,
@@ -98,8 +104,15 @@ var InngestRun = class extends Run {
98
104
  });
99
105
  }
100
106
  }
101
- async start({
102
- inputData
107
+ async start(params) {
108
+ return this._start(params);
109
+ }
110
+ async _start({
111
+ inputData,
112
+ initialState,
113
+ outputOptions,
114
+ tracingOptions,
115
+ format
103
116
  }) {
104
117
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
105
118
  workflowName: this.workflowId,
@@ -112,18 +125,24 @@ var InngestRun = class extends Run {
112
125
  context: {},
113
126
  activePaths: [],
114
127
  suspendedPaths: {},
128
+ resumeLabels: {},
115
129
  waitingPaths: {},
116
130
  timestamp: Date.now(),
117
131
  status: "running"
118
132
  }
119
133
  });
120
134
  const inputDataToUse = await this._validateInput(inputData);
135
+ const initialStateToUse = await this._validateInitialState(initialState ?? {});
121
136
  const eventOutput = await this.inngest.send({
122
137
  name: `workflow.${this.workflowId}`,
123
138
  data: {
124
139
  inputData: inputDataToUse,
140
+ initialState: initialStateToUse,
125
141
  runId: this.runId,
126
- resourceId: this.resourceId
142
+ resourceId: this.resourceId,
143
+ outputOptions,
144
+ tracingOptions,
145
+ format
127
146
  }
128
147
  });
129
148
  const eventId = eventOutput.ids[0];
@@ -152,10 +171,11 @@ var InngestRun = class extends Run {
152
171
  return p;
153
172
  }
154
173
  async _resume(params) {
174
+ const storage = this.#mastra?.getStorage();
155
175
  const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
156
176
  (step) => typeof step === "string" ? step : step?.id
157
177
  );
158
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
178
+ const snapshot = await storage?.loadWorkflowSnapshot({
159
179
  workflowName: this.workflowId,
160
180
  runId: this.runId
161
181
  });
@@ -165,6 +185,7 @@ var InngestRun = class extends Run {
165
185
  name: `workflow.${this.workflowId}`,
166
186
  data: {
167
187
  inputData: resumeDataToUse,
188
+ initialState: snapshot?.value ?? {},
168
189
  runId: this.runId,
169
190
  workflowId: this.workflowId,
170
191
  stepResults: snapshot?.context,
@@ -188,12 +209,12 @@ var InngestRun = class extends Run {
188
209
  }
189
210
  return result;
190
211
  }
191
- watch(cb, type = "watch") {
212
+ watch(cb) {
192
213
  let active = true;
193
214
  const streamPromise = subscribe(
194
215
  {
195
216
  channel: `workflow:${this.workflowId}:${this.runId}`,
196
- topics: [type],
217
+ topics: ["watch"],
197
218
  app: this.inngest
198
219
  },
199
220
  (message) => {
@@ -211,20 +232,35 @@ var InngestRun = class extends Run {
211
232
  });
212
233
  };
213
234
  }
214
- stream({ inputData, runtimeContext } = {}) {
235
+ streamLegacy({ inputData, requestContext } = {}) {
215
236
  const { readable, writable } = new TransformStream();
216
237
  const writer = writable.getWriter();
217
238
  const unwatch = this.watch(async (event) => {
218
239
  try {
240
+ await writer.write({
241
+ // @ts-ignore
242
+ type: "start",
243
+ // @ts-ignore
244
+ payload: { runId: this.runId }
245
+ });
219
246
  const e = {
220
247
  ...event,
221
248
  type: event.type.replace("workflow-", "")
222
249
  };
250
+ if (e.type === "step-output") {
251
+ e.type = e.payload.output.type;
252
+ e.payload = e.payload.output.payload;
253
+ }
223
254
  await writer.write(e);
224
255
  } catch {
225
256
  }
226
- }, "watch-v2");
257
+ });
227
258
  this.closeStreamAction = async () => {
259
+ await writer.write({
260
+ type: "finish",
261
+ // @ts-ignore
262
+ payload: { runId: this.runId }
263
+ });
228
264
  unwatch();
229
265
  try {
230
266
  await writer.close();
@@ -234,7 +270,7 @@ var InngestRun = class extends Run {
234
270
  writer.releaseLock();
235
271
  }
236
272
  };
237
- this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
273
+ this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
238
274
  if (result.status !== "suspended") {
239
275
  this.closeStreamAction?.().catch(() => {
240
276
  });
@@ -246,6 +282,82 @@ var InngestRun = class extends Run {
246
282
  getWorkflowState: () => this.executionResults
247
283
  };
248
284
  }
285
+ stream({
286
+ inputData,
287
+ requestContext,
288
+ tracingOptions,
289
+ closeOnSuspend = true,
290
+ initialState,
291
+ outputOptions
292
+ } = {}) {
293
+ if (this.closeStreamAction && this.streamOutput) {
294
+ return this.streamOutput;
295
+ }
296
+ this.closeStreamAction = async () => {
297
+ };
298
+ const self = this;
299
+ const stream = new ReadableStream({
300
+ async start(controller) {
301
+ const unwatch = self.watch(async ({ type, from = ChunkFrom.WORKFLOW, payload }) => {
302
+ controller.enqueue({
303
+ type,
304
+ runId: self.runId,
305
+ from,
306
+ payload: {
307
+ stepName: payload?.id,
308
+ ...payload
309
+ }
310
+ });
311
+ });
312
+ self.closeStreamAction = async () => {
313
+ unwatch();
314
+ try {
315
+ await controller.close();
316
+ } catch (err) {
317
+ console.error("Error closing stream:", err);
318
+ }
319
+ };
320
+ const executionResultsPromise = self._start({
321
+ inputData,
322
+ requestContext,
323
+ // tracingContext, // We are not able to pass a reference to a span here, what to do?
324
+ initialState,
325
+ tracingOptions,
326
+ outputOptions,
327
+ format: "vnext"
328
+ });
329
+ let executionResults;
330
+ try {
331
+ executionResults = await executionResultsPromise;
332
+ if (closeOnSuspend) {
333
+ self.closeStreamAction?.().catch(() => {
334
+ });
335
+ } else if (executionResults.status !== "suspended") {
336
+ self.closeStreamAction?.().catch(() => {
337
+ });
338
+ }
339
+ if (self.streamOutput) {
340
+ self.streamOutput.updateResults(
341
+ executionResults
342
+ );
343
+ }
344
+ } catch (err) {
345
+ self.streamOutput?.rejectResults(err);
346
+ self.closeStreamAction?.().catch(() => {
347
+ });
348
+ }
349
+ }
350
+ });
351
+ this.streamOutput = new WorkflowRunOutput({
352
+ runId: this.runId,
353
+ workflowId: this.workflowId,
354
+ stream
355
+ });
356
+ return this.streamOutput;
357
+ }
358
+ streamVNext(args = {}) {
359
+ return this.stream(args);
360
+ }
249
361
  };
250
362
  var InngestWorkflow = class _InngestWorkflow extends Workflow {
251
363
  #mastra;
@@ -262,13 +374,13 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
262
374
  this.#mastra = params.mastra;
263
375
  this.inngest = inngest;
264
376
  }
265
- async getWorkflowRuns(args) {
377
+ async listWorkflowRuns(args) {
266
378
  const storage = this.#mastra?.getStorage();
267
379
  if (!storage) {
268
380
  this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
269
381
  return { runs: [], total: 0 };
270
382
  }
271
- return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
383
+ return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
272
384
  }
273
385
  async getWorkflowRunById(runId) {
274
386
  const storage = this.#mastra?.getStorage();
@@ -297,16 +409,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
297
409
  }
298
410
  }
299
411
  }
300
- /**
301
- * @deprecated Use createRunAsync() instead.
302
- * @throws {Error} Always throws an error directing users to use createRunAsync()
303
- */
304
- createRun(_options) {
305
- throw new Error(
306
- "createRun() has been deprecated. Please use createRunAsync() instead.\n\nMigration guide:\n Before: const run = workflow.createRun();\n After: const run = await workflow.createRunAsync();\n\nNote: createRunAsync() is an async method, so make sure your calling function is async."
307
- );
308
- }
309
- async createRunAsync(options) {
412
+ async createRun(options) {
310
413
  const runIdToUse = options?.runId || randomUUID();
311
414
  const run = this.runs.get(runIdToUse) ?? new InngestRun(
312
415
  {
@@ -324,8 +427,12 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
324
427
  this.inngest
325
428
  );
326
429
  this.runs.set(runIdToUse, run);
430
+ const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
431
+ workflowStatus: run.workflowRunStatus,
432
+ stepResults: {}
433
+ });
327
434
  const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
328
- if (!workflowSnapshotInStorage) {
435
+ if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
329
436
  await this.mastra?.getStorage()?.persistWorkflowSnapshot({
330
437
  workflowName: this.id,
331
438
  runId: runIdToUse,
@@ -339,6 +446,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
339
446
  waitingPaths: {},
340
447
  serializedStepGraph: this.serializedStepGraph,
341
448
  suspendedPaths: {},
449
+ resumeLabels: {},
342
450
  result: void 0,
343
451
  error: void 0,
344
452
  // @ts-ignore
@@ -363,7 +471,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
363
471
  },
364
472
  { event: `workflow.${this.id}` },
365
473
  async ({ event, step, attempt, publish }) => {
366
- let { inputData, runId, resourceId, resume } = event.data;
474
+ let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
367
475
  if (!runId) {
368
476
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
369
477
  return randomUUID();
@@ -391,7 +499,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
391
499
  once: (_event, _callback) => {
392
500
  }
393
501
  };
394
- const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
502
+ const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
395
503
  const result = await engine.execute({
396
504
  workflowId: this.id,
397
505
  runId,
@@ -399,14 +507,30 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
399
507
  graph: this.executionGraph,
400
508
  serializedStepGraph: this.serializedStepGraph,
401
509
  input: inputData,
510
+ initialState,
402
511
  emitter,
403
512
  retryConfig: this.retryConfig,
404
- runtimeContext: new RuntimeContext(),
513
+ requestContext: new RequestContext(),
405
514
  // TODO
406
515
  resume,
516
+ format,
407
517
  abortController: new AbortController(),
408
- currentSpan: void 0
409
- // TODO: Pass actual parent AI span from workflow execution context
518
+ // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
519
+ outputOptions,
520
+ writableStream: new WritableStream({
521
+ write(chunk) {
522
+ void emitter.emit("watch", chunk).catch(() => {
523
+ });
524
+ }
525
+ })
526
+ });
527
+ await step.run(`workflow.${this.id}.finalize`, async () => {
528
+ if (result.status === "failed") {
529
+ throw new NonRetriableError(`Workflow failed`, {
530
+ cause: result
531
+ });
532
+ }
533
+ return result;
410
534
  });
411
535
  return { result, runId };
412
536
  }
@@ -436,7 +560,7 @@ function isAgent(params) {
436
560
  function isTool(params) {
437
561
  return params instanceof Tool;
438
562
  }
439
- function createStep(params) {
563
+ function createStep(params, agentOptions) {
440
564
  if (isAgent(params)) {
441
565
  return {
442
566
  id: params.name,
@@ -444,12 +568,23 @@ function createStep(params) {
444
568
  // @ts-ignore
445
569
  inputSchema: z.object({
446
570
  prompt: z.string()
571
+ // resourceId: z.string().optional(),
572
+ // threadId: z.string().optional(),
447
573
  }),
448
574
  // @ts-ignore
449
575
  outputSchema: z.object({
450
576
  text: z.string()
451
577
  }),
452
- execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
578
+ execute: async ({
579
+ inputData,
580
+ [EMITTER_SYMBOL]: emitter,
581
+ [STREAM_FORMAT_SYMBOL]: streamFormat,
582
+ requestContext,
583
+ tracingContext,
584
+ abortSignal,
585
+ abort,
586
+ writer
587
+ }) => {
453
588
  let streamPromise = {};
454
589
  streamPromise.promise = new Promise((resolve, reject) => {
455
590
  streamPromise.resolve = resolve;
@@ -459,34 +594,60 @@ function createStep(params) {
459
594
  name: params.name,
460
595
  args: inputData
461
596
  };
462
- const { fullStream } = await params.stream(inputData.prompt, {
463
- runtimeContext,
464
- tracingContext,
465
- onFinish: (result) => {
466
- streamPromise.resolve(result.text);
467
- },
468
- abortSignal
469
- });
470
- if (abortSignal.aborted) {
471
- return abort();
597
+ let stream;
598
+ if ((await params.getModel()).specificationVersion === "v1") {
599
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
600
+ ...agentOptions ?? {},
601
+ // resourceId: inputData.resourceId,
602
+ // threadId: inputData.threadId,
603
+ requestContext,
604
+ tracingContext,
605
+ onFinish: (result) => {
606
+ streamPromise.resolve(result.text);
607
+ void agentOptions?.onFinish?.(result);
608
+ },
609
+ abortSignal
610
+ });
611
+ stream = fullStream;
612
+ } else {
613
+ const modelOutput = await params.stream(inputData.prompt, {
614
+ ...agentOptions ?? {},
615
+ requestContext,
616
+ tracingContext,
617
+ onFinish: (result) => {
618
+ streamPromise.resolve(result.text);
619
+ void agentOptions?.onFinish?.(result);
620
+ },
621
+ abortSignal
622
+ });
623
+ stream = modelOutput.fullStream;
472
624
  }
473
- await emitter.emit("watch-v2", {
474
- type: "tool-call-streaming-start",
475
- ...toolData ?? {}
476
- });
477
- for await (const chunk of fullStream) {
478
- if (chunk.type === "text-delta") {
479
- await emitter.emit("watch-v2", {
480
- type: "tool-call-delta",
481
- ...toolData ?? {},
482
- argsTextDelta: chunk.textDelta
483
- });
625
+ if (streamFormat === "legacy") {
626
+ await emitter.emit("watch", {
627
+ type: "tool-call-streaming-start",
628
+ ...toolData ?? {}
629
+ });
630
+ for await (const chunk of stream) {
631
+ if (chunk.type === "text-delta") {
632
+ await emitter.emit("watch", {
633
+ type: "tool-call-delta",
634
+ ...toolData ?? {},
635
+ argsTextDelta: chunk.textDelta
636
+ });
637
+ }
638
+ }
639
+ await emitter.emit("watch", {
640
+ type: "tool-call-streaming-finish",
641
+ ...toolData ?? {}
642
+ });
643
+ } else {
644
+ for await (const chunk of stream) {
645
+ await writer.write(chunk);
484
646
  }
485
647
  }
486
- await emitter.emit("watch-v2", {
487
- type: "tool-call-streaming-finish",
488
- ...toolData ?? {}
489
- });
648
+ if (abortSignal.aborted) {
649
+ return abort();
650
+ }
490
651
  return {
491
652
  text: await streamPromise.promise
492
653
  };
@@ -505,11 +666,11 @@ function createStep(params) {
505
666
  description: params.description,
506
667
  inputSchema: params.inputSchema,
507
668
  outputSchema: params.outputSchema,
508
- execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
669
+ execute: async ({ inputData, mastra, requestContext, tracingContext, suspend, resumeData }) => {
509
670
  return params.execute({
510
671
  context: inputData,
511
672
  mastra: wrapMastra(mastra, tracingContext),
512
- runtimeContext,
673
+ requestContext,
513
674
  tracingContext,
514
675
  suspend,
515
676
  resumeData
@@ -531,7 +692,10 @@ function createStep(params) {
531
692
  function init(inngest) {
532
693
  return {
533
694
  createWorkflow(params) {
534
- return new InngestWorkflow(params, inngest);
695
+ return new InngestWorkflow(
696
+ params,
697
+ inngest
698
+ );
535
699
  },
536
700
  createStep,
537
701
  cloneStep(step, opts) {
@@ -540,6 +704,9 @@ function init(inngest) {
540
704
  description: step.description,
541
705
  inputSchema: step.inputSchema,
542
706
  outputSchema: step.outputSchema,
707
+ resumeSchema: step.resumeSchema,
708
+ suspendSchema: step.suspendSchema,
709
+ stateSchema: step.stateSchema,
543
710
  execute: step.execute,
544
711
  component: step.component
545
712
  };
@@ -566,73 +733,25 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
566
733
  this.inngestStep = inngestStep;
567
734
  this.inngestAttempts = inngestAttempts;
568
735
  }
569
- async execute(params) {
570
- await params.emitter.emit("watch-v2", {
571
- type: "workflow-start",
572
- payload: { runId: params.runId }
573
- });
574
- const result = await super.execute(params);
575
- await params.emitter.emit("watch-v2", {
576
- type: "workflow-finish",
577
- payload: { runId: params.runId }
578
- });
579
- return result;
580
- }
581
- async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
736
+ async fmtReturnValue(emitter, stepResults, lastOutput, error) {
582
737
  const base = {
583
738
  status: lastOutput.status,
584
739
  steps: stepResults
585
740
  };
586
741
  if (lastOutput.status === "success") {
587
- await emitter.emit("watch", {
588
- type: "watch",
589
- payload: {
590
- workflowState: {
591
- status: lastOutput.status,
592
- steps: stepResults,
593
- result: lastOutput.output
594
- }
595
- },
596
- eventTimestamp: Date.now()
597
- });
598
742
  base.result = lastOutput.output;
599
743
  } else if (lastOutput.status === "failed") {
600
744
  base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
601
- await emitter.emit("watch", {
602
- type: "watch",
603
- payload: {
604
- workflowState: {
605
- status: lastOutput.status,
606
- steps: stepResults,
607
- result: null,
608
- error: base.error
609
- }
610
- },
611
- eventTimestamp: Date.now()
612
- });
613
745
  } else if (lastOutput.status === "suspended") {
614
- await emitter.emit("watch", {
615
- type: "watch",
616
- payload: {
617
- workflowState: {
618
- status: lastOutput.status,
619
- steps: stepResults,
620
- result: null,
621
- error: null
622
- }
623
- },
624
- eventTimestamp: Date.now()
625
- });
626
746
  const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
627
747
  if (stepResult?.status === "suspended") {
628
- const nestedPath = stepResult?.payload?.__workflow_meta?.path;
748
+ const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
629
749
  return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
630
750
  }
631
751
  return [];
632
752
  });
633
753
  base.suspended = suspendedStepIds;
634
754
  }
635
- executionSpan?.end();
636
755
  return base;
637
756
  }
638
757
  // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
@@ -646,14 +765,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
646
765
  stepResults,
647
766
  emitter,
648
767
  abortController,
649
- runtimeContext,
768
+ requestContext,
650
769
  executionContext,
651
770
  writableStream,
652
771
  tracingContext
653
772
  }) {
654
773
  let { duration, fn } = entry;
655
774
  const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
656
- type: AISpanType.WORKFLOW_SLEEP,
775
+ type: SpanType.WORKFLOW_SLEEP,
657
776
  name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
658
777
  attributes: {
659
778
  durationMs: duration,
@@ -664,41 +783,53 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
664
783
  if (fn) {
665
784
  const stepCallId = randomUUID();
666
785
  duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
667
- return await fn({
668
- runId,
669
- workflowId,
670
- mastra: this.mastra,
671
- runtimeContext,
672
- inputData: prevOutput,
673
- runCount: -1,
674
- tracingContext: {
675
- currentSpan: sleepSpan
676
- },
677
- getInitData: () => stepResults?.input,
678
- getStepResult: getStepResult.bind(this, stepResults),
679
- // TODO: this function shouldn't have suspend probably?
680
- suspend: async (_suspendPayload) => {
681
- },
682
- bail: () => {
683
- },
684
- abort: () => {
685
- abortController?.abort();
686
- },
687
- [EMITTER_SYMBOL]: emitter,
688
- // TODO: add streamVNext support
689
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
690
- engine: { step: this.inngestStep },
691
- abortSignal: abortController?.signal,
692
- writer: new ToolStream(
786
+ return await fn(
787
+ createDeprecationProxy(
693
788
  {
694
- prefix: "workflow-step",
695
- callId: stepCallId,
696
- name: "sleep",
697
- runId
789
+ runId,
790
+ workflowId,
791
+ mastra: this.mastra,
792
+ requestContext,
793
+ inputData: prevOutput,
794
+ state: executionContext.state,
795
+ setState: (state) => {
796
+ executionContext.state = state;
797
+ },
798
+ retryCount: -1,
799
+ tracingContext: {
800
+ currentSpan: sleepSpan
801
+ },
802
+ getInitData: () => stepResults?.input,
803
+ getStepResult: getStepResult.bind(this, stepResults),
804
+ // TODO: this function shouldn't have suspend probably?
805
+ suspend: async (_suspendPayload) => {
806
+ },
807
+ bail: () => {
808
+ },
809
+ abort: () => {
810
+ abortController?.abort();
811
+ },
812
+ [EMITTER_SYMBOL]: emitter,
813
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
814
+ engine: { step: this.inngestStep },
815
+ abortSignal: abortController?.signal,
816
+ writer: new ToolStream(
817
+ {
818
+ prefix: "workflow-step",
819
+ callId: stepCallId,
820
+ name: "sleep",
821
+ runId
822
+ },
823
+ writableStream
824
+ )
698
825
  },
699
- writableStream
826
+ {
827
+ paramName: "runCount",
828
+ deprecationMessage: runCountDeprecationMessage,
829
+ logger: this.logger
830
+ }
700
831
  )
701
- });
832
+ );
702
833
  });
703
834
  sleepSpan?.update({
704
835
  attributes: {
@@ -722,14 +853,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
722
853
  stepResults,
723
854
  emitter,
724
855
  abortController,
725
- runtimeContext,
856
+ requestContext,
726
857
  executionContext,
727
858
  writableStream,
728
859
  tracingContext
729
860
  }) {
730
861
  let { date, fn } = entry;
731
862
  const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
732
- type: AISpanType.WORKFLOW_SLEEP,
863
+ type: SpanType.WORKFLOW_SLEEP,
733
864
  name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
734
865
  attributes: {
735
866
  untilDate: date,
@@ -741,41 +872,53 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
741
872
  if (fn) {
742
873
  date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
743
874
  const stepCallId = randomUUID();
744
- return await fn({
745
- runId,
746
- workflowId,
747
- mastra: this.mastra,
748
- runtimeContext,
749
- inputData: prevOutput,
750
- runCount: -1,
751
- tracingContext: {
752
- currentSpan: sleepUntilSpan
753
- },
754
- getInitData: () => stepResults?.input,
755
- getStepResult: getStepResult.bind(this, stepResults),
756
- // TODO: this function shouldn't have suspend probably?
757
- suspend: async (_suspendPayload) => {
758
- },
759
- bail: () => {
760
- },
761
- abort: () => {
762
- abortController?.abort();
763
- },
764
- [EMITTER_SYMBOL]: emitter,
765
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
766
- // TODO: add streamVNext support
767
- engine: { step: this.inngestStep },
768
- abortSignal: abortController?.signal,
769
- writer: new ToolStream(
875
+ return await fn(
876
+ createDeprecationProxy(
770
877
  {
771
- prefix: "workflow-step",
772
- callId: stepCallId,
773
- name: "sleep",
774
- runId
878
+ runId,
879
+ workflowId,
880
+ mastra: this.mastra,
881
+ requestContext,
882
+ inputData: prevOutput,
883
+ state: executionContext.state,
884
+ setState: (state) => {
885
+ executionContext.state = state;
886
+ },
887
+ retryCount: -1,
888
+ tracingContext: {
889
+ currentSpan: sleepUntilSpan
890
+ },
891
+ getInitData: () => stepResults?.input,
892
+ getStepResult: getStepResult.bind(this, stepResults),
893
+ // TODO: this function shouldn't have suspend probably?
894
+ suspend: async (_suspendPayload) => {
895
+ },
896
+ bail: () => {
897
+ },
898
+ abort: () => {
899
+ abortController?.abort();
900
+ },
901
+ [EMITTER_SYMBOL]: emitter,
902
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
903
+ engine: { step: this.inngestStep },
904
+ abortSignal: abortController?.signal,
905
+ writer: new ToolStream(
906
+ {
907
+ prefix: "workflow-step",
908
+ callId: stepCallId,
909
+ name: "sleep",
910
+ runId
911
+ },
912
+ writableStream
913
+ )
775
914
  },
776
- writableStream
915
+ {
916
+ paramName: "runCount",
917
+ deprecationMessage: runCountDeprecationMessage,
918
+ logger: this.logger
919
+ }
777
920
  )
778
- });
921
+ );
779
922
  });
780
923
  if (date && !(date instanceof Date)) {
781
924
  date = new Date(date);
@@ -799,16 +942,6 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
799
942
  throw e;
800
943
  }
801
944
  }
802
- async executeWaitForEvent({ event, timeout }) {
803
- const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
804
- event: `user-event-${event}`,
805
- timeout: timeout ?? 5e3
806
- });
807
- if (eventData === null) {
808
- throw "Timeout waiting for event";
809
- }
810
- return eventData?.data;
811
- }
812
945
  async executeStep({
813
946
  step,
814
947
  stepResults,
@@ -817,14 +950,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
817
950
  prevOutput,
818
951
  emitter,
819
952
  abortController,
820
- runtimeContext,
953
+ requestContext,
821
954
  tracingContext,
822
955
  writableStream,
823
956
  disableScorers
824
957
  }) {
825
- const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
958
+ const stepSpan = tracingContext?.currentSpan?.createChildSpan({
826
959
  name: `workflow step: '${step.id}'`,
827
- type: AISpanType.WORKFLOW_STEP,
960
+ type: SpanType.WORKFLOW_STEP,
828
961
  input: prevOutput,
829
962
  attributes: {
830
963
  stepId: step.id
@@ -841,27 +974,6 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
841
974
  async () => {
842
975
  const startedAt2 = Date.now();
843
976
  await emitter.emit("watch", {
844
- type: "watch",
845
- payload: {
846
- currentStep: {
847
- id: step.id,
848
- status: "running"
849
- },
850
- workflowState: {
851
- status: "running",
852
- steps: {
853
- ...stepResults,
854
- [step.id]: {
855
- status: "running"
856
- }
857
- },
858
- result: null,
859
- error: null
860
- }
861
- },
862
- eventTimestamp: Date.now()
863
- });
864
- await emitter.emit("watch-v2", {
865
977
  type: "workflow-step-start",
866
978
  payload: {
867
979
  id: step.id,
@@ -877,61 +989,66 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
877
989
  const isResume = !!resume?.steps?.length;
878
990
  let result;
879
991
  let runId;
880
- if (isResume) {
881
- runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? randomUUID();
882
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
883
- workflowName: step.id,
884
- runId
885
- });
886
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
887
- function: step.getFunction(),
888
- data: {
889
- inputData,
890
- runId,
891
- resume: {
992
+ try {
993
+ if (isResume) {
994
+ runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
995
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
996
+ workflowName: step.id,
997
+ runId
998
+ });
999
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1000
+ function: step.getFunction(),
1001
+ data: {
1002
+ inputData,
1003
+ initialState: executionContext.state ?? snapshot?.value ?? {},
892
1004
  runId,
893
- steps: resume.steps.slice(1),
894
- stepResults: snapshot?.context,
895
- resumePayload: resume.resumePayload,
896
- // @ts-ignore
897
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1005
+ resume: {
1006
+ runId,
1007
+ steps: resume.steps.slice(1),
1008
+ stepResults: snapshot?.context,
1009
+ resumePayload: resume.resumePayload,
1010
+ // @ts-ignore
1011
+ resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1012
+ },
1013
+ outputOptions: { includeState: true }
898
1014
  }
899
- }
900
- });
901
- result = invokeResp.result;
902
- runId = invokeResp.runId;
903
- } else {
904
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
905
- function: step.getFunction(),
906
- data: {
907
- inputData
908
- }
909
- });
910
- result = invokeResp.result;
911
- runId = invokeResp.runId;
1015
+ });
1016
+ result = invokeResp.result;
1017
+ runId = invokeResp.runId;
1018
+ executionContext.state = invokeResp.result.state;
1019
+ } else {
1020
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1021
+ function: step.getFunction(),
1022
+ data: {
1023
+ inputData,
1024
+ initialState: executionContext.state ?? {},
1025
+ outputOptions: { includeState: true }
1026
+ }
1027
+ });
1028
+ result = invokeResp.result;
1029
+ runId = invokeResp.runId;
1030
+ executionContext.state = invokeResp.result.state;
1031
+ }
1032
+ } catch (e) {
1033
+ const errorCause = e?.cause;
1034
+ if (errorCause && typeof errorCause === "object") {
1035
+ result = errorCause;
1036
+ runId = errorCause.runId || randomUUID();
1037
+ } else {
1038
+ runId = randomUUID();
1039
+ result = {
1040
+ status: "failed",
1041
+ error: e instanceof Error ? e : new Error(String(e)),
1042
+ steps: {},
1043
+ input: inputData
1044
+ };
1045
+ }
912
1046
  }
913
1047
  const res = await this.inngestStep.run(
914
1048
  `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
915
1049
  async () => {
916
1050
  if (result.status === "failed") {
917
1051
  await emitter.emit("watch", {
918
- type: "watch",
919
- payload: {
920
- currentStep: {
921
- id: step.id,
922
- status: "failed",
923
- error: result?.error
924
- },
925
- workflowState: {
926
- status: "running",
927
- steps: stepResults,
928
- result: null,
929
- error: null
930
- }
931
- },
932
- eventTimestamp: Date.now()
933
- });
934
- await emitter.emit("watch-v2", {
935
1052
  type: "workflow-step-result",
936
1053
  payload: {
937
1054
  id: step.id,
@@ -947,26 +1064,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
947
1064
  return stepRes2?.status === "suspended";
948
1065
  });
949
1066
  for (const [stepName, stepResult] of suspendedSteps) {
950
- const suspendPath = [stepName, ...stepResult?.payload?.__workflow_meta?.path ?? []];
1067
+ const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
951
1068
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
952
1069
  await emitter.emit("watch", {
953
- type: "watch",
954
- payload: {
955
- currentStep: {
956
- id: step.id,
957
- status: "suspended",
958
- payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
959
- },
960
- workflowState: {
961
- status: "running",
962
- steps: stepResults,
963
- result: null,
964
- error: null
965
- }
966
- },
967
- eventTimestamp: Date.now()
968
- });
969
- await emitter.emit("watch-v2", {
970
1070
  type: "workflow-step-suspended",
971
1071
  payload: {
972
1072
  id: step.id,
@@ -977,27 +1077,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
977
1077
  executionContext,
978
1078
  result: {
979
1079
  status: "suspended",
980
- payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
1080
+ payload: stepResult.payload,
1081
+ suspendPayload: {
1082
+ ...stepResult?.suspendPayload,
1083
+ __workflow_meta: { runId, path: suspendPath }
1084
+ }
981
1085
  }
982
1086
  };
983
1087
  }
984
- await emitter.emit("watch", {
985
- type: "watch",
986
- payload: {
987
- currentStep: {
988
- id: step.id,
989
- status: "suspended",
990
- payload: {}
991
- },
992
- workflowState: {
993
- status: "running",
994
- steps: stepResults,
995
- result: null,
996
- error: null
997
- }
998
- },
999
- eventTimestamp: Date.now()
1000
- });
1001
1088
  return {
1002
1089
  executionContext,
1003
1090
  result: {
@@ -1007,23 +1094,6 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1007
1094
  };
1008
1095
  }
1009
1096
  await emitter.emit("watch", {
1010
- type: "watch",
1011
- payload: {
1012
- currentStep: {
1013
- id: step.id,
1014
- status: "success",
1015
- output: result?.result
1016
- },
1017
- workflowState: {
1018
- status: "running",
1019
- steps: stepResults,
1020
- result: null,
1021
- error: null
1022
- }
1023
- },
1024
- eventTimestamp: Date.now()
1025
- });
1026
- await emitter.emit("watch-v2", {
1027
1097
  type: "workflow-step-result",
1028
1098
  payload: {
1029
1099
  id: step.id,
@@ -1031,7 +1101,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1031
1101
  output: result?.result
1032
1102
  }
1033
1103
  });
1034
- await emitter.emit("watch-v2", {
1104
+ await emitter.emit("watch", {
1035
1105
  type: "workflow-step-finish",
1036
1106
  payload: {
1037
1107
  id: step.id,
@@ -1042,132 +1112,170 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1042
1112
  }
1043
1113
  );
1044
1114
  Object.assign(executionContext, res.executionContext);
1045
- return res.result;
1115
+ return {
1116
+ ...res.result,
1117
+ startedAt,
1118
+ endedAt: Date.now(),
1119
+ payload: inputData,
1120
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1121
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1122
+ };
1046
1123
  }
1047
- const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1048
- let execResults;
1049
- let suspended;
1050
- let bailed;
1051
- try {
1052
- if (validationError) {
1053
- throw validationError;
1124
+ const stepCallId = randomUUID();
1125
+ let stepRes;
1126
+ try {
1127
+ stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1128
+ let execResults;
1129
+ let suspended;
1130
+ let bailed;
1131
+ try {
1132
+ if (validationError) {
1133
+ throw validationError;
1134
+ }
1135
+ const result = await step.execute({
1136
+ runId: executionContext.runId,
1137
+ mastra: this.mastra,
1138
+ requestContext,
1139
+ writer: new ToolStream(
1140
+ {
1141
+ prefix: "workflow-step",
1142
+ callId: stepCallId,
1143
+ name: step.id,
1144
+ runId: executionContext.runId
1145
+ },
1146
+ writableStream
1147
+ ),
1148
+ state: executionContext?.state ?? {},
1149
+ setState: (state) => {
1150
+ executionContext.state = state;
1151
+ },
1152
+ inputData,
1153
+ resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1154
+ tracingContext: {
1155
+ currentSpan: stepSpan
1156
+ },
1157
+ getInitData: () => stepResults?.input,
1158
+ getStepResult: getStepResult.bind(this, stepResults),
1159
+ suspend: async (suspendPayload, suspendOptions) => {
1160
+ executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1161
+ if (suspendOptions?.resumeLabel) {
1162
+ const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
1163
+ for (const label of resumeLabel) {
1164
+ executionContext.resumeLabels[label] = {
1165
+ stepId: step.id,
1166
+ foreachIndex: executionContext.foreachIndex
1167
+ };
1168
+ }
1169
+ }
1170
+ suspended = { payload: suspendPayload };
1171
+ },
1172
+ bail: (result2) => {
1173
+ bailed = { payload: result2 };
1174
+ },
1175
+ resume: {
1176
+ steps: resume?.steps?.slice(1) || [],
1177
+ resumePayload: resume?.resumePayload,
1178
+ // @ts-ignore
1179
+ runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1180
+ },
1181
+ [EMITTER_SYMBOL]: emitter,
1182
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
1183
+ engine: {
1184
+ step: this.inngestStep
1185
+ },
1186
+ abortSignal: abortController.signal
1187
+ });
1188
+ const endedAt = Date.now();
1189
+ execResults = {
1190
+ status: "success",
1191
+ output: result,
1192
+ startedAt,
1193
+ endedAt,
1194
+ payload: inputData,
1195
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1196
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1197
+ };
1198
+ } catch (e) {
1199
+ const stepFailure = {
1200
+ status: "failed",
1201
+ payload: inputData,
1202
+ error: e instanceof Error ? e.message : String(e),
1203
+ endedAt: Date.now(),
1204
+ startedAt,
1205
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1206
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1207
+ };
1208
+ execResults = stepFailure;
1209
+ const fallbackErrorMessage = `Step ${step.id} failed`;
1210
+ stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1211
+ throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1212
+ cause: execResults
1213
+ });
1054
1214
  }
1055
- const result = await step.execute({
1056
- runId: executionContext.runId,
1057
- mastra: this.mastra,
1058
- runtimeContext,
1059
- writableStream,
1060
- inputData,
1061
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1062
- tracingContext: {
1063
- currentSpan: stepAISpan
1064
- },
1065
- getInitData: () => stepResults?.input,
1066
- getStepResult: getStepResult.bind(this, stepResults),
1067
- suspend: async (suspendPayload) => {
1068
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1069
- suspended = { payload: suspendPayload };
1070
- },
1071
- bail: (result2) => {
1072
- bailed = { payload: result2 };
1073
- },
1074
- resume: {
1075
- steps: resume?.steps?.slice(1) || [],
1076
- resumePayload: resume?.resumePayload,
1077
- // @ts-ignore
1078
- runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
1079
- },
1080
- [EMITTER_SYMBOL]: emitter,
1081
- engine: {
1082
- step: this.inngestStep
1083
- },
1084
- abortSignal: abortController.signal
1085
- });
1086
- const endedAt = Date.now();
1087
- execResults = {
1088
- status: "success",
1089
- output: result,
1090
- startedAt,
1091
- endedAt,
1092
- payload: inputData,
1093
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1094
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1095
- };
1096
- } catch (e) {
1097
- execResults = {
1098
- status: "failed",
1099
- payload: inputData,
1100
- error: e instanceof Error ? e.message : String(e),
1101
- endedAt: Date.now(),
1102
- startedAt,
1103
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1104
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1105
- };
1106
- }
1107
- if (suspended) {
1108
- execResults = {
1109
- status: "suspended",
1110
- suspendedPayload: suspended.payload,
1111
- payload: inputData,
1112
- suspendedAt: Date.now(),
1113
- startedAt,
1114
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1115
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1116
- };
1117
- } else if (bailed) {
1118
- execResults = { status: "bailed", output: bailed.payload, payload: inputData, endedAt: Date.now(), startedAt };
1119
- }
1120
- if (execResults.status === "failed") {
1121
- if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
1122
- const error = new Error(execResults.error);
1123
- stepAISpan?.error({ error });
1124
- throw error;
1215
+ if (suspended) {
1216
+ execResults = {
1217
+ status: "suspended",
1218
+ suspendPayload: suspended.payload,
1219
+ payload: inputData,
1220
+ suspendedAt: Date.now(),
1221
+ startedAt,
1222
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1223
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1224
+ };
1225
+ } else if (bailed) {
1226
+ execResults = {
1227
+ status: "bailed",
1228
+ output: bailed.payload,
1229
+ payload: inputData,
1230
+ endedAt: Date.now(),
1231
+ startedAt
1232
+ };
1125
1233
  }
1126
- }
1127
- await emitter.emit("watch", {
1128
- type: "watch",
1129
- payload: {
1130
- currentStep: {
1131
- id: step.id,
1132
- ...execResults
1133
- },
1134
- workflowState: {
1135
- status: "running",
1136
- steps: { ...stepResults, [step.id]: execResults },
1137
- result: null,
1138
- error: null
1139
- }
1140
- },
1141
- eventTimestamp: Date.now()
1234
+ if (execResults.status === "suspended") {
1235
+ await emitter.emit("watch", {
1236
+ type: "workflow-step-suspended",
1237
+ payload: {
1238
+ id: step.id,
1239
+ ...execResults
1240
+ }
1241
+ });
1242
+ } else {
1243
+ await emitter.emit("watch", {
1244
+ type: "workflow-step-result",
1245
+ payload: {
1246
+ id: step.id,
1247
+ ...execResults
1248
+ }
1249
+ });
1250
+ await emitter.emit("watch", {
1251
+ type: "workflow-step-finish",
1252
+ payload: {
1253
+ id: step.id,
1254
+ metadata: {}
1255
+ }
1256
+ });
1257
+ }
1258
+ stepSpan?.end({ output: execResults });
1259
+ return { result: execResults, executionContext, stepResults };
1142
1260
  });
1143
- if (execResults.status === "suspended") {
1144
- await emitter.emit("watch-v2", {
1145
- type: "workflow-step-suspended",
1146
- payload: {
1147
- id: step.id,
1148
- ...execResults
1149
- }
1150
- });
1151
- } else {
1152
- await emitter.emit("watch-v2", {
1153
- type: "workflow-step-result",
1154
- payload: {
1155
- id: step.id,
1156
- ...execResults
1157
- }
1158
- });
1159
- await emitter.emit("watch-v2", {
1160
- type: "workflow-step-finish",
1161
- payload: {
1162
- id: step.id,
1163
- metadata: {}
1164
- }
1165
- });
1166
- }
1167
- stepAISpan?.end({ output: execResults });
1168
- return { result: execResults, executionContext, stepResults };
1169
- });
1170
- if (disableScorers !== false) {
1261
+ } catch (e) {
1262
+ const stepFailure = e instanceof Error ? e?.cause : {
1263
+ status: "failed",
1264
+ error: e instanceof Error ? e.message : String(e),
1265
+ payload: inputData,
1266
+ startedAt,
1267
+ endedAt: Date.now()
1268
+ };
1269
+ stepRes = {
1270
+ result: stepFailure,
1271
+ executionContext,
1272
+ stepResults: {
1273
+ ...stepResults,
1274
+ [step.id]: stepFailure
1275
+ }
1276
+ };
1277
+ }
1278
+ if (disableScorers !== false && stepRes.result.status === "success") {
1171
1279
  await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1172
1280
  if (step.scorers) {
1173
1281
  await this.runScorers({
@@ -1177,15 +1285,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1177
1285
  output: stepRes.result,
1178
1286
  workflowId: executionContext.workflowId,
1179
1287
  stepId: step.id,
1180
- runtimeContext,
1288
+ requestContext,
1181
1289
  disableScorers,
1182
- tracingContext: { currentSpan: stepAISpan }
1290
+ tracingContext: { currentSpan: stepSpan }
1183
1291
  });
1184
1292
  }
1185
1293
  });
1186
1294
  }
1187
1295
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1188
1296
  Object.assign(stepResults, stepRes.stepResults);
1297
+ executionContext.state = stepRes.executionContext.state;
1189
1298
  return stepRes.result;
1190
1299
  }
1191
1300
  async persistStepUpdate({
@@ -1202,16 +1311,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1202
1311
  await this.inngestStep.run(
1203
1312
  `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
1204
1313
  async () => {
1314
+ const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
1315
+ if (!shouldPersistSnapshot) {
1316
+ return;
1317
+ }
1205
1318
  await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1206
1319
  workflowName: workflowId,
1207
1320
  runId,
1208
1321
  resourceId,
1209
1322
  snapshot: {
1210
1323
  runId,
1211
- value: {},
1324
+ value: executionContext.state,
1212
1325
  context: stepResults,
1213
1326
  activePaths: [],
1214
1327
  suspendedPaths: executionContext.suspendedPaths,
1328
+ resumeLabels: executionContext.resumeLabels,
1215
1329
  waitingPaths: {},
1216
1330
  serializedStepGraph,
1217
1331
  status: workflowStatus,
@@ -1229,20 +1343,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1229
1343
  runId,
1230
1344
  entry,
1231
1345
  prevOutput,
1232
- prevStep,
1233
1346
  stepResults,
1234
- serializedStepGraph,
1235
1347
  resume,
1236
1348
  executionContext,
1237
1349
  emitter,
1238
1350
  abortController,
1239
- runtimeContext,
1351
+ requestContext,
1240
1352
  writableStream,
1241
1353
  disableScorers,
1242
1354
  tracingContext
1243
1355
  }) {
1244
1356
  const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1245
- type: AISpanType.WORKFLOW_CONDITIONAL,
1357
+ type: SpanType.WORKFLOW_CONDITIONAL,
1246
1358
  name: `conditional: '${entry.conditions.length} conditions'`,
1247
1359
  input: prevOutput,
1248
1360
  attributes: {
@@ -1255,7 +1367,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1255
1367
  entry.conditions.map(
1256
1368
  (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1257
1369
  const evalSpan = conditionalSpan?.createChildSpan({
1258
- type: AISpanType.WORKFLOW_CONDITIONAL_EVAL,
1370
+ type: SpanType.WORKFLOW_CONDITIONAL_EVAL,
1259
1371
  name: `condition: '${index}'`,
1260
1372
  input: prevOutput,
1261
1373
  attributes: {
@@ -1264,43 +1376,55 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1264
1376
  tracingPolicy: this.options?.tracingPolicy
1265
1377
  });
1266
1378
  try {
1267
- const result = await cond({
1268
- runId,
1269
- workflowId,
1270
- mastra: this.mastra,
1271
- runtimeContext,
1272
- runCount: -1,
1273
- inputData: prevOutput,
1274
- tracingContext: {
1275
- currentSpan: evalSpan
1276
- },
1277
- getInitData: () => stepResults?.input,
1278
- getStepResult: getStepResult.bind(this, stepResults),
1279
- // TODO: this function shouldn't have suspend probably?
1280
- suspend: async (_suspendPayload) => {
1281
- },
1282
- bail: () => {
1283
- },
1284
- abort: () => {
1285
- abortController.abort();
1286
- },
1287
- [EMITTER_SYMBOL]: emitter,
1288
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
1289
- // TODO: add streamVNext support
1290
- engine: {
1291
- step: this.inngestStep
1292
- },
1293
- abortSignal: abortController.signal,
1294
- writer: new ToolStream(
1379
+ const result = await cond(
1380
+ createDeprecationProxy(
1295
1381
  {
1296
- prefix: "workflow-step",
1297
- callId: randomUUID(),
1298
- name: "conditional",
1299
- runId
1382
+ runId,
1383
+ workflowId,
1384
+ mastra: this.mastra,
1385
+ requestContext,
1386
+ retryCount: -1,
1387
+ inputData: prevOutput,
1388
+ state: executionContext.state,
1389
+ setState: (state) => {
1390
+ executionContext.state = state;
1391
+ },
1392
+ tracingContext: {
1393
+ currentSpan: evalSpan
1394
+ },
1395
+ getInitData: () => stepResults?.input,
1396
+ getStepResult: getStepResult.bind(this, stepResults),
1397
+ // TODO: this function shouldn't have suspend probably?
1398
+ suspend: async (_suspendPayload) => {
1399
+ },
1400
+ bail: () => {
1401
+ },
1402
+ abort: () => {
1403
+ abortController.abort();
1404
+ },
1405
+ [EMITTER_SYMBOL]: emitter,
1406
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
1407
+ engine: {
1408
+ step: this.inngestStep
1409
+ },
1410
+ abortSignal: abortController.signal,
1411
+ writer: new ToolStream(
1412
+ {
1413
+ prefix: "workflow-step",
1414
+ callId: randomUUID(),
1415
+ name: "conditional",
1416
+ runId
1417
+ },
1418
+ writableStream
1419
+ )
1300
1420
  },
1301
- writableStream
1421
+ {
1422
+ paramName: "runCount",
1423
+ deprecationMessage: runCountDeprecationMessage,
1424
+ logger: this.logger
1425
+ }
1302
1426
  )
1303
- });
1427
+ );
1304
1428
  evalSpan?.end({
1305
1429
  output: result,
1306
1430
  attributes: {
@@ -1328,13 +1452,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1328
1452
  }
1329
1453
  });
1330
1454
  const results = await Promise.all(
1331
- stepsToRun.map(
1332
- (step, index) => this.executeEntry({
1333
- workflowId,
1334
- runId,
1335
- entry: step,
1336
- serializedStepGraph,
1337
- prevStep,
1455
+ stepsToRun.map(async (step, index) => {
1456
+ const currStepResult = stepResults[step.step.id];
1457
+ if (currStepResult && currStepResult.status === "success") {
1458
+ return currStepResult;
1459
+ }
1460
+ const result = await this.executeStep({
1461
+ step: step.step,
1462
+ prevOutput,
1338
1463
  stepResults,
1339
1464
  resume,
1340
1465
  executionContext: {
@@ -1342,31 +1467,34 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1342
1467
  runId,
1343
1468
  executionPath: [...executionContext.executionPath, index],
1344
1469
  suspendedPaths: executionContext.suspendedPaths,
1470
+ resumeLabels: executionContext.resumeLabels,
1345
1471
  retryConfig: executionContext.retryConfig,
1346
- executionSpan: executionContext.executionSpan
1472
+ state: executionContext.state
1347
1473
  },
1348
1474
  emitter,
1349
1475
  abortController,
1350
- runtimeContext,
1476
+ requestContext,
1351
1477
  writableStream,
1352
1478
  disableScorers,
1353
1479
  tracingContext: {
1354
1480
  currentSpan: conditionalSpan
1355
1481
  }
1356
- })
1357
- )
1482
+ });
1483
+ stepResults[step.step.id] = result;
1484
+ return result;
1485
+ })
1358
1486
  );
1359
- const hasFailed = results.find((result) => result.result.status === "failed");
1360
- const hasSuspended = results.find((result) => result.result.status === "suspended");
1487
+ const hasFailed = results.find((result) => result.status === "failed");
1488
+ const hasSuspended = results.find((result) => result.status === "suspended");
1361
1489
  if (hasFailed) {
1362
- execResults = { status: "failed", error: hasFailed.result.error };
1490
+ execResults = { status: "failed", error: hasFailed.error };
1363
1491
  } else if (hasSuspended) {
1364
- execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
1492
+ execResults = { status: "suspended", suspendPayload: hasSuspended.suspendPayload };
1365
1493
  } else {
1366
1494
  execResults = {
1367
1495
  status: "success",
1368
1496
  output: results.reduce((acc, result, index) => {
1369
- if (result.result.status === "success") {
1497
+ if (result.status === "success") {
1370
1498
  acc[stepsToRun[index].step.id] = result.output;
1371
1499
  }
1372
1500
  return acc;