@mastra/inngest 0.0.0-monorepo-binary-20251013210052 → 0.0.0-netlify-no-bundle-20251127120354

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,9 +1,11 @@
1
1
  'use strict';
2
2
 
3
3
  var crypto = require('crypto');
4
+ var web = require('stream/web');
4
5
  var realtime = require('@inngest/realtime');
5
- var aiTracing = require('@mastra/core/ai-tracing');
6
6
  var di = require('@mastra/core/di');
7
+ var observability = require('@mastra/core/observability');
8
+ var stream = require('@mastra/core/stream');
7
9
  var tools = require('@mastra/core/tools');
8
10
  var workflows = require('@mastra/core/workflows');
9
11
  var _constants = require('@mastra/core/workflows/_constants');
@@ -18,7 +20,7 @@ function serve({
18
20
  functions: userFunctions = [],
19
21
  registerOptions
20
22
  }) {
21
- const wfs = mastra.getWorkflows();
23
+ const wfs = mastra.listWorkflows();
22
24
  const workflowFunctions = Array.from(
23
25
  new Set(
24
26
  Object.values(wfs).flatMap((wf) => {
@@ -57,11 +59,12 @@ var InngestRun = class extends workflows.Run {
57
59
  }
58
60
  async getRunOutput(eventId) {
59
61
  let runs = await this.getRuns(eventId);
62
+ const storage = this.#mastra?.getStorage();
60
63
  while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
61
64
  await new Promise((resolve) => setTimeout(resolve, 1e3));
62
65
  runs = await this.getRuns(eventId);
63
66
  if (runs?.[0]?.status === "Failed") {
64
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
67
+ const snapshot = await storage?.loadWorkflowSnapshot({
65
68
  workflowName: this.workflowId,
66
69
  runId: this.runId
67
70
  });
@@ -70,7 +73,7 @@ var InngestRun = class extends workflows.Run {
70
73
  };
71
74
  }
72
75
  if (runs?.[0]?.status === "Cancelled") {
73
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
76
+ const snapshot = await storage?.loadWorkflowSnapshot({
74
77
  workflowName: this.workflowId,
75
78
  runId: this.runId
76
79
  });
@@ -79,38 +82,40 @@ var InngestRun = class extends workflows.Run {
79
82
  }
80
83
  return runs?.[0];
81
84
  }
82
- async sendEvent(event, data) {
83
- await this.inngest.send({
84
- name: `user-event-${event}`,
85
- data
86
- });
87
- }
88
85
  async cancel() {
86
+ const storage = this.#mastra?.getStorage();
89
87
  await this.inngest.send({
90
88
  name: `cancel.workflow.${this.workflowId}`,
91
89
  data: {
92
90
  runId: this.runId
93
91
  }
94
92
  });
95
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
93
+ const snapshot = await storage?.loadWorkflowSnapshot({
96
94
  workflowName: this.workflowId,
97
95
  runId: this.runId
98
96
  });
99
97
  if (snapshot) {
100
- await this.#mastra?.storage?.persistWorkflowSnapshot({
98
+ await storage?.persistWorkflowSnapshot({
101
99
  workflowName: this.workflowId,
102
100
  runId: this.runId,
103
101
  resourceId: this.resourceId,
104
102
  snapshot: {
105
103
  ...snapshot,
106
- status: "canceled"
104
+ status: "canceled",
105
+ value: snapshot.value
107
106
  }
108
107
  });
109
108
  }
110
109
  }
111
- async start({
110
+ async start(params) {
111
+ return this._start(params);
112
+ }
113
+ async _start({
112
114
  inputData,
113
- initialState
115
+ initialState,
116
+ outputOptions,
117
+ tracingOptions,
118
+ format
114
119
  }) {
115
120
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
116
121
  workflowName: this.workflowId,
@@ -119,13 +124,15 @@ var InngestRun = class extends workflows.Run {
119
124
  snapshot: {
120
125
  runId: this.runId,
121
126
  serializedStepGraph: this.serializedStepGraph,
127
+ status: "running",
122
128
  value: {},
123
129
  context: {},
124
130
  activePaths: [],
125
131
  suspendedPaths: {},
132
+ activeStepsPath: {},
133
+ resumeLabels: {},
126
134
  waitingPaths: {},
127
- timestamp: Date.now(),
128
- status: "running"
135
+ timestamp: Date.now()
129
136
  }
130
137
  });
131
138
  const inputDataToUse = await this._validateInput(inputData);
@@ -136,7 +143,10 @@ var InngestRun = class extends workflows.Run {
136
143
  inputData: inputDataToUse,
137
144
  initialState: initialStateToUse,
138
145
  runId: this.runId,
139
- resourceId: this.resourceId
146
+ resourceId: this.resourceId,
147
+ outputOptions,
148
+ tracingOptions,
149
+ format
140
150
  }
141
151
  });
142
152
  const eventId = eventOutput.ids[0];
@@ -165,10 +175,16 @@ var InngestRun = class extends workflows.Run {
165
175
  return p;
166
176
  }
167
177
  async _resume(params) {
168
- const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
169
- (step) => typeof step === "string" ? step : step?.id
170
- );
171
- const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
178
+ const storage = this.#mastra?.getStorage();
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
+ }
187
+ const snapshot = await storage?.loadWorkflowSnapshot({
172
188
  workflowName: this.workflowId,
173
189
  runId: this.runId
174
190
  });
@@ -186,8 +202,7 @@ var InngestRun = class extends workflows.Run {
186
202
  steps,
187
203
  stepResults: snapshot?.context,
188
204
  resumePayload: resumeDataToUse,
189
- // @ts-ignore
190
- resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
205
+ resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
191
206
  }
192
207
  }
193
208
  });
@@ -202,12 +217,103 @@ var InngestRun = class extends workflows.Run {
202
217
  }
203
218
  return result;
204
219
  }
205
- watch(cb, type = "watch") {
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
+ }
311
+ watch(cb) {
206
312
  let active = true;
207
313
  const streamPromise = realtime.subscribe(
208
314
  {
209
315
  channel: `workflow:${this.workflowId}:${this.runId}`,
210
- topics: [type],
316
+ topics: ["watch"],
211
317
  app: this.inngest
212
318
  },
213
319
  (message) => {
@@ -225,20 +331,35 @@ var InngestRun = class extends workflows.Run {
225
331
  });
226
332
  };
227
333
  }
228
- stream({ inputData, runtimeContext } = {}) {
334
+ streamLegacy({ inputData, requestContext } = {}) {
229
335
  const { readable, writable } = new TransformStream();
230
336
  const writer = writable.getWriter();
337
+ void writer.write({
338
+ // @ts-ignore
339
+ type: "start",
340
+ // @ts-ignore
341
+ payload: { runId: this.runId }
342
+ });
231
343
  const unwatch = this.watch(async (event) => {
232
344
  try {
233
345
  const e = {
234
346
  ...event,
235
347
  type: event.type.replace("workflow-", "")
236
348
  };
349
+ if (e.type === "step-output") {
350
+ e.type = e.payload.output.type;
351
+ e.payload = e.payload.output.payload;
352
+ }
237
353
  await writer.write(e);
238
354
  } catch {
239
355
  }
240
- }, "watch-v2");
356
+ });
241
357
  this.closeStreamAction = async () => {
358
+ await writer.write({
359
+ type: "finish",
360
+ // @ts-ignore
361
+ payload: { runId: this.runId }
362
+ });
242
363
  unwatch();
243
364
  try {
244
365
  await writer.close();
@@ -248,7 +369,7 @@ var InngestRun = class extends workflows.Run {
248
369
  writer.releaseLock();
249
370
  }
250
371
  };
251
- this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
372
+ this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
252
373
  if (result.status !== "suspended") {
253
374
  this.closeStreamAction?.().catch(() => {
254
375
  });
@@ -260,6 +381,151 @@ var InngestRun = class extends workflows.Run {
260
381
  getWorkflowState: () => this.executionResults
261
382
  };
262
383
  }
384
+ stream({
385
+ inputData,
386
+ requestContext,
387
+ tracingOptions,
388
+ closeOnSuspend = true,
389
+ initialState,
390
+ outputOptions
391
+ } = {}) {
392
+ if (this.closeStreamAction && this.streamOutput) {
393
+ return this.streamOutput;
394
+ }
395
+ this.closeStreamAction = async () => {
396
+ };
397
+ const self = this;
398
+ const stream$1 = new web.ReadableStream({
399
+ async start(controller) {
400
+ const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
401
+ controller.enqueue({
402
+ type,
403
+ runId: self.runId,
404
+ from,
405
+ payload: {
406
+ stepName: payload?.id,
407
+ ...payload
408
+ }
409
+ });
410
+ });
411
+ self.closeStreamAction = async () => {
412
+ unwatch();
413
+ try {
414
+ await controller.close();
415
+ } catch (err) {
416
+ console.error("Error closing stream:", err);
417
+ }
418
+ };
419
+ const executionResultsPromise = self._start({
420
+ inputData,
421
+ requestContext,
422
+ // tracingContext, // We are not able to pass a reference to a span here, what to do?
423
+ initialState,
424
+ tracingOptions,
425
+ outputOptions,
426
+ format: "vnext"
427
+ });
428
+ let executionResults;
429
+ try {
430
+ executionResults = await executionResultsPromise;
431
+ if (closeOnSuspend) {
432
+ self.closeStreamAction?.().catch(() => {
433
+ });
434
+ } else if (executionResults.status !== "suspended") {
435
+ self.closeStreamAction?.().catch(() => {
436
+ });
437
+ }
438
+ if (self.streamOutput) {
439
+ self.streamOutput.updateResults(
440
+ executionResults
441
+ );
442
+ }
443
+ } catch (err) {
444
+ self.streamOutput?.rejectResults(err);
445
+ self.closeStreamAction?.().catch(() => {
446
+ });
447
+ }
448
+ }
449
+ });
450
+ this.streamOutput = new stream.WorkflowRunOutput({
451
+ runId: this.runId,
452
+ workflowId: this.workflowId,
453
+ stream: stream$1
454
+ });
455
+ return this.streamOutput;
456
+ }
457
+ streamVNext(args = {}) {
458
+ return this.stream(args);
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
+ }
263
529
  };
