@mastra/inngest 1.0.0-beta.1 → 1.0.0-beta.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # @mastra/inngest
2
2
 
3
+ ## 1.0.0-beta.3
4
+
5
+ ### Patch Changes
6
+
7
+ - - Fix tool suspension throwing error when `outputSchema` is passed to tool during creation ([#10444](https://github.com/mastra-ai/mastra/pull/10444))
8
+ - Pass `suspendSchema` and `resumeSchema` from tool into step created when creating step from tool
9
+ - Updated dependencies [[`21a15de`](https://github.com/mastra-ai/mastra/commit/21a15de369fe82aac26bb642ed7be73505475e8b), [`feb7ee4`](https://github.com/mastra-ai/mastra/commit/feb7ee4d09a75edb46c6669a3beaceec78811747), [`b0e2ea5`](https://github.com/mastra-ai/mastra/commit/b0e2ea5b52c40fae438b9e2f7baee6f0f89c5442), [`c456e01`](https://github.com/mastra-ai/mastra/commit/c456e0149e3c176afcefdbd9bb1d2c5917723725), [`ab035c2`](https://github.com/mastra-ai/mastra/commit/ab035c2ef6d8cc7bb25f06f1a38508bd9e6f126b), [`1a46a56`](https://github.com/mastra-ai/mastra/commit/1a46a566f45a3fcbadc1cf36bf86d351f264bfa3), [`3cf540b`](https://github.com/mastra-ai/mastra/commit/3cf540b9fbfea8f4fc8d3a2319a4e6c0b0cbfd52), [`1c6ce51`](https://github.com/mastra-ai/mastra/commit/1c6ce51f875915ab57fd36873623013699a2a65d), [`898a972`](https://github.com/mastra-ai/mastra/commit/898a9727d286c2510d6b702dfd367e6aaf5c6b0f), [`a97003a`](https://github.com/mastra-ai/mastra/commit/a97003aa1cf2f4022a41912324a1e77263b326b8), [`ccc141e`](https://github.com/mastra-ai/mastra/commit/ccc141ed27da0abc3a3fc28e9e5128152e8e37f4), [`fe3b897`](https://github.com/mastra-ai/mastra/commit/fe3b897c2ccbcd2b10e81b099438c7337feddf89), [`00123ba`](https://github.com/mastra-ai/mastra/commit/00123ba96dc9e5cd0b110420ebdba56d8f237b25), [`29c4309`](https://github.com/mastra-ai/mastra/commit/29c4309f818b24304c041bcb4a8f19b5f13f6b62), [`16785ce`](https://github.com/mastra-ai/mastra/commit/16785ced928f6f22638f4488cf8a125d99211799), [`de8239b`](https://github.com/mastra-ai/mastra/commit/de8239bdcb1d8c0cfa06da21f1569912a66bbc8a), [`b5e6cd7`](https://github.com/mastra-ai/mastra/commit/b5e6cd77fc8c8e64e0494c1d06cee3d84e795d1e), [`3759cb0`](https://github.com/mastra-ai/mastra/commit/3759cb064935b5f74c65ac2f52a1145f7352899d), [`651e772`](https://github.com/mastra-ai/mastra/commit/651e772eb1475fb13e126d3fcc01751297a88214), [`b61b93f`](https://github.com/mastra-ai/mastra/commit/b61b93f9e058b11dd2eec169853175d31dbdd567), [`bae33d9`](https://github.com/mastra-ai/mastra/commit/bae33d91a63fbb64d1e80519e1fc1acaed1e9013), [`c0b731f`](https://github.com/mastra-ai/mastra/commit/c0b731fb27d712dc8582e846df5c0332a6a0c5ba), [`43ca8f2`](https://github.com/mastra-ai/mastra/commit/43ca8f2c7334851cc7b4d3d2f037d8784bfbdd5f), [`2ca67cc`](https://github.com/mastra-ai/mastra/commit/2ca67cc3bb1f6a617353fdcab197d9efebe60d6f), [`9e67002`](https://github.com/mastra-ai/mastra/commit/9e67002b52c9be19936c420a489dbee9c5fd6a78), [`35edc49`](https://github.com/mastra-ai/mastra/commit/35edc49ac0556db609189641d6341e76771b81fc)]:
10
+ - @mastra/core@1.0.0-beta.5
11
+
12
+ ## 1.0.0-beta.2
13
+
14
+ ### Patch Changes
15
+
16
+ - dependencies updates: ([#10120](https://github.com/mastra-ai/mastra/pull/10120))
17
+ - Updated dependency [`@inngest/realtime@^0.4.5` ↗︎](https://www.npmjs.com/package/@inngest/realtime/v/0.4.5) (from `^0.4.4`, in `dependencies`)
18
+
19
+ - fix resumeStream type to use resumeSchema ([#10202](https://github.com/mastra-ai/mastra/pull/10202))
20
+
21
+ - Add restart method to workflow run that allows restarting an active workflow run ([#9750](https://github.com/mastra-ai/mastra/pull/9750))
22
+ Add status filter to `listWorkflowRuns`
23
+ Add automatic restart to restart active workflow runs when server starts
24
+
25
+ - Validate schemas by default in workflow. Previously, if you want schemas in the workflow to be validated, you'd have to add `validateInputs` option, now, this will be done by default but can be disabled. ([#10186](https://github.com/mastra-ai/mastra/pull/10186))
26
+
27
+ For workflows whose schemas and step schemas you don't want validated, do this
28
+
29
+ ```diff
30
+ createWorkflow({
31
+ + options: {
32
+ + validateInputs: false
33
+ + }
34
+ })
35
+ ```
36
+
37
+ - Fix inngest parallel workflow ([#10169](https://github.com/mastra-ai/mastra/pull/10169))
38
+ Fix tool as step in inngest
39
+ Fix inngest nested workflow
40
+
41
+ - Add timeTravel to workflows. This makes it possible to start a workflow run from a particular step in the workflow ([#9994](https://github.com/mastra-ai/mastra/pull/9994))
42
+
43
+ Example code:
44
+
45
+ ```ts
46
+ const result = await run.timeTravel({
47
+ step: 'step2',
48
+ inputData: {
49
+ value: 'input',
50
+ },
51
+ });
52
+ ```
53
+
54
+ - Updated dependencies [[`2319326`](https://github.com/mastra-ai/mastra/commit/2319326f8c64e503a09bbcf14be2dd65405445e0), [`d629361`](https://github.com/mastra-ai/mastra/commit/d629361a60f6565b5bfb11976fdaf7308af858e2), [`08c31c1`](https://github.com/mastra-ai/mastra/commit/08c31c188ebccd598acaf55e888b6397d01f7eae), [`fd3d338`](https://github.com/mastra-ai/mastra/commit/fd3d338a2c362174ed5b383f1f011ad9fb0302aa), [`c30400a`](https://github.com/mastra-ai/mastra/commit/c30400a49b994b1b97256fe785eb6c906fc2b232), [`69e0a87`](https://github.com/mastra-ai/mastra/commit/69e0a878896a2da9494945d86e056a5f8f05b851), [`01f8878`](https://github.com/mastra-ai/mastra/commit/01f88783de25e4de048c1c8aace43e26373c6ea5), [`4c77209`](https://github.com/mastra-ai/mastra/commit/4c77209e6c11678808b365d545845918c40045c8), [`d827d08`](https://github.com/mastra-ai/mastra/commit/d827d0808ffe1f3553a84e975806cc989b9735dd), [`23c10a1`](https://github.com/mastra-ai/mastra/commit/23c10a1efdd9a693c405511ab2dc8a1236603162), [`676ccc7`](https://github.com/mastra-ai/mastra/commit/676ccc7fe92468d2d45d39c31a87825c89fd1ea0), [`c10398d`](https://github.com/mastra-ai/mastra/commit/c10398d5b88f1d4af556f4267ff06f1d11e89179), [`00c2387`](https://github.com/mastra-ai/mastra/commit/00c2387f5f04a365316f851e58666ac43f8c4edf), [`ad6250d`](https://github.com/mastra-ai/mastra/commit/ad6250dbdaad927e29f74a27b83f6c468b50a705), [`3a73998`](https://github.com/mastra-ai/mastra/commit/3a73998fa4ebeb7f3dc9301afe78095fc63e7999), [`e16d553`](https://github.com/mastra-ai/mastra/commit/e16d55338403c7553531cc568125c63d53653dff), [`4d59f58`](https://github.com/mastra-ai/mastra/commit/4d59f58de2d90d6e2810a19d4518e38ddddb9038), [`e1bb9c9`](https://github.com/mastra-ai/mastra/commit/e1bb9c94b4eb68b019ae275981be3feb769b5365), [`351a11f`](https://github.com/mastra-ai/mastra/commit/351a11fcaf2ed1008977fa9b9a489fc422e51cd4)]:
55
+ - @mastra/core@1.0.0-beta.3
56
+
3
57
  ## 1.0.0-beta.1
4
58
 
5
59
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -101,7 +101,8 @@ var InngestRun = class extends workflows.Run {
101
101
  resourceId: this.resourceId,
102
102
  snapshot: {
103
103
  ...snapshot,
104
- status: "canceled"
104
+ status: "canceled",
105
+ value: snapshot.value
105
106
  }
106
107
  });
107
108
  }
@@ -123,14 +124,15 @@ var InngestRun = class extends workflows.Run {
123
124
  snapshot: {
124
125
  runId: this.runId,
125
126
  serializedStepGraph: this.serializedStepGraph,
127
+ status: "running",
126
128
  value: {},
127
129
  context: {},
128
130
  activePaths: [],
129
131
  suspendedPaths: {},
132
+ activeStepsPath: {},
130
133
  resumeLabels: {},
131
134
  waitingPaths: {},
132
- timestamp: Date.now(),
133
- status: "running"
135
+ timestamp: Date.now()
134
136
  }
135
137
  });
136
138
  const inputDataToUse = await this._validateInput(inputData);
@@ -174,9 +176,14 @@ var InngestRun = class extends workflows.Run {
174
176
  }
175
177
  async _resume(params) {
176
178
  const storage = this.#mastra?.getStorage();
177
- const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
178
- (step) => typeof step === "string" ? step : step?.id
179
- );
179
+ let steps = [];
180
+ if (typeof params.step === "string") {
181
+ steps = params.step.split(".");
182
+ } else {
183
+ steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
184
+ (step) => typeof step === "string" ? step : step?.id
185
+ );
186
+ }
180
187
  const snapshot = await storage?.loadWorkflowSnapshot({
181
188
  workflowName: this.workflowId,
182
189
  runId: this.runId
@@ -195,8 +202,7 @@ var InngestRun = class extends workflows.Run {
195
202
  steps,
196
203
  stepResults: snapshot?.context,
197
204
  resumePayload: resumeDataToUse,
198
- // @ts-ignore
199
- resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
205
+ resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
200
206
  }
201
207
  }
202
208
  });
@@ -211,6 +217,97 @@ var InngestRun = class extends workflows.Run {
211
217
  }
212
218
  return result;
213
219
  }
220
+ async timeTravel(params) {
221
+ const p = this._timeTravel(params).then((result) => {
222
+ if (result.status !== "suspended") {
223
+ this.closeStreamAction?.().catch(() => {
224
+ });
225
+ }
226
+ return result;
227
+ });
228
+ this.executionResults = p;
229
+ return p;
230
+ }
231
+ async _timeTravel(params) {
232
+ if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
233
+ throw new Error("Step is required and must be a valid step or array of steps");
234
+ }
235
+ let steps = [];
236
+ if (typeof params.step === "string") {
237
+ steps = params.step.split(".");
238
+ } else {
239
+ steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
240
+ (step) => typeof step === "string" ? step : step?.id
241
+ );
242
+ }
243
+ if (steps.length === 0) {
244
+ throw new Error("No steps provided to timeTravel");
245
+ }
246
+ const storage = this.#mastra?.getStorage();
247
+ const snapshot = await storage?.loadWorkflowSnapshot({
248
+ workflowName: this.workflowId,
249
+ runId: this.runId
250
+ });
251
+ if (!snapshot) {
252
+ await storage?.persistWorkflowSnapshot({
253
+ workflowName: this.workflowId,
254
+ runId: this.runId,
255
+ resourceId: this.resourceId,
256
+ snapshot: {
257
+ runId: this.runId,
258
+ serializedStepGraph: this.serializedStepGraph,
259
+ status: "pending",
260
+ value: {},
261
+ context: {},
262
+ activePaths: [],
263
+ suspendedPaths: {},
264
+ activeStepsPath: {},
265
+ resumeLabels: {},
266
+ waitingPaths: {},
267
+ timestamp: Date.now()
268
+ }
269
+ });
270
+ }
271
+ if (snapshot?.status === "running") {
272
+ throw new Error("This workflow run is still running, cannot time travel");
273
+ }
274
+ let inputDataToUse = params.inputData;
275
+ if (inputDataToUse && steps.length === 1) {
276
+ inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]]);
277
+ }
278
+ const timeTravelData = workflows.createTimeTravelExecutionParams({
279
+ steps,
280
+ inputData: inputDataToUse,
281
+ resumeData: params.resumeData,
282
+ context: params.context,
283
+ nestedStepsContext: params.nestedStepsContext,
284
+ snapshot: snapshot ?? { context: {} },
285
+ graph: this.executionGraph,
286
+ initialState: params.initialState
287
+ });
288
+ const eventOutput = await this.inngest.send({
289
+ name: `workflow.${this.workflowId}`,
290
+ data: {
291
+ initialState: timeTravelData.state,
292
+ runId: this.runId,
293
+ workflowId: this.workflowId,
294
+ stepResults: timeTravelData.stepResults,
295
+ timeTravel: timeTravelData,
296
+ tracingOptions: params.tracingOptions,
297
+ outputOptions: params.outputOptions
298
+ }
299
+ });
300
+ const eventId = eventOutput.ids[0];
301
+ if (!eventId) {
302
+ throw new Error("Event ID is not set");
303
+ }
304
+ const runOutput = await this.getRunOutput(eventId);
305
+ const result = runOutput?.output?.result;
306
+ if (result.status === "failed") {
307
+ result.error = new Error(result.error);
308
+ }
309
+ return result;
310
+ }
214
311
  watch(cb) {
215
312
  let active = true;
216
313
  const streamPromise = realtime.subscribe(
@@ -360,6 +457,75 @@ var InngestRun = class extends workflows.Run {
360
457
  streamVNext(args = {}) {
361
458
  return this.stream(args);
362
459
  }
460
+ timeTravelStream({
461
+ inputData,
462
+ resumeData,
463
+ initialState,
464
+ step,
465
+ context,
466
+ nestedStepsContext,
467
+ requestContext,
468
+ tracingOptions,
469
+ outputOptions
470
+ }) {
471
+ this.closeStreamAction = async () => {
472
+ };
473
+ const self = this;
474
+ const stream$1 = new web.ReadableStream({
475
+ async start(controller) {
476
+ const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
477
+ controller.enqueue({
478
+ type,
479
+ runId: self.runId,
480
+ from,
481
+ payload: {
482
+ stepName: payload?.id,
483
+ ...payload
484
+ }
485
+ });
486
+ });
487
+ self.closeStreamAction = async () => {
488
+ unwatch();
489
+ try {
490
+ await controller.close();
491
+ } catch (err) {
492
+ console.error("Error closing stream:", err);
493
+ }
494
+ };
495
+ const executionResultsPromise = self._timeTravel({
496
+ inputData,
497
+ step,
498
+ context,
499
+ nestedStepsContext,
500
+ resumeData,
501
+ initialState,
502
+ requestContext,
503
+ tracingOptions,
504
+ outputOptions
505
+ });
506
+ self.executionResults = executionResultsPromise;
507
+ let executionResults;
508
+ try {
509
+ executionResults = await executionResultsPromise;
510
+ self.closeStreamAction?.().catch(() => {
511
+ });
512
+ if (self.streamOutput) {
513
+ self.streamOutput.updateResults(executionResults);
514
+ }
515
+ } catch (err) {
516
+ self.streamOutput?.rejectResults(err);
517
+ self.closeStreamAction?.().catch(() => {
518
+ });
519
+ }
520
+ }
521
+ });
522
+ this.streamOutput = new stream.WorkflowRunOutput({
523
+ runId: this.runId,
524
+ workflowId: this.workflowId,
525
+ stream: stream$1
526
+ });
527
+ return this.streamOutput;
528
+ }
363
529
  };
364
530
  var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
365
531
  #mastra;
@@ -369,6 +535,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
369
535
  constructor(params, inngest) {
370
536
  const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
371
537
  super(workflowParams);
538
+ this.engineType = "inngest";
372
539
  const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
373
540
  ([_, value]) => value !== void 0
374
541
  );
@@ -424,7 +591,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
424
591
  mastra: this.#mastra,
425
592
  retryConfig: this.retryConfig,
426
593
  cleanup: () => this.runs.delete(runIdToUse),
427
- workflowSteps: this.steps
594
+ workflowSteps: this.steps,
595
+ workflowEngineType: this.engineType,
596
+ validateInputs: this.options.validateInputs
428
597
  },
429
598
  this.inngest
430
599
  );
@@ -445,13 +614,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
445
614
  value: {},
446
615
  context: {},
447
616
  activePaths: [],
617
+ activeStepsPath: {},
448
618
  waitingPaths: {},
449
619
  serializedStepGraph: this.serializedStepGraph,
450
620
  suspendedPaths: {},
451
621
  resumeLabels: {},
452
622
  result: void 0,
453
623
  error: void 0,
454
- // @ts-ignore
455
624
  timestamp: Date.now()
456
625
  }
457
626
  });
@@ -465,15 +634,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
465
634
  this.function = this.inngest.createFunction(
466
635
  {
467
636
  id: `workflow.${this.id}`,
468
- // @ts-ignore
469
- retries: this.retryConfig?.attempts ?? 0,
637
+ retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
470
638
  cancelOn: [{ event: `cancel.workflow.${this.id}` }],
471
639
  // Spread flow control configuration
472
640
  ...this.flowControlConfig
473
641
  },
474
642
  { event: `workflow.${this.id}` },
475
643
  async ({ event, step, attempt, publish }) => {
476
- let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
644
+ let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
477
645
  if (!runId) {
478
646
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
479
647
  return crypto.randomUUID();
@@ -515,11 +683,12 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
515
683
  requestContext: new di.RequestContext(),
516
684
  // TODO
517
685
  resume,
686
+ timeTravel,
518
687
  format,
519
688
  abortController: new AbortController(),
520
689
  // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
521
690
  outputOptions,
522
- writableStream: new WritableStream({
691
+ writableStream: new web.WritableStream({
523
692
  write(chunk) {
524
693
  void emitter.emit("watch", chunk).catch(() => {
525
694
  });
@@ -567,13 +736,11 @@ function createStep(params, agentOptions) {
567
736
  return {
568
737
  id: params.name,
569
738
  description: params.getDescription(),
570
- // @ts-ignore
571
739
  inputSchema: zod.z.object({
572
740
  prompt: zod.z.string()
573
741
  // resourceId: z.string().optional(),
574
742
  // threadId: z.string().optional(),
575
743
  }),
576
- // @ts-ignore
577
744
  outputSchema: zod.z.object({
578
745
  text: zod.z.string()
579
746
  }),
@@ -663,20 +830,38 @@ function createStep(params, agentOptions) {
663
830
  }
664
831
  return {
665
832
  // TODO: tool probably should have strong id type
666
- // @ts-ignore
667
833
  id: params.id,
668
834
  description: params.description,
669
835
  inputSchema: params.inputSchema,
670
836
  outputSchema: params.outputSchema,
671
- execute: async ({ inputData, mastra, requestContext, tracingContext, suspend, resumeData }) => {
672
- return params.execute({
673
- context: inputData,
674
- mastra: observability.wrapMastra(mastra, tracingContext),
837
+ suspendSchema: params.suspendSchema,
838
+ resumeSchema: params.resumeSchema,
839
+ execute: async ({
840
+ inputData,
841
+ mastra,
842
+ requestContext,
843
+ tracingContext,
844
+ suspend,
845
+ resumeData,
846
+ runId,
847
+ workflowId,
848
+ state,
849
+ setState
850
+ }) => {
851
+ const toolContext = {
852
+ mastra,
675
853
  requestContext,
676
854
  tracingContext,
677
- suspend,
678
- resumeData
679
- });
855
+ workflow: {
856
+ runId,
857
+ resumeData,
858
+ suspend,
859
+ workflowId,
860
+ state,
861
+ setState
862
+ }
863
+ };
864
+ return params.execute(inputData, toolContext);
680
865
  },
681
866
  component: "TOOL"
682
867
  };
@@ -710,6 +895,8 @@ function init(inngest) {
710
895
  suspendSchema: step.suspendSchema,
711
896
  stateSchema: step.stateSchema,
712
897
  execute: step.execute,
898
+ retries: step.retries,
899
+ scorers: step.scorers,
713
900
  component: step.component
714
901
  };
715
902
  },
@@ -949,6 +1136,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
949
1136
  stepResults,
950
1137
  executionContext,
951
1138
  resume,
1139
+ timeTravel,
952
1140
  prevOutput,
953
1141
  emitter,
954
1142
  abortController,
@@ -969,7 +1157,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
969
1157
  const { inputData, validationError } = await workflows.validateStepInput({
970
1158
  prevOutput,
971
1159
  step,
972
- validateInputs: this.options?.validateInputs ?? false
1160
+ validateInputs: this.options?.validateInputs ?? true
973
1161
  });
974
1162
  const startedAt = await this.inngestStep.run(
975
1163
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
@@ -991,9 +1179,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
991
1179
  const isResume = !!resume?.steps?.length;
992
1180
  let result;
993
1181
  let runId;
1182
+ const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
994
1183
  try {
995
1184
  if (isResume) {
996
- runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
1185
+ runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
997
1186
  const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
998
1187
  workflowName: step.id,
999
1188
  runId
@@ -1009,8 +1198,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1009
1198
  steps: resume.steps.slice(1),
1010
1199
  stepResults: snapshot?.context,
1011
1200
  resumePayload: resume.resumePayload,
1012
- // @ts-ignore
1013
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1201
+ resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
1014
1202
  },
1015
1203
  outputOptions: { includeState: true }
1016
1204
  }
@@ -1018,6 +1206,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1018
1206
  result = invokeResp.result;
1019
1207
  runId = invokeResp.runId;
1020
1208
  executionContext.state = invokeResp.result.state;
1209
+ } else if (isTimeTravel) {
1210
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1211
+ workflowName: step.id,
1212
+ runId: executionContext.runId
1213
+ }) ?? { context: {} };
1214
+ const timeTravelParams = workflows.createTimeTravelExecutionParams({
1215
+ steps: timeTravel.steps.slice(1),
1216
+ inputData: timeTravel.inputData,
1217
+ resumeData: timeTravel.resumeData,
1218
+ context: timeTravel.nestedStepResults?.[step.id] ?? {},
1219
+ nestedStepsContext: timeTravel.nestedStepResults ?? {},
1220
+ snapshot,
1221
+ graph: step.buildExecutionGraph()
1222
+ });
1223
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1224
+ function: step.getFunction(),
1225
+ data: {
1226
+ timeTravel: timeTravelParams,
1227
+ initialState: executionContext.state ?? {},
1228
+ runId: executionContext.runId,
1229
+ outputOptions: { includeState: true }
1230
+ }
1231
+ });
1232
+ result = invokeResp.result;
1233
+ runId = invokeResp.runId;
1234
+ executionContext.state = invokeResp.result.state;
1021
1235
  } else {
1022
1236
  const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1023
1237
  function: step.getFunction(),
@@ -1130,14 +1344,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1130
1344
  let execResults;
1131
1345
  let suspended;
1132
1346
  let bailed;
1347
+ const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
1348
+ resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
1349
+ step
1350
+ });
1351
+ let resumeDataToUse;
1352
+ if (timeTravelResumeData && !timeTravelResumeValidationError) {
1353
+ resumeDataToUse = timeTravelResumeData;
1354
+ } else if (timeTravelResumeData && timeTravelResumeValidationError) {
1355
+ this.logger.warn("Time travel resume data validation failed", {
1356
+ stepId: step.id,
1357
+ error: timeTravelResumeValidationError.message
1358
+ });
1359
+ } else if (resume?.steps[0] === step.id) {
1360
+ resumeDataToUse = resume?.resumePayload;
1361
+ }
1133
1362
  try {
1134
1363
  if (validationError) {
1135
1364
  throw validationError;
1136
1365
  }
1366
+ const retryCount = this.getOrGenerateRetryCount(step.id);
1137
1367
  const result = await step.execute({
1138
1368
  runId: executionContext.runId,
1369
+ workflowId: executionContext.workflowId,
1139
1370
  mastra: this.mastra,
1140
1371
  requestContext,
1372
+ retryCount,
1141
1373
  writer: new tools.ToolStream(
1142
1374
  {
1143
1375
  prefix: "workflow-step",
@@ -1152,13 +1384,20 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1152
1384
  executionContext.state = state;
1153
1385
  },
1154
1386
  inputData,
1155
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1387
+ resumeData: resumeDataToUse,
1156
1388
  tracingContext: {
1157
1389
  currentSpan: stepSpan
1158
1390
  },
1159
1391
  getInitData: () => stepResults?.input,
1160
1392
  getStepResult: workflows.getStepResult.bind(this, stepResults),
1161
1393
  suspend: async (suspendPayload, suspendOptions) => {
1394
+ const { suspendData, validationError: validationError2 } = await workflows.validateStepSuspendData({
1395
+ suspendData: suspendPayload,
1396
+ step
1397
+ });
1398
+ if (validationError2) {
1399
+ throw validationError2;
1400
+ }
1162
1401
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1163
1402
  if (suspendOptions?.resumeLabel) {
1164
1403
  const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
@@ -1169,16 +1408,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1169
1408
  };
1170
1409
  }
1171
1410
  }
1172
- suspended = { payload: suspendPayload };
1411
+ suspended = { payload: suspendData };
1173
1412
  },
1174
1413
  bail: (result2) => {
1175
1414
  bailed = { payload: result2 };
1176
1415
  },
1177
- resume: {
1178
- steps: resume?.steps?.slice(1) || [],
1179
- resumePayload: resume?.resumePayload,
1180
- // @ts-ignore
1181
- runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1416
+ abort: () => {
1417
+ abortController?.abort();
1182
1418
  },
1183
1419
  [_constants.EMITTER_SYMBOL]: emitter,
1184
1420
  [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
@@ -1194,8 +1430,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1194
1430
  startedAt,
1195
1431
  endedAt,
1196
1432
  payload: inputData,
1197
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1198
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1433
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1434
+ resumePayload: resumeDataToUse
1199
1435
  };
1200
1436
  } catch (e) {
1201
1437
  const stepFailure = {
@@ -1204,8 +1440,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1204
1440
  error: e instanceof Error ? e.message : String(e),
1205
1441
  endedAt: Date.now(),
1206
1442
  startedAt,
1207
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1208
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1443
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1444
+ resumePayload: resumeDataToUse
1209
1445
  };
1210
1446
  execResults = stepFailure;
1211
1447
  const fallbackErrorMessage = `Step ${step.id} failed`;
@@ -1222,8 +1458,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1222
1458
  payload: inputData,
1223
1459
  suspendedAt: Date.now(),
1224
1460
  startedAt,
1225
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1226
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1461
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1462
+ resumePayload: resumeDataToUse
1227
1463
  };
1228
1464
  } else if (bailed) {
1229
1465
  execResults = {
@@ -1296,7 +1532,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1296
1532
  });
1297
1533
  }
1298
1534
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1299
- Object.assign(stepResults, stepRes.stepResults);
1300
1535
  executionContext.state = stepRes.executionContext.state;
1301
1536
  return stepRes.result;
1302
1537
  }
@@ -1324,17 +1559,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1324
1559
  resourceId,
1325
1560
  snapshot: {
1326
1561
  runId,
1562
+ status: workflowStatus,
1327
1563
  value: executionContext.state,
1328
1564
  context: stepResults,
1329
- activePaths: [],
1565
+ activePaths: executionContext.executionPath,
1566
+ activeStepsPath: executionContext.activeStepsPath,
1330
1567
  suspendedPaths: executionContext.suspendedPaths,
1331
1568
  resumeLabels: executionContext.resumeLabels,
1332
1569
  waitingPaths: {},
1333
1570
  serializedStepGraph,
1334
- status: workflowStatus,
1335
1571
  result,
1336
1572
  error,
1337
- // @ts-ignore
1338
1573
  timestamp: Date.now()
1339
1574
  }
1340
1575
  });
@@ -1347,6 +1582,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1347
1582
  entry,
1348
1583
  prevOutput,
1349
1584
  stepResults,
1585
+ timeTravel,
1350
1586
  resume,
1351
1587
  executionContext,
1352
1588
  emitter,
@@ -1465,10 +1701,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1465
1701
  prevOutput,
1466
1702
  stepResults,
1467
1703
  resume,
1704
+ timeTravel,
1468
1705
  executionContext: {
1469
1706
  workflowId,
1470
1707
  runId,
1471
1708
  executionPath: [...executionContext.executionPath, index],
1709
+ activeStepsPath: executionContext.activeStepsPath,
1472
1710
  suspendedPaths: executionContext.suspendedPaths,
1473
1711
  resumeLabels: executionContext.resumeLabels,
1474
1712
  retryConfig: executionContext.retryConfig,
@@ -1502,7 +1740,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1502
1740
  status: "success",
1503
1741
  output: results.reduce((acc, result, index) => {
1504
1742
  if (result.status === "success") {
1505
- acc[stepsToRun[index].step.id] = result.output;
1743
+ if ("step" in stepsToRun[index]) {
1744
+ acc[stepsToRun[index].step.id] = result.output;
1745
+ }
1506
1746
  }
1507
1747
  return acc;
1508
1748
  }, {})