@mastra/inngest 0.0.0-chore-core-swap-aiv5-ai-package-naming-20251009203931 → 0.0.0-client-js-listmessages-agentid-fix-20251119175531

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();
231
337
  const unwatch = this.watch(async (event) => {
232
338
  try {
339
+ await writer.write({
340
+ // @ts-ignore
341
+ type: "start",
342
+ // @ts-ignore
343
+ payload: { runId: this.runId }
344
+ });
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,36 @@ 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
+ execute: async ({
838
+ inputData,
839
+ mastra,
840
+ requestContext,
841
+ tracingContext,
842
+ suspend,
843
+ resumeData,
844
+ runId,
845
+ workflowId,
846
+ state,
847
+ setState
848
+ }) => {
849
+ const toolContext = {
850
+ mastra,
851
+ requestContext,
568
852
  tracingContext,
569
- suspend,
570
- resumeData
571
- });
853
+ resumeData,
854
+ workflow: {
855
+ runId,
856
+ suspend,
857
+ workflowId,
858
+ state,
859
+ setState
860
+ }
861
+ };
862
+ return params.execute(inputData, toolContext);
572
863
  },
573
864
  component: "TOOL"
574
865
  };
@@ -602,6 +893,8 @@ function init(inngest) {
602
893
  suspendSchema: step.suspendSchema,
603
894
  stateSchema: step.stateSchema,
604
895
  execute: step.execute,
896
+ retries: step.retries,
897
+ scorers: step.scorers,
605
898
  component: step.component
606
899
  };
607
900
  },
@@ -627,63 +920,16 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
627
920
  this.inngestStep = inngestStep;
628
921
  this.inngestAttempts = inngestAttempts;
629
922
  }
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) {
923
+ async fmtReturnValue(emitter, stepResults, lastOutput, error) {
643
924
  const base = {
644
925
  status: lastOutput.status,
645
926
  steps: stepResults
646
927
  };
647
928
  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
929
  base.result = lastOutput.output;
660
930
  } else if (lastOutput.status === "failed") {
661
931
  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
932
  } 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
933
  const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
688
934
  if (stepResult?.status === "suspended") {
689
935
  const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
@@ -693,7 +939,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
693
939
  });
694
940
  base.suspended = suspendedStepIds;
695
941
  }
696
- executionSpan?.end();
697
942
  return base;
698
943
  }
699
944
  // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
@@ -707,14 +952,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
707
952
  stepResults,
708
953
  emitter,
709
954
  abortController,
710
- runtimeContext,
955
+ requestContext,
711
956
  executionContext,
712
957
  writableStream,
713
958
  tracingContext
714
959
  }) {
715
960
  let { duration, fn } = entry;
716
961
  const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
717
- type: aiTracing.AISpanType.WORKFLOW_SLEEP,
962
+ type: observability.SpanType.WORKFLOW_SLEEP,
718
963
  name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
719
964
  attributes: {
720
965
  durationMs: duration,
@@ -725,45 +970,53 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
725
970
  if (fn) {
726
971
  const stepCallId = crypto.randomUUID();
727
972
  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(
973
+ return await fn(
974
+ workflows.createDeprecationProxy(
758
975
  {
759
- prefix: "workflow-step",
760
- callId: stepCallId,
761
- name: "sleep",
762
- runId
976
+ runId,
977
+ workflowId,
978
+ mastra: this.mastra,
979
+ requestContext,
980
+ inputData: prevOutput,
981
+ state: executionContext.state,
982
+ setState: (state) => {
983
+ executionContext.state = state;
984
+ },
985
+ retryCount: -1,
986
+ tracingContext: {
987
+ currentSpan: sleepSpan
988
+ },
989
+ getInitData: () => stepResults?.input,
990
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
991
+ // TODO: this function shouldn't have suspend probably?
992
+ suspend: async (_suspendPayload) => {
993
+ },
994
+ bail: () => {
995
+ },
996
+ abort: () => {
997
+ abortController?.abort();
998
+ },
999
+ [_constants.EMITTER_SYMBOL]: emitter,
1000
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1001
+ engine: { step: this.inngestStep },
1002
+ abortSignal: abortController?.signal,
1003
+ writer: new tools.ToolStream(
1004
+ {
1005
+ prefix: "workflow-step",
1006
+ callId: stepCallId,
1007
+ name: "sleep",
1008
+ runId
1009
+ },
1010
+ writableStream
1011
+ )
763
1012
  },
764
- writableStream
1013
+ {
1014
+ paramName: "runCount",
1015
+ deprecationMessage: workflows.runCountDeprecationMessage,
1016
+ logger: this.logger
1017
+ }
765
1018
  )
766
- });
1019
+ );
767
1020
  });
