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