@mastra/inngest 0.0.0-remove-unused-model-providers-api-20251030210744 → 0.0.0-safe-stringify-telemetry-20251205024938

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
@@ -20,7 +20,7 @@ function serve({
20
20
  functions: userFunctions = [],
21
21
  registerOptions
22
22
  }) {
23
- const wfs = mastra.listWorkflows();
23
+ const wfs = mastra.getWorkflows();
24
24
  const workflowFunctions = Array.from(
25
25
  new Set(
26
26
  Object.values(wfs).flatMap((wf) => {
@@ -105,20 +105,15 @@ var InngestRun = class extends workflows.Run {
105
105
  resourceId: this.resourceId,
106
106
  snapshot: {
107
107
  ...snapshot,
108
- status: "canceled"
108
+ status: "canceled",
109
+ value: snapshot.value
109
110
  }
110
111
  });
111
112
  }
112
113
  }
113
- async start(params) {
114
- return this._start(params);
115
- }
116
- async _start({
114
+ async start({
117
115
  inputData,
118
- initialState,
119
- outputOptions,
120
- tracingOptions,
121
- format
116
+ initialState
122
117
  }) {
123
118
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
124
119
  workflowName: this.workflowId,
@@ -127,14 +122,15 @@ var InngestRun = class extends workflows.Run {
127
122
  snapshot: {
128
123
  runId: this.runId,
129
124
  serializedStepGraph: this.serializedStepGraph,
125
+ status: "running",
130
126
  value: {},
131
127
  context: {},
132
128
  activePaths: [],
133
129
  suspendedPaths: {},
130
+ activeStepsPath: {},
134
131
  resumeLabels: {},
135
132
  waitingPaths: {},
136
- timestamp: Date.now(),
137
- status: "running"
133
+ timestamp: Date.now()
138
134
  }
139
135
  });
140
136
  const inputDataToUse = await this._validateInput(inputData);
@@ -145,10 +141,7 @@ var InngestRun = class extends workflows.Run {
145
141
  inputData: inputDataToUse,
146
142
  initialState: initialStateToUse,
147
143
  runId: this.runId,
148
- resourceId: this.resourceId,
149
- outputOptions,
150
- tracingOptions,
151
- format
144
+ resourceId: this.resourceId
152
145
  }
153
146
  });
154
147
  const eventId = eventOutput.ids[0];
@@ -177,10 +170,16 @@ var InngestRun = class extends workflows.Run {
177
170
  return p;
178
171
  }
179
172
  async _resume(params) {
180
- const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
181
- (step) => typeof step === "string" ? step : step?.id
182
- );
183
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
173
+ const storage = this.#mastra?.getStorage();
174
+ let steps = [];
175
+ if (typeof params.step === "string") {
176
+ steps = params.step.split(".");
177
+ } else {
178
+ steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
179
+ (step) => typeof step === "string" ? step : step?.id
180
+ );
181
+ }
182
+ const snapshot = await storage?.loadWorkflowSnapshot({
184
183
  workflowName: this.workflowId,
185
184
  runId: this.runId
186
185
  });
@@ -237,35 +236,111 @@ var InngestRun = class extends workflows.Run {
237
236
  });
238
237
  };
239
238
  }
