@mastra/inngest 0.0.0-fix-issue-10434-concurrent-write-corruption-20251124213939 → 0.0.0-fix-backport-setserver-20251201151948

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
@@ -3,8 +3,8 @@
3
3
  var crypto = require('crypto');
4
4
  var web = require('stream/web');
5
5
  var realtime = require('@inngest/realtime');
6
+ var aiTracing = require('@mastra/core/ai-tracing');
6
7
  var di = require('@mastra/core/di');
7
- var observability = require('@mastra/core/observability');
8
8
  var stream = require('@mastra/core/stream');
9
9
  var tools = require('@mastra/core/tools');
10
10
  var workflows = require('@mastra/core/workflows');
@@ -20,7 +20,7 @@ function serve({
20
20
  functions: userFunctions = [],
21
21
  registerOptions
22
22
  }) {
23
- const wfs = mastra.listWorkflows();
23
+ const wfs = mastra.getWorkflows();
24
24
  const workflowFunctions = Array.from(
25
25
  new Set(
26
26
  Object.values(wfs).flatMap((wf) => {
@@ -59,12 +59,11 @@ var InngestRun = class extends workflows.Run {
59
59
  }
60
60
  async getRunOutput(eventId) {
61
61
  let runs = await this.getRuns(eventId);
62
- const storage = this.#mastra?.getStorage();
63
62
  while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
64
63
  await new Promise((resolve) => setTimeout(resolve, 1e3));
65
64
  runs = await this.getRuns(eventId);
66
65
  if (runs?.[0]?.status === "Failed") {
67
- const snapshot = await storage?.loadWorkflowSnapshot({
66
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
68
67
  workflowName: this.workflowId,
69
68
  runId: this.runId
70
69
  });
@@ -73,7 +72,7 @@ var InngestRun = class extends workflows.Run {
73
72
  };
74
73
  }
75
74
  if (runs?.[0]?.status === "Cancelled") {
76
- const snapshot = await storage?.loadWorkflowSnapshot({
75
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
77
76
  workflowName: this.workflowId,
78
77
  runId: this.runId
79
78
  });
@@ -82,40 +81,38 @@ var InngestRun = class extends workflows.Run {
82
81
  }
83
82
  return runs?.[0];
84
83
  }
84
+ async sendEvent(event, data) {
85
+ await this.inngest.send({
86
+ name: `user-event-${event}`,
87
+ data
88
+ });
89
+ }
85
90
  async cancel() {
86
- const storage = this.#mastra?.getStorage();
87
91
  await this.inngest.send({
88
92
  name: `cancel.workflow.${this.workflowId}`,
89
93
  data: {
90
94
  runId: this.runId
91
95
  }
92
96
  });
93
- const snapshot = await storage?.loadWorkflowSnapshot({
97
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
94
98
  workflowName: this.workflowId,
95
99
  runId: this.runId
96
100
  });
97
101
  if (snapshot) {
98
- await storage?.persistWorkflowSnapshot({
102
+ await this.#mastra?.storage?.persistWorkflowSnapshot({
99
103
  workflowName: this.workflowId,
100
104
  runId: this.runId,
101
105
  resourceId: this.resourceId,
102
106
  snapshot: {
103
107
  ...snapshot,
104
- status: "canceled",
105
- value: snapshot.value
108
+ status: "canceled"
106
109
  }
107
110
  });
108
111
  }
109
112
  }
110
- async start(params) {
111
- return this._start(params);
112
- }
113
- async _start({
113
+ async start({
114
114
  inputData,
115
- initialState,
116
- outputOptions,
117
- tracingOptions,
118
- format
115
+ initialState
119
116
  }) {
120
117
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
121
118
  workflowName: this.workflowId,
@@ -124,15 +121,14 @@ var InngestRun = class extends workflows.Run {
124
121
  snapshot: {
125
122
  runId: this.runId,
126
123
  serializedStepGraph: this.serializedStepGraph,
127
- status: "running",
128
124
  value: {},
129
125
  context: {},
130
126
  activePaths: [],
131
127
  suspendedPaths: {},
132
- activeStepsPath: {},
133
128
  resumeLabels: {},
134
129
  waitingPaths: {},
135
- timestamp: Date.now()
130
+ timestamp: Date.now(),
131
+ status: "running"
136
132
  }
137
133
  });
138
134
  const inputDataToUse = await this._validateInput(inputData);
@@ -143,10 +139,7 @@ var InngestRun = class extends workflows.Run {
143
139
  inputData: inputDataToUse,
144
140
  initialState: initialStateToUse,
145
141
  runId: this.runId,
146
- resourceId: this.resourceId,
147
- outputOptions,
148
- tracingOptions,
149
- format
142
+ resourceId: this.resourceId
150
143
  }
151
144
  });
152
145
  const eventId = eventOutput.ids[0];
@@ -175,16 +168,10 @@ var InngestRun = class extends workflows.Run {
175
168
  return p;
176
169
  }
177
170
  async _resume(params) {
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({
171
+ const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
172
+ (step) => typeof step === "string" ? step : step?.id
173
+ );
174
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
188
175
  workflowName: this.workflowId,
189
176
  runId: this.runId
190
177
  });
@@ -202,99 +189,9 @@ var InngestRun = class extends workflows.Run {
202
189
  steps,
203
190
  stepResults: snapshot?.context,
204
191
  resumePayload: resumeDataToUse,
205
- resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
206
- }
207
- }
208
- });
209
- const eventId = eventOutput.ids[0];
210
- if (!eventId) {
211
- throw new Error("Event ID is not set");
212
- }
213
- const runOutput = await this.getRunOutput(eventId);
214
- const result = runOutput?.output?.result;
215
- if (result.status === "failed") {
216
- result.error = new Error(result.error);
217
- }
218
- return result;
219
- }
220
- async timeTravel(params) {
221
- const p = this._timeTravel(params).then((result) => {
222
- if (result.status !== "suspended") {
223
- this.closeStreamAction?.().catch(() => {
224
- });
225
- }
226
- return result;
227
- });
228
- this.executionResults = p;
229
- return p;
230
- }
231
- async _timeTravel(params) {
232
- if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
233
- throw new Error("Step is required and must be a valid step or array of steps");
234
- }
235
- let steps = [];
236
- if (typeof params.step === "string") {
237
- steps = params.step.split(".");
238
- } else {
239
- steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
240
- (step) => typeof step === "string" ? step : step?.id
241
- );
242
- }
243
- if (steps.length === 0) {
244
- throw new Error("No steps provided to timeTravel");
245
- }
246
- const storage = this.#mastra?.getStorage();
247
- const snapshot = await storage?.loadWorkflowSnapshot({
248
- workflowName: this.workflowId,
249
- runId: this.runId
250
- });
251
- if (!snapshot) {
252
- await storage?.persistWorkflowSnapshot({
253
- workflowName: this.workflowId,
254
- runId: this.runId,
255
- resourceId: this.resourceId,
256
- snapshot: {
257
- runId: this.runId,
258
- serializedStepGraph: this.serializedStepGraph,
259
- status: "pending",
260
- value: {},
261
- context: {},
262
- activePaths: [],
263
- suspendedPaths: {},
264
- activeStepsPath: {},
265
- resumeLabels: {},
266
- waitingPaths: {},
267
- timestamp: Date.now()
192
+ // @ts-ignore
193
+ resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
268
194
  }
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
195
  }
299
196
  });
300
197
  const eventId = eventOutput.ids[0];
@@ -308,12 +205,12 @@ var InngestRun = class extends workflows.Run {
308
205
  }
309
206
  return result;
310
207
  }