768
1021
  sleepSpan?.update({
769
1022
  attributes: {
@@ -787,14 +1040,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
787
1040
  stepResults,
788
1041
  emitter,
789
1042
  abortController,
790
- runtimeContext,
1043
+ requestContext,
791
1044
  executionContext,
792
1045
  writableStream,
793
1046
  tracingContext
794
1047
  }) {
795
1048
  let { date, fn } = entry;
796
1049
  const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
797
- type: aiTracing.AISpanType.WORKFLOW_SLEEP,
1050
+ type: observability.SpanType.WORKFLOW_SLEEP,
798
1051
  name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
799
1052
  attributes: {
800
1053
  untilDate: date,
@@ -806,45 +1059,53 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
806
1059
  if (fn) {
807
1060
  date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
808
1061
  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(
1062
+ return await fn(
1063
+ workflows.createDeprecationProxy(
839
1064
  {
840
- prefix: "workflow-step",
841
- callId: stepCallId,
842
- name: "sleep",
843
- runId
1065
+ runId,
1066
+ workflowId,
1067
+ mastra: this.mastra,
1068
+ requestContext,
1069
+ inputData: prevOutput,
1070
+ state: executionContext.state,
1071
+ setState: (state) => {
1072
+ executionContext.state = state;
1073
+ },
1074
+ retryCount: -1,
1075
+ tracingContext: {
1076
+ currentSpan: sleepUntilSpan
1077
+ },
1078
+ getInitData: () => stepResults?.input,
1079
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1080
+ // TODO: this function shouldn't have suspend probably?
1081
+ suspend: async (_suspendPayload) => {
1082
+ },
1083
+ bail: () => {
1084
+ },
1085
+ abort: () => {
1086
+ abortController?.abort();
1087
+ },
1088
+ [_constants.EMITTER_SYMBOL]: emitter,
1089
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1090
+ engine: { step: this.inngestStep },
1091
+ abortSignal: abortController?.signal,
1092
+ writer: new tools.ToolStream(
1093
+ {
1094
+ prefix: "workflow-step",
1095
+ callId: stepCallId,
1096
+ name: "sleep",
1097
+ runId
1098
+ },
1099
+ writableStream
1100
+ )
844
1101
  },
845
- writableStream
1102
+ {
1103
+ paramName: "runCount",
1104
+ deprecationMessage: workflows.runCountDeprecationMessage,
1105
+ logger: this.logger
1106
+ }
846
1107
  )
847
- });
1108
+ );
848
1109
  });
849
1110
  if (date && !(date instanceof Date)) {
850
1111
  date = new Date(date);
@@ -868,32 +1129,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
868
1129
  throw e;
869
1130
  }
870
1131
  }
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
1132
  async executeStep({
882
1133
  step,
883
1134
  stepResults,
884
1135
  executionContext,
885
1136
  resume,
1137
+ timeTravel,
886
1138
  prevOutput,
887
1139
  emitter,
888
1140
  abortController,
889
- runtimeContext,
1141
+ requestContext,
890
1142
  tracingContext,
891
1143
  writableStream,
892
1144
  disableScorers
893
1145
  }) {
894
- const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
1146
+ const stepSpan = tracingContext?.currentSpan?.createChildSpan({
895
1147
  name: `workflow step: '${step.id}'`,
896
- type: aiTracing.AISpanType.WORKFLOW_STEP,
1148
+ type: observability.SpanType.WORKFLOW_STEP,
897
1149
  input: prevOutput,
898
1150
  attributes: {
899
1151
  stepId: step.id
@@ -903,34 +1155,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
903
1155
  const { inputData, validationError } = await workflows.validateStepInput({
904
1156
  prevOutput,
905
1157
  step,
906
- validateInputs: this.options?.validateInputs ?? false
1158
+ validateInputs: this.options?.validateInputs ?? true
907
1159
  });
908
1160
  const startedAt = await this.inngestStep.run(
909
1161
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
910
1162
  async () => {
911
1163
  const startedAt2 = Date.now();
912
1164
  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
1165
  type: "workflow-step-start",
935
1166
  payload: {
936
1167
  id: step.id,
@@ -946,9 +1177,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
946
1177
  const isResume = !!resume?.steps?.length;
947
1178
  let result;
948
1179
  let runId;
1180
+ const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
949
1181
  try {
950
1182
  if (isResume) {
951
- runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
1183
+ runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
952
1184
  const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
953
1185
  workflowName: step.id,
954
1186
  runId
@@ -964,8 +1196,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
964
1196
  steps: resume.steps.slice(1),
965
1197
  stepResults: snapshot?.context,
966
1198
  resumePayload: resume.resumePayload,
967
- // @ts-ignore
968
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1199
+ resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
969
1200
  },
970
1201
  outputOptions: { includeState: true }
971
1202
  }
@@ -973,6 +1204,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
973
1204
  result = invokeResp.result;
974
1205
  runId = invokeResp.runId;
975
1206
  executionContext.state = invokeResp.result.state;
1207
+ } else if (isTimeTravel) {
1208
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1209
+ workflowName: step.id,
1210
+ runId: executionContext.runId
1211
+ }) ?? { context: {} };
1212
+ const timeTravelParams = workflows.createTimeTravelExecutionParams({
1213
+ steps: timeTravel.steps.slice(1),
1214
+ inputData: timeTravel.inputData,
1215
+ resumeData: timeTravel.resumeData,
1216
+ context: timeTravel.nestedStepResults?.[step.id] ?? {},
1217
+ nestedStepsContext: timeTravel.nestedStepResults ?? {},
1218
+ snapshot,
1219
+ graph: step.buildExecutionGraph()
1220
+ });
1221
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1222
+ function: step.getFunction(),
1223
+ data: {
1224
+ timeTravel: timeTravelParams,
1225
+ initialState: executionContext.state ?? {},
1226
+ runId: executionContext.runId,
1227
+ outputOptions: { includeState: true }
1228
+ }
1229
+ });
1230
+ result = invokeResp.result;
1231
+ runId = invokeResp.runId;
1232
+ executionContext.state = invokeResp.result.state;
976
1233
  } else {
977
1234
  const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
978
1235
  function: step.getFunction(),
@@ -1006,23 +1263,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1006
1263
  async () => {
1007
1264
  if (result.status === "failed") {
1008
1265
  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
1266
  type: "workflow-step-result",
1027
1267
  payload: {
1028
1268
  id: step.id,
@@ -1041,27 +1281,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1041
1281
  const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
1042
1282
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1043
1283
  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
1284
  type: "workflow-step-suspended",
1066
1285
  payload: {
1067
1286
  id: step.id,
@@ -1080,23 +1299,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1080
1299
  }
1081
1300
  };
1082
1301
  }
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
1302
  return {
1101
1303
  executionContext,
1102
1304
  result: {
@@ -1106,23 +1308,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1106
1308
  };
1107
1309
  }
1108
1310
  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
1311
  type: "workflow-step-result",
1127
1312
  payload: {
1128
1313
  id: step.id,
@@ -1130,7 +1315,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1130
1315
  output: result?.result
1131
1316
  }
1132
1317
  });
1133
- await emitter.emit("watch-v2", {
1318
+ await emitter.emit("watch", {
1134
1319
  type: "workflow-step-finish",
1135
1320
  payload: {
1136
1321
  id: step.id,
@@ -1150,46 +1335,80 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1150
1335
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1151
1336
  };
1152
1337
  }
1338
+ const stepCallId = crypto.randomUUID();
1153
1339
  let stepRes;
1154
1340
  try {
1155
1341
  stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1156
1342
  let execResults;
1157
1343
  let suspended;
1158
1344
  let bailed;
1345
+ const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
1346
+ resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
1347
+ step
1348
+ });
1349
+ let resumeDataToUse;
1350
+ if (timeTravelResumeData && !timeTravelResumeValidationError) {
1351
+ resumeDataToUse = timeTravelResumeData;
1352
+ } else if (timeTravelResumeData && timeTravelResumeValidationError) {
1353
+ this.logger.warn("Time travel resume data validation failed", {
1354
+ stepId: step.id,
1355
+ error: timeTravelResumeValidationError.message
1356
+ });
1357
+ } else if (resume?.steps[0] === step.id) {
1358
+ resumeDataToUse = resume?.resumePayload;
1359
+ }
1159
1360
  try {
1160
1361
  if (validationError) {
1161
1362
  throw validationError;
1162
1363
  }
1364
+ const retryCount = this.getOrGenerateRetryCount(step.id);
1163
1365
  const result = await step.execute({
1164
1366
  runId: executionContext.runId,
1367
+ workflowId: executionContext.workflowId,
1165
1368
  mastra: this.mastra,
1166
- runtimeContext,
1167
- writableStream,
1369
+ requestContext,
1370
+ retryCount,
1371
+ writer: new tools.ToolStream(
1372
+ {
1373
+ prefix: "workflow-step",
1374
+ callId: stepCallId,
1375
+ name: step.id,
1376
+ runId: executionContext.runId
1377
+ },
1378
+ writableStream
1379
+ ),
1168
1380
  state: executionContext?.state ?? {},
1169
1381
  setState: (state) => {
1170
1382
  executionContext.state = state;
1171
1383
  },
1172
1384
  inputData,
1173
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1385
+ resumeData: resumeDataToUse,
1174
1386
  tracingContext: {
1175
- currentSpan: stepAISpan
1387
+ currentSpan: stepSpan
1176
1388
  },
1177
1389
  getInitData: () => stepResults?.input,
1178
1390
  getStepResult: workflows.getStepResult.bind(this, stepResults),
1179
- suspend: async (suspendPayload) => {
1391
+ suspend: async (suspendPayload, suspendOptions) => {
1180
1392
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1393
+ if (suspendOptions?.resumeLabel) {
1394
+ const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
1395
+ for (const label of resumeLabel) {
1396
+ executionContext.resumeLabels[label] = {
1397
+ stepId: step.id,
1398
+ foreachIndex: executionContext.foreachIndex
1399
+ };
1400
+ }
1401
+ }
1181
1402
  suspended = { payload: suspendPayload };
1182
1403
  },
1183
1404
  bail: (result2) => {
1184
1405
  bailed = { payload: result2 };
1185
1406
  },
1186
- resume: {
1187
- steps: resume?.steps?.slice(1) || [],
1188
- resumePayload: resume?.resumePayload,
1189
- // @ts-ignore
1190
- runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1407
+ abort: () => {
1408
+ abortController?.abort();
1191
1409
  },
1192
1410
  [_constants.EMITTER_SYMBOL]: emitter,
1411
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1193
1412
  engine: {
1194
1413
  step: this.inngestStep
1195
1414
  },
@@ -1202,8 +1421,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1202
1421
  startedAt,
1203
1422
  endedAt,
1204
1423
  payload: inputData,
1205
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1206
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1424
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1425
+ resumePayload: resumeDataToUse
1207
1426
  };
1208
1427
  } catch (e) {
1209
1428
  const stepFailure = {
@@ -1212,12 +1431,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1212
1431
  error: e instanceof Error ? e.message : String(e),
1213
1432
  endedAt: Date.now(),
1214
1433
  startedAt,
1215
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1216
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1434
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1435
+ resumePayload: resumeDataToUse
1217
1436
  };
1218
1437
  execResults = stepFailure;
1219
1438
  const fallbackErrorMessage = `Step ${step.id} failed`;
1220
- stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1439
+ stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1221
1440
  throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1222
1441
  cause: execResults
1223
1442
  });
@@ -1226,11 +1445,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1226
1445
  execResults = {
1227
1446
  status: "suspended",
1228
1447
  suspendPayload: suspended.payload,
1448
+ ...execResults.output ? { suspendOutput: execResults.output } : {},
1229
1449
  payload: inputData,
1230
1450
  suspendedAt: Date.now(),
1231
1451
  startedAt,
1232
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1233
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1452
+ resumedAt: resumeDataToUse ? startedAt : void 0,
1453
+ resumePayload: resumeDataToUse
1234
1454
  };
1235
1455
  } else if (bailed) {
1236
1456
  execResults = {
@@ -1241,24 +1461,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1241
1461
  startedAt
1242
1462
  };
1243
1463
  }
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
1464
  if (execResults.status === "suspended") {
1261
- await emitter.emit("watch-v2", {
1465
+ await emitter.emit("watch", {
1262
1466
  type: "workflow-step-suspended",
1263
1467
  payload: {
1264
1468
  id: step.id,
@@ -1266,14 +1470,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1266
1470
  }
1267
1471
  });
1268
1472
  } else {
1269
- await emitter.emit("watch-v2", {
1473
+ await emitter.emit("watch", {
1270
1474
  type: "workflow-step-result",
1271
1475
  payload: {
1272
1476
  id: step.id,
1273
1477
  ...execResults
1274
1478
  }
1275
1479
  });
1276
- await emitter.emit("watch-v2", {
1480
+ await emitter.emit("watch", {
1277
1481
  type: "workflow-step-finish",
1278
1482
  payload: {
1279
1483
  id: step.id,
@@ -1281,7 +1485,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1281
1485
  }
1282
1486
  });
1283
1487
  }
1284
- stepAISpan?.end({ output: execResults });
1488
+ stepSpan?.end({ output: execResults });
1285
1489
  return { result: execResults, executionContext, stepResults };
1286
1490
  });
1287
1491
  } catch (e) {
@@ -1311,15 +1515,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1311
1515
  output: stepRes.result,
1312
1516
  workflowId: executionContext.workflowId,
1313
1517
  stepId: step.id,
1314
- runtimeContext,
1518
+ requestContext,
1315
1519
  disableScorers,
1316
- tracingContext: { currentSpan: stepAISpan }
1520
+ tracingContext: { currentSpan: stepSpan }
1317
1521
  });
1318
1522
  }
1319
1523
  });
1320
1524
  }
1321
1525
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1322
- Object.assign(stepResults, stepRes.stepResults);
1323
1526
  executionContext.state = stepRes.executionContext.state;
1324
1527
  return stepRes.result;
1325
1528
  }
@@ -1347,16 +1550,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1347
1550
  resourceId,
1348
1551
  snapshot: {
1349
1552
  runId,
1553
+ status: workflowStatus,
1350
1554
  value: executionContext.state,
1351
1555
  context: stepResults,
1352
- activePaths: [],
1556
+ activePaths: executionContext.executionPath,
1557
+ activeStepsPath: executionContext.activeStepsPath,
1353
1558
  suspendedPaths: executionContext.suspendedPaths,
1559
+ resumeLabels: executionContext.resumeLabels,
1354
1560
  waitingPaths: {},
1355
1561
  serializedStepGraph,
1356
- status: workflowStatus,
1357
1562
  result,
1358
1563
  error,
1359
- // @ts-ignore
1360
1564
  timestamp: Date.now()
1361
1565
  }
1362
1566
  });