240
- streamLegacy({ inputData, requestContext } = {}) {
239
+ async timeTravel(params) {
240
+ const p = this._timeTravel(params).then((result) => {
241
+ if (result.status !== "suspended") {
242
+ this.closeStreamAction?.().catch(() => {
243
+ });
244
+ }
245
+ return result;
246
+ });
247
+ this.executionResults = p;
248
+ return p;
249
+ }
250
+ async _timeTravel(params) {
251
+ if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
252
+ throw new Error("Step is required and must be a valid step or array of steps");
253
+ }
254
+ let steps = [];
255
+ if (typeof params.step === "string") {
256
+ steps = params.step.split(".");
257
+ } else {
258
+ steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
259
+ (step) => typeof step === "string" ? step : step?.id
260
+ );
261
+ }
262
+ if (steps.length === 0) {
263
+ throw new Error("No steps provided to timeTravel");
264
+ }
265
+ const storage = this.#mastra?.getStorage();
266
+ const snapshot = await storage?.loadWorkflowSnapshot({
267
+ workflowName: this.workflowId,
268
+ runId: this.runId
269
+ });
270
+ if (!snapshot) {
271
+ await storage?.persistWorkflowSnapshot({
272
+ workflowName: this.workflowId,
273
+ runId: this.runId,
274
+ resourceId: this.resourceId,
275
+ snapshot: {
276
+ runId: this.runId,
277
+ serializedStepGraph: this.serializedStepGraph,
278
+ status: "pending",
279
+ value: {},
280
+ context: {},
281
+ activePaths: [],
282
+ suspendedPaths: {},
283
+ activeStepsPath: {},
284
+ resumeLabels: {},
285
+ waitingPaths: {},
286
+ timestamp: Date.now()
287
+ }
288
+ });
289
+ }
290
+ if (snapshot?.status === "running") {
291
+ throw new Error("This workflow run is still running, cannot time travel");
292
+ }
293
+ let inputDataToUse = params.inputData;
294
+ if (inputDataToUse && steps.length === 1) {
295
+ inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]]);
296
+ }
297
+ const timeTravelData = workflows.createTimeTravelExecutionParams({
298
+ steps,
299
+ inputData: inputDataToUse,
300
+ resumeData: params.resumeData,
301
+ context: params.context,
302
+ nestedStepsContext: params.nestedStepsContext,
303
+ snapshot: snapshot ?? { context: {} },
304
+ graph: this.executionGraph,
305
+ initialState: params.initialState
306
+ });
307
+ const eventOutput = await this.inngest.send({
308
+ name: `workflow.${this.workflowId}`,
309
+ data: {
310
+ initialState: timeTravelData.state,
311
+ runId: this.runId,
312
+ workflowId: this.workflowId,
313
+ stepResults: timeTravelData.stepResults,
314
+ timeTravel: timeTravelData,
315
+ tracingOptions: params.tracingOptions,
316
+ outputOptions: params.outputOptions
317
+ }
318
+ });
319
+ const eventId = eventOutput.ids[0];
320
+ if (!eventId) {
321
+ throw new Error("Event ID is not set");
322
+ }
323
+ const runOutput = await this.getRunOutput(eventId);
324
+ const result = runOutput?.output?.result;
325
+ if (result.status === "failed") {
326
+ result.error = new Error(result.error);
327
+ }
328
+ return result;
329
+ }
330
+ streamLegacy({ inputData, runtimeContext } = {}) {
241
331
  const { readable, writable } = new TransformStream();
242
332
  const writer = writable.getWriter();
243
333
  const unwatch = this.watch(async (event) => {
244
334
  try {
245
- await writer.write({
246
- // @ts-ignore
247
- type: "start",
248
- // @ts-ignore
249
- payload: { runId: this.runId }
250
- });
251
335
  const e = {
252
336
  ...event,
253
337
  type: event.type.replace("workflow-", "")
254
338
  };
255
- if (e.type === "step-output") {
256
- e.type = e.payload.output.type;
257
- e.payload = e.payload.output.payload;
258
- }
259
339
  await writer.write(e);
260
340
  } catch {
261
341
  }
262
342
  }, "watch-v2");
263
343
  this.closeStreamAction = async () => {
264
- await writer.write({
265
- type: "finish",
266
- // @ts-ignore
267
- payload: { runId: this.runId }
268
- });
269
344
  unwatch();
270
345
  try {
271
346
  await writer.close();
@@ -275,7 +350,7 @@ var InngestRun = class extends workflows.Run {
275
350
  writer.releaseLock();
276
351
  }
277
352
  };
278
- this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
353
+ this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
279
354
  if (result.status !== "suspended") {
280
355
  this.closeStreamAction?.().catch(() => {
281
356
  });
@@ -289,18 +364,69 @@ var InngestRun = class extends workflows.Run {
289
364
  }
290
365
  stream({
291
366
  inputData,
292
- requestContext,
293
- tracingOptions,
294
- closeOnSuspend = true,
367
+ runtimeContext,
368
+ closeOnSuspend = true
369
+ } = {}) {
370
+ const self = this;
371
+ let streamOutput;
372
+ const stream$1 = new web.ReadableStream({
373
+ async start(controller) {
374
+ const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
375
+ controller.enqueue({
376
+ type,
377
+ runId: self.runId,
378
+ from,
379
+ payload: {
380
+ stepName: payload.id,
381
+ ...payload
382
+ }
383
+ });
384
+ }, "watch-v2");
385
+ self.closeStreamAction = async () => {
386
+ unwatch();
387
+ try {
388
+ await controller.close();
389
+ } catch (err) {
390
+ console.error("Error closing stream:", err);
391
+ }
392
+ };
393
+ const executionResultsPromise = self.start({
394
+ inputData,
395
+ runtimeContext
396
+ });
397
+ const executionResults = await executionResultsPromise;
398
+ if (closeOnSuspend) {
399
+ self.closeStreamAction?.().catch(() => {
400
+ });
401
+ } else if (executionResults.status !== "suspended") {
402
+ self.closeStreamAction?.().catch(() => {
403
+ });
404
+ }
405
+ if (streamOutput) {
406
+ streamOutput.updateResults(executionResults);
407
+ }
408
+ }
409
+ });
410
+ streamOutput = new stream.WorkflowRunOutput({
411
+ runId: this.runId,
412
+ workflowId: this.workflowId,
413
+ stream: stream$1
414
+ });
415
+ return streamOutput;
416
+ }
417
+ timeTravelStream({
418
+ inputData,
419
+ resumeData,
295
420
  initialState,
421
+ step,
422
+ context,
423
+ nestedStepsContext,
424
+ runtimeContext,
425
+ tracingOptions,
296
426
  outputOptions
297
- } = {}) {
298
- if (this.closeStreamAction && this.streamOutput) {
299
- return this.streamOutput;
300
- }
301
- this.closeStreamAction = async () => {
302
- };
427
+ }) {
303
428
  const self = this;
429
+ let streamOutput;
304
430
  const stream$1 = new web.ReadableStream({
305
431
  async start(controller) {
306
432
  const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
@@ -322,46 +448,39 @@ var InngestRun = class extends workflows.Run {
322
448
  console.error("Error closing stream:", err);
323
449
  }
324
450
  };
325
- const executionResultsPromise = self._start({
451
+ const executionResultsPromise = self._timeTravel({
326
452
  inputData,
327
- requestContext,
328
- // tracingContext, // We are not able to pass a reference to a span here, what to do?
453
+ step,
454
+ context,
455
+ nestedStepsContext,
456
+ resumeData,
329
457
  initialState,
458
+ runtimeContext,
330
459
  tracingOptions,
331
- outputOptions,
332
- format: "vnext"
460
+ outputOptions
333
461
  });
462
+ self.executionResults = executionResultsPromise;
334
463
  let executionResults;
335
464
  try {
336
465
  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
- );
466
+ self.closeStreamAction?.().catch(() => {
467
+ });
468
+ if (streamOutput) {
469
+ streamOutput.updateResults(executionResults);
348
470
  }
349
471
  } catch (err) {
350
- self.streamOutput?.rejectResults(err);
472
+ streamOutput?.rejectResults(err);
351
473
  self.closeStreamAction?.().catch(() => {
352
474
  });
353
475
  }
354
476
  }
355
477
  });
356
- this.streamOutput = new stream.WorkflowRunOutput({
478
+ streamOutput = new stream.WorkflowRunOutput({
357
479
  runId: this.runId,
358
480
  workflowId: this.workflowId,
359
481
  stream: stream$1
360
482
  });
361
- return this.streamOutput;
362
- }
363
- streamVNext(args = {}) {
364
- return this.stream(args);
483
+ return streamOutput;
365
484
  }
366
485
  };
367
486
  var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
@@ -372,6 +491,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
372
491
  constructor(params, inngest) {
373
492
  const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
374
493
  super(workflowParams);
494
+ this.engineType = "inngest";
375
495
  const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
376
496
  ([_, value]) => value !== void 0
377
497
  );
@@ -379,13 +499,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
379
499
  this.#mastra = params.mastra;
380
500
  this.inngest = inngest;
381
501
  }