311
- watch(cb) {
208
+ watch(cb, type = "watch") {
312
209
  let active = true;
313
210
  const streamPromise = realtime.subscribe(
314
211
  {
315
212
  channel: `workflow:${this.workflowId}:${this.runId}`,
316
- topics: ["watch"],
213
+ topics: [type],
317
214
  app: this.inngest
318
215
  },
319
216
  (message) => {
@@ -331,35 +228,20 @@ var InngestRun = class extends workflows.Run {
331
228
  });
332
229
  };
333
230
  }
334
- streamLegacy({ inputData, requestContext } = {}) {
231
+ streamLegacy({ inputData, runtimeContext } = {}) {
335
232
  const { readable, writable } = new TransformStream();
336
233
  const writer = writable.getWriter();
337
234
  const unwatch = this.watch(async (event) => {
338
235
  try {
339
- await writer.write({
340
- // @ts-ignore
341
- type: "start",
342
- // @ts-ignore
343
- payload: { runId: this.runId }
344
- });
345
236
  const e = {
346
237
  ...event,
347
238
  type: event.type.replace("workflow-", "")
348
239
  };
349
- if (e.type === "step-output") {
350
- e.type = e.payload.output.type;
351
- e.payload = e.payload.output.payload;
352
- }
353
240
  await writer.write(e);
354
241
  } catch {
355
242
  }
356
- });
243
+ }, "watch-v2");
357
244
  this.closeStreamAction = async () => {
358
- await writer.write({
359
- type: "finish",
360
- // @ts-ignore
361
- payload: { runId: this.runId }
362
- });
363
245
  unwatch();
364
246
  try {
365
247
  await writer.close();
@@ -369,7 +251,7 @@ var InngestRun = class extends workflows.Run {
369
251
  writer.releaseLock();
370
252
  }
371
253
  };
372
- this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
254
+ this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
373
255
  if (result.status !== "suspended") {
374
256
  this.closeStreamAction?.().catch(() => {
375
257
  });
@@ -383,94 +265,11 @@ var InngestRun = class extends workflows.Run {
383
265
  }
384
266
  stream({
385
267
  inputData,
386
- requestContext,
387
- tracingOptions,
388
- closeOnSuspend = true,
389
- initialState,
390
- outputOptions
268
+ runtimeContext,
269
+ closeOnSuspend = true
391
270
  } = {}) {
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
271
  const self = this;
272
+ let streamOutput;
474
273
  const stream$1 = new web.ReadableStream({
475
274
  async start(controller) {
476
275
  const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
@@ -479,11 +278,11 @@ var InngestRun = class extends workflows.Run {
479
278
  runId: self.runId,
480
279
  from,
481
280
  payload: {
482
- stepName: payload?.id,
281
+ stepName: payload.id,
483
282
  ...payload
484
283
  }
485
284
  });
486
- });
285
+ }, "watch-v2");
487
286
  self.closeStreamAction = async () => {
488
287
  unwatch();
489
288
  try {
@@ -492,39 +291,29 @@ var InngestRun = class extends workflows.Run {
492
291
  console.error("Error closing stream:", err);
493
292
  }
494
293
  };
495
- const executionResultsPromise = self._timeTravel({
294
+ const executionResultsPromise = self.start({
496
295
  inputData,
497
- step,
498
- context,
499
- nestedStepsContext,
500
- resumeData,
501
- initialState,
502
- requestContext,
503
- tracingOptions,
504
- outputOptions
296
+ runtimeContext
505
297
  });
506
- self.executionResults = executionResultsPromise;
507
- let executionResults;
508
- try {
509
- executionResults = await executionResultsPromise;
298
+ const executionResults = await executionResultsPromise;
299
+ if (closeOnSuspend) {
510
300
  self.closeStreamAction?.().catch(() => {
511
301
  });
512
- if (self.streamOutput) {
513
- self.streamOutput.updateResults(executionResults);
514
- }
515
- } catch (err) {
516
- self.streamOutput?.rejectResults(err);
302
+ } else if (executionResults.status !== "suspended") {
517
303
  self.closeStreamAction?.().catch(() => {
518
304
  });
519
305
  }
306
+ if (streamOutput) {
307
+ streamOutput.updateResults(executionResults);
308
+ }
520
309
  }
521
310
  });
522
- this.streamOutput = new stream.WorkflowRunOutput({
311
+ streamOutput = new stream.WorkflowRunOutput({
523
312
  runId: this.runId,
524
313
  workflowId: this.workflowId,
525
314
  stream: stream$1
526
315
  });
527
- return this.streamOutput;
316
+ return streamOutput;
528
317
  }
529
318
  };
530
319
  var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
@@ -535,7 +324,6 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
535
324
  constructor(params, inngest) {
536
325
  const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
537
326
  super(workflowParams);
538
- this.engineType = "inngest";
539
327
  const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
540
328
  ([_, value]) => value !== void 0
541
329
  );
@@ -543,13 +331,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
543
331
  this.#mastra = params.mastra;
544
332
  this.inngest = inngest;
545
333
  }
546
- async listWorkflowRuns(args) {
334
+ async getWorkflowRuns(args) {
547
335
  const storage = this.#mastra?.getStorage();
548
336
  if (!storage) {
549
337
  this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
550
338
  return { runs: [], total: 0 };
551
339
  }
552
- return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
340
+ return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
553
341
  }
554
342
  async getWorkflowRunById(runId) {
555
343
  const storage = this.#mastra?.getStorage();
@@ -578,7 +366,16 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
578
366
  }
579
367
  }
580
368
  }
581
- async createRun(options) {
369
+ /**
370
+ * @deprecated Use createRunAsync() instead.
371
+ * @throws {Error} Always throws an error directing users to use createRunAsync()
372
+ */
373
+ createRun(_options) {
374
+ throw new Error(
375
+ "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."
376
+ );
377
+ }
378
+ async createRunAsync(options) {
582
379
  const runIdToUse = options?.runId || crypto.randomUUID();
583
380
  const run = this.runs.get(runIdToUse) ?? new InngestRun(
584
381
  {
@@ -591,9 +388,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
591
388
  mastra: this.#mastra,
592
389
  retryConfig: this.retryConfig,
593
390
  cleanup: () => this.runs.delete(runIdToUse),
594
- workflowSteps: this.steps,
595
- workflowEngineType: this.engineType,
596
- validateInputs: this.options.validateInputs
391
+ workflowSteps: this.steps
597
392
  },
598
393
  this.inngest
599
394
  );
@@ -614,13 +409,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
614
409
  value: {},
615
410
  context: {},
616
411
  activePaths: [],
617
- activeStepsPath: {},
618
412
  waitingPaths: {},
619
413
  serializedStepGraph: this.serializedStepGraph,
620
414
  suspendedPaths: {},
621
415
  resumeLabels: {},
622
416
  result: void 0,
623
417
  error: void 0,
418
+ // @ts-ignore
624
419
  timestamp: Date.now()
625
420
  }
626
421
  });