@@ -1368,20 +1572,19 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1368
1572
  runId,
1369
1573
  entry,
1370
1574
  prevOutput,
1371
- prevStep,
1372
1575
  stepResults,
1373
- serializedStepGraph,
1576
+ timeTravel,
1374
1577
  resume,
1375
1578
  executionContext,
1376
1579
  emitter,
1377
1580
  abortController,
1378
- runtimeContext,
1581
+ requestContext,
1379
1582
  writableStream,
1380
1583
  disableScorers,
1381
1584
  tracingContext
1382
1585
  }) {
1383
1586
  const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1384
- type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL,
1587
+ type: observability.SpanType.WORKFLOW_CONDITIONAL,
1385
1588
  name: `conditional: '${entry.conditions.length} conditions'`,
1386
1589
  input: prevOutput,
1387
1590
  attributes: {
@@ -1394,7 +1597,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1394
1597
  entry.conditions.map(
1395
1598
  (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1396
1599
  const evalSpan = conditionalSpan?.createChildSpan({
1397
- type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL_EVAL,
1600
+ type: observability.SpanType.WORKFLOW_CONDITIONAL_EVAL,
1398
1601
  name: `condition: '${index}'`,
1399
1602
  input: prevOutput,
1400
1603
  attributes: {
@@ -1403,47 +1606,55 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1403
1606
  tracingPolicy: this.options?.tracingPolicy
1404
1607
  });
1405
1608
  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(
1609
+ const result = await cond(
1610
+ workflows.createDeprecationProxy(
1438
1611
  {
1439
- prefix: "workflow-step",
1440
- callId: crypto.randomUUID(),
1441
- name: "conditional",
1442
- runId
1612
+ runId,
1613
+ workflowId,
1614
+ mastra: this.mastra,
1615
+ requestContext,
1616
+ retryCount: -1,
1617
+ inputData: prevOutput,
1618
+ state: executionContext.state,
1619
+ setState: (state) => {
1620
+ executionContext.state = state;
1621
+ },
1622
+ tracingContext: {
1623
+ currentSpan: evalSpan
1624
+ },
1625
+ getInitData: () => stepResults?.input,
1626
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1627
+ // TODO: this function shouldn't have suspend probably?
1628
+ suspend: async (_suspendPayload) => {
1629
+ },
1630
+ bail: () => {
1631
+ },
1632
+ abort: () => {
1633
+ abortController.abort();
1634
+ },
1635
+ [_constants.EMITTER_SYMBOL]: emitter,
1636
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1637
+ engine: {
1638
+ step: this.inngestStep
1639
+ },
1640
+ abortSignal: abortController.signal,
1641
+ writer: new tools.ToolStream(
1642
+ {
1643
+ prefix: "workflow-step",
1644
+ callId: crypto.randomUUID(),
1645
+ name: "conditional",
1646
+ runId
1647
+ },
1648
+ writableStream
1649
+ )
1443
1650
  },
1444
- writableStream
1651
+ {
1652
+ paramName: "runCount",
1653
+ deprecationMessage: workflows.runCountDeprecationMessage,
1654
+ logger: this.logger
1655
+ }
1445
1656
  )
1446
- });
1657
+ );
1447
1658
  evalSpan?.end({
1448
1659
  output: result,
1449
1660
  attributes: {
@@ -1471,47 +1682,58 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1471
1682
  }
1472
1683
  });
1473
1684
  const results = await Promise.all(
1474
- stepsToRun.map(
1475
- (step, index) => this.executeEntry({
1476
- workflowId,
1477
- runId,
1478
- entry: step,
1479
- serializedStepGraph,
1480
- prevStep,
1685
+ stepsToRun.map(async (step, index) => {
1686
+ const currStepResult = stepResults[step.step.id];
1687
+ if (currStepResult && currStepResult.status === "success") {
1688
+ return currStepResult;
1689
+ }
1690
+ const result = await this.executeStep({
1691
+ step: step.step,
1692
+ prevOutput,
1481
1693
  stepResults,
1482
1694
  resume,
1695
+ timeTravel,
1483
1696
  executionContext: {
1484
1697
  workflowId,
1485
1698
  runId,
1486
1699
  executionPath: [...executionContext.executionPath, index],
1700
+ activeStepsPath: executionContext.activeStepsPath,
1487
1701
  suspendedPaths: executionContext.suspendedPaths,
1702
+ resumeLabels: executionContext.resumeLabels,
1488
1703
  retryConfig: executionContext.retryConfig,
1489
- executionSpan: executionContext.executionSpan,
1490
1704
  state: executionContext.state
1491
1705
  },
1492
1706
  emitter,
1493
1707
  abortController,
1494
- runtimeContext,
1708
+ requestContext,
1495
1709
  writableStream,
1496
1710
  disableScorers,
1497
1711
  tracingContext: {
1498
1712
  currentSpan: conditionalSpan
1499
1713
  }
1500
- })
1501
- )
1714
+ });
1715
+ stepResults[step.step.id] = result;
1716
+ return result;
1717
+ })
1502
1718
  );
1503
- const hasFailed = results.find((result) => result.result.status === "failed");
1504
- const hasSuspended = results.find((result) => result.result.status === "suspended");
1719
+ const hasFailed = results.find((result) => result.status === "failed");
1720
+ const hasSuspended = results.find((result) => result.status === "suspended");
1505
1721
  if (hasFailed) {
1506
- execResults = { status: "failed", error: hasFailed.result.error };
1722
+ execResults = { status: "failed", error: hasFailed.error };
1507
1723
  } else if (hasSuspended) {
1508
- execResults = { status: "suspended", suspendPayload: hasSuspended.result.suspendPayload };
1724
+ execResults = {
1725
+ status: "suspended",
1726
+ suspendPayload: hasSuspended.suspendPayload,
1727
+ ...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
1728
+ };
1509
1729
  } else {
1510
1730
  execResults = {
1511
1731
  status: "success",
1512
1732
  output: results.reduce((acc, result, index) => {
1513
- if (result.result.status === "success") {
1514
- acc[stepsToRun[index].step.id] = result.output;
1733
+ if (result.status === "success") {
1734
+ if ("step" in stepsToRun[index]) {
1735
+ acc[stepsToRun[index].step.id] = result.output;
1736
+ }
1515
1737
  }
1516
1738
  return acc;
1517
1739
  }, {})