264
530
  var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
265
531
  #mastra;
@@ -269,6 +535,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
269
535
  constructor(params, inngest) {
270
536
  const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
271
537
  super(workflowParams);
538
+ this.engineType = "inngest";
272
539
  const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
273
540
  ([_, value]) => value !== void 0
274
541
  );
@@ -276,13 +543,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
276
543
  this.#mastra = params.mastra;
277
544
  this.inngest = inngest;
278
545
  }
279
- async getWorkflowRuns(args) {
546
+ async listWorkflowRuns(args) {
280
547
  const storage = this.#mastra?.getStorage();
281
548
  if (!storage) {
282
549
  this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
283
550
  return { runs: [], total: 0 };
284
551
  }
285
- return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
552
+ return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
286
553
  }
287
554
  async getWorkflowRunById(runId) {
288
555
  const storage = this.#mastra?.getStorage();
@@ -311,16 +578,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
311
578
  }
312
579
  }
313
580
  }
314
- /**
315
- * @deprecated Use createRunAsync() instead.
316
- * @throws {Error} Always throws an error directing users to use createRunAsync()
317
- */
318
- createRun(_options) {
319
- throw new Error(
320
- "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."
321
- );
322
- }
323
- async createRunAsync(options) {
581
+ async createRun(options) {
324
582
  const runIdToUse = options?.runId || crypto.randomUUID();
325
583
  const run = this.runs.get(runIdToUse) ?? new InngestRun(
326
584
  {
@@ -333,7 +591,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
333
591
  mastra: this.#mastra,
334
592
  retryConfig: this.retryConfig,
335
593
  cleanup: () => this.runs.delete(runIdToUse),
336
- workflowSteps: this.steps
594
+ workflowSteps: this.steps,
595
+ workflowEngineType: this.engineType,
596
+ validateInputs: this.options.validateInputs
337
597
  },
338
598
  this.inngest
339
599
  );
@@ -354,12 +614,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
354
614
  value: {},
355
615
  context: {},
356
616
  activePaths: [],
617
+ activeStepsPath: {},
357
618
  waitingPaths: {},
358
619
  serializedStepGraph: this.serializedStepGraph,
359
620
  suspendedPaths: {},
621
+ resumeLabels: {},
360
622
  result: void 0,
361
623
  error: void 0,
362
- // @ts-ignore
363
624
  timestamp: Date.now()
364
625
  }
365
626
  });