@@ -634,14 +429,15 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
634
429
  this.function = this.inngest.createFunction(
635
430
  {
636
431
  id: `workflow.${this.id}`,
637
- retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
432
+ // @ts-ignore
433
+ retries: this.retryConfig?.attempts ?? 0,
638
434
  cancelOn: [{ event: `cancel.workflow.${this.id}` }],
639
435
  // Spread flow control configuration
640
436
  ...this.flowControlConfig
641
437
  },
642
438
  { event: `workflow.${this.id}` },
643
439
  async ({ event, step, attempt, publish }) => {
644
- let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
440
+ let { inputData, initialState, runId, resourceId, resume, outputOptions } = event.data;
645
441
  if (!runId) {
646
442
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
647
443
  return crypto.randomUUID();
@@ -680,20 +476,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
680
476
  initialState,
681
477
  emitter,
682
478
  retryConfig: this.retryConfig,
683
- requestContext: new di.RequestContext(),
479
+ runtimeContext: new di.RuntimeContext(),
684
480
  // TODO
685
481
  resume,
686
- timeTravel,
687
- format,
688
482
  abortController: new AbortController(),
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
- })
483
+ currentSpan: void 0,
484
+ // TODO: Pass actual parent AI span from workflow execution context
485
+ outputOptions
697
486
  });