382
- async listWorkflowRuns(args) {
502
+ async getWorkflowRuns(args) {
383
503
  const storage = this.#mastra?.getStorage();
384
504
  if (!storage) {
385
505
  this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
386
506
  return { runs: [], total: 0 };
387
507
  }
388
- return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
508
+ return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
389
509
  }
390
510
  async getWorkflowRunById(runId) {
391
511
  const storage = this.#mastra?.getStorage();
@@ -436,7 +556,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
436
556
  mastra: this.#mastra,
437
557
  retryConfig: this.retryConfig,
438
558
  cleanup: () => this.runs.delete(runIdToUse),
439
- workflowSteps: this.steps
559
+ workflowSteps: this.steps,
560
+ workflowEngineType: this.engineType,
561
+ validateInputs: this.options.validateInputs
440
562
  },
441
563
  this.inngest
442
564
  );
@@ -457,6 +579,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
457
579
  value: {},
458
580
  context: {},
459
581
  activePaths: [],
582
+ activeStepsPath: {},
460
583
  waitingPaths: {},
461
584
  serializedStepGraph: this.serializedStepGraph,
462
585
  suspendedPaths: {},
@@ -485,7 +608,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
485
608
  },
486
609
  { event: `workflow.${this.id}` },
487
610
  async ({ event, step, attempt, publish }) => {
488
- let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
611
+ let { inputData, initialState, runId, resourceId, resume, outputOptions, timeTravel } = event.data;
489
612
  if (!runId) {
490
613
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
491
614
  return crypto.randomUUID();
@@ -524,19 +647,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
524
647
  initialState,
525
648
  emitter,
526
649
  retryConfig: this.retryConfig,
527
- requestContext: new di.RequestContext(),
650
+ runtimeContext: new di.RuntimeContext(),
528
651
  // TODO
529
652
  resume,
530
- format,
653
+ timeTravel,
531
654
  abortController: new AbortController(),
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
- })
655
+ currentSpan: void 0,
656
+ // TODO: Pass actual parent AI span from workflow execution context
657
+ outputOptions
540
658
  });