@@ -373,15 +634,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
373
634
  this.function = this.inngest.createFunction(
374
635
  {
375
636
  id: `workflow.${this.id}`,
376
- // @ts-ignore
377
- retries: this.retryConfig?.attempts ?? 0,
637
+ retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
378
638
  cancelOn: [{ event: `cancel.workflow.${this.id}` }],
379
639
  // Spread flow control configuration
380
640
  ...this.flowControlConfig
381
641
  },
382
642
  { event: `workflow.${this.id}` },
383
643
  async ({ event, step, attempt, publish }) => {
384
- let { inputData, initialState, runId, resourceId, resume, outputOptions } = event.data;
644
+ let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
385
645
  if (!runId) {
386
646
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
387
647
  return crypto.randomUUID();
@@ -420,13 +680,20 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
420
680
  initialState,
421
681
  emitter,
422
682
  retryConfig: this.retryConfig,
423
- runtimeContext: new di.RuntimeContext(),
683
+ requestContext: new di.RequestContext(),
424
684
  // TODO
425
685
  resume,
686
+ timeTravel,
687
+ format,
426
688
  abortController: new AbortController(),
427
- currentSpan: void 0,
428
- // TODO: Pass actual parent AI span from workflow execution context
429
- outputOptions
689
+ // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
690
+ outputOptions,
691
+ writableStream: new web.WritableStream({
692
+ write(chunk) {
693
+ void emitter.emit("watch", chunk).catch(() => {
694
+ });
695
+ }
696
+ })
430
697
  });
431
698
  await step.run(`workflow.${this.id}.finalize`, async () => {
432
699
  if (result.status === "failed") {
@@ -464,20 +731,29 @@ function isAgent(params) {
464
731
  function isTool(params) {
465
732
  return params instanceof tools.Tool;
466
733
  }
467
- function createStep(params) {
734
+ function createStep(params, agentOptions) {
468
735
  if (isAgent(params)) {
469
736
  return {
470
737
  id: params.name,
471
738
  description: params.getDescription(),
472
- // @ts-ignore
473
739
  inputSchema: zod.z.object({
474
740
  prompt: zod.z.string()
741
+ // resourceId: z.string().optional(),
742
+ // threadId: z.string().optional(),
475
743
  }),
476
- // @ts-ignore
477
744
  outputSchema: zod.z.object({
478
745
  text: zod.z.string()
479
746
  }),
480
- execute: async ({ inputData, [_constants.EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
747
+ execute: async ({
748
+ inputData,
749
+ [_constants.EMITTER_SYMBOL]: emitter,
750
+ [_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
751
+ requestContext,
752
+ tracingContext,
753
+ abortSignal,
754
+ abort,
755
+ writer
756
+ }) => {
481
757
  let streamPromise = {};
482
758
  streamPromise.promise = new Promise((resolve, reject) => {
483
759
  streamPromise.resolve = resolve;
@@ -487,61 +763,60 @@ function createStep(params) {
487
763
  name: params.name,
488
764
  args: inputData
489
765
  };
490
- if ((await params.getLLM()).getModel().specificationVersion === `v2`) {
491
- const { fullStream } = await params.stream(inputData.prompt, {
492
- runtimeContext,
766
+ let stream;
767
+ if ((await params.getModel()).specificationVersion === "v1") {
768
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
769
+ ...agentOptions ?? {},
770
+ // resourceId: inputData.resourceId,
771
+ // threadId: inputData.threadId,
772
+ requestContext,
493
773
  tracingContext,
494
774
  onFinish: (result) => {
495
775
  streamPromise.resolve(result.text);
776
+ void agentOptions?.onFinish?.(result);
496
777
  },
497
778
  abortSignal
498
779
  });
499
- if (abortSignal.aborted) {
500
- return abort();
501
- }
502
- await emitter.emit("watch-v2", {
503
- type: "tool-call-streaming-start",
504
- ...toolData ?? {}
505
- });
506
- for await (const chunk of fullStream) {
507
- if (chunk.type === "text-delta") {
508
- await emitter.emit("watch-v2", {
509
- type: "tool-call-delta",
510
- ...toolData ?? {},
511
- argsTextDelta: chunk.payload.text
512
- });
513
- }
514
- }
780
+ stream = fullStream;
515
781
  } else {
516
- const { fullStream } = await params.streamLegacy(inputData.prompt, {
517
- runtimeContext,
782
+ const modelOutput = await params.stream(inputData.prompt, {
783
+ ...agentOptions ?? {},
784
+ requestContext,
518
785
  tracingContext,
519
786
  onFinish: (result) => {
520
787
  streamPromise.resolve(result.text);
788
+ void agentOptions?.onFinish?.(result);
521
789
  },
522
790
  abortSignal
523
791
  });
524
- if (abortSignal.aborted) {
525
- return abort();
526
- }
527
- await emitter.emit("watch-v2", {
792
+ stream = modelOutput.fullStream;
793
+ }
794
+ if (streamFormat === "legacy") {
795
+ await emitter.emit("watch", {
528
796
  type: "tool-call-streaming-start",
529
797
  ...toolData ?? {}
530
798
  });
531
- for await (const chunk of fullStream) {
799
+ for await (const chunk of stream) {
532
800
  if (chunk.type === "text-delta") {
533
- await emitter.emit("watch-v2", {
801
+ await emitter.emit("watch", {
534
802
  type: "tool-call-delta",
535
803
  ...toolData ?? {},
536
804
  argsTextDelta: chunk.textDelta
537
805
  });
538
806
  }
539
807
  }
808
+ await emitter.emit("watch", {
809
+ type: "tool-call-streaming-finish",
810
+ ...toolData ?? {}
811
+ });
812
+ } else {
813
+ for await (const chunk of stream) {
814
+ await writer.write(chunk);
815
+ }
816
+ }
817
+ if (abortSignal.aborted) {
818
+ return abort();
540
819
  }
541
- await emitter.emit("watch-v2", {
542
- type: "tool-call-streaming-finish",
543
- ...toolData ?? {}
544
- });
545
820
  return {
546
821
  text: await streamPromise.promise
547
822
  };
@@ -555,20 +830,38 @@ function createStep(params) {
555
830
  }
556
831
  return {
557
832
  // TODO: tool probably should have strong id type
558
- // @ts-ignore
559
833
  id: params.id,
560
834
  description: params.description,
561
835
  inputSchema: params.inputSchema,
562
836
  outputSchema: params.outputSchema,
563
- execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
564
- return params.execute({
565
- context: inputData,
566
- mastra: aiTracing.wrapMastra(mastra, tracingContext),
567
- runtimeContext,
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,
853
+ requestContext,
568
854
  tracingContext,
569
- suspend,
570
- resumeData
571
- });
855
+ workflow: {
856
+ runId,
857
+ resumeData,
858
+ suspend,
859
+ workflowId,
860
+ state,
861
+ setState
862
+ }
863
+ };
864
+ return params.execute(inputData, toolContext);
572
865
  },
573
866
  component: "TOOL"
574
867
  };
@@ -602,6 +895,8 @@ function init(inngest) {
602
895
  suspendSchema: step.suspendSchema,
603
896
  stateSchema: step.stateSchema,
604
897
  execute: step.execute,
898
+ retries: step.retries,
899
+ scorers: step.scorers,
605
900
  component: step.component
606
901
  };
607
902
  },
@@ -611,7 +906,8 @@ function init(inngest) {
611
906
  inputSchema: workflow.inputSchema,
612
907
  outputSchema: workflow.outputSchema,
613
908
  steps: workflow.stepDefs,
614
- mastra: workflow.mastra
909
+ mastra: workflow.mastra,
910
+ options: workflow.options
615
911
  });
616
912
  wf.setStepFlow(workflow.stepGraph);
617
913
  wf.commit();
@@ -627,63 +923,16 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
627
923
  this.inngestStep = inngestStep;
628
924
  this.inngestAttempts = inngestAttempts;
629
925
  }
630
- async execute(params) {
631
- await params.emitter.emit("watch-v2", {
632
- type: "workflow-start",
633
- payload: { runId: params.runId }
634
- });
635
- const result = await super.execute(params);
636
- await params.emitter.emit("watch-v2", {
637
- type: "workflow-finish",
638
- payload: { runId: params.runId }
639
- });
640
- return result;
641
- }
642
- async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
926
+ async fmtReturnValue(emitter, stepResults, lastOutput, error) {
643
927
  const base = {
644
928
  status: lastOutput.status,
645
929
  steps: stepResults
646
930
  };
647
931
  if (lastOutput.status === "success") {
648
- await emitter.emit("watch", {
649
- type: "watch",
650
- payload: {
651
- workflowState: {
652
- status: lastOutput.status,
653
- steps: stepResults,
654
- result: lastOutput.output
655
- }
656
- },
657
- eventTimestamp: Date.now()
658
- });
659
932
  base.result = lastOutput.output;
660
933
  } else if (lastOutput.status === "failed") {
661
934
  base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
662
- await emitter.emit("watch", {
663
- type: "watch",
664
- payload: {
665
- workflowState: {
666
- status: lastOutput.status,
667
- steps: stepResults,
668
- result: null,
669
- error: base.error
670
- }
671
- },
672
- eventTimestamp: Date.now()
673
- });
674
935
  } else if (lastOutput.status === "suspended") {
675
- await emitter.emit("watch", {
676
- type: "watch",
677
- payload: {
678
- workflowState: {
679
- status: lastOutput.status,
680
- steps: stepResults,
681
- result: null,
682
- error: null
683
- }
684
- },
685
- eventTimestamp: Date.now()
686
- });
687
936
  const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
688
937
  if (stepResult?.status === "suspended") {
689
938
  const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
@@ -693,7 +942,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
693
942
  });
694
943
  base.suspended = suspendedStepIds;
695
944
  }
696
- executionSpan?.end();
697
945
  return base;
698
946
  }
699
947
  // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
@@ -707,14 +955,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
707
955
  stepResults,
708
956
  emitter,
709
957
  abortController,
710
- runtimeContext,
958
+ requestContext,
711
959
  executionContext,
712
960
  writableStream,
713
961
  tracingContext
714
962
  }) {
715
963
  let { duration, fn } = entry;
716
964
  const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
717
- type: aiTracing.AISpanType.WORKFLOW_SLEEP,
965
+ type: observability.SpanType.WORKFLOW_SLEEP,
718
966
  name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
719
967
  attributes: {
720
968
  durationMs: duration,
@@ -725,45 +973,53 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
725
973
  if (fn) {
726
974
  const stepCallId = crypto.randomUUID();
727
975
  duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
728
- return await fn({
729
- runId,
730
- workflowId,
731
- mastra: this.mastra,
732
- runtimeContext,
733
- inputData: prevOutput,
734
- state: executionContext.state,
735
- setState: (state) => {
736
- executionContext.state = state;
737
- },
738
- runCount: -1,
739
- tracingContext: {
740
- currentSpan: sleepSpan
741
- },
742
- getInitData: () => stepResults?.input,
743
- getStepResult: workflows.getStepResult.bind(this, stepResults),
744
- // TODO: this function shouldn't have suspend probably?
745
- suspend: async (_suspendPayload) => {
746
- },
747
- bail: () => {
748
- },
749
- abort: () => {
750
- abortController?.abort();
751
- },
752
- [_constants.EMITTER_SYMBOL]: emitter,
753
- // TODO: add streamVNext support
754
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
755
- engine: { step: this.inngestStep },
756
- abortSignal: abortController?.signal,
757
- writer: new tools.ToolStream(
976
+ return await fn(
977
+ workflows.createDeprecationProxy(
758
978
  {
759
- prefix: "workflow-step",
760
- callId: stepCallId,
761
- name: "sleep",
762
- runId
979
+ runId,
980
+ workflowId,
981
+ mastra: this.mastra,
982
+ requestContext,
983
+ inputData: prevOutput,
984
+ state: executionContext.state,
985
+ setState: (state) => {
986
+ executionContext.state = state;
987
+ },
988
+ retryCount: -1,
989
+ tracingContext: {
990
+ currentSpan: sleepSpan
991
+ },
992
+ getInitData: () => stepResults?.input,
993
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
994
+ // TODO: this function shouldn't have suspend probably?
995
+ suspend: async (_suspendPayload) => {
996
+ },
997
+ bail: () => {
998
+ },
999
+ abort: () => {
1000
+ abortController?.abort();
1001
+ },
1002
+ [_constants.EMITTER_SYMBOL]: emitter,
1003
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1004
+ engine: { step: this.inngestStep },
1005
+ abortSignal: abortController?.signal,
1006
+ writer: new tools.ToolStream(
1007
+ {
1008
+ prefix: "workflow-step",
1009
+ callId: stepCallId,
1010
+ name: "sleep",
1011
+ runId
1012
+ },
1013
+ writableStream
1014
+ )
763
1015
  },
764
- writableStream
1016
+ {
1017
+ paramName: "runCount",
1018
+ deprecationMessage: workflows.runCountDeprecationMessage,
1019
+ logger: this.logger
1020
+ }
765
1021
  )
766
- });
1022
+ );
767
1023
  });
768
1024
  sleepSpan?.update({
769
1025
  attributes: {
@@ -787,14 +1043,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
787
1043
  stepResults,
788
1044
  emitter,
789
1045
  abortController,
790
- runtimeContext,
1046
+ requestContext,
791
1047
  executionContext,
792
1048
  writableStream,
793
1049
  tracingContext
794
1050
  }) {
795
1051
  let { date, fn } = entry;
796
1052
  const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
797
- type: aiTracing.AISpanType.WORKFLOW_SLEEP,
1053
+ type: observability.SpanType.WORKFLOW_SLEEP,
798
1054
  name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
799
1055
  attributes: {
800
1056
  untilDate: date,
@@ -806,45 +1062,53 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
806
1062
  if (fn) {
807
1063
  date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
808
1064
  const stepCallId = crypto.randomUUID();
809
- return await fn({
810
- runId,
811
- workflowId,
812
- mastra: this.mastra,
813
- runtimeContext,
814
- inputData: prevOutput,
815
- state: executionContext.state,
816
- setState: (state) => {
817
- executionContext.state = state;
818
- },
819
- runCount: -1,
820
- tracingContext: {
821
- currentSpan: sleepUntilSpan
822
- },
823
- getInitData: () => stepResults?.input,
824
- getStepResult: workflows.getStepResult.bind(this, stepResults),
825
- // TODO: this function shouldn't have suspend probably?
826
- suspend: async (_suspendPayload) => {
827
- },
828
- bail: () => {
829
- },
830
- abort: () => {
831
- abortController?.abort();
832
- },
833
- [_constants.EMITTER_SYMBOL]: emitter,
834
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
835
- // TODO: add streamVNext support
836
- engine: { step: this.inngestStep },
837
- abortSignal: abortController?.signal,
838
- writer: new tools.ToolStream(
1065
+ return await fn(
1066
+ workflows.createDeprecationProxy(
839
1067
  {
840
- prefix: "workflow-step",
841
- callId: stepCallId,
842
- name: "sleep",
843
- runId
1068
+ runId,
1069
+ workflowId,
1070
+ mastra: this.mastra,
1071
+ requestContext,
1072
+ inputData: prevOutput,
1073
+ state: executionContext.state,
1074
+ setState: (state) => {
1075
+ executionContext.state = state;
1076
+ },
1077
+ retryCount: -1,
1078
+ tracingContext: {
1079
+ currentSpan: sleepUntilSpan
1080
+ },
1081
+ getInitData: () => stepResults?.input,
1082
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1083
+ // TODO: this function shouldn't have suspend probably?
1084
+ suspend: async (_suspendPayload) => {
1085
+ },
1086
+ bail: () => {
1087
+ },
1088
+ abort: () => {
1089
+ abortController?.abort();
1090
+ },
1091
+ [_constants.EMITTER_SYMBOL]: emitter,
1092
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1093
+ engine: { step: this.inngestStep },
1094
+ abortSignal: abortController?.signal,
1095
+ writer: new tools.ToolStream(
1096
+ {
1097
+ prefix: "workflow-step",
1098
+ callId: stepCallId,
1099
+ name: "sleep",
1100
+ runId
1101
+ },
1102
+ writableStream
1103
+ )
844
1104
  },
845
- writableStream
1105
+ {
1106
+ paramName: "runCount",
1107
+ deprecationMessage: workflows.runCountDeprecationMessage,
1108
+ logger: this.logger
1109
+ }
846
1110
  )
847
- });
1111
+ );
848
1112
  });
849
1113
  if (date && !(date instanceof Date)) {
850
1114
  date = new Date(date);
@@ -868,32 +1132,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
868
1132
  throw e;
869
1133
  }
870
1134
  }
871
- async executeWaitForEvent({ event, timeout }) {
872
- const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
873
- event: `user-event-${event}`,
874
- timeout: timeout ?? 5e3
875
- });
876
- if (eventData === null) {
877
- throw "Timeout waiting for event";
878
- }
879
- return eventData?.data;
880
- }
881
1135
  async executeStep({
882
1136
  step,
883
1137
  stepResults,
884
1138
  executionContext,
885
1139
  resume,
1140
+ timeTravel,
886
1141
  prevOutput,
887
1142
  emitter,
888
1143
  abortController,
889
- runtimeContext,
1144
+ requestContext,
890
1145
  tracingContext,
891
1146
  writableStream,
892
1147
  disableScorers
893
1148
  }) {
894
- const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
1149
+ const stepSpan = tracingContext?.currentSpan?.createChildSpan({
895
1150
  name: `workflow step: '${step.id}'`,
896
- type: aiTracing.AISpanType.WORKFLOW_STEP,
1151
+ type: observability.SpanType.WORKFLOW_STEP,
897
1152
  input: prevOutput,
898
1153
  attributes: {
899
1154
  stepId: step.id
@@ -903,34 +1158,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
903
1158
  const { inputData, validationError } = await workflows.validateStepInput({
904
1159
  prevOutput,
905
1160
  step,
906
- validateInputs: this.options?.validateInputs ?? false
1161
+ validateInputs: this.options?.validateInputs ?? true
907
1162
  });
908
1163
  const startedAt = await this.inngestStep.run(
909
1164
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
910
1165
  async () => {
911
1166
  const startedAt2 = Date.now();
912
1167
  await emitter.emit("watch", {
913
- type: "watch",
914
- payload: {
915
- currentStep: {
916
- id: step.id,
917
- status: "running"
918
- },
919
- workflowState: {
920
- status: "running",
921
- steps: {
922
- ...stepResults,
923
- [step.id]: {
924
- status: "running"
925
- }
926
- },
927
- result: null,
928
- error: null
929
- }
930
- },
931
- eventTimestamp: Date.now()
932
- });
933
- await emitter.emit("watch-v2", {
934
1168
  type: "workflow-step-start",
935
1169
  payload: {
936
1170
  id: step.id,
@@ -946,9 +1180,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
946
1180
  const isResume = !!resume?.steps?.length;
947
1181
  let result;
948
1182
  let runId;
1183
+ const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
949
1184
  try {
950
1185
  if (isResume) {
951
- runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
1186
+ runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
952
1187
  const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
953
1188
  workflowName: step.id,
954
1189
  runId
@@ -964,8 +1199,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
964
1199
  steps: resume.steps.slice(1),
965
1200
  stepResults: snapshot?.context,
966
1201
  resumePayload: resume.resumePayload,
967
- // @ts-ignore
968
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1202
+ resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
969
1203
  },
970
1204
  outputOptions: { includeState: true }
971
1205
  }
@@ -973,6 +1207,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
973
1207
  result = invokeResp.result;
974
1208
  runId = invokeResp.runId;
975
1209
  executionContext.state = invokeResp.result.state;
1210
+ } else if (isTimeTravel) {
1211
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1212
+ workflowName: step.id,
1213
+ runId: executionContext.runId
1214
+ }) ?? { context: {} };
1215
+ const timeTravelParams = workflows.createTimeTravelExecutionParams({
1216
+ steps: timeTravel.steps.slice(1),
1217
+ inputData: timeTravel.inputData,
1218
+ resumeData: timeTravel.resumeData,
1219
+ context: timeTravel.nestedStepResults?.[step.id] ?? {},
1220
+ nestedStepsContext: timeTravel.nestedStepResults ?? {},
1221
+ snapshot,
1222
+ graph: step.buildExecutionGraph()
1223
+ });
1224
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1225
+ function: step.getFunction(),
1226
+ data: {
1227
+ timeTravel: timeTravelParams,
1228
+ initialState: executionContext.state ?? {},
1229
+ runId: executionContext.runId,
1230
+ outputOptions: { includeState: true }
1231
+ }
1232
+ });
1233
+ result = invokeResp.result;
1234
+ runId = invokeResp.runId;
1235
+ executionContext.state = invokeResp.result.state;
976
1236
  } else {
977
1237
  const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
978
1238
  function: step.getFunction(),
@@ -1006,23 +1266,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1006
1266
  async () => {
1007
1267
  if (result.status === "failed") {
1008
1268
  await emitter.emit("watch", {
1009
- type: "watch",
1010
- payload: {
1011
- currentStep: {
1012
- id: step.id,
1013
- status: "failed",
1014
- error: result?.error
1015
- },
1016
- workflowState: {
1017
- status: "running",
1018
- steps: stepResults,
1019
- result: null,
1020
- error: null
1021
- }
1022
- },
1023
- eventTimestamp: Date.now()
1024
- });
1025
- await emitter.emit("watch-v2", {
1026
1269
  type: "workflow-step-result",
1027
1270
  payload: {
1028
1271
  id: step.id,
@@ -1041,27 +1284,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1041
1284
  const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
1042
1285
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1043
1286
  await emitter.emit("watch", {
1044
- type: "watch",
1045
- payload: {
1046
- currentStep: {
1047
- id: step.id,
1048
- status: "suspended",
1049
- payload: stepResult.payload,
1050
- suspendPayload: {
1051
- ...stepResult?.suspendPayload,
1052
- __workflow_meta: { runId, path: suspendPath }
1053
- }
1054
- },
1055
- workflowState: {
1056
- status: "running",
1057
- steps: stepResults,
1058
- result: null,
1059
- error: null
1060
- }
1061
- },
1062
- eventTimestamp: Date.now()
1063
- });
1064
- await emitter.emit("watch-v2", {
1065
1287
  type: "workflow-step-suspended",
1066
1288
  payload: {
1067
1289
  id: step.id,
@@ -1080,23 +1302,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1080
1302
  }
1081
1303
  };
1082
1304
  }
1083
- await emitter.emit("watch", {
1084
- type: "watch",
1085
- payload: {
1086
- currentStep: {
1087
- id: step.id,
1088
- status: "suspended",
1089
- payload: {}
1090
- },
1091
- workflowState: {
1092
- status: "running",
1093
- steps: stepResults,
1094
- result: null,
1095
- error: null
1096
- }
1097
- },
1098
- eventTimestamp: Date.now()
1099
- });
1100
1305
  return {
1101
1306
  executionContext,
1102
1307
  result: {
@@ -1106,23 +1311,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1106
1311
  };
1107
1312
  }
1108
1313
  await emitter.emit("watch", {
1109
- type: "watch",
1110
- payload: {
1111
- currentStep: {
1112
- id: step.id,
1113
- status: "success",
1114
- output: result?.result
1115
- },
1116
- workflowState: {
1117
- status: "running",
1118
- steps: stepResults,
1119
- result: null,
1120
- error: null
1121
- }
1122
- },
1123
- eventTimestamp: Date.now()
1124
- });
1125
- await emitter.emit("watch-v2", {
1126
1314
  type: "workflow-step-result",
1127
1315
  payload: {
1128
1316
  id: step.id,
@@ -1130,7 +1318,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1130
1318
  output: result?.result
1131
1319
  }
1132
1320
  });
1133
- await emitter.emit("watch-v2", {
1321
+ await emitter.emit("watch", {
1134
1322
  type: "workflow-step-finish",
1135
1323
  payload: {
1136
1324
  id: step.id,
@@ -1150,46 +1338,87 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1150
1338
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1151
1339
  };
1152
1340
  }
1341
+ const stepCallId = crypto.randomUUID();
1153
1342
  let stepRes;
1154
1343
  try {
1155
1344
  stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1156
1345
  let execResults;
1157
1346
  let suspended;
1158
1347
  let bailed;
1348
+ const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
1349
+ resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
1350
+ step
1351
+ });
1352
+ let resumeDataToUse;
1353
+ if (timeTravelResumeData && !timeTravelResumeValidationError) {
1354
+ resumeDataToUse = timeTravelResumeData;
1355
+ } else if (timeTravelResumeData && timeTravelResumeValidationError) {
1356
+ this.logger.warn("Time travel resume data validation failed", {
1357
+ stepId: step.id,
1358
+ error: timeTravelResumeValidationError.message
1359
+ });
1360
+ } else if (resume?.steps[0] === step.id) {
1361
+ resumeDataToUse = resume?.resumePayload;
1362
+ }
1159
1363
  try {
1160
1364
  if (validationError) {
1161
1365
  throw validationError;
1162
1366
  }
1367
+ const retryCount = this.getOrGenerateRetryCount(step.id);
1163
1368
  const result = await step.execute({
1164
1369
  runId: executionContext.runId,
1370
+ workflowId: executionContext.workflowId,
1165
1371
  mastra: this.mastra,
1166
- runtimeContext,
1167
- writableStream,
1372
+ requestContext,
1373
+ retryCount,
1374
+ writer: new tools.ToolStream(
1375
+ {
1376
+ prefix: "workflow-step",
1377
+ callId: stepCallId,
1378
+ name: step.id,
1379
+ runId: executionContext.runId
1380
+ },
1381
+ writableStream
1382
+ ),
1168
1383
  state: executionContext?.state ?? {},
1169
1384
  setState: (state) => {
1170
1385
  executionContext.state = state;
1171
1386
  },
1172
1387
  inputData,
1173
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1388
+ resumeData: resumeDataToUse,
1174
1389
  tracingContext: {
1175
- currentSpan: stepAISpan
1390
+ currentSpan: stepSpan
1176
1391
  },
1177
1392
  getInitData: () => stepResults?.input,
1178
1393
  getStepResult: workflows.getStepResult.bind(this, stepResults),
1179
- suspend: async (suspendPayload) => {
1394
+ suspend: async (suspendPayload, suspendOptions) => {
1395
+ const { suspendData, validationError: validationError2 } = await workflows.validateStepSuspendData({
1396
+ suspendData: suspendPayload,
1397
+ step
1398
+ });
1399
+ if (validationError2) {
1400
+ throw validationError2;
1401
+ }
1180
1402
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1181
- suspended = { payload: suspendPayload };
1403
+ if (suspendOptions?.resumeLabel) {
1404
+ const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
1405
+ for (const label of resumeLabel) {
1406
+ executionContext.resumeLabels[label] = {
1407
+ stepId: step.id,
1408
+ foreachIndex: executionContext.foreachIndex
1409
+ };
1410
+ }
1411
+ }
1412
+ suspended = { payload: suspendData };
1182
1413
  },
1183
1414
  bail: (result2) => {
1184
1415
  bailed = { payload: result2 };
1185
1416
  },
1186
- resume: {
1187
- steps: resume?.steps?.slice(1) || [],
1188
- resumePayload: resume?.resumePayload,
1189
- // @ts-ignore
1190
- runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1417
+ abort: () => {
1418
+ abortController?.abort();
1191
1419
  },
1192
1420
  [_constants.EMITTER_SYMBOL]: emitter,
1421
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1193
1422
  engine: {
1194
1423
  step: this.inngestStep
1195
1424
  },
@@ -1202,8 +1431,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1202
1431
  startedAt,
1203
1432
  endedAt,
1204
1433
  payload: inputData,
1205
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1206
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1434
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1435
+ resumePayload: resumeDataToUse
1207
1436
  };
1208
1437
  } catch (e) {
1209
1438
  const stepFailure = {
@@ -1212,12 +1441,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1212
1441
  error: e instanceof Error ? e.message : String(e),
1213
1442
  endedAt: Date.now(),
1214
1443
  startedAt,
1215
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1216
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1444
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1445
+ resumePayload: resumeDataToUse
1217
1446
  };
1218
1447
  execResults = stepFailure;
1219
1448
  const fallbackErrorMessage = `Step ${step.id} failed`;
1220
- stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1449
+ stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1221
1450
  throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1222
1451
  cause: execResults
1223
1452
  });
@@ -1226,11 +1455,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1226
1455
  execResults = {
1227
1456
  status: "suspended",
1228
1457
  suspendPayload: suspended.payload,
1458
+ ...execResults.output ? { suspendOutput: execResults.output } : {},
1229
1459
  payload: inputData,
1230
1460
  suspendedAt: Date.now(),
1231
1461
  startedAt,
1232
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1233
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1462
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1463
+ resumePayload: resumeDataToUse
1234
1464
  };
1235
1465
  } else if (bailed) {
1236
1466
  execResults = {
@@ -1241,24 +1471,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1241
1471
  startedAt
1242
1472
  };
1243
1473
  }
1244
- await emitter.emit("watch", {
1245
- type: "watch",
1246
- payload: {
1247
- currentStep: {
1248
- id: step.id,
1249
- ...execResults
1250
- },
1251
- workflowState: {
1252
- status: "running",
1253
- steps: { ...stepResults, [step.id]: execResults },
1254
- result: null,
1255
- error: null
1256
- }
1257
- },
1258
- eventTimestamp: Date.now()
1259
- });
1260
1474
  if (execResults.status === "suspended") {
1261
- await emitter.emit("watch-v2", {
1475
+ await emitter.emit("watch", {
1262
1476
  type: "workflow-step-suspended",
1263
1477
  payload: {
1264
1478
  id: step.id,
@@ -1266,14 +1480,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1266
1480
  }
1267
1481
  });
1268
1482
  } else {
1269
- await emitter.emit("watch-v2", {
1483
+ await emitter.emit("watch", {
1270
1484
  type: "workflow-step-result",
1271
1485
  payload: {
1272
1486
  id: step.id,
1273
1487
  ...execResults
1274
1488
  }
1275
1489
  });
1276
- await emitter.emit("watch-v2", {
1490
+ await emitter.emit("watch", {
1277
1491
  type: "workflow-step-finish",
1278
1492
  payload: {
1279
1493
  id: step.id,
@@ -1281,7 +1495,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1281
1495
  }
1282
1496
  });
1283
1497
  }
1284
- stepAISpan?.end({ output: execResults });
1498
+ stepSpan?.end({ output: execResults });
1285
1499
  return { result: execResults, executionContext, stepResults };
1286
1500
  });
1287
1501
  } catch (e) {
@@ -1292,6 +1506,20 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1292
1506
  startedAt,
1293
1507
  endedAt: Date.now()
1294
1508
  };
1509
+ await emitter.emit("watch", {
1510
+ type: "workflow-step-result",
1511
+ payload: {
1512
+ id: step.id,
1513
+ ...stepFailure
1514
+ }
1515
+ });
1516
+ await emitter.emit("watch", {
1517
+ type: "workflow-step-finish",
1518
+ payload: {
1519
+ id: step.id,
1520
+ metadata: {}
1521
+ }
1522
+ });
1295
1523
  stepRes = {
1296
1524
  result: stepFailure,
1297
1525
  executionContext,
@@ -1311,15 +1539,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1311
1539
  output: stepRes.result,
1312
1540
  workflowId: executionContext.workflowId,
1313
1541
  stepId: step.id,
1314
- runtimeContext,
1542
+ requestContext,
1315
1543
  disableScorers,
1316
- tracingContext: { currentSpan: stepAISpan }
1544
+ tracingContext: { currentSpan: stepSpan }
1317
1545
  });
1318
1546
  }
1319
1547
  });
1320
1548
  }
1321
1549
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1322
- Object.assign(stepResults, stepRes.stepResults);
1323
1550
  executionContext.state = stepRes.executionContext.state;
1324
1551
  return stepRes.result;
1325
1552
  }
@@ -1347,16 +1574,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1347
1574
  resourceId,
1348
1575
  snapshot: {
1349
1576
  runId,
1577
+ status: workflowStatus,
1350
1578
  value: executionContext.state,
1351
1579
  context: stepResults,
1352
- activePaths: [],
1580
+ activePaths: executionContext.executionPath,
1581
+ activeStepsPath: executionContext.activeStepsPath,
1353
1582
  suspendedPaths: executionContext.suspendedPaths,
1583
+ resumeLabels: executionContext.resumeLabels,
1354
1584
  waitingPaths: {},
1355
1585
  serializedStepGraph,
1356
- status: workflowStatus,
1357
1586
  result,
1358
1587
  error,
1359
- // @ts-ignore
1360
1588
  timestamp: Date.now()
1361
1589
  }
1362
1590
  });
@@ -1368,20 +1596,19 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1368
1596
  runId,
1369
1597
  entry,
1370
1598
  prevOutput,
1371
- prevStep,
1372
1599
  stepResults,
1373
- serializedStepGraph,
1600
+ timeTravel,
1374
1601
  resume,
1375
1602
  executionContext,
1376
1603
  emitter,
1377
1604
  abortController,
1378
- runtimeContext,
1605
+ requestContext,
1379
1606
  writableStream,
1380
1607
  disableScorers,
1381
1608
  tracingContext
1382
1609
  }) {
1383
1610
  const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1384
- type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL,
1611
+ type: observability.SpanType.WORKFLOW_CONDITIONAL,
1385
1612
  name: `conditional: '${entry.conditions.length} conditions'`,
1386
1613
  input: prevOutput,
1387
1614
  attributes: {
@@ -1394,7 +1621,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1394
1621
  entry.conditions.map(
1395
1622
  (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1396
1623
  const evalSpan = conditionalSpan?.createChildSpan({
1397
- type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL_EVAL,
1624
+ type: observability.SpanType.WORKFLOW_CONDITIONAL_EVAL,
1398
1625
  name: `condition: '${index}'`,
1399
1626
  input: prevOutput,
1400
1627
  attributes: {
@@ -1403,47 +1630,55 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1403
1630
  tracingPolicy: this.options?.tracingPolicy
1404
1631
  });
1405
1632
  try {
1406
- const result = await cond({
1407
- runId,
1408
- workflowId,
1409
- mastra: this.mastra,
1410
- runtimeContext,
1411
- runCount: -1,
1412
- inputData: prevOutput,
1413
- state: executionContext.state,
1414
- setState: (state) => {
1415
- executionContext.state = state;
1416
- },
1417
- tracingContext: {
1418
- currentSpan: evalSpan
1419
- },
1420
- getInitData: () => stepResults?.input,
1421
- getStepResult: workflows.getStepResult.bind(this, stepResults),
1422
- // TODO: this function shouldn't have suspend probably?
1423
- suspend: async (_suspendPayload) => {
1424
- },
1425
- bail: () => {
1426
- },
1427
- abort: () => {
1428
- abortController.abort();
1429
- },
1430
- [_constants.EMITTER_SYMBOL]: emitter,
1431
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1432
- // TODO: add streamVNext support
1433
- engine: {
1434
- step: this.inngestStep
1435
- },
1436
- abortSignal: abortController.signal,
1437
- writer: new tools.ToolStream(
1633
+ const result = await cond(
1634
+ workflows.createDeprecationProxy(
1438
1635
  {
1439
- prefix: "workflow-step",
1440
- callId: crypto.randomUUID(),
1441
- name: "conditional",
1442
- runId
1636
+ runId,
1637
+ workflowId,
1638
+ mastra: this.mastra,
1639
+ requestContext,
1640
+ retryCount: -1,
1641
+ inputData: prevOutput,
1642
+ state: executionContext.state,
1643
+ setState: (state) => {
1644
+ executionContext.state = state;
1645
+ },
1646
+ tracingContext: {
1647
+ currentSpan: evalSpan
1648
+ },
1649
+ getInitData: () => stepResults?.input,
1650
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1651
+ // TODO: this function shouldn't have suspend probably?
1652
+ suspend: async (_suspendPayload) => {
1653
+ },
1654
+ bail: () => {
1655
+ },
1656
+ abort: () => {
1657
+ abortController.abort();
1658
+ },
1659
+ [_constants.EMITTER_SYMBOL]: emitter,
1660
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1661
+ engine: {
1662
+ step: this.inngestStep
1663
+ },
1664
+ abortSignal: abortController.signal,
1665
+ writer: new tools.ToolStream(
1666
+ {
1667
+ prefix: "workflow-step",
1668
+ callId: crypto.randomUUID(),
1669
+ name: "conditional",
1670
+ runId
1671
+ },
1672
+ writableStream
1673
+ )
1443
1674
  },
1444
- writableStream
1675
+ {
1676
+ paramName: "runCount",
1677
+ deprecationMessage: workflows.runCountDeprecationMessage,
1678
+ logger: this.logger
1679
+ }
1445
1680
  )
1446
- });
1681
+ );
1447
1682
  evalSpan?.end({
1448
1683
  output: result,
1449
1684
  attributes: {
@@ -1471,47 +1706,58 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1471
1706
  }
1472
1707
  });
1473
1708
  const results = await Promise.all(
1474
- stepsToRun.map(
1475
- (step, index) => this.executeEntry({
1476
- workflowId,
1477
- runId,
1478
- entry: step,
1479
- serializedStepGraph,
1480
- prevStep,
1709
+ stepsToRun.map(async (step, index) => {
1710
+ const currStepResult = stepResults[step.step.id];
1711
+ if (currStepResult && currStepResult.status === "success") {
1712
+ return currStepResult;
1713
+ }
1714
+ const result = await this.executeStep({
1715
+ step: step.step,
1716
+ prevOutput,
1481
1717
  stepResults,
1482
1718
  resume,
1719
+ timeTravel,
1483
1720
  executionContext: {
1484
1721
  workflowId,
1485
1722
  runId,
1486
1723
  executionPath: [...executionContext.executionPath, index],
1724
+ activeStepsPath: executionContext.activeStepsPath,
1487
1725
  suspendedPaths: executionContext.suspendedPaths,
1726
+ resumeLabels: executionContext.resumeLabels,
1488
1727
  retryConfig: executionContext.retryConfig,
1489
- executionSpan: executionContext.executionSpan,
1490
1728
  state: executionContext.state
1491
1729
  },
1492
1730
  emitter,
1493
1731
  abortController,
1494
- runtimeContext,
1732
+ requestContext,
1495
1733
  writableStream,
1496
1734
  disableScorers,
1497
1735
  tracingContext: {
1498
1736
  currentSpan: conditionalSpan
1499
1737
  }
1500
- })
1501
- )
1738
+ });
1739
+ stepResults[step.step.id] = result;
1740
+ return result;
1741
+ })
1502
1742
  );
1503
- const hasFailed = results.find((result) => result.result.status === "failed");
1504
- const hasSuspended = results.find((result) => result.result.status === "suspended");
1743
+ const hasFailed = results.find((result) => result.status === "failed");
1744
+ const hasSuspended = results.find((result) => result.status === "suspended");
1505
1745
  if (hasFailed) {
1506
- execResults = { status: "failed", error: hasFailed.result.error };
1746
+ execResults = { status: "failed", error: hasFailed.error };
1507
1747
  } else if (hasSuspended) {
1508
- execResults = { status: "suspended", suspendPayload: hasSuspended.result.suspendPayload };
1748
+ execResults = {
1749
+ status: "suspended",
1750
+ suspendPayload: hasSuspended.suspendPayload,
1751
+ ...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
1752
+ };
1509
1753
  } else {
1510
1754
  execResults = {
1511
1755
  status: "success",
1512
1756
  output: results.reduce((acc, result, index) => {
1513
- if (result.result.status === "success") {
1514
- acc[stepsToRun[index].step.id] = result.output;
1757
+ if (result.status === "success") {
1758
+ if ("step" in stepsToRun[index]) {
1759
+ acc[stepsToRun[index].step.id] = result.output;
1760
+ }
1515
1761
  }
1516
1762
  return acc;
1517
1763
  }, {})