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