541
659
  await step.run(`workflow.${this.id}.finalize`, async () => {
542
660
  if (result.status === "failed") {
@@ -574,7 +692,7 @@ function isAgent(params) {
574
692
  function isTool(params) {
575
693
  return params instanceof tools.Tool;
576
694
  }
577
- function createStep(params, agentOptions) {
695
+ function createStep(params) {
578
696
  if (isAgent(params)) {
579
697
  return {
580
698
  id: params.name,
@@ -582,23 +700,12 @@ function createStep(params, agentOptions) {
582
700
  // @ts-ignore
583
701
  inputSchema: zod.z.object({
584
702
  prompt: zod.z.string()
585
- // resourceId: z.string().optional(),
586
- // threadId: z.string().optional(),
587
703
  }),
588
704
  // @ts-ignore
589
705
  outputSchema: zod.z.object({
590
706
  text: zod.z.string()
591
707
  }),
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
- }) => {
708
+ execute: async ({ inputData, [_constants.EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
602
709
  let streamPromise = {};
603
710
  streamPromise.promise = new Promise((resolve, reject) => {
604
711
  streamPromise.resolve = resolve;
@@ -608,40 +715,48 @@ function createStep(params, agentOptions) {
608
715
  name: params.name,
609
716
  args: inputData
610
717
  };
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,
718
+ if ((await params.getLLM()).getModel().specificationVersion === `v2`) {
719
+ const { fullStream } = await params.stream(inputData.prompt, {
720
+ runtimeContext,
618
721
  tracingContext,
619
722
  onFinish: (result) => {
620
723
  streamPromise.resolve(result.text);
621
- void agentOptions?.onFinish?.(result);
622
724
  },
623
725
  abortSignal
624
726
  });
625
- stream = fullStream;
727
+ if (abortSignal.aborted) {
728
+ return abort();
729
+ }
730
+ await emitter.emit("watch-v2", {
731
+ type: "tool-call-streaming-start",
732
+ ...toolData ?? {}
733
+ });
734
+ for await (const chunk of fullStream) {
735
+ if (chunk.type === "text-delta") {
736
+ await emitter.emit("watch-v2", {
737
+ type: "tool-call-delta",
738
+ ...toolData ?? {},
739
+ argsTextDelta: chunk.payload.text
740
+ });
741
+ }
742
+ }
626
743
  } else {
627
- const modelOutput = await params.stream(inputData.prompt, {
628
- ...agentOptions ?? {},
629
- requestContext,
744
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
745
+ runtimeContext,
630
746
  tracingContext,
631
747
  onFinish: (result) => {
632
748
  streamPromise.resolve(result.text);
633
- void agentOptions?.onFinish?.(result);
634
749
  },
635
750
  abortSignal
636
751
  });
637
- stream = modelOutput.fullStream;
638
- }
639
- if (streamFormat === "legacy") {
752
+ if (abortSignal.aborted) {
753
+ return abort();
754
+ }
640
755
  await emitter.emit("watch-v2", {
641
756
  type: "tool-call-streaming-start",
642
757
  ...toolData ?? {}
643
758
  });
644
- for await (const chunk of stream) {
759
+ for await (const chunk of fullStream) {
645
760
  if (chunk.type === "text-delta") {
646
761
  await emitter.emit("watch-v2", {
647
762
  type: "tool-call-delta",
@@ -650,18 +765,11 @@ function createStep(params, agentOptions) {
650
765
  });
651
766
  }
652
767
  }
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
- }
662
- if (abortSignal.aborted) {
663
- return abort();
664
768
  }
769
+ await emitter.emit("watch-v2", {
770
+ type: "tool-call-streaming-finish",
771
+ ...toolData ?? {}
772
+ });
665
773
  return {
666
774
  text: await streamPromise.promise
667
775
  };
@@ -680,11 +788,11 @@ function createStep(params, agentOptions) {
680
788
  description: params.description,
681
789
  inputSchema: params.inputSchema,
682
790
  outputSchema: params.outputSchema,
683
- execute: async ({ inputData, mastra, requestContext, tracingContext, suspend, resumeData }) => {
791
+ execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
684
792
  return params.execute({
685
793
  context: inputData,
686
794
  mastra: aiTracing.wrapMastra(mastra, tracingContext),
687
- requestContext,
795
+ runtimeContext,
688
796
  tracingContext,
689
797
  suspend,
690
798
  resumeData
@@ -747,7 +855,19 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
747
855
  this.inngestStep = inngestStep;
748
856
  this.inngestAttempts = inngestAttempts;
749
857
  }
750
- async fmtReturnValue(emitter, stepResults, lastOutput, error) {
858
+ async execute(params) {
859
+ await params.emitter.emit("watch-v2", {
860
+ type: "workflow-start",
861
+ payload: { runId: params.runId }
862
+ });
863
+ const result = await super.execute(params);
864
+ await params.emitter.emit("watch-v2", {
865
+ type: "workflow-finish",
866
+ payload: { runId: params.runId }
867
+ });
868
+ return result;
869
+ }
870
+ async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
751
871
  const base = {
752
872
  status: lastOutput.status,
753
873
  steps: stepResults
@@ -801,6 +921,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
801
921
  });
802
922
  base.suspended = suspendedStepIds;
803
923
  }
924
+ executionSpan?.end();
804
925
  return base;
805
926
  }
806
927
  // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
@@ -814,7 +935,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
814
935
  stepResults,
815
936
  emitter,
816
937
  abortController,
817
- requestContext,
938
+ runtimeContext,
818
939
  executionContext,
819
940
  writableStream,
820
941
  tracingContext
@@ -832,54 +953,45 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
832
953
  if (fn) {
833
954
  const stepCallId = crypto.randomUUID();
834
955
  duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
835
- return await fn(
836
- workflows.createDeprecationProxy(
956
+ return await fn({
957
+ runId,
958
+ workflowId,
959
+ mastra: this.mastra,
960
+ runtimeContext,
961
+ inputData: prevOutput,
962
+ state: executionContext.state,
963
+ setState: (state) => {
964
+ executionContext.state = state;
965
+ },
966
+ runCount: -1,
967
+ tracingContext: {
968
+ currentSpan: sleepSpan
969
+ },
970
+ getInitData: () => stepResults?.input,
971
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
972
+ // TODO: this function shouldn't have suspend probably?
973
+ suspend: async (_suspendPayload) => {
974
+ },
975
+ bail: () => {
976
+ },
977
+ abort: () => {
978
+ abortController?.abort();
979
+ },
980
+ [_constants.EMITTER_SYMBOL]: emitter,
981
+ // TODO: add streamVNext support
982
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
983
+ engine: { step: this.inngestStep },
984
+ abortSignal: abortController?.signal,
985
+ writer: new tools.ToolStream(
837
986
  {
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
- )
987
+ prefix: "workflow-step",
988
+ callId: stepCallId,
989
+ name: "sleep",
990
+ runId
875
991
  },
876
- {
877
- paramName: "runCount",
878
- deprecationMessage: workflows.runCountDeprecationMessage,
879
- logger: this.logger
880
- }
992
+ writableStream
881
993
  )
882
- );
994
+ });
883
995
  });
884
996
  sleepSpan?.update({
885
997
  attributes: {
@@ -903,7 +1015,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
903
1015
  stepResults,
904
1016
  emitter,
905
1017
  abortController,
906
- requestContext,
1018
+ runtimeContext,
907
1019
  executionContext,
908
1020
  writableStream,
909
1021
  tracingContext
@@ -922,54 +1034,45 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
922
1034
  if (fn) {
923
1035
  date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
924
1036
  const stepCallId = crypto.randomUUID();
925
- return await fn(
926
- workflows.createDeprecationProxy(
1037
+ return await fn({
1038
+ runId,
1039
+ workflowId,
1040
+ mastra: this.mastra,
1041
+ runtimeContext,
1042
+ inputData: prevOutput,
1043
+ state: executionContext.state,
1044
+ setState: (state) => {
1045
+ executionContext.state = state;
1046
+ },
1047
+ runCount: -1,
1048
+ tracingContext: {
1049
+ currentSpan: sleepUntilSpan
1050
+ },
1051
+ getInitData: () => stepResults?.input,
1052
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1053
+ // TODO: this function shouldn't have suspend probably?
1054
+ suspend: async (_suspendPayload) => {
1055
+ },
1056
+ bail: () => {
1057
+ },
1058
+ abort: () => {
1059
+ abortController?.abort();
1060
+ },
1061
+ [_constants.EMITTER_SYMBOL]: emitter,
1062
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1063
+ // TODO: add streamVNext support
1064
+ engine: { step: this.inngestStep },
1065
+ abortSignal: abortController?.signal,
1066
+ writer: new tools.ToolStream(
927
1067
  {
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
- )
1068
+ prefix: "workflow-step",
1069
+ callId: stepCallId,
1070
+ name: "sleep",
1071
+ runId
965
1072
  },
966
- {
967
- paramName: "runCount",
968
- deprecationMessage: workflows.runCountDeprecationMessage,
969
- logger: this.logger
970
- }
1073
+ writableStream
971
1074
  )
972
- );
1075
+ });
973
1076
  });
974
1077
  if (date && !(date instanceof Date)) {
975
1078
  date = new Date(date);
@@ -1008,10 +1111,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1008
1111
  stepResults,
1009
1112
  executionContext,
1010
1113
  resume,
1114
+ timeTravel,
1011
1115
  prevOutput,
1012
1116
  emitter,
1013
1117
  abortController,
1014
- requestContext,
1118
+ runtimeContext,
1015
1119
  tracingContext,
1016
1120
  writableStream,
1017
1121
  disableScorers
@@ -1071,6 +1175,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1071
1175
  const isResume = !!resume?.steps?.length;
1072
1176
  let result;
1073
1177
  let runId;
1178
+ const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
1074
1179
  try {
1075
1180
  if (isResume) {
1076
1181
  runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
@@ -1098,6 +1203,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1098
1203
  result = invokeResp.result;
1099
1204
  runId = invokeResp.runId;
1100
1205
  executionContext.state = invokeResp.result.state;
1206
+ } else if (isTimeTravel) {
1207
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1208
+ workflowName: step.id,
1209
+ runId: executionContext.runId
1210
+ }) ?? { context: {} };
1211
+ const timeTravelParams = workflows.createTimeTravelExecutionParams({
1212
+ steps: timeTravel.steps.slice(1),
1213
+ inputData: timeTravel.inputData,
1214
+ resumeData: timeTravel.resumeData,
1215
+ context: timeTravel.nestedStepResults?.[step.id] ?? {},
1216
+ nestedStepsContext: timeTravel.nestedStepResults ?? {},
1217
+ snapshot,
1218
+ graph: step.buildExecutionGraph()
1219
+ });
1220
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1221
+ function: step.getFunction(),
1222
+ data: {
1223
+ timeTravel: timeTravelParams,
1224
+ initialState: executionContext.state ?? {},
1225
+ runId: executionContext.runId,
1226
+ outputOptions: { includeState: true }
1227
+ }
1228
+ });
1229
+ result = invokeResp.result;
1230
+ runId = invokeResp.runId;
1231
+ executionContext.state = invokeResp.result.state;
1101
1232
  } else {
1102
1233
  const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1103
1234
  function: step.getFunction(),
@@ -1158,12 +1289,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1158
1289
  });
1159
1290
  return { executionContext, result: { status: "failed", error: result?.error } };
1160
1291
  } else if (result.status === "suspended") {
1161
- const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
1162
- const stepRes2 = stepResult;
1292
+ const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult2]) => {
1293
+ const stepRes2 = stepResult2;
1163
1294
  return stepRes2?.status === "suspended";
1164
1295
  });
1165
- for (const [stepName, stepResult] of suspendedSteps) {
1166
- const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
1296
+ for (const [stepName, stepResult2] of suspendedSteps) {
1297
+ const suspendPath = [stepName, ...stepResult2?.suspendPayload?.__workflow_meta?.path ?? []];
1167
1298
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1168
1299
  await emitter.emit("watch", {
1169
1300
  type: "watch",
@@ -1171,9 +1302,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1171
1302
  currentStep: {
1172
1303
  id: step.id,
1173
1304
  status: "suspended",
1174
- payload: stepResult.payload,
1305
+ payload: stepResult2.payload,
1175
1306
  suspendPayload: {
1176
- ...stepResult?.suspendPayload,
1307
+ ...stepResult2?.suspendPayload,
1177
1308
  __workflow_meta: { runId, path: suspendPath }
1178
1309
  }
1179
1310
  },
@@ -1197,9 +1328,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1197
1328
  executionContext,
1198
1329
  result: {
1199
1330
  status: "suspended",
1200
- payload: stepResult.payload,
1331
+ payload: stepResult2.payload,
1201
1332
  suspendPayload: {
1202
- ...stepResult?.suspendPayload,
1333
+ ...stepResult2?.suspendPayload,
1203
1334
  __workflow_meta: { runId, path: suspendPath }
1204
1335
  }
1205
1336
  }
@@ -1266,7 +1397,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1266
1397
  }
1267
1398
  );
1268
1399
  Object.assign(executionContext, res.executionContext);
1269
- return {
1400
+ const stepResult = {
1270
1401
  ...res.result,
1271
1402
  startedAt,
1272
1403
  endedAt: Date.now(),
@@ -1274,14 +1405,29 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1274
1405
  resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1275
1406
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1276
1407
  };
1408
+ return { result: stepResult, executionContextState: executionContext.state };
1277
1409
  }
1278
- const stepCallId = crypto.randomUUID();
1279
1410
  let stepRes;
1280
1411
  try {
1281
1412
  stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1282
1413
  let execResults;
1283
1414
  let suspended;
1284
1415
  let bailed;
1416
+ const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
1417
+ resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
1418
+ step
1419
+ });
1420
+ let resumeDataToUse;
1421
+ if (timeTravelResumeData && !timeTravelResumeValidationError) {
1422
+ resumeDataToUse = timeTravelResumeData;
1423
+ } else if (timeTravelResumeData && timeTravelResumeValidationError) {
1424
+ this.logger.warn("Time travel resume data validation failed", {
1425
+ stepId: step.id,
1426
+ error: timeTravelResumeValidationError.message
1427
+ });
1428
+ } else if (resume?.steps[0] === step.id) {
1429
+ resumeDataToUse = resume?.resumePayload;
1430
+ }
1285
1431
  try {
1286
1432
  if (validationError) {
1287
1433
  throw validationError;
@@ -1289,22 +1435,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1289
1435
  const result = await step.execute({
1290
1436
  runId: executionContext.runId,
1291
1437
  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
- ),
1438
+ runtimeContext,
1439
+ writableStream,
1302
1440
  state: executionContext?.state ?? {},
1303
1441
  setState: (state) => {
1304
1442
  executionContext.state = state;
1305
1443
  },
1306
1444
  inputData,
1307
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1445
+ resumeData: resumeDataToUse,
1308
1446
  tracingContext: {
1309
1447
  currentSpan: stepAISpan
1310
1448
  },
@@ -1333,7 +1471,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1333
1471
  runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1334
1472
  },
1335
1473
  [_constants.EMITTER_SYMBOL]: emitter,
1336
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1337
1474
  engine: {
1338
1475
  step: this.inngestStep
1339
1476
  },
@@ -1346,18 +1483,18 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1346
1483
  startedAt,
1347
1484
  endedAt,
1348
1485
  payload: inputData,
1349
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1350
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1486
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1487
+ resumePayload: resumeDataToUse
1351
1488
  };
1352
1489
  } catch (e) {
1353
1490
  const stepFailure = {
1354
1491
  status: "failed",
1355
1492
  payload: inputData,
1356
- error: e instanceof Error ? e.message : String(e),
1493
+ error: e instanceof Error ? e.stack ?? e.message : String(e),
1357
1494
  endedAt: Date.now(),
1358
1495
  startedAt,
1359
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1360
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1496
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1497
+ resumePayload: resumeDataToUse
1361
1498
  };
1362
1499
  execResults = stepFailure;
1363
1500
  const fallbackErrorMessage = `Step ${step.id} failed`;
@@ -1373,8 +1510,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1373
1510
  payload: inputData,
1374
1511
  suspendedAt: Date.now(),
1375
1512
  startedAt,
1376
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1377
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1513
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1514
+ resumePayload: resumeDataToUse
1378
1515
  };
1379
1516
  } else if (bailed) {
1380
1517
  execResults = {
@@ -1431,11 +1568,25 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1431
1568
  } catch (e) {
1432
1569
  const stepFailure = e instanceof Error ? e?.cause : {
1433
1570
  status: "failed",
1434
- error: e instanceof Error ? e.message : String(e),
1571
+ error: e instanceof Error ? e.stack ?? e.message : String(e),
1435
1572
  payload: inputData,
1436
1573
  startedAt,
1437
1574
  endedAt: Date.now()
1438
1575
  };
1576
+ await emitter.emit("watch-v2", {
1577
+ type: "workflow-step-result",
1578
+ payload: {
1579
+ id: step.id,
1580
+ ...stepFailure
1581
+ }
1582
+ });
1583
+ await emitter.emit("watch-v2", {
1584
+ type: "workflow-step-finish",
1585
+ payload: {
1586
+ id: step.id,
1587
+ metadata: {}
1588
+ }
1589
+ });
1439
1590
  stepRes = {
1440
1591
  result: stepFailure,
1441
1592
  executionContext,
@@ -1455,7 +1606,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1455
1606
  output: stepRes.result,
1456
1607
  workflowId: executionContext.workflowId,
1457
1608
  stepId: step.id,
1458
- requestContext,
1609
+ runtimeContext,
1459
1610
  disableScorers,
1460
1611
  tracingContext: { currentSpan: stepAISpan }
1461
1612
  });
@@ -1463,9 +1614,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1463
1614
  });
1464
1615
  }
1465
1616
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1466
- Object.assign(stepResults, stepRes.stepResults);
1467
1617
  executionContext.state = stepRes.executionContext.state;
1468
- return stepRes.result;
1618
+ return {
1619
+ result: stepRes.result,
1620
+ executionContextState: stepRes.executionContext.state
1621
+ };
1469
1622
  }
1470
1623
  async persistStepUpdate({
1471
1624
  workflowId,
@@ -1491,14 +1644,15 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1491
1644
  resourceId,
1492
1645
  snapshot: {
1493
1646
  runId,
1647
+ status: workflowStatus,
1494
1648
  value: executionContext.state,
1495
1649
  context: stepResults,
1496
- activePaths: [],
1650
+ activePaths: executionContext.executionPath,
1651
+ activeStepsPath: executionContext.activeStepsPath,
1497
1652
  suspendedPaths: executionContext.suspendedPaths,
1498
1653
  resumeLabels: executionContext.resumeLabels,
1499
1654
  waitingPaths: {},
1500
1655
  serializedStepGraph,
1501
- status: workflowStatus,
1502
1656
  result,
1503
1657
  error,
1504
1658
  // @ts-ignore
@@ -1514,11 +1668,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1514
1668
  entry,
1515
1669
  prevOutput,
1516
1670
  stepResults,
1671
+ timeTravel,
1517
1672
  resume,
1518
1673
  executionContext,
1519
1674
  emitter,
1520
1675
  abortController,
1521
- requestContext,
1676
+ runtimeContext,
1522
1677
  writableStream,
1523
1678
  disableScorers,
1524
1679
  tracingContext
@@ -1546,56 +1701,47 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1546
1701
  tracingPolicy: this.options?.tracingPolicy
1547
1702
  });
1548
1703
  try {
1549
- const result = await cond(
1550
- workflows.createDeprecationProxy(
1704
+ const result = await cond({
1705
+ runId,
1706
+ workflowId,
1707
+ mastra: this.mastra,
1708
+ runtimeContext,
1709
+ runCount: -1,
1710
+ inputData: prevOutput,
1711
+ state: executionContext.state,
1712
+ setState: (state) => {
1713
+ executionContext.state = state;
1714
+ },
1715
+ tracingContext: {
1716
+ currentSpan: evalSpan
1717
+ },
1718
+ getInitData: () => stepResults?.input,
1719
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1720
+ // TODO: this function shouldn't have suspend probably?
1721
+ suspend: async (_suspendPayload) => {
1722
+ },
1723
+ bail: () => {
1724
+ },
1725
+ abort: () => {
1726
+ abortController.abort();
1727
+ },
1728
+ [_constants.EMITTER_SYMBOL]: emitter,
1729
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1730
+ // TODO: add streamVNext support
1731
+ engine: {
1732
+ step: this.inngestStep
1733
+ },
1734
+ abortSignal: abortController.signal,
1735
+ writer: new tools.ToolStream(
1551
1736
  {
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
- )
1737
+ prefix: "workflow-step",
1738
+ callId: crypto.randomUUID(),
1739
+ name: "conditional",
1740
+ runId
1591
1741
  },
1592
- {
1593
- paramName: "runCount",
1594
- deprecationMessage: workflows.runCountDeprecationMessage,
1595
- logger: this.logger
1596
- }
1742
+ writableStream
1597
1743
  )
1598
- );
1744
+ });
1599
1745
  evalSpan?.end({
1600
1746
  output: result,
1601
1747
  attributes: {
@@ -1633,26 +1779,30 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1633
1779
  prevOutput,
1634
1780
  stepResults,
1635
1781
  resume,
1782
+ timeTravel,
1636
1783
  executionContext: {
1637
1784
  workflowId,
1638
1785
  runId,
1639
1786
  executionPath: [...executionContext.executionPath, index],
1787
+ activeStepsPath: executionContext.activeStepsPath,
1640
1788
  suspendedPaths: executionContext.suspendedPaths,
1641
1789
  resumeLabels: executionContext.resumeLabels,
1642
1790
  retryConfig: executionContext.retryConfig,
1791
+ executionSpan: executionContext.executionSpan,
1643
1792
  state: executionContext.state
1644
1793
  },
1645
1794
  emitter,
1646
1795
  abortController,
1647
- requestContext,
1796
+ runtimeContext,
1648
1797
  writableStream,
1649
1798
  disableScorers,
1650
1799
  tracingContext: {
1651
1800
  currentSpan: conditionalSpan
1652
1801
  }
1653
1802
  });
1654
- stepResults[step.step.id] = result;
1655
- return result;
1803
+ stepResults[step.step.id] = result.result;
1804
+ executionContext.state = result.executionContextState;
1805
+ return result.result;
1656
1806
  })
1657
1807
  );
1658
1808
  const hasFailed = results.find((result) => result.status === "failed");