698
487
  await step.run(`workflow.${this.id}.finalize`, async () => {
699
488
  if (result.status === "failed") {
@@ -731,29 +520,20 @@ function isAgent(params) {
731
520
  function isTool(params) {
732
521
  return params instanceof tools.Tool;
733
522
  }
734
- function createStep(params, agentOptions) {
523
+ function createStep(params) {
735
524
  if (isAgent(params)) {
736
525
  return {
737
526
  id: params.name,
738
527
  description: params.getDescription(),
528
+ // @ts-ignore
739
529
  inputSchema: zod.z.object({
740
530
  prompt: zod.z.string()
741
- // resourceId: z.string().optional(),
742
- // threadId: z.string().optional(),
743
531
  }),
532
+ // @ts-ignore
744
533
  outputSchema: zod.z.object({
745
534
  text: zod.z.string()
746
535
  }),
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
- }) => {
536
+ execute: async ({ inputData, [_constants.EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
757
537
  let streamPromise = {};
758
538
  streamPromise.promise = new Promise((resolve, reject) => {
759
539
  streamPromise.resolve = resolve;
@@ -763,60 +543,61 @@ function createStep(params, agentOptions) {
763
543
  name: params.name,
764
544
  args: inputData
765
545
  };
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,
546
+ if ((await params.getLLM()).getModel().specificationVersion === `v2`) {
547
+ const { fullStream } = await params.stream(inputData.prompt, {
548
+ runtimeContext,
773
549
  tracingContext,
774
550
  onFinish: (result) => {
775
551
  streamPromise.resolve(result.text);
776
- void agentOptions?.onFinish?.(result);
777
552
  },
778
553
  abortSignal
779
554
  });
780
- stream = fullStream;
555
+ if (abortSignal.aborted) {
556
+ return abort();
557
+ }
558
+ await emitter.emit("watch-v2", {
559
+ type: "tool-call-streaming-start",
560
+ ...toolData ?? {}
561
+ });
562
+ for await (const chunk of fullStream) {
563
+ if (chunk.type === "text-delta") {
564
+ await emitter.emit("watch-v2", {
565
+ type: "tool-call-delta",
566
+ ...toolData ?? {},
567
+ argsTextDelta: chunk.payload.text
568
+ });
569
+ }
570
+ }
781
571
  } else {
782
- const modelOutput = await params.stream(inputData.prompt, {
783
- ...agentOptions ?? {},
784
- requestContext,
572
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
573
+ runtimeContext,
785
574
  tracingContext,
786
575
  onFinish: (result) => {
787
576
  streamPromise.resolve(result.text);
788
- void agentOptions?.onFinish?.(result);
789
577
  },
790
578
  abortSignal
791
579
  });
792
- stream = modelOutput.fullStream;
793
- }
794
- if (streamFormat === "legacy") {
795
- await emitter.emit("watch", {
580
+ if (abortSignal.aborted) {
581
+ return abort();
582
+ }
583
+ await emitter.emit("watch-v2", {
796
584
  type: "tool-call-streaming-start",
797
585
  ...toolData ?? {}
798
586
  });
799
- for await (const chunk of stream) {
587
+ for await (const chunk of fullStream) {
800
588
  if (chunk.type === "text-delta") {
801
- await emitter.emit("watch", {
589
+ await emitter.emit("watch-v2", {
802
590
  type: "tool-call-delta",
803
591
  ...toolData ?? {},
804
592
  argsTextDelta: chunk.textDelta
805
593
  });
806
594
  }
807
595
  }
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();
819
596
  }
597
+ await emitter.emit("watch-v2", {
598
+ type: "tool-call-streaming-finish",
599
+ ...toolData ?? {}
600
+ });
820
601
  return {
821
602
  text: await streamPromise.promise
822
603
  };
@@ -830,38 +611,20 @@ function createStep(params, agentOptions) {
830
611
  }
831
612
  return {
832
613
  // TODO: tool probably should have strong id type
614
+ // @ts-ignore
833
615
  id: params.id,
834
616
  description: params.description,
835
617
  inputSchema: params.inputSchema,
836
618
  outputSchema: params.outputSchema,
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,
619
+ execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
620
+ return params.execute({
621
+ context: inputData,
622
+ mastra: aiTracing.wrapMastra(mastra, tracingContext),
623
+ runtimeContext,
854
624
  tracingContext,
855
- workflow: {
856
- runId,
857
- resumeData,
858
- suspend,
859
- workflowId,
860
- state,
861
- setState
862
- }
863
- };
864
- return params.execute(inputData, toolContext);
625
+ suspend,
626
+ resumeData
627
+ });
865
628
  },
866
629
  component: "TOOL"
867
630
  };
@@ -895,8 +658,6 @@ function init(inngest) {
895
658
  suspendSchema: step.suspendSchema,
896
659
  stateSchema: step.stateSchema,
897
660
  execute: step.execute,
898
- retries: step.retries,
899
- scorers: step.scorers,
900
661
  component: step.component
901
662
  };
902
663
  },
@@ -922,16 +683,63 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
922
683
  this.inngestStep = inngestStep;
923
684
  this.inngestAttempts = inngestAttempts;
924
685
  }
925
- async fmtReturnValue(emitter, stepResults, lastOutput, error) {
686
+ async execute(params) {
687
+ await params.emitter.emit("watch-v2", {
688
+ type: "workflow-start",
689
+ payload: { runId: params.runId }
690
+ });
691
+ const result = await super.execute(params);
692
+ await params.emitter.emit("watch-v2", {
693
+ type: "workflow-finish",
694
+ payload: { runId: params.runId }
695
+ });
696
+ return result;
697
+ }
698
+ async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
926
699
  const base = {
927
700
  status: lastOutput.status,
928
701
  steps: stepResults
929
702
  };
930
703
  if (lastOutput.status === "success") {
704
+ await emitter.emit("watch", {
705
+ type: "watch",
706
+ payload: {
707
+ workflowState: {
708
+ status: lastOutput.status,
709
+ steps: stepResults,
710
+ result: lastOutput.output
711
+ }
712
+ },
713
+ eventTimestamp: Date.now()
714
+ });
931
715
  base.result = lastOutput.output;
932
716
  } else if (lastOutput.status === "failed") {
933
717
  base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
718
+ await emitter.emit("watch", {
719
+ type: "watch",
720
+ payload: {
721
+ workflowState: {
722
+ status: lastOutput.status,
723
+ steps: stepResults,
724
+ result: null,
725
+ error: base.error
726
+ }
727
+ },
728
+ eventTimestamp: Date.now()
729
+ });
934
730
  } else if (lastOutput.status === "suspended") {
731
+ await emitter.emit("watch", {
732
+ type: "watch",
733
+ payload: {
734
+ workflowState: {
735
+ status: lastOutput.status,
736
+ steps: stepResults,
737
+ result: null,
738
+ error: null
739
+ }
740
+ },
741
+ eventTimestamp: Date.now()
742
+ });
935
743
  const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
936
744
  if (stepResult?.status === "suspended") {
937
745
  const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
@@ -941,6 +749,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
941
749
  });
942
750
  base.suspended = suspendedStepIds;
943
751
  }
752
+ executionSpan?.end();
944
753
  return base;
945
754
  }
946
755
  // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
@@ -954,14 +763,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
954
763
  stepResults,
955
764
  emitter,
956
765
  abortController,
957
- requestContext,
766
+ runtimeContext,
958
767
  executionContext,
959
768
  writableStream,
960
769
  tracingContext
961
770
  }) {
962
771
  let { duration, fn } = entry;
963
772
  const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
964
- type: observability.SpanType.WORKFLOW_SLEEP,
773
+ type: aiTracing.AISpanType.WORKFLOW_SLEEP,
965
774
  name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
966
775
  attributes: {
967
776
  durationMs: duration,
@@ -972,53 +781,45 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
972
781
  if (fn) {
973
782
  const stepCallId = crypto.randomUUID();
974
783
  duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
975
- return await fn(
976
- workflows.createDeprecationProxy(
784
+ return await fn({
785
+ runId,
786
+ workflowId,
787
+ mastra: this.mastra,
788
+ runtimeContext,
789
+ inputData: prevOutput,
790
+ state: executionContext.state,
791
+ setState: (state) => {
792
+ executionContext.state = state;
793
+ },
794
+ runCount: -1,
795
+ tracingContext: {
796
+ currentSpan: sleepSpan
797
+ },
798
+ getInitData: () => stepResults?.input,
799
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
800
+ // TODO: this function shouldn't have suspend probably?
801
+ suspend: async (_suspendPayload) => {
802
+ },
803
+ bail: () => {
804
+ },
805
+ abort: () => {
806
+ abortController?.abort();
807
+ },
808
+ [_constants.EMITTER_SYMBOL]: emitter,
809
+ // TODO: add streamVNext support
810
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
811
+ engine: { step: this.inngestStep },
812
+ abortSignal: abortController?.signal,
813
+ writer: new tools.ToolStream(
977
814
  {
978
- runId,
979
- workflowId,
980
- mastra: this.mastra,
981
- requestContext,
982
- inputData: prevOutput,
983
- state: executionContext.state,
984
- setState: (state) => {
985
- executionContext.state = state;
986
- },
987
- retryCount: -1,
988
- tracingContext: {
989
- currentSpan: sleepSpan
990
- },
991
- getInitData: () => stepResults?.input,
992
- getStepResult: workflows.getStepResult.bind(this, stepResults),
993
- // TODO: this function shouldn't have suspend probably?
994
- suspend: async (_suspendPayload) => {
995
- },
996
- bail: () => {
997
- },
998
- abort: () => {
999
- abortController?.abort();
1000
- },
1001
- [_constants.EMITTER_SYMBOL]: emitter,
1002
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1003
- engine: { step: this.inngestStep },
1004
- abortSignal: abortController?.signal,
1005
- writer: new tools.ToolStream(
1006
- {
1007
- prefix: "workflow-step",
1008
- callId: stepCallId,
1009
- name: "sleep",
1010
- runId
1011
- },
1012
- writableStream
1013
- )
815
+ prefix: "workflow-step",
816
+ callId: stepCallId,
817
+ name: "sleep",
818
+ runId
1014
819
  },
1015
- {
1016
- paramName: "runCount",
1017
- deprecationMessage: workflows.runCountDeprecationMessage,
1018
- logger: this.logger
1019
- }
820
+ writableStream
1020
821
  )
1021
- );
822
+ });
1022
823
  });
1023
824
  sleepSpan?.update({
1024
825
  attributes: {
@@ -1042,14 +843,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1042
843
  stepResults,
1043
844
  emitter,
1044
845
  abortController,
1045
- requestContext,
846
+ runtimeContext,
1046
847
  executionContext,
1047
848
  writableStream,
1048
849
  tracingContext
1049
850
  }) {
1050
851
  let { date, fn } = entry;
1051
852
  const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
1052
- type: observability.SpanType.WORKFLOW_SLEEP,
853
+ type: aiTracing.AISpanType.WORKFLOW_SLEEP,
1053
854
  name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
1054
855
  attributes: {
1055
856
  untilDate: date,
@@ -1061,53 +862,45 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1061
862
  if (fn) {
1062
863
  date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
1063
864
  const stepCallId = crypto.randomUUID();
1064
- return await fn(
1065
- workflows.createDeprecationProxy(
865
+ return await fn({
866
+ runId,
867
+ workflowId,
868
+ mastra: this.mastra,
869
+ runtimeContext,
870
+ inputData: prevOutput,
871
+ state: executionContext.state,
872
+ setState: (state) => {
873
+ executionContext.state = state;
874
+ },
875
+ runCount: -1,
876
+ tracingContext: {
877
+ currentSpan: sleepUntilSpan
878
+ },
879
+ getInitData: () => stepResults?.input,
880
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
881
+ // TODO: this function shouldn't have suspend probably?
882
+ suspend: async (_suspendPayload) => {
883
+ },
884
+ bail: () => {
885
+ },
886
+ abort: () => {
887
+ abortController?.abort();
888
+ },
889
+ [_constants.EMITTER_SYMBOL]: emitter,
890
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
891
+ // TODO: add streamVNext support
892
+ engine: { step: this.inngestStep },
893
+ abortSignal: abortController?.signal,
894
+ writer: new tools.ToolStream(
1066
895
  {
1067
- runId,
1068
- workflowId,
1069
- mastra: this.mastra,
1070
- requestContext,
1071
- inputData: prevOutput,
1072
- state: executionContext.state,
1073
- setState: (state) => {
1074
- executionContext.state = state;
1075
- },
1076
- retryCount: -1,
1077
- tracingContext: {
1078
- currentSpan: sleepUntilSpan
1079
- },
1080
- getInitData: () => stepResults?.input,
1081
- getStepResult: workflows.getStepResult.bind(this, stepResults),
1082
- // TODO: this function shouldn't have suspend probably?
1083
- suspend: async (_suspendPayload) => {
1084
- },
1085
- bail: () => {
1086
- },
1087
- abort: () => {
1088
- abortController?.abort();
1089
- },
1090
- [_constants.EMITTER_SYMBOL]: emitter,
1091
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1092
- engine: { step: this.inngestStep },
1093
- abortSignal: abortController?.signal,
1094
- writer: new tools.ToolStream(
1095
- {
1096
- prefix: "workflow-step",
1097
- callId: stepCallId,
1098
- name: "sleep",
1099
- runId
1100
- },
1101
- writableStream
1102
- )
896
+ prefix: "workflow-step",
897
+ callId: stepCallId,
898
+ name: "sleep",
899
+ runId
1103
900
  },
1104
- {
1105
- paramName: "runCount",
1106
- deprecationMessage: workflows.runCountDeprecationMessage,
1107
- logger: this.logger
1108
- }
901
+ writableStream
1109
902
  )
1110
- );
903
+ });
1111
904
  });
1112
905
  if (date && !(date instanceof Date)) {
1113
906
  date = new Date(date);
@@ -1131,23 +924,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1131
924
  throw e;
1132
925
  }
1133
926
  }
927
+ async executeWaitForEvent({ event, timeout }) {
928
+ const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
929
+ event: `user-event-${event}`,
930
+ timeout: timeout ?? 5e3
931
+ });
932
+ if (eventData === null) {
933
+ throw "Timeout waiting for event";
934
+ }
935
+ return eventData?.data;
936
+ }
1134
937
  async executeStep({
1135
938
  step,
1136
939
  stepResults,
1137
940
  executionContext,
1138
941
  resume,
1139
- timeTravel,
1140
942
  prevOutput,
1141
943
  emitter,
1142
944
  abortController,
1143
- requestContext,
945
+ runtimeContext,
1144
946
  tracingContext,
1145
947
  writableStream,
1146
948
  disableScorers
1147
949
  }) {
1148
- const stepSpan = tracingContext?.currentSpan?.createChildSpan({
950
+ const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
1149
951
  name: `workflow step: '${step.id}'`,
1150
- type: observability.SpanType.WORKFLOW_STEP,
952
+ type: aiTracing.AISpanType.WORKFLOW_STEP,
1151
953
  input: prevOutput,
1152
954
  attributes: {
1153
955
  stepId: step.id
@@ -1157,13 +959,34 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1157
959
  const { inputData, validationError } = await workflows.validateStepInput({
1158
960
  prevOutput,
1159
961
  step,
1160
- validateInputs: this.options?.validateInputs ?? true
962
+ validateInputs: this.options?.validateInputs ?? false
1161
963
  });
1162
964
  const startedAt = await this.inngestStep.run(
1163
965
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
1164
966
  async () => {
1165
967
  const startedAt2 = Date.now();
1166
968
  await emitter.emit("watch", {
969
+ type: "watch",
970
+ payload: {
971
+ currentStep: {
972
+ id: step.id,
973
+ status: "running"
974
+ },
975
+ workflowState: {
976
+ status: "running",
977
+ steps: {
978
+ ...stepResults,
979
+ [step.id]: {
980
+ status: "running"
981
+ }
982
+ },
983
+ result: null,
984
+ error: null
985
+ }
986
+ },
987
+ eventTimestamp: Date.now()
988
+ });
989
+ await emitter.emit("watch-v2", {
1167
990
  type: "workflow-step-start",
1168
991
  payload: {
1169
992
  id: step.id,
@@ -1179,10 +1002,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1179
1002
  const isResume = !!resume?.steps?.length;
1180
1003
  let result;
1181
1004
  let runId;
1182
- const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
1183
1005
  try {
1184
1006
  if (isResume) {
1185
- runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
1007
+ runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
1186
1008
  const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1187
1009
  workflowName: step.id,
1188
1010
  runId
@@ -1198,7 +1020,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1198
1020
  steps: resume.steps.slice(1),
1199
1021
  stepResults: snapshot?.context,
1200
1022
  resumePayload: resume.resumePayload,
1201
- resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
1023
+ // @ts-ignore
1024
+ resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1202
1025
  },
1203
1026
  outputOptions: { includeState: true }
1204
1027
  }
@@ -1206,32 +1029,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1206
1029
  result = invokeResp.result;
1207
1030
  runId = invokeResp.runId;
1208
1031
  executionContext.state = invokeResp.result.state;
1209
- } else if (isTimeTravel) {
1210
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1211
- workflowName: step.id,
1212
- runId: executionContext.runId
1213
- }) ?? { context: {} };
1214
- const timeTravelParams = workflows.createTimeTravelExecutionParams({
1215
- steps: timeTravel.steps.slice(1),
1216
- inputData: timeTravel.inputData,
1217
- resumeData: timeTravel.resumeData,
1218
- context: timeTravel.nestedStepResults?.[step.id] ?? {},
1219
- nestedStepsContext: timeTravel.nestedStepResults ?? {},
1220
- snapshot,
1221
- graph: step.buildExecutionGraph()
1222
- });
1223
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1224
- function: step.getFunction(),
1225
- data: {
1226
- timeTravel: timeTravelParams,
1227
- initialState: executionContext.state ?? {},
1228
- runId: executionContext.runId,
1229
- outputOptions: { includeState: true }
1230
- }
1231
- });
1232
- result = invokeResp.result;
1233
- runId = invokeResp.runId;
1234
- executionContext.state = invokeResp.result.state;
1235
1032
  } else {
1236
1033
  const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1237
1034
  function: step.getFunction(),
@@ -1265,6 +1062,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1265
1062
  async () => {
1266
1063
  if (result.status === "failed") {
1267
1064
  await emitter.emit("watch", {
1065
+ type: "watch",
1066
+ payload: {
1067
+ currentStep: {
1068
+ id: step.id,
1069
+ status: "failed",
1070
+ error: result?.error
1071
+ },
1072
+ workflowState: {
1073
+ status: "running",
1074
+ steps: stepResults,
1075
+ result: null,
1076
+ error: null
1077
+ }
1078
+ },
1079
+ eventTimestamp: Date.now()
1080
+ });
1081
+ await emitter.emit("watch-v2", {
1268
1082
  type: "workflow-step-result",
1269
1083
  payload: {
1270
1084
  id: step.id,
@@ -1283,6 +1097,27 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1283
1097
  const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
1284
1098
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1285
1099
  await emitter.emit("watch", {
1100
+ type: "watch",
1101
+ payload: {
1102
+ currentStep: {
1103
+ id: step.id,
1104
+ status: "suspended",
1105
+ payload: stepResult.payload,
1106
+ suspendPayload: {
1107
+ ...stepResult?.suspendPayload,
1108
+ __workflow_meta: { runId, path: suspendPath }
1109
+ }
1110
+ },
1111
+ workflowState: {
1112
+ status: "running",
1113
+ steps: stepResults,
1114
+ result: null,
1115
+ error: null
1116
+ }
1117
+ },
1118
+ eventTimestamp: Date.now()
1119
+ });
1120
+ await emitter.emit("watch-v2", {
1286
1121
  type: "workflow-step-suspended",
1287
1122
  payload: {
1288
1123
  id: step.id,
@@ -1301,6 +1136,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1301
1136
  }
1302
1137
  };
1303
1138
  }
1139
+ await emitter.emit("watch", {
1140
+ type: "watch",
1141
+ payload: {
1142
+ currentStep: {
1143
+ id: step.id,
1144
+ status: "suspended",
1145
+ payload: {}
1146
+ },
1147
+ workflowState: {
1148
+ status: "running",
1149
+ steps: stepResults,
1150
+ result: null,
1151
+ error: null
1152
+ }
1153
+ },
1154
+ eventTimestamp: Date.now()
1155
+ });
1304
1156
  return {
1305
1157
  executionContext,
1306
1158
  result: {
@@ -1310,6 +1162,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1310
1162
  };
1311
1163
  }
1312
1164
  await emitter.emit("watch", {
1165
+ type: "watch",
1166
+ payload: {
1167
+ currentStep: {
1168
+ id: step.id,
1169
+ status: "success",
1170
+ output: result?.result
1171
+ },
1172
+ workflowState: {
1173
+ status: "running",
1174
+ steps: stepResults,
1175
+ result: null,
1176
+ error: null
1177
+ }
1178
+ },
1179
+ eventTimestamp: Date.now()
1180
+ });
1181
+ await emitter.emit("watch-v2", {
1313
1182
  type: "workflow-step-result",
1314
1183
  payload: {
1315
1184
  id: step.id,
@@ -1317,7 +1186,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1317
1186
  output: result?.result
1318
1187
  }
1319
1188
  });
1320
- await emitter.emit("watch", {
1189
+ await emitter.emit("watch-v2", {
1321
1190
  type: "workflow-step-finish",
1322
1191
  payload: {
1323
1192
  id: step.id,
@@ -1337,67 +1206,33 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1337
1206
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1338
1207
  };
1339
1208
  }
1340
- const stepCallId = crypto.randomUUID();
1341
1209
  let stepRes;
1342
1210
  try {
1343
1211
  stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1344
1212
  let execResults;
1345
1213
  let suspended;
1346
1214
  let bailed;
1347
- const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
1348
- resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
1349
- step
1350
- });
1351
- let resumeDataToUse;
1352
- if (timeTravelResumeData && !timeTravelResumeValidationError) {
1353
- resumeDataToUse = timeTravelResumeData;
1354
- } else if (timeTravelResumeData && timeTravelResumeValidationError) {
1355
- this.logger.warn("Time travel resume data validation failed", {
1356
- stepId: step.id,
1357
- error: timeTravelResumeValidationError.message
1358
- });
1359
- } else if (resume?.steps[0] === step.id) {
1360
- resumeDataToUse = resume?.resumePayload;
1361
- }
1362
1215
  try {
1363
1216
  if (validationError) {
1364
1217
  throw validationError;
1365
1218
  }
1366
- const retryCount = this.getOrGenerateRetryCount(step.id);
1367
1219
  const result = await step.execute({
1368
1220
  runId: executionContext.runId,
1369
- workflowId: executionContext.workflowId,
1370
1221
  mastra: this.mastra,
1371
- requestContext,
1372
- retryCount,
1373
- writer: new tools.ToolStream(
1374
- {
1375
- prefix: "workflow-step",
1376
- callId: stepCallId,
1377
- name: step.id,
1378
- runId: executionContext.runId
1379
- },
1380
- writableStream
1381
- ),
1222
+ runtimeContext,
1223
+ writableStream,
1382
1224
  state: executionContext?.state ?? {},
1383
1225
  setState: (state) => {
1384
1226
  executionContext.state = state;
1385
1227
  },
1386
1228
  inputData,
1387
- resumeData: resumeDataToUse,
1229
+ resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1388
1230
  tracingContext: {
1389
- currentSpan: stepSpan
1231
+ currentSpan: stepAISpan
1390
1232
  },
1391
1233
  getInitData: () => stepResults?.input,
1392
1234
  getStepResult: workflows.getStepResult.bind(this, stepResults),
1393
1235
  suspend: async (suspendPayload, suspendOptions) => {
1394
- const { suspendData, validationError: validationError2 } = await workflows.validateStepSuspendData({
1395
- suspendData: suspendPayload,
1396
- step
1397
- });
1398
- if (validationError2) {
1399
- throw validationError2;
1400
- }
1401
1236
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1402
1237
  if (suspendOptions?.resumeLabel) {
1403
1238
  const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
@@ -1408,16 +1243,18 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1408
1243
  };
1409
1244
  }
1410
1245
  }
1411
- suspended = { payload: suspendData };
1246
+ suspended = { payload: suspendPayload };
1412
1247
  },
1413
1248
  bail: (result2) => {
1414
1249
  bailed = { payload: result2 };
1415
1250
  },
1416
- abort: () => {
1417
- abortController?.abort();
1251
+ resume: {
1252
+ steps: resume?.steps?.slice(1) || [],
1253
+ resumePayload: resume?.resumePayload,
1254
+ // @ts-ignore
1255
+ runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1418
1256
  },
1419
1257
  [_constants.EMITTER_SYMBOL]: emitter,
1420
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1421
1258
  engine: {
1422
1259
  step: this.inngestStep
1423
1260
  },
@@ -1430,22 +1267,22 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1430
1267
  startedAt,
1431
1268
  endedAt,
1432
1269
  payload: inputData,
1433
- resumedAt: resumeDataToUse ? startedAt : void 0,
1434
- resumePayload: resumeDataToUse
1270
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1271
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1435
1272
  };
1436
1273
  } catch (e) {
1437
1274
  const stepFailure = {
1438
1275
  status: "failed",
1439
1276
  payload: inputData,
1440
- error: e instanceof Error ? e.message : String(e),
1277
+ error: e instanceof Error ? e.stack ?? e.message : String(e),
1441
1278
  endedAt: Date.now(),
1442
1279
  startedAt,
1443
- resumedAt: resumeDataToUse ? startedAt : void 0,
1444
- resumePayload: resumeDataToUse
1280
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1281
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1445
1282
  };
1446
1283
  execResults = stepFailure;
1447
1284
  const fallbackErrorMessage = `Step ${step.id} failed`;
1448
- stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1285
+ stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1449
1286
  throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1450
1287
  cause: execResults
1451
1288
  });
@@ -1454,12 +1291,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1454
1291
  execResults = {
1455
1292
  status: "suspended",
1456
1293
  suspendPayload: suspended.payload,
1457
- ...execResults.output ? { suspendOutput: execResults.output } : {},
1458
1294
  payload: inputData,
1459
1295
  suspendedAt: Date.now(),
1460
1296
  startedAt,
1461
- resumedAt: resumeDataToUse ? startedAt : void 0,
1462
- resumePayload: resumeDataToUse
1297
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1298
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1463
1299
  };
1464
1300
  } else if (bailed) {
1465
1301
  execResults = {
@@ -1470,8 +1306,24 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1470
1306
  startedAt
1471
1307
  };
1472
1308
  }
1309
+ await emitter.emit("watch", {
1310
+ type: "watch",
1311
+ payload: {
1312
+ currentStep: {
1313
+ id: step.id,
1314
+ ...execResults
1315
+ },
1316
+ workflowState: {
1317
+ status: "running",
1318
+ steps: { ...stepResults, [step.id]: execResults },
1319
+ result: null,
1320
+ error: null
1321
+ }
1322
+ },
1323
+ eventTimestamp: Date.now()
1324
+ });
1473
1325
  if (execResults.status === "suspended") {
1474
- await emitter.emit("watch", {
1326
+ await emitter.emit("watch-v2", {
1475
1327
  type: "workflow-step-suspended",
1476
1328
  payload: {
1477
1329
  id: step.id,
@@ -1479,14 +1331,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1479
1331
  }
1480
1332
  });
1481
1333
  } else {
1482
- await emitter.emit("watch", {
1334
+ await emitter.emit("watch-v2", {
1483
1335
  type: "workflow-step-result",
1484
1336
  payload: {
1485
1337
  id: step.id,
1486
1338
  ...execResults
1487
1339
  }
1488
1340
  });
1489
- await emitter.emit("watch", {
1341
+ await emitter.emit("watch-v2", {
1490
1342
  type: "workflow-step-finish",
1491
1343
  payload: {
1492
1344
  id: step.id,
@@ -1494,17 +1346,31 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1494
1346
  }
1495
1347
  });
1496
1348
  }
1497
- stepSpan?.end({ output: execResults });
1349
+ stepAISpan?.end({ output: execResults });
1498
1350
  return { result: execResults, executionContext, stepResults };
1499
1351
  });
1500
1352
  } catch (e) {
1501
1353
  const stepFailure = e instanceof Error ? e?.cause : {
1502
1354
  status: "failed",
1503
- error: e instanceof Error ? e.message : String(e),
1355
+ error: e instanceof Error ? e.stack ?? e.message : String(e),
1504
1356
  payload: inputData,
1505
1357
  startedAt,
1506
1358
  endedAt: Date.now()
1507
1359
  };
1360
+ await emitter.emit("watch-v2", {
1361
+ type: "workflow-step-result",
1362
+ payload: {
1363
+ id: step.id,
1364
+ ...stepFailure
1365
+ }
1366
+ });
1367
+ await emitter.emit("watch-v2", {
1368
+ type: "workflow-step-finish",
1369
+ payload: {
1370
+ id: step.id,
1371
+ metadata: {}
1372
+ }
1373
+ });
1508
1374
  stepRes = {
1509
1375
  result: stepFailure,
1510
1376
  executionContext,
@@ -1524,14 +1390,15 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1524
1390
  output: stepRes.result,
1525
1391
  workflowId: executionContext.workflowId,
1526
1392
  stepId: step.id,
1527
- requestContext,
1393
+ runtimeContext,
1528
1394
  disableScorers,
1529
- tracingContext: { currentSpan: stepSpan }
1395
+ tracingContext: { currentSpan: stepAISpan }
1530
1396
  });
1531
1397
  }
1532
1398
  });
1533
1399
  }
1534
1400
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1401
+ Object.assign(stepResults, stepRes.stepResults);
1535
1402
  executionContext.state = stepRes.executionContext.state;
1536
1403
  return stepRes.result;
1537
1404
  }
@@ -1559,17 +1426,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1559
1426
  resourceId,
1560
1427
  snapshot: {
1561
1428
  runId,
1562
- status: workflowStatus,
1563
1429
  value: executionContext.state,
1564
1430
  context: stepResults,
1565
- activePaths: executionContext.executionPath,
1566
- activeStepsPath: executionContext.activeStepsPath,
1431
+ activePaths: [],
1567
1432
  suspendedPaths: executionContext.suspendedPaths,
1568
1433
  resumeLabels: executionContext.resumeLabels,
1569
1434
  waitingPaths: {},
1570
1435
  serializedStepGraph,
1436
+ status: workflowStatus,
1571
1437
  result,
1572
1438
  error,
1439
+ // @ts-ignore
1573
1440
  timestamp: Date.now()
1574
1441
  }
1575
1442
  });
@@ -1582,18 +1449,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1582
1449
  entry,
1583
1450
  prevOutput,
1584
1451
  stepResults,
1585
- timeTravel,
1586
1452
  resume,
1587
1453
  executionContext,
1588
1454
  emitter,
1589
1455
  abortController,
1590
- requestContext,
1456
+ runtimeContext,
1591
1457
  writableStream,
1592
1458
  disableScorers,
1593
1459
  tracingContext
1594
1460
  }) {
1595
1461
  const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1596
- type: observability.SpanType.WORKFLOW_CONDITIONAL,
1462
+ type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL,
1597
1463
  name: `conditional: '${entry.conditions.length} conditions'`,
1598
1464
  input: prevOutput,
1599
1465
  attributes: {
@@ -1606,7 +1472,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1606
1472
  entry.conditions.map(
1607
1473
  (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1608
1474
  const evalSpan = conditionalSpan?.createChildSpan({
1609
- type: observability.SpanType.WORKFLOW_CONDITIONAL_EVAL,
1475
+ type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL_EVAL,
1610
1476
  name: `condition: '${index}'`,
1611
1477
  input: prevOutput,
1612
1478
  attributes: {
@@ -1615,55 +1481,47 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1615
1481
  tracingPolicy: this.options?.tracingPolicy
1616
1482
  });
1617
1483
  try {
1618
- const result = await cond(
1619
- workflows.createDeprecationProxy(
1484
+ const result = await cond({
1485
+ runId,
1486
+ workflowId,
1487
+ mastra: this.mastra,
1488
+ runtimeContext,
1489
+ runCount: -1,
1490
+ inputData: prevOutput,
1491
+ state: executionContext.state,
1492
+ setState: (state) => {
1493
+ executionContext.state = state;
1494
+ },
1495
+ tracingContext: {
1496
+ currentSpan: evalSpan
1497
+ },
1498
+ getInitData: () => stepResults?.input,
1499
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1500
+ // TODO: this function shouldn't have suspend probably?
1501
+ suspend: async (_suspendPayload) => {
1502
+ },
1503
+ bail: () => {
1504
+ },
1505
+ abort: () => {
1506
+ abortController.abort();
1507
+ },
1508
+ [_constants.EMITTER_SYMBOL]: emitter,
1509
+ [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1510
+ // TODO: add streamVNext support
1511
+ engine: {
1512
+ step: this.inngestStep
1513
+ },
1514
+ abortSignal: abortController.signal,
1515
+ writer: new tools.ToolStream(
1620
1516
  {
1621
- runId,
1622
- workflowId,
1623
- mastra: this.mastra,
1624
- requestContext,
1625
- retryCount: -1,
1626
- inputData: prevOutput,
1627
- state: executionContext.state,
1628
- setState: (state) => {
1629
- executionContext.state = state;
1630
- },
1631
- tracingContext: {
1632
- currentSpan: evalSpan
1633
- },
1634
- getInitData: () => stepResults?.input,
1635
- getStepResult: workflows.getStepResult.bind(this, stepResults),
1636
- // TODO: this function shouldn't have suspend probably?
1637
- suspend: async (_suspendPayload) => {
1638
- },
1639
- bail: () => {
1640
- },
1641
- abort: () => {
1642
- abortController.abort();
1643
- },
1644
- [_constants.EMITTER_SYMBOL]: emitter,
1645
- [_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
1646
- engine: {
1647
- step: this.inngestStep
1648
- },
1649
- abortSignal: abortController.signal,
1650
- writer: new tools.ToolStream(
1651
- {
1652
- prefix: "workflow-step",
1653
- callId: crypto.randomUUID(),
1654
- name: "conditional",
1655
- runId
1656
- },
1657
- writableStream
1658
- )
1517
+ prefix: "workflow-step",
1518
+ callId: crypto.randomUUID(),
1519
+ name: "conditional",
1520
+ runId
1659
1521
  },
1660
- {
1661
- paramName: "runCount",
1662
- deprecationMessage: workflows.runCountDeprecationMessage,
1663
- logger: this.logger
1664
- }
1522
+ writableStream
1665
1523
  )
1666
- );
1524
+ });
1667
1525
  evalSpan?.end({
1668
1526
  output: result,
1669
1527
  attributes: {
@@ -1701,20 +1559,19 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1701
1559
  prevOutput,
1702
1560
  stepResults,
1703
1561
  resume,
1704
- timeTravel,
1705
1562
  executionContext: {
1706
1563
  workflowId,
1707
1564
  runId,
1708
1565
  executionPath: [...executionContext.executionPath, index],
1709
- activeStepsPath: executionContext.activeStepsPath,
1710
1566
  suspendedPaths: executionContext.suspendedPaths,
1711
1567
  resumeLabels: executionContext.resumeLabels,
1712
1568
  retryConfig: executionContext.retryConfig,
1569
+ executionSpan: executionContext.executionSpan,
1713
1570
  state: executionContext.state
1714
1571
  },
1715
1572
  emitter,
1716
1573
  abortController,
1717
- requestContext,
1574
+ runtimeContext,
1718
1575
  writableStream,
1719
1576
  disableScorers,
1720
1577
  tracingContext: {
@@ -1730,19 +1587,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1730
1587
  if (hasFailed) {
1731
1588
  execResults = { status: "failed", error: hasFailed.error };
1732
1589
  } else if (hasSuspended) {
1733
- execResults = {
1734
- status: "suspended",
1735
- suspendPayload: hasSuspended.suspendPayload,
1736
- ...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
1737
- };
1590
+ execResults = { status: "suspended", suspendPayload: hasSuspended.suspendPayload };
1738
1591
  } else {
1739
1592
  execResults = {
1740
1593
  status: "success",
1741
1594
  output: results.reduce((acc, result, index) => {
1742
1595
  if (result.status === "success") {
1743
- if ("step" in stepsToRun[index]) {
1744
- acc[stepsToRun[index].step.id] = result.output;
1745
- }
1596
+ acc[stepsToRun[index].step.id] = result.output;
1746
1597
  }
1747
1598
  return acc;
1748
1599
  }, {})