@mastra/inngest 0.0.0-remove-unused-import-20250909212718 → 0.0.0-remove-unused-model-providers-api-20251030210744

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,19 +1,27 @@
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
6
  var aiTracing = require('@mastra/core/ai-tracing');
6
7
  var di = require('@mastra/core/di');
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
 
13
16
  // src/index.ts
14
- function serve({ mastra, inngest }) {
15
- const wfs = mastra.getWorkflows();
16
- const functions = Array.from(
17
+ function serve({
18
+ mastra,
19
+ inngest,
20
+ functions: userFunctions = [],
21
+ registerOptions
22
+ }) {
23
+ const wfs = mastra.listWorkflows();
24
+ const workflowFunctions = Array.from(
17
25
  new Set(
18
26
  Object.values(wfs).flatMap((wf) => {
19
27
  if (wf instanceof InngestWorkflow) {
@@ -25,8 +33,9 @@ function serve({ mastra, inngest }) {
25
33
  )
26
34
  );
27
35
  return hono.serve({
36
+ ...registerOptions,
28
37
  client: inngest,
29
- functions
38
+ functions: [...workflowFunctions, ...userFunctions]
30
39
  });
31
40
  }
32
41
  var InngestRun = class extends workflows.Run {
@@ -54,9 +63,15 @@ var InngestRun = class extends workflows.Run {
54
63
  await new Promise((resolve) => setTimeout(resolve, 1e3));
55
64
  runs = await this.getRuns(eventId);
56
65
  if (runs?.[0]?.status === "Failed") {
57
- console.log("run", runs?.[0]);
58
- throw new Error(`Function run ${runs?.[0]?.status}`);
59
- } else if (runs?.[0]?.status === "Cancelled") {
66
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
67
+ workflowName: this.workflowId,
68
+ runId: this.runId
69
+ });
70
+ return {
71
+ output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
72
+ };
73
+ }
74
+ if (runs?.[0]?.status === "Cancelled") {
60
75
  const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
61
76
  workflowName: this.workflowId,
62
77
  runId: this.runId
@@ -87,6 +102,7 @@ var InngestRun = class extends workflows.Run {
87
102
  await this.#mastra?.storage?.persistWorkflowSnapshot({
88
103
  workflowName: this.workflowId,
89
104
  runId: this.runId,
105
+ resourceId: this.resourceId,
90
106
  snapshot: {
91
107
  ...snapshot,
92
108
  status: "canceled"
@@ -94,12 +110,20 @@ var InngestRun = class extends workflows.Run {
94
110
  });
95
111
  }
96
112
  }
97
- async start({
98
- inputData
113
+ async start(params) {
114
+ return this._start(params);
115
+ }
116
+ async _start({
117
+ inputData,
118
+ initialState,
119
+ outputOptions,
120
+ tracingOptions,
121
+ format
99
122
  }) {
100
123
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
101
124
  workflowName: this.workflowId,
102
125
  runId: this.runId,
126
+ resourceId: this.resourceId,
103
127
  snapshot: {
104
128
  runId: this.runId,
105
129
  serializedStepGraph: this.serializedStepGraph,
@@ -107,16 +131,24 @@ var InngestRun = class extends workflows.Run {
107
131
  context: {},
108
132
  activePaths: [],
109
133
  suspendedPaths: {},
134
+ resumeLabels: {},
110
135
  waitingPaths: {},
111
136
  timestamp: Date.now(),
112
137
  status: "running"
113
138
  }
114
139
  });
140
+ const inputDataToUse = await this._validateInput(inputData);
141
+ const initialStateToUse = await this._validateInitialState(initialState ?? {});
115
142
  const eventOutput = await this.inngest.send({
116
143
  name: `workflow.${this.workflowId}`,
117
144
  data: {
118
- inputData,
119
- runId: this.runId
145
+ inputData: inputDataToUse,
146
+ initialState: initialStateToUse,
147
+ runId: this.runId,
148
+ resourceId: this.resourceId,
149
+ outputOptions,
150
+ tracingOptions,
151
+ format
120
152
  }
121
153
  });
122
154
  const eventId = eventOutput.ids[0];
@@ -152,17 +184,20 @@ var InngestRun = class extends workflows.Run {
152
184
  workflowName: this.workflowId,
153
185
  runId: this.runId
154
186
  });
187
+ const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
188
+ const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
155
189
  const eventOutput = await this.inngest.send({
156
190
  name: `workflow.${this.workflowId}`,
157
191
  data: {
158
- inputData: params.resumeData,
192
+ inputData: resumeDataToUse,
193
+ initialState: snapshot?.value ?? {},
159
194
  runId: this.runId,
160
195
  workflowId: this.workflowId,
161
196
  stepResults: snapshot?.context,
162
197
  resume: {
163
198
  steps,
164
199
  stepResults: snapshot?.context,
165
- resumePayload: params.resumeData,
200
+ resumePayload: resumeDataToUse,
166
201
  // @ts-ignore
167
202
  resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
168
203
  }
@@ -202,44 +237,35 @@ var InngestRun = class extends workflows.Run {
202
237
  });
203
238
  };
204
239
  }
205
- stream({ inputData, runtimeContext } = {}) {
240
+ streamLegacy({ inputData, requestContext } = {}) {
206
241
  const { readable, writable } = new TransformStream();
207
- let currentToolData = void 0;
208
242
  const writer = writable.getWriter();
209
243
  const unwatch = this.watch(async (event) => {
210
- if (event.type === "workflow-agent-call-start") {
211
- currentToolData = {
212
- name: event.payload.name,
213
- args: event.payload.args
214
- };
244
+ try {
215
245
  await writer.write({
216
- ...event.payload,
217
- type: "tool-call-streaming-start"
246
+ // @ts-ignore
247
+ type: "start",
248
+ // @ts-ignore
249
+ payload: { runId: this.runId }
218
250
  });
219
- return;
220
- }
221
- try {
222
- if (event.type === "workflow-agent-call-finish") {
223
- return;
224
- } else if (!event.type.startsWith("workflow-")) {
225
- if (event.type === "text-delta") {
226
- await writer.write({
227
- type: "tool-call-delta",
228
- ...currentToolData ?? {},
229
- argsTextDelta: event.textDelta
230
- });
231
- }
232
- return;
233
- }
234
251
  const e = {
235
252
  ...event,
236
253
  type: event.type.replace("workflow-", "")
237
254
  };
255
+ if (e.type === "step-output") {
256
+ e.type = e.payload.output.type;
257
+ e.payload = e.payload.output.payload;
258
+ }
238
259
  await writer.write(e);
239
260
  } catch {
240
261
  }
241
262
  }, "watch-v2");
242
263
  this.closeStreamAction = async () => {
264
+ await writer.write({
265
+ type: "finish",
266
+ // @ts-ignore
267
+ payload: { runId: this.runId }
268
+ });
243
269
  unwatch();
244
270
  try {
245
271
  await writer.close();
@@ -249,7 +275,7 @@ var InngestRun = class extends workflows.Run {
249
275
  writer.releaseLock();
250
276
  }
251
277
  };
252
- this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
278
+ this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
253
279
  if (result.status !== "suspended") {
254
280
  this.closeStreamAction?.().catch(() => {
255
281
  });
@@ -261,6 +287,82 @@ var InngestRun = class extends workflows.Run {
261
287
  getWorkflowState: () => this.executionResults
262
288
  };
263
289
  }
290
+ stream({
291
+ inputData,
292
+ requestContext,
293
+ tracingOptions,
294
+ closeOnSuspend = true,
295
+ initialState,
296
+ outputOptions
297
+ } = {}) {
298
+ if (this.closeStreamAction && this.streamOutput) {
299
+ return this.streamOutput;
300
+ }
301
+ this.closeStreamAction = async () => {
302
+ };
303
+ const self = this;
304
+ const stream$1 = new web.ReadableStream({
305
+ async start(controller) {
306
+ const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
307
+ controller.enqueue({
308
+ type,
309
+ runId: self.runId,
310
+ from,
311
+ payload: {
312
+ stepName: payload?.id,
313
+ ...payload
314
+ }
315
+ });
316
+ }, "watch-v2");
317
+ self.closeStreamAction = async () => {
318
+ unwatch();
319
+ try {
320
+ await controller.close();
321
+ } catch (err) {
322
+ console.error("Error closing stream:", err);
323
+ }
324
+ };
325
+ const executionResultsPromise = self._start({
326
+ inputData,
327
+ requestContext,
328
+ // tracingContext, // We are not able to pass a reference to a span here, what to do?
329
+ initialState,
330
+ tracingOptions,
331
+ outputOptions,
332
+ format: "vnext"
333
+ });
334
+ let executionResults;
335
+ try {
336
+ executionResults = await executionResultsPromise;
337
+ if (closeOnSuspend) {
338
+ self.closeStreamAction?.().catch(() => {
339
+ });
340
+ } else if (executionResults.status !== "suspended") {
341
+ self.closeStreamAction?.().catch(() => {
342
+ });
343
+ }
344
+ if (self.streamOutput) {
345
+ self.streamOutput.updateResults(
346
+ executionResults
347
+ );
348
+ }
349
+ } catch (err) {
350
+ self.streamOutput?.rejectResults(err);
351
+ self.closeStreamAction?.().catch(() => {
352
+ });
353
+ }
354
+ }
355
+ });
356
+ this.streamOutput = new stream.WorkflowRunOutput({
357
+ runId: this.runId,
358
+ workflowId: this.workflowId,
359
+ stream: stream$1
360
+ });
361
+ return this.streamOutput;
362
+ }
363
+ streamVNext(args = {}) {
364
+ return this.stream(args);
365
+ }
264
366
  };
265
367
  var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
266
368
  #mastra;
@@ -277,13 +379,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
277
379
  this.#mastra = params.mastra;
278
380
  this.inngest = inngest;
279
381
  }
280
- async getWorkflowRuns(args) {
382
+ async listWorkflowRuns(args) {
281
383
  const storage = this.#mastra?.getStorage();
282
384
  if (!storage) {
283
385
  this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
284
386
  return { runs: [], total: 0 };
285
387
  }
286
- return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
388
+ return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
287
389
  }
288
390
  async getWorkflowRunById(runId) {
289
391
  const storage = this.#mastra?.getStorage();
@@ -312,23 +414,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
312
414
  }
313
415
  }
314
416
  }
315
- createRun(options) {
316
- const runIdToUse = options?.runId || crypto.randomUUID();
317
- const run = this.runs.get(runIdToUse) ?? new InngestRun(
318
- {
319
- workflowId: this.id,
320
- runId: runIdToUse,
321
- executionEngine: this.executionEngine,
322
- executionGraph: this.executionGraph,
323
- serializedStepGraph: this.serializedStepGraph,
324
- mastra: this.#mastra,
325
- retryConfig: this.retryConfig,
326
- cleanup: () => this.runs.delete(runIdToUse)
327
- },
328
- this.inngest
417
+ /**
418
+ * @deprecated Use createRunAsync() instead.
419
+ * @throws {Error} Always throws an error directing users to use createRunAsync()
420
+ */
421
+ createRun(_options) {
422
+ throw new Error(
423
+ "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."
329
424
  );
330
- this.runs.set(runIdToUse, run);
331
- return run;
332
425
  }
333
426
  async createRunAsync(options) {
334
427
  const runIdToUse = options?.runId || crypto.randomUUID();
@@ -336,21 +429,28 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
336
429
  {
337
430
  workflowId: this.id,
338
431
  runId: runIdToUse,
432
+ resourceId: options?.resourceId,
339
433
  executionEngine: this.executionEngine,
340
434
  executionGraph: this.executionGraph,
341
435
  serializedStepGraph: this.serializedStepGraph,
342
436
  mastra: this.#mastra,
343
437
  retryConfig: this.retryConfig,
344
- cleanup: () => this.runs.delete(runIdToUse)
438
+ cleanup: () => this.runs.delete(runIdToUse),
439
+ workflowSteps: this.steps
345
440
  },
346
441
  this.inngest
347
442
  );
348
443
  this.runs.set(runIdToUse, run);
444
+ const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
445
+ workflowStatus: run.workflowRunStatus,
446
+ stepResults: {}
447
+ });
349
448
  const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
350
- if (!workflowSnapshotInStorage) {
449
+ if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
351
450
  await this.mastra?.getStorage()?.persistWorkflowSnapshot({
352
451
  workflowName: this.id,
353
452
  runId: runIdToUse,
453
+ resourceId: options?.resourceId,
354
454
  snapshot: {
355
455
  runId: runIdToUse,
356
456
  status: "pending",
@@ -360,6 +460,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
360
460
  waitingPaths: {},
361
461
  serializedStepGraph: this.serializedStepGraph,
362
462
  suspendedPaths: {},
463
+ resumeLabels: {},
363
464
  result: void 0,
364
465
  error: void 0,
365
466
  // @ts-ignore
@@ -384,7 +485,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
384
485
  },
385
486
  { event: `workflow.${this.id}` },
386
487
  async ({ event, step, attempt, publish }) => {
387
- let { inputData, runId, resume } = event.data;
488
+ let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
388
489
  if (!runId) {
389
490
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
390
491
  return crypto.randomUUID();
@@ -412,21 +513,38 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
412
513
  once: (_event, _callback) => {
413
514
  }
414
515
  };
415
- const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
516
+ const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
416
517
  const result = await engine.execute({
417
518
  workflowId: this.id,
418
519
  runId,
520
+ resourceId,
419
521
  graph: this.executionGraph,
420
522
  serializedStepGraph: this.serializedStepGraph,
421
523
  input: inputData,
524
+ initialState,
422
525
  emitter,
423
526
  retryConfig: this.retryConfig,
424
- runtimeContext: new di.RuntimeContext(),
527
+ requestContext: new di.RequestContext(),
425
528
  // TODO
426
529
  resume,
530
+ format,
427
531
  abortController: new AbortController(),
428
- currentSpan: void 0
429
- // TODO: Pass actual parent AI span from workflow execution context
532
+ // currentSpan: undefined, // TODO: Pass actual parent AI span from workflow execution context
533
+ outputOptions,
534
+ writableStream: new WritableStream({
535
+ write(chunk) {
536
+ void emitter.emit("watch-v2", chunk).catch(() => {
537
+ });
538
+ }
539
+ })
540
+ });
541
+ await step.run(`workflow.${this.id}.finalize`, async () => {
542
+ if (result.status === "failed") {
543
+ throw new inngest.NonRetriableError(`Workflow failed`, {
544
+ cause: result
545
+ });
546
+ }
547
+ return result;
430
548
  });
431
549
  return { result, runId };
432
550
  }
@@ -456,10 +574,11 @@ function isAgent(params) {
456
574
  function isTool(params) {
457
575
  return params instanceof tools.Tool;
458
576
  }
459
- function createStep(params) {
577
+ function createStep(params, agentOptions) {
460
578
  if (isAgent(params)) {
461
579
  return {
462
580
  id: params.name,
581
+ description: params.getDescription(),
463
582
  // @ts-ignore
464
583
  inputSchema: zod.z.object({
465
584
  prompt: zod.z.string()
@@ -470,7 +589,16 @@ function createStep(params) {
470
589
  outputSchema: zod.z.object({
471
590
  text: zod.z.string()
472
591
  }),
473
- execute: async ({ inputData, [_constants.EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
592
+ execute: async ({
593
+ inputData,
594
+ [_constants.EMITTER_SYMBOL]: emitter,
595
+ [_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
596
+ requestContext,
597
+ tracingContext,
598
+ abortSignal,
599
+ abort,
600
+ writer
601
+ }) => {
474
602
  let streamPromise = {};
475
603
  streamPromise.promise = new Promise((resolve, reject) => {
476
604
  streamPromise.resolve = resolve;
@@ -480,34 +608,65 @@ function createStep(params) {
480
608
  name: params.name,
481
609
  args: inputData
482
610
  };
483
- await emitter.emit("watch-v2", {
484
- type: "workflow-agent-call-start",
485
- payload: toolData
486
- });
487
- const { fullStream } = await params.stream(inputData.prompt, {
488
- // resourceId: inputData.resourceId,
489
- // threadId: inputData.threadId,
490
- runtimeContext,
491
- tracingContext,
492
- onFinish: (result) => {
493
- streamPromise.resolve(result.text);
494
- },
495
- abortSignal
496
- });
611
+ let stream;
612
+ if ((await params.getModel()).specificationVersion === "v1") {
613
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
614
+ ...agentOptions ?? {},
615
+ // resourceId: inputData.resourceId,
616
+ // threadId: inputData.threadId,
617
+ requestContext,
618
+ tracingContext,
619
+ onFinish: (result) => {
620
+ streamPromise.resolve(result.text);
621
+ void agentOptions?.onFinish?.(result);
622
+ },
623
+ abortSignal
624
+ });
625
+ stream = fullStream;
626
+ } else {
627
+ const modelOutput = await params.stream(inputData.prompt, {
628
+ ...agentOptions ?? {},
629
+ requestContext,
630
+ tracingContext,
631
+ onFinish: (result) => {
632
+ streamPromise.resolve(result.text);
633
+ void agentOptions?.onFinish?.(result);
634
+ },
635
+ abortSignal
636
+ });
637
+ stream = modelOutput.fullStream;
638
+ }
639
+ if (streamFormat === "legacy") {
640
+ await emitter.emit("watch-v2", {
641
+ type: "tool-call-streaming-start",
642
+ ...toolData ?? {}
643
+ });
644
+ for await (const chunk of stream) {
645
+ if (chunk.type === "text-delta") {
646
+ await emitter.emit("watch-v2", {
647
+ type: "tool-call-delta",
648
+ ...toolData ?? {},
649
+ argsTextDelta: chunk.textDelta
650
+ });
651
+ }
652
+ }
653
+ await emitter.emit("watch-v2", {
654
+ type: "tool-call-streaming-finish",
655
+ ...toolData ?? {}
656
+ });
657
+ } else {
658
+ for await (const chunk of stream) {
659
+ await writer.write(chunk);
660
+ }
661
+ }
497
662
  if (abortSignal.aborted) {
498
663
  return abort();
499
664
  }
500
- for await (const chunk of fullStream) {
501
- await emitter.emit("watch-v2", chunk);
502
- }
503
- await emitter.emit("watch-v2", {
504
- type: "workflow-agent-call-finish",
505
- payload: toolData
506
- });
507
665
  return {
508
666
  text: await streamPromise.promise
509
667
  };
510
- }
668
+ },
669
+ component: params.component
511
670
  };
512
671
  }
513
672
  if (isTool(params)) {
@@ -518,16 +677,20 @@ function createStep(params) {
518
677
  // TODO: tool probably should have strong id type
519
678
  // @ts-ignore
520
679
  id: params.id,
680
+ description: params.description,
521
681
  inputSchema: params.inputSchema,
522
682
  outputSchema: params.outputSchema,
523
- execute: async ({ inputData, mastra, runtimeContext, tracingContext }) => {
683
+ execute: async ({ inputData, mastra, requestContext, tracingContext, suspend, resumeData }) => {
524
684
  return params.execute({
525
685
  context: inputData,
526
686
  mastra: aiTracing.wrapMastra(mastra, tracingContext),
527
- runtimeContext,
528
- tracingContext
687
+ requestContext,
688
+ tracingContext,
689
+ suspend,
690
+ resumeData
529
691
  });
530
- }
692
+ },
693
+ component: "TOOL"
531
694
  };
532
695
  }
533
696
  return {
@@ -543,7 +706,10 @@ function createStep(params) {
543
706
  function init(inngest) {
544
707
  return {
545
708
  createWorkflow(params) {
546
- return new InngestWorkflow(params, inngest);
709
+ return new InngestWorkflow(
710
+ params,
711
+ inngest
712
+ );
547
713
  },
548
714
  createStep,
549
715
  cloneStep(step, opts) {
@@ -552,7 +718,11 @@ function init(inngest) {
552
718
  description: step.description,
553
719
  inputSchema: step.inputSchema,
554
720
  outputSchema: step.outputSchema,
555
- execute: step.execute
721
+ resumeSchema: step.resumeSchema,
722
+ suspendSchema: step.suspendSchema,
723
+ stateSchema: step.stateSchema,
724
+ execute: step.execute,
725
+ component: step.component
556
726
  };
557
727
  },
558
728
  cloneWorkflow(workflow, opts) {
@@ -572,24 +742,12 @@ function init(inngest) {
572
742
  var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
573
743
  inngestStep;
574
744
  inngestAttempts;
575
- constructor(mastra, inngestStep, inngestAttempts = 0) {
576
- super({ mastra });
745
+ constructor(mastra, inngestStep, inngestAttempts = 0, options) {
746
+ super({ mastra, options });
577
747
  this.inngestStep = inngestStep;
578
748
  this.inngestAttempts = inngestAttempts;
579
749
  }
580
- async execute(params) {
581
- await params.emitter.emit("watch-v2", {
582
- type: "workflow-start",
583
- payload: { runId: params.runId }
584
- });
585
- const result = await super.execute(params);
586
- await params.emitter.emit("watch-v2", {
587
- type: "workflow-finish",
588
- payload: { runId: params.runId }
589
- });
590
- return result;
591
- }
592
- async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
750
+ async fmtReturnValue(emitter, stepResults, lastOutput, error) {
593
751
  const base = {
594
752
  status: lastOutput.status,
595
753
  steps: stepResults
@@ -636,14 +794,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
636
794
  });
637
795
  const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
638
796
  if (stepResult?.status === "suspended") {
639
- const nestedPath = stepResult?.payload?.__workflow_meta?.path;
797
+ const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
640
798
  return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
641
799
  }
642
800
  return [];
643
801
  });
644
802
  base.suspended = suspendedStepIds;
645
803
  }
646
- executionSpan?.end();
647
804
  return base;
648
805
  }
649
806
  // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
@@ -657,7 +814,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
657
814
  stepResults,
658
815
  emitter,
659
816
  abortController,
660
- runtimeContext,
817
+ requestContext,
661
818
  executionContext,
662
819
  writableStream,
663
820
  tracingContext
@@ -669,55 +826,60 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
669
826
  attributes: {
670
827
  durationMs: duration,
671
828
  sleepType: fn ? "dynamic" : "fixed"
672
- }
829
+ },
830
+ tracingPolicy: this.options?.tracingPolicy
673
831
  });
674
832
  if (fn) {
675
833
  const stepCallId = crypto.randomUUID();
676
834
  duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
677
- return await fn({
678
- runId,
679
- workflowId,
680
- mastra: this.mastra,
681
- runtimeContext,
682
- inputData: prevOutput,
683
- runCount: -1,
684
- tracingContext: {
685
- currentSpan: sleepSpan
686
- },
687
- getInitData: () => stepResults?.input,
688
- getStepResult: (step) => {
689
- if (!step?.id) {
690
- return null;
691
- }
692
- const result = stepResults[step.id];
693
- if (result?.status === "success") {
694
- return result.output;
695
- }
696
- return null;
697
- },
698
- // TODO: this function shouldn't have suspend probably?
699
- suspend: async (_suspendPayload) => {
700
- },
701
- bail: () => {
702
- },
703
- abort: () => {
704
- abortController?.abort();
705
- },
706
- [_constants.EMITTER_SYMBOL]: emitter,
707
- // TODO: add streamVNext support
708
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
709
- engine: { step: this.inngestStep },
710
- abortSignal: abortController?.signal,
711
- writer: new tools.ToolStream(
835
+ return await fn(
836
+ workflows.createDeprecationProxy(
712
837
  {
713
- prefix: "workflow-step",
714
- callId: stepCallId,
715
- name: "sleep",
716
- runId
838
+ runId,
839
+ workflowId,
840
+ mastra: this.mastra,
841
+ requestContext,
842
+ inputData: prevOutput,
843
+ state: executionContext.state,
844
+ setState: (state) => {
845
+ executionContext.state = state;
846
+ },
847
+ runCount: -1,
848
+ retryCount: -1,
849
+ tracingContext: {
850
+ currentSpan: sleepSpan
851
+ },
852
+ getInitData: () => stepResults?.input,
853
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
854
+ // TODO: this function shouldn't have suspend probably?
855
+ suspend: async (_suspendPayload) => {
856
+ },
857
+ bail: () => {
858
+ },
859
+ abort: () => {
860
+ abortController?.abort();
861
+ },
862
+ [_constants.EMITTER_SYMBOL]: emitter,
863
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
864
+ engine: { step: this.inngestStep },
865
+ abortSignal: abortController?.signal,
866
+ writer: new tools.ToolStream(
867
+ {
868
+ prefix: "workflow-step",
869
+ callId: stepCallId,
870
+ name: "sleep",
871
+ runId
872
+ },
873
+ writableStream
874
+ )
717
875
  },
718
- writableStream
876
+ {
877
+ paramName: "runCount",
878
+ deprecationMessage: workflows.runCountDeprecationMessage,
879
+ logger: this.logger
880
+ }
719
881
  )
720
- });
882
+ );
721
883
  });
722
884
  sleepSpan?.update({
723
885
  attributes: {
@@ -741,7 +903,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
741
903
  stepResults,
742
904
  emitter,
743
905
  abortController,
744
- runtimeContext,
906
+ requestContext,
745
907
  executionContext,
746
908
  writableStream,
747
909
  tracingContext
@@ -754,56 +916,64 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
754
916
  untilDate: date,
755
917
  durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
756
918
  sleepType: fn ? "dynamic" : "fixed"
757
- }
919
+ },
920
+ tracingPolicy: this.options?.tracingPolicy
758
921
  });
759
922
  if (fn) {
760
923
  date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
761
924
  const stepCallId = crypto.randomUUID();
762
- return await fn({
763
- runId,
764
- workflowId,
765
- mastra: this.mastra,
766
- runtimeContext,
767
- inputData: prevOutput,
768
- runCount: -1,
769
- tracingContext: {
770
- currentSpan: sleepUntilSpan
771
- },
772
- getInitData: () => stepResults?.input,
773
- getStepResult: (step) => {
774
- if (!step?.id) {
775
- return null;
776
- }
777
- const result = stepResults[step.id];
778
- if (result?.status === "success") {
779
- return result.output;
780
- }
781
- return null;
782
- },
783
- // TODO: this function shouldn't have suspend probably?
784
- suspend: async (_suspendPayload) => {
785
- },
786
- bail: () => {
787
- },
788
- abort: () => {
789
- abortController?.abort();
790
- },
791
- [_constants.EMITTER_SYMBOL]: emitter,
792
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
793
- // TODO: add streamVNext support
794
- engine: { step: this.inngestStep },
795
- abortSignal: abortController?.signal,
796
- writer: new tools.ToolStream(
925
+ return await fn(
926
+ workflows.createDeprecationProxy(
797
927
  {
798
- prefix: "workflow-step",
799
- callId: stepCallId,
800
- name: "sleep",
801
- runId
928
+ runId,
929
+ workflowId,
930
+ mastra: this.mastra,
931
+ requestContext,
932
+ inputData: prevOutput,
933
+ state: executionContext.state,
934
+ setState: (state) => {
935
+ executionContext.state = state;
936
+ },
937
+ runCount: -1,
938
+ retryCount: -1,
939
+ tracingContext: {
940
+ currentSpan: sleepUntilSpan
941
+ },
942
+ getInitData: () => stepResults?.input,
943
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
944
+ // TODO: this function shouldn't have suspend probably?
945
+ suspend: async (_suspendPayload) => {
946
+ },
947
+ bail: () => {
948
+ },
949
+ abort: () => {
950
+ abortController?.abort();
951
+ },
952
+ [_constants.EMITTER_SYMBOL]: emitter,
953
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
954
+ engine: { step: this.inngestStep },
955
+ abortSignal: abortController?.signal,
956
+ writer: new tools.ToolStream(
957
+ {
958
+ prefix: "workflow-step",
959
+ callId: stepCallId,
960
+ name: "sleep",
961
+ runId
962
+ },
963
+ writableStream
964
+ )
802
965
  },
803
- writableStream
966
+ {
967
+ paramName: "runCount",
968
+ deprecationMessage: workflows.runCountDeprecationMessage,
969
+ logger: this.logger
970
+ }
804
971
  )
805
- });
972
+ );
806
973
  });
974
+ if (date && !(date instanceof Date)) {
975
+ date = new Date(date);
976
+ }
807
977
  const time = !date ? 0 : date.getTime() - Date.now();
808
978
  sleepUntilSpan?.update({
809
979
  attributes: {
@@ -841,7 +1011,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
841
1011
  prevOutput,
842
1012
  emitter,
843
1013
  abortController,
844
- runtimeContext,
1014
+ requestContext,
845
1015
  tracingContext,
846
1016
  writableStream,
847
1017
  disableScorers
@@ -852,7 +1022,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
852
1022
  input: prevOutput,
853
1023
  attributes: {
854
1024
  stepId: step.id
855
- }
1025
+ },
1026
+ tracingPolicy: this.options?.tracingPolicy
1027
+ });
1028
+ const { inputData, validationError } = await workflows.validateStepInput({
1029
+ prevOutput,
1030
+ step,
1031
+ validateInputs: this.options?.validateInputs ?? false
856
1032
  });
857
1033
  const startedAt = await this.inngestStep.run(
858
1034
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
@@ -884,7 +1060,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
884
1060
  payload: {
885
1061
  id: step.id,
886
1062
  status: "running",
887
- payload: prevOutput,
1063
+ payload: inputData,
888
1064
  startedAt: startedAt2
889
1065
  }
890
1066
  });
@@ -895,38 +1071,60 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
895
1071
  const isResume = !!resume?.steps?.length;
896
1072
  let result;
897
1073
  let runId;
898
- if (isResume) {
899
- runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? crypto.randomUUID();
900
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
901
- workflowName: step.id,
902
- runId
903
- });
904
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
905
- function: step.getFunction(),
906
- data: {
907
- inputData: prevOutput,
908
- runId,
909
- resume: {
1074
+ try {
1075
+ if (isResume) {
1076
+ runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
1077
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1078
+ workflowName: step.id,
1079
+ runId
1080
+ });
1081
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1082
+ function: step.getFunction(),
1083
+ data: {
1084
+ inputData,
1085
+ initialState: executionContext.state ?? snapshot?.value ?? {},
910
1086
  runId,
911
- steps: resume.steps.slice(1),
912
- stepResults: snapshot?.context,
913
- resumePayload: resume.resumePayload,
914
- // @ts-ignore
915
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1087
+ resume: {
1088
+ runId,
1089
+ steps: resume.steps.slice(1),
1090
+ stepResults: snapshot?.context,
1091
+ resumePayload: resume.resumePayload,
1092
+ // @ts-ignore
1093
+ resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1094
+ },
1095
+ outputOptions: { includeState: true }
916
1096
  }
917
- }
918
- });
919
- result = invokeResp.result;
920
- runId = invokeResp.runId;
921
- } else {
922
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
923
- function: step.getFunction(),
924
- data: {
925
- inputData: prevOutput
926
- }
927
- });
928
- result = invokeResp.result;
929
- runId = invokeResp.runId;
1097
+ });
1098
+ result = invokeResp.result;
1099
+ runId = invokeResp.runId;
1100
+ executionContext.state = invokeResp.result.state;
1101
+ } else {
1102
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1103
+ function: step.getFunction(),
1104
+ data: {
1105
+ inputData,
1106
+ initialState: executionContext.state ?? {},
1107
+ outputOptions: { includeState: true }
1108
+ }
1109
+ });
1110
+ result = invokeResp.result;
1111
+ runId = invokeResp.runId;
1112
+ executionContext.state = invokeResp.result.state;
1113
+ }
1114
+ } catch (e) {
1115
+ const errorCause = e?.cause;
1116
+ if (errorCause && typeof errorCause === "object") {
1117
+ result = errorCause;
1118
+ runId = errorCause.runId || crypto.randomUUID();
1119
+ } else {
1120
+ runId = crypto.randomUUID();
1121
+ result = {
1122
+ status: "failed",
1123
+ error: e instanceof Error ? e : new Error(String(e)),
1124
+ steps: {},
1125
+ input: inputData
1126
+ };
1127
+ }
930
1128
  }
931
1129
  const res = await this.inngestStep.run(
932
1130
  `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
@@ -965,7 +1163,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
965
1163
  return stepRes2?.status === "suspended";
966
1164
  });
967
1165
  for (const [stepName, stepResult] of suspendedSteps) {
968
- const suspendPath = [stepName, ...stepResult?.payload?.__workflow_meta?.path ?? []];
1166
+ const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
969
1167
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
970
1168
  await emitter.emit("watch", {
971
1169
  type: "watch",
@@ -973,7 +1171,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
973
1171
  currentStep: {
974
1172
  id: step.id,
975
1173
  status: "suspended",
976
- payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
1174
+ payload: stepResult.payload,
1175
+ suspendPayload: {
1176
+ ...stepResult?.suspendPayload,
1177
+ __workflow_meta: { runId, path: suspendPath }
1178
+ }
977
1179
  },
978
1180
  workflowState: {
979
1181
  status: "running",
@@ -995,7 +1197,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
995
1197
  executionContext,
996
1198
  result: {
997
1199
  status: "suspended",
998
- payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
1200
+ payload: stepResult.payload,
1201
+ suspendPayload: {
1202
+ ...stepResult?.suspendPayload,
1203
+ __workflow_meta: { runId, path: suspendPath }
1204
+ }
999
1205
  }
1000
1206
  };
1001
1207
  }
@@ -1060,145 +1266,196 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1060
1266
  }
1061
1267
  );
1062
1268
  Object.assign(executionContext, res.executionContext);
1063
- return res.result;
1269
+ return {
1270
+ ...res.result,
1271
+ startedAt,
1272
+ endedAt: Date.now(),
1273
+ payload: inputData,
1274
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1275
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1276
+ };
1064
1277
  }
1065
- const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1066
- let execResults;
1067
- let suspended;
1068
- let bailed;
1069
- try {
1070
- const result = await step.execute({
1071
- runId: executionContext.runId,
1072
- mastra: this.mastra,
1073
- runtimeContext,
1074
- writableStream,
1075
- inputData: prevOutput,
1076
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1077
- tracingContext: {
1078
- currentSpan: stepAISpan
1079
- },
1080
- getInitData: () => stepResults?.input,
1081
- getStepResult: (step2) => {
1082
- const result2 = stepResults[step2.id];
1083
- if (result2?.status === "success") {
1084
- return result2.output;
1278
+ const stepCallId = crypto.randomUUID();
1279
+ let stepRes;
1280
+ try {
1281
+ stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1282
+ let execResults;
1283
+ let suspended;
1284
+ let bailed;
1285
+ try {
1286
+ if (validationError) {
1287
+ throw validationError;
1288
+ }
1289
+ const result = await step.execute({
1290
+ runId: executionContext.runId,
1291
+ mastra: this.mastra,
1292
+ requestContext,
1293
+ writer: new tools.ToolStream(
1294
+ {
1295
+ prefix: "workflow-step",
1296
+ callId: stepCallId,
1297
+ name: step.id,
1298
+ runId: executionContext.runId
1299
+ },
1300
+ writableStream
1301
+ ),
1302
+ state: executionContext?.state ?? {},
1303
+ setState: (state) => {
1304
+ executionContext.state = state;
1305
+ },
1306
+ inputData,
1307
+ resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1308
+ tracingContext: {
1309
+ currentSpan: stepAISpan
1310
+ },
1311
+ getInitData: () => stepResults?.input,
1312
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1313
+ suspend: async (suspendPayload, suspendOptions) => {
1314
+ executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1315
+ if (suspendOptions?.resumeLabel) {
1316
+ const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
1317
+ for (const label of resumeLabel) {
1318
+ executionContext.resumeLabels[label] = {
1319
+ stepId: step.id,
1320
+ foreachIndex: executionContext.foreachIndex
1321
+ };
1322
+ }
1323
+ }
1324
+ suspended = { payload: suspendPayload };
1325
+ },
1326
+ bail: (result2) => {
1327
+ bailed = { payload: result2 };
1328
+ },
1329
+ resume: {
1330
+ steps: resume?.steps?.slice(1) || [],
1331
+ resumePayload: resume?.resumePayload,
1332
+ // @ts-ignore
1333
+ runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1334
+ },
1335
+ [_constants.EMITTER_SYMBOL]: emitter,
1336
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1337
+ engine: {
1338
+ step: this.inngestStep
1339
+ },
1340
+ abortSignal: abortController.signal
1341
+ });
1342
+ const endedAt = Date.now();
1343
+ execResults = {
1344
+ status: "success",
1345
+ output: result,
1346
+ startedAt,
1347
+ endedAt,
1348
+ payload: inputData,
1349
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1350
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1351
+ };
1352
+ } catch (e) {
1353
+ const stepFailure = {
1354
+ status: "failed",
1355
+ payload: inputData,
1356
+ error: e instanceof Error ? e.message : String(e),
1357
+ endedAt: Date.now(),
1358
+ startedAt,
1359
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1360
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1361
+ };
1362
+ execResults = stepFailure;
1363
+ const fallbackErrorMessage = `Step ${step.id} failed`;
1364
+ stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1365
+ throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1366
+ cause: execResults
1367
+ });
1368
+ }
1369
+ if (suspended) {
1370
+ execResults = {
1371
+ status: "suspended",
1372
+ suspendPayload: suspended.payload,
1373
+ payload: inputData,
1374
+ suspendedAt: Date.now(),
1375
+ startedAt,
1376
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1377
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1378
+ };
1379
+ } else if (bailed) {
1380
+ execResults = {
1381
+ status: "bailed",
1382
+ output: bailed.payload,
1383
+ payload: inputData,
1384
+ endedAt: Date.now(),
1385
+ startedAt
1386
+ };
1387
+ }
1388
+ await emitter.emit("watch", {
1389
+ type: "watch",
1390
+ payload: {
1391
+ currentStep: {
1392
+ id: step.id,
1393
+ ...execResults
1394
+ },
1395
+ workflowState: {
1396
+ status: "running",
1397
+ steps: { ...stepResults, [step.id]: execResults },
1398
+ result: null,
1399
+ error: null
1085
1400
  }
1086
- return null;
1087
- },
1088
- suspend: async (suspendPayload) => {
1089
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1090
- suspended = { payload: suspendPayload };
1091
- },
1092
- bail: (result2) => {
1093
- bailed = { payload: result2 };
1094
- },
1095
- resume: {
1096
- steps: resume?.steps?.slice(1) || [],
1097
- resumePayload: resume?.resumePayload,
1098
- // @ts-ignore
1099
- runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
1100
- },
1101
- [_constants.EMITTER_SYMBOL]: emitter,
1102
- engine: {
1103
- step: this.inngestStep
1104
1401
  },
1105
- abortSignal: abortController.signal
1402
+ eventTimestamp: Date.now()
1106
1403
  });
1107
- const endedAt = Date.now();
1108
- execResults = {
1109
- status: "success",
1110
- output: result,
1111
- startedAt,
1112
- endedAt,
1113
- payload: prevOutput,
1114
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1115
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1116
- };
1117
- } catch (e) {
1118
- execResults = {
1119
- status: "failed",
1120
- payload: prevOutput,
1121
- error: e instanceof Error ? e.message : String(e),
1122
- endedAt: Date.now(),
1123
- startedAt,
1124
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1125
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1126
- };
1127
- }
1128
- if (suspended) {
1129
- execResults = {
1130
- status: "suspended",
1131
- suspendedPayload: suspended.payload,
1132
- payload: prevOutput,
1133
- suspendedAt: Date.now(),
1134
- startedAt,
1135
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1136
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1137
- };
1138
- } else if (bailed) {
1139
- execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
1140
- }
1141
- if (execResults.status === "failed") {
1142
- if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
1143
- const error = new Error(execResults.error);
1144
- stepAISpan?.error({ error });
1145
- throw error;
1404
+ if (execResults.status === "suspended") {
1405
+ await emitter.emit("watch-v2", {
1406
+ type: "workflow-step-suspended",
1407
+ payload: {
1408
+ id: step.id,
1409
+ ...execResults
1410
+ }
1411
+ });
1412
+ } else {
1413
+ await emitter.emit("watch-v2", {
1414
+ type: "workflow-step-result",
1415
+ payload: {
1416
+ id: step.id,
1417
+ ...execResults
1418
+ }
1419
+ });
1420
+ await emitter.emit("watch-v2", {
1421
+ type: "workflow-step-finish",
1422
+ payload: {
1423
+ id: step.id,
1424
+ metadata: {}
1425
+ }
1426
+ });
1146
1427
  }
1147
- }
1148
- await emitter.emit("watch", {
1149
- type: "watch",
1150
- payload: {
1151
- currentStep: {
1152
- id: step.id,
1153
- ...execResults
1154
- },
1155
- workflowState: {
1156
- status: "running",
1157
- steps: { ...stepResults, [step.id]: execResults },
1158
- result: null,
1159
- error: null
1160
- }
1161
- },
1162
- eventTimestamp: Date.now()
1428
+ stepAISpan?.end({ output: execResults });
1429
+ return { result: execResults, executionContext, stepResults };
1163
1430
  });
1164
- if (execResults.status === "suspended") {
1165
- await emitter.emit("watch-v2", {
1166
- type: "workflow-step-suspended",
1167
- payload: {
1168
- id: step.id,
1169
- ...execResults
1170
- }
1171
- });
1172
- } else {
1173
- await emitter.emit("watch-v2", {
1174
- type: "workflow-step-result",
1175
- payload: {
1176
- id: step.id,
1177
- ...execResults
1178
- }
1179
- });
1180
- await emitter.emit("watch-v2", {
1181
- type: "workflow-step-finish",
1182
- payload: {
1183
- id: step.id,
1184
- metadata: {}
1185
- }
1186
- });
1187
- }
1188
- stepAISpan?.end({ output: execResults });
1189
- return { result: execResults, executionContext, stepResults };
1190
- });
1191
- if (disableScorers !== false) {
1431
+ } catch (e) {
1432
+ const stepFailure = e instanceof Error ? e?.cause : {
1433
+ status: "failed",
1434
+ error: e instanceof Error ? e.message : String(e),
1435
+ payload: inputData,
1436
+ startedAt,
1437
+ endedAt: Date.now()
1438
+ };
1439
+ stepRes = {
1440
+ result: stepFailure,
1441
+ executionContext,
1442
+ stepResults: {
1443
+ ...stepResults,
1444
+ [step.id]: stepFailure
1445
+ }
1446
+ };
1447
+ }
1448
+ if (disableScorers !== false && stepRes.result.status === "success") {
1192
1449
  await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1193
1450
  if (step.scorers) {
1194
1451
  await this.runScorers({
1195
1452
  scorers: step.scorers,
1196
1453
  runId: executionContext.runId,
1197
- input: prevOutput,
1454
+ input: inputData,
1198
1455
  output: stepRes.result,
1199
1456
  workflowId: executionContext.workflowId,
1200
1457
  stepId: step.id,
1201
- runtimeContext,
1458
+ requestContext,
1202
1459
  disableScorers,
1203
1460
  tracingContext: { currentSpan: stepAISpan }
1204
1461
  });
@@ -1207,12 +1464,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1207
1464
  }
1208
1465
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1209
1466
  Object.assign(stepResults, stepRes.stepResults);
1467
+ executionContext.state = stepRes.executionContext.state;
1210
1468
  return stepRes.result;
1211
1469
  }
1212
1470
  async persistStepUpdate({
1213
1471
  workflowId,
1214
1472
  runId,
1215
1473
  stepResults,
1474
+ resourceId,
1216
1475
  executionContext,
1217
1476
  serializedStepGraph,
1218
1477
  workflowStatus,
@@ -1222,15 +1481,21 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1222
1481
  await this.inngestStep.run(
1223
1482
  `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
1224
1483
  async () => {
1484
+ const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
1485
+ if (!shouldPersistSnapshot) {
1486
+ return;
1487
+ }
1225
1488
  await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1226
1489
  workflowName: workflowId,
1227
1490
  runId,
1491
+ resourceId,
1228
1492
  snapshot: {
1229
1493
  runId,
1230
- value: {},
1494
+ value: executionContext.state,
1231
1495
  context: stepResults,
1232
1496
  activePaths: [],
1233
1497
  suspendedPaths: executionContext.suspendedPaths,
1498
+ resumeLabels: executionContext.resumeLabels,
1234
1499
  waitingPaths: {},
1235
1500
  serializedStepGraph,
1236
1501
  status: workflowStatus,
@@ -1248,25 +1513,24 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1248
1513
  runId,
1249
1514
  entry,
1250
1515
  prevOutput,
1251
- prevStep,
1252
1516
  stepResults,
1253
- serializedStepGraph,
1254
1517
  resume,
1255
1518
  executionContext,
1256
1519
  emitter,
1257
1520
  abortController,
1258
- runtimeContext,
1521
+ requestContext,
1259
1522
  writableStream,
1260
1523
  disableScorers,
1261
1524
  tracingContext
1262
1525
  }) {
1263
1526
  const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1264
1527
  type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL,
1265
- name: `conditional: ${entry.conditions.length} conditions`,
1528
+ name: `conditional: '${entry.conditions.length} conditions'`,
1266
1529
  input: prevOutput,
1267
1530
  attributes: {
1268
1531
  conditionCount: entry.conditions.length
1269
- }
1532
+ },
1533
+ tracingPolicy: this.options?.tracingPolicy
1270
1534
  });
1271
1535
  let execResults;
1272
1536
  const truthyIndexes = (await Promise.all(
@@ -1274,59 +1538,64 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1274
1538
  (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1275
1539
  const evalSpan = conditionalSpan?.createChildSpan({
1276
1540
  type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL_EVAL,
1277
- name: `condition ${index}`,
1541
+ name: `condition: '${index}'`,
1278
1542
  input: prevOutput,
1279
1543
  attributes: {
1280
1544
  conditionIndex: index
1281
- }
1545
+ },
1546
+ tracingPolicy: this.options?.tracingPolicy
1282
1547
  });
1283
1548
  try {
1284
- const result = await cond({
1285
- runId,
1286
- workflowId,
1287
- mastra: this.mastra,
1288
- runtimeContext,
1289
- runCount: -1,
1290
- inputData: prevOutput,
1291
- tracingContext: {
1292
- currentSpan: evalSpan
1293
- },
1294
- getInitData: () => stepResults?.input,
1295
- getStepResult: (step) => {
1296
- if (!step?.id) {
1297
- return null;
1298
- }
1299
- const result2 = stepResults[step.id];
1300
- if (result2?.status === "success") {
1301
- return result2.output;
1302
- }
1303
- return null;
1304
- },
1305
- // TODO: this function shouldn't have suspend probably?
1306
- suspend: async (_suspendPayload) => {
1307
- },
1308
- bail: () => {
1309
- },
1310
- abort: () => {
1311
- abortController.abort();
1312
- },
1313
- [_constants.EMITTER_SYMBOL]: emitter,
1314
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1315
- // TODO: add streamVNext support
1316
- engine: {
1317
- step: this.inngestStep
1318
- },
1319
- abortSignal: abortController.signal,
1320
- writer: new tools.ToolStream(
1549
+ const result = await cond(
1550
+ workflows.createDeprecationProxy(
1321
1551
  {
1322
- prefix: "workflow-step",
1323
- callId: crypto.randomUUID(),
1324
- name: "conditional",
1325
- runId
1552
+ runId,
1553
+ workflowId,
1554
+ mastra: this.mastra,
1555
+ requestContext,
1556
+ runCount: -1,
1557
+ retryCount: -1,
1558
+ inputData: prevOutput,
1559
+ state: executionContext.state,
1560
+ setState: (state) => {
1561
+ executionContext.state = state;
1562
+ },
1563
+ tracingContext: {
1564
+ currentSpan: evalSpan
1565
+ },
1566
+ getInitData: () => stepResults?.input,
1567
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1568
+ // TODO: this function shouldn't have suspend probably?
1569
+ suspend: async (_suspendPayload) => {
1570
+ },
1571
+ bail: () => {
1572
+ },
1573
+ abort: () => {
1574
+ abortController.abort();
1575
+ },
1576
+ [_constants.EMITTER_SYMBOL]: emitter,
1577
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1578
+ engine: {
1579
+ step: this.inngestStep
1580
+ },
1581
+ abortSignal: abortController.signal,
1582
+ writer: new tools.ToolStream(
1583
+ {
1584
+ prefix: "workflow-step",
1585
+ callId: crypto.randomUUID(),
1586
+ name: "conditional",
1587
+ runId
1588
+ },
1589
+ writableStream
1590
+ )
1326
1591
  },
1327
- writableStream
1592
+ {
1593
+ paramName: "runCount",
1594
+ deprecationMessage: workflows.runCountDeprecationMessage,
1595
+ logger: this.logger
1596
+ }
1328
1597
  )
1329
- });
1598
+ );
1330
1599
  evalSpan?.end({
1331
1600
  output: result,
1332
1601
  attributes: {
@@ -1354,13 +1623,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1354
1623
  }
1355
1624
  });
1356
1625
  const results = await Promise.all(
1357
- stepsToRun.map(
1358
- (step, index) => this.executeEntry({
1359
- workflowId,
1360
- runId,
1361
- entry: step,
1362
- serializedStepGraph,
1363
- prevStep,
1626
+ stepsToRun.map(async (step, index) => {
1627
+ const currStepResult = stepResults[step.step.id];
1628
+ if (currStepResult && currStepResult.status === "success") {
1629
+ return currStepResult;
1630
+ }
1631
+ const result = await this.executeStep({
1632
+ step: step.step,
1633
+ prevOutput,
1364
1634
  stepResults,
1365
1635
  resume,
1366
1636
  executionContext: {
@@ -1368,31 +1638,34 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1368
1638
  runId,
1369
1639
  executionPath: [...executionContext.executionPath, index],
1370
1640
  suspendedPaths: executionContext.suspendedPaths,
1641
+ resumeLabels: executionContext.resumeLabels,
1371
1642
  retryConfig: executionContext.retryConfig,
1372
- executionSpan: executionContext.executionSpan
1643
+ state: executionContext.state
1373
1644
  },
1374
1645
  emitter,
1375
1646
  abortController,
1376
- runtimeContext,
1647
+ requestContext,
1377
1648
  writableStream,
1378
1649
  disableScorers,
1379
1650
  tracingContext: {
1380
1651
  currentSpan: conditionalSpan
1381
1652
  }
1382
- })
1383
- )
1653
+ });
1654
+ stepResults[step.step.id] = result;
1655
+ return result;
1656
+ })
1384
1657
  );
1385
- const hasFailed = results.find((result) => result.result.status === "failed");
1386
- const hasSuspended = results.find((result) => result.result.status === "suspended");
1658
+ const hasFailed = results.find((result) => result.status === "failed");
1659
+ const hasSuspended = results.find((result) => result.status === "suspended");
1387
1660
  if (hasFailed) {
1388
- execResults = { status: "failed", error: hasFailed.result.error };
1661
+ execResults = { status: "failed", error: hasFailed.error };
1389
1662
  } else if (hasSuspended) {
1390
- execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
1663
+ execResults = { status: "suspended", suspendPayload: hasSuspended.suspendPayload };
1391
1664
  } else {
1392
1665
  execResults = {
1393
1666
  status: "success",
1394
1667
  output: results.reduce((acc, result, index) => {
1395
- if (result.result.status === "success") {
1668
+ if (result.status === "success") {
1396
1669
  acc[stepsToRun[index].step.id] = result.output;
1397
1670
  }
1398
1671
  return acc;