@mastra/inngest 0.0.0-share-agent-metadata-with-cloud-20250718110128 → 0.0.0-sidebar-window-undefined-fix-20251029233656

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.js CHANGED
@@ -1,16 +1,25 @@
1
1
  import { randomUUID } from 'crypto';
2
+ import { ReadableStream } from 'stream/web';
2
3
  import { subscribe } from '@inngest/realtime';
4
+ import { wrapMastra, AISpanType } from '@mastra/core/ai-tracing';
3
5
  import { RuntimeContext } from '@mastra/core/di';
4
- import { Tool } from '@mastra/core/tools';
5
- import { Run, Workflow, DefaultExecutionEngine } from '@mastra/core/workflows';
6
- import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
6
+ import { ChunkFrom, WorkflowRunOutput } from '@mastra/core/stream';
7
+ import { ToolStream, Tool } from '@mastra/core/tools';
8
+ import { Run, Workflow, DefaultExecutionEngine, createDeprecationProxy, getStepResult, runCountDeprecationMessage, validateStepInput } from '@mastra/core/workflows';
9
+ import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
10
+ import { NonRetriableError, RetryAfterError } from 'inngest';
7
11
  import { serve as serve$1 } from 'inngest/hono';
8
12
  import { z } from 'zod';
9
13
 
10
14
  // src/index.ts
11
- function serve({ mastra, inngest }) {
15
+ function serve({
16
+ mastra,
17
+ inngest,
18
+ functions: userFunctions = [],
19
+ registerOptions
20
+ }) {
12
21
  const wfs = mastra.getWorkflows();
13
- const functions = Array.from(
22
+ const workflowFunctions = Array.from(
14
23
  new Set(
15
24
  Object.values(wfs).flatMap((wf) => {
16
25
  if (wf instanceof InngestWorkflow) {
@@ -22,8 +31,9 @@ function serve({ mastra, inngest }) {
22
31
  )
23
32
  );
24
33
  return serve$1({
34
+ ...registerOptions,
25
35
  client: inngest,
26
- functions
36
+ functions: [...workflowFunctions, ...userFunctions]
27
37
  });
28
38
  }
29
39
  var InngestRun = class extends Run {
@@ -51,9 +61,15 @@ var InngestRun = class extends Run {
51
61
  await new Promise((resolve) => setTimeout(resolve, 1e3));
52
62
  runs = await this.getRuns(eventId);
53
63
  if (runs?.[0]?.status === "Failed") {
54
- console.log("run", runs?.[0]);
55
- throw new Error(`Function run ${runs?.[0]?.status}`);
56
- } else if (runs?.[0]?.status === "Cancelled") {
64
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
65
+ workflowName: this.workflowId,
66
+ runId: this.runId
67
+ });
68
+ return {
69
+ output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
70
+ };
71
+ }
72
+ if (runs?.[0]?.status === "Cancelled") {
57
73
  const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
58
74
  workflowName: this.workflowId,
59
75
  runId: this.runId
@@ -84,6 +100,7 @@ var InngestRun = class extends Run {
84
100
  await this.#mastra?.storage?.persistWorkflowSnapshot({
85
101
  workflowName: this.workflowId,
86
102
  runId: this.runId,
103
+ resourceId: this.resourceId,
87
104
  snapshot: {
88
105
  ...snapshot,
89
106
  status: "canceled"
@@ -92,11 +109,13 @@ var InngestRun = class extends Run {
92
109
  }
93
110
  }
94
111
  async start({
95
- inputData
112
+ inputData,
113
+ initialState
96
114
  }) {
97
115
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
98
116
  workflowName: this.workflowId,
99
117
  runId: this.runId,
118
+ resourceId: this.resourceId,
100
119
  snapshot: {
101
120
  runId: this.runId,
102
121
  serializedStepGraph: this.serializedStepGraph,
@@ -104,15 +123,21 @@ var InngestRun = class extends Run {
104
123
  context: {},
105
124
  activePaths: [],
106
125
  suspendedPaths: {},
126
+ resumeLabels: {},
127
+ waitingPaths: {},
107
128
  timestamp: Date.now(),
108
129
  status: "running"
109
130
  }
110
131
  });
132
+ const inputDataToUse = await this._validateInput(inputData);
133
+ const initialStateToUse = await this._validateInitialState(initialState ?? {});
111
134
  const eventOutput = await this.inngest.send({
112
135
  name: `workflow.${this.workflowId}`,
113
136
  data: {
114
- inputData,
115
- runId: this.runId
137
+ inputData: inputDataToUse,
138
+ initialState: initialStateToUse,
139
+ runId: this.runId,
140
+ resourceId: this.resourceId
116
141
  }
117
142
  });
118
143
  const eventId = eventOutput.ids[0];
@@ -148,16 +173,20 @@ var InngestRun = class extends Run {
148
173
  workflowName: this.workflowId,
149
174
  runId: this.runId
150
175
  });
176
+ const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
177
+ const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
151
178
  const eventOutput = await this.inngest.send({
152
179
  name: `workflow.${this.workflowId}`,
153
180
  data: {
154
- inputData: params.resumeData,
181
+ inputData: resumeDataToUse,
182
+ initialState: snapshot?.value ?? {},
155
183
  runId: this.runId,
184
+ workflowId: this.workflowId,
156
185
  stepResults: snapshot?.context,
157
186
  resume: {
158
187
  steps,
159
188
  stepResults: snapshot?.context,
160
- resumePayload: params.resumeData,
189
+ resumePayload: resumeDataToUse,
161
190
  // @ts-ignore
162
191
  resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
163
192
  }
@@ -197,12 +226,16 @@ var InngestRun = class extends Run {
197
226
  });
198
227
  };
199
228
  }
200
- stream({ inputData, runtimeContext } = {}) {
229
+ streamLegacy({ inputData, runtimeContext } = {}) {
201
230
  const { readable, writable } = new TransformStream();
202
231
  const writer = writable.getWriter();
203
232
  const unwatch = this.watch(async (event) => {
204
233
  try {
205
- await writer.write(event);
234
+ const e = {
235
+ ...event,
236
+ type: event.type.replace("workflow-", "")
237
+ };
238
+ await writer.write(e);
206
239
  } catch {
207
240
  }
208
241
  }, "watch-v2");
@@ -228,13 +261,71 @@ var InngestRun = class extends Run {
228
261
  getWorkflowState: () => this.executionResults
229
262
  };
230
263
  }
264
+ stream({
265
+ inputData,
266
+ runtimeContext,
267
+ closeOnSuspend = true
268
+ } = {}) {
269
+ const self = this;
270
+ let streamOutput;
271
+ const stream = new ReadableStream({
272
+ async start(controller) {
273
+ const unwatch = self.watch(async ({ type, from = ChunkFrom.WORKFLOW, payload }) => {
274
+ controller.enqueue({
275
+ type,
276
+ runId: self.runId,
277
+ from,
278
+ payload: {
279
+ stepName: payload.id,
280
+ ...payload
281
+ }
282
+ });
283
+ }, "watch-v2");
284
+ self.closeStreamAction = async () => {
285
+ unwatch();
286
+ try {
287
+ await controller.close();
288
+ } catch (err) {
289
+ console.error("Error closing stream:", err);
290
+ }
291
+ };
292
+ const executionResultsPromise = self.start({
293
+ inputData,
294
+ runtimeContext
295
+ });
296
+ const executionResults = await executionResultsPromise;
297
+ if (closeOnSuspend) {
298
+ self.closeStreamAction?.().catch(() => {
299
+ });
300
+ } else if (executionResults.status !== "suspended") {
301
+ self.closeStreamAction?.().catch(() => {
302
+ });
303
+ }
304
+ if (streamOutput) {
305
+ streamOutput.updateResults(executionResults);
306
+ }
307
+ }
308
+ });
309
+ streamOutput = new WorkflowRunOutput({
310
+ runId: this.runId,
311
+ workflowId: this.workflowId,
312
+ stream
313
+ });
314
+ return streamOutput;
315
+ }
231
316
  };
232
317
  var InngestWorkflow = class _InngestWorkflow extends Workflow {
233
318
  #mastra;
234
319
  inngest;
235
320
  function;
321
+ flowControlConfig;
236
322
  constructor(params, inngest) {
237
- super(params);
323
+ const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
324
+ super(workflowParams);
325
+ const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
326
+ ([_, value]) => value !== void 0
327
+ );
328
+ this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
238
329
  this.#mastra = params.mastra;
239
330
  this.inngest = inngest;
240
331
  }
@@ -255,27 +346,6 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
255
346
  const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
256
347
  return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
257
348
  }
258
- async getWorkflowRunExecutionResult(runId) {
259
- const storage = this.#mastra?.getStorage();
260
- if (!storage) {
261
- this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
262
- return null;
263
- }
264
- const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
265
- if (!run?.snapshot) {
266
- return null;
267
- }
268
- if (typeof run.snapshot === "string") {
269
- return null;
270
- }
271
- return {
272
- status: run.snapshot.status,
273
- result: run.snapshot.result,
274
- error: run.snapshot.error,
275
- payload: run.snapshot.context?.input,
276
- steps: run.snapshot.context
277
- };
278
- }
279
349
  __registerMastra(mastra) {
280
350
  this.#mastra = mastra;
281
351
  this.executionEngine.__registerMastra(mastra);
@@ -294,23 +364,14 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
294
364
  }
295
365
  }
296
366
  }
297
- createRun(options) {
298
- const runIdToUse = options?.runId || randomUUID();
299
- const run = this.runs.get(runIdToUse) ?? new InngestRun(
300
- {
301
- workflowId: this.id,
302
- runId: runIdToUse,
303
- executionEngine: this.executionEngine,
304
- executionGraph: this.executionGraph,
305
- serializedStepGraph: this.serializedStepGraph,
306
- mastra: this.#mastra,
307
- retryConfig: this.retryConfig,
308
- cleanup: () => this.runs.delete(runIdToUse)
309
- },
310
- this.inngest
367
+ /**
368
+ * @deprecated Use createRunAsync() instead.
369
+ * @throws {Error} Always throws an error directing users to use createRunAsync()
370
+ */
371
+ createRun(_options) {
372
+ throw new Error(
373
+ "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."
311
374
  );
312
- this.runs.set(runIdToUse, run);
313
- return run;
314
375
  }
315
376
  async createRunAsync(options) {
316
377
  const runIdToUse = options?.runId || randomUUID();
@@ -318,29 +379,38 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
318
379
  {
319
380
  workflowId: this.id,
320
381
  runId: runIdToUse,
382
+ resourceId: options?.resourceId,
321
383
  executionEngine: this.executionEngine,
322
384
  executionGraph: this.executionGraph,
323
385
  serializedStepGraph: this.serializedStepGraph,
324
386
  mastra: this.#mastra,
325
387
  retryConfig: this.retryConfig,
326
- cleanup: () => this.runs.delete(runIdToUse)
388
+ cleanup: () => this.runs.delete(runIdToUse),
389
+ workflowSteps: this.steps
327
390
  },
328
391
  this.inngest
329
392
  );
330
393
  this.runs.set(runIdToUse, run);
331
- const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
332
- if (!workflowSnapshotInStorage) {
394
+ const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
395
+ workflowStatus: run.workflowRunStatus,
396
+ stepResults: {}
397
+ });
398
+ const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
399
+ if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
333
400
  await this.mastra?.getStorage()?.persistWorkflowSnapshot({
334
401
  workflowName: this.id,
335
402
  runId: runIdToUse,
403
+ resourceId: options?.resourceId,
336
404
  snapshot: {
337
405
  runId: runIdToUse,
338
406
  status: "pending",
339
407
  value: {},
340
408
  context: {},
341
409
  activePaths: [],
410
+ waitingPaths: {},
342
411
  serializedStepGraph: this.serializedStepGraph,
343
412
  suspendedPaths: {},
413
+ resumeLabels: {},
344
414
  result: void 0,
345
415
  error: void 0,
346
416
  // @ts-ignore
@@ -359,11 +429,13 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
359
429
  id: `workflow.${this.id}`,
360
430
  // @ts-ignore
361
431
  retries: this.retryConfig?.attempts ?? 0,
362
- cancelOn: [{ event: `cancel.workflow.${this.id}` }]
432
+ cancelOn: [{ event: `cancel.workflow.${this.id}` }],
433
+ // Spread flow control configuration
434
+ ...this.flowControlConfig
363
435
  },
364
436
  { event: `workflow.${this.id}` },
365
437
  async ({ event, step, attempt, publish }) => {
366
- let { inputData, runId, resume } = event.data;
438
+ let { inputData, initialState, runId, resourceId, resume, outputOptions } = event.data;
367
439
  if (!runId) {
368
440
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
369
441
  return randomUUID();
@@ -391,19 +463,32 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
391
463
  once: (_event, _callback) => {
392
464
  }
393
465
  };
394
- const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
466
+ const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
395
467
  const result = await engine.execute({
396
468
  workflowId: this.id,
397
469
  runId,
470
+ resourceId,
398
471
  graph: this.executionGraph,
399
472
  serializedStepGraph: this.serializedStepGraph,
400
473
  input: inputData,
474
+ initialState,
401
475
  emitter,
402
476
  retryConfig: this.retryConfig,
403
477
  runtimeContext: new RuntimeContext(),
404
478
  // TODO
405
479
  resume,
406
- abortController: new AbortController()
480
+ abortController: new AbortController(),
481
+ currentSpan: void 0,
482
+ // TODO: Pass actual parent AI span from workflow execution context
483
+ outputOptions
484
+ });
485
+ await step.run(`workflow.${this.id}.finalize`, async () => {
486
+ if (result.status === "failed") {
487
+ throw new NonRetriableError(`Workflow failed`, {
488
+ cause: result
489
+ });
490
+ }
491
+ return result;
407
492
  });
408
493
  return { result, runId };
409
494
  }
@@ -437,17 +522,16 @@ function createStep(params) {
437
522
  if (isAgent(params)) {
438
523
  return {
439
524
  id: params.name,
525
+ description: params.getDescription(),
440
526
  // @ts-ignore
441
527
  inputSchema: z.object({
442
528
  prompt: z.string()
443
- // resourceId: z.string().optional(),
444
- // threadId: z.string().optional(),
445
529
  }),
446
530
  // @ts-ignore
447
531
  outputSchema: z.object({
448
532
  text: z.string()
449
533
  }),
450
- execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
534
+ execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
451
535
  let streamPromise = {};
452
536
  streamPromise.promise = new Promise((resolve, reject) => {
453
537
  streamPromise.resolve = resolve;
@@ -457,50 +541,66 @@ function createStep(params) {
457
541
  name: params.name,
458
542
  args: inputData
459
543
  };
460
- await emitter.emit("watch-v2", {
461
- type: "tool-call-streaming-start",
462
- ...toolData
463
- });
464
- const { fullStream } = await params.stream(inputData.prompt, {
465
- // resourceId: inputData.resourceId,
466
- // threadId: inputData.threadId,
467
- runtimeContext,
468
- onFinish: (result) => {
469
- streamPromise.resolve(result.text);
470
- },
471
- abortSignal
472
- });
473
- if (abortSignal.aborted) {
474
- return abort();
475
- }
476
- for await (const chunk of fullStream) {
477
- switch (chunk.type) {
478
- case "text-delta":
544
+ if ((await params.getLLM()).getModel().specificationVersion === `v2`) {
545
+ const { fullStream } = await params.stream(inputData.prompt, {
546
+ runtimeContext,
547
+ tracingContext,
548
+ onFinish: (result) => {
549
+ streamPromise.resolve(result.text);
550
+ },
551
+ abortSignal
552
+ });
553
+ if (abortSignal.aborted) {
554
+ return abort();
555
+ }
556
+ await emitter.emit("watch-v2", {
557
+ type: "tool-call-streaming-start",
558
+ ...toolData ?? {}
559
+ });
560
+ for await (const chunk of fullStream) {
561
+ if (chunk.type === "text-delta") {
479
562
  await emitter.emit("watch-v2", {
480
563
  type: "tool-call-delta",
481
- ...toolData,
564
+ ...toolData ?? {},
565
+ argsTextDelta: chunk.payload.text
566
+ });
567
+ }
568
+ }
569
+ } else {
570
+ const { fullStream } = await params.streamLegacy(inputData.prompt, {
571
+ runtimeContext,
572
+ tracingContext,
573
+ onFinish: (result) => {
574
+ streamPromise.resolve(result.text);
575
+ },
576
+ abortSignal
577
+ });
578
+ if (abortSignal.aborted) {
579
+ return abort();
580
+ }
581
+ await emitter.emit("watch-v2", {
582
+ type: "tool-call-streaming-start",
583
+ ...toolData ?? {}
584
+ });
585
+ for await (const chunk of fullStream) {
586
+ if (chunk.type === "text-delta") {
587
+ await emitter.emit("watch-v2", {
588
+ type: "tool-call-delta",
589
+ ...toolData ?? {},
482
590
  argsTextDelta: chunk.textDelta
483
591
  });
484
- break;
485
- case "step-start":
486
- case "step-finish":
487
- case "finish":
488
- break;
489
- case "tool-call":
490
- case "tool-result":
491
- case "tool-call-streaming-start":
492
- case "tool-call-delta":
493
- case "source":
494
- case "file":
495
- default:
496
- await emitter.emit("watch-v2", chunk);
497
- break;
592
+ }
498
593
  }
499
594
  }
595
+ await emitter.emit("watch-v2", {
596
+ type: "tool-call-streaming-finish",
597
+ ...toolData ?? {}
598
+ });
500
599
  return {
501
600
  text: await streamPromise.promise
502
601
  };
503
- }
602
+ },
603
+ component: params.component
504
604
  };
505
605
  }
506
606
  if (isTool(params)) {
@@ -511,15 +611,20 @@ function createStep(params) {
511
611
  // TODO: tool probably should have strong id type
512
612
  // @ts-ignore
513
613
  id: params.id,
614
+ description: params.description,
514
615
  inputSchema: params.inputSchema,
515
616
  outputSchema: params.outputSchema,
516
- execute: async ({ inputData, mastra, runtimeContext }) => {
617
+ execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
517
618
  return params.execute({
518
619
  context: inputData,
519
- mastra,
520
- runtimeContext
620
+ mastra: wrapMastra(mastra, tracingContext),
621
+ runtimeContext,
622
+ tracingContext,
623
+ suspend,
624
+ resumeData
521
625
  });
522
- }
626
+ },
627
+ component: "TOOL"
523
628
  };
524
629
  }
525
630
  return {
@@ -535,7 +640,10 @@ function createStep(params) {
535
640
  function init(inngest) {
536
641
  return {
537
642
  createWorkflow(params) {
538
- return new InngestWorkflow(params, inngest);
643
+ return new InngestWorkflow(
644
+ params,
645
+ inngest
646
+ );
539
647
  },
540
648
  createStep,
541
649
  cloneStep(step, opts) {
@@ -544,7 +652,11 @@ function init(inngest) {
544
652
  description: step.description,
545
653
  inputSchema: step.inputSchema,
546
654
  outputSchema: step.outputSchema,
547
- execute: step.execute
655
+ resumeSchema: step.resumeSchema,
656
+ suspendSchema: step.suspendSchema,
657
+ stateSchema: step.stateSchema,
658
+ execute: step.execute,
659
+ component: step.component
548
660
  };
549
661
  },
550
662
  cloneWorkflow(workflow, opts) {
@@ -564,24 +676,24 @@ function init(inngest) {
564
676
  var InngestExecutionEngine = class extends DefaultExecutionEngine {
565
677
  inngestStep;
566
678
  inngestAttempts;
567
- constructor(mastra, inngestStep, inngestAttempts = 0) {
568
- super({ mastra });
679
+ constructor(mastra, inngestStep, inngestAttempts = 0, options) {
680
+ super({ mastra, options });
569
681
  this.inngestStep = inngestStep;
570
682
  this.inngestAttempts = inngestAttempts;
571
683
  }
572
684
  async execute(params) {
573
685
  await params.emitter.emit("watch-v2", {
574
- type: "start",
686
+ type: "workflow-start",
575
687
  payload: { runId: params.runId }
576
688
  });
577
689
  const result = await super.execute(params);
578
690
  await params.emitter.emit("watch-v2", {
579
- type: "finish",
691
+ type: "workflow-finish",
580
692
  payload: { runId: params.runId }
581
693
  });
582
694
  return result;
583
695
  }
584
- async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
696
+ async fmtReturnValue(emitter, stepResults, lastOutput, error) {
585
697
  const base = {
586
698
  status: lastOutput.status,
587
699
  steps: stepResults
@@ -628,41 +740,15 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
628
740
  });
629
741
  const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
630
742
  if (stepResult?.status === "suspended") {
631
- const nestedPath = stepResult?.payload?.__workflow_meta?.path;
743
+ const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
632
744
  return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
633
745
  }
634
746
  return [];
635
747
  });
636
748
  base.suspended = suspendedStepIds;
637
749
  }
638
- executionSpan?.end();
639
750
  return base;
640
751
  }
641
- async superExecuteStep({
642
- workflowId,
643
- runId,
644
- step,
645
- stepResults,
646
- executionContext,
647
- resume,
648
- prevOutput,
649
- emitter,
650
- abortController,
651
- runtimeContext
652
- }) {
653
- return super.executeStep({
654
- workflowId,
655
- runId,
656
- step,
657
- stepResults,
658
- executionContext,
659
- resume,
660
- prevOutput,
661
- emitter,
662
- abortController,
663
- runtimeContext
664
- });
665
- }
666
752
  // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
667
753
  // await this.inngestStep.sleep(id, duration);
668
754
  // }
@@ -674,43 +760,87 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
674
760
  stepResults,
675
761
  emitter,
676
762
  abortController,
677
- runtimeContext
763
+ runtimeContext,
764
+ executionContext,
765
+ writableStream,
766
+ tracingContext
678
767
  }) {
679
768
  let { duration, fn } = entry;
769
+ const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
770
+ type: AISpanType.WORKFLOW_SLEEP,
771
+ name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
772
+ attributes: {
773
+ durationMs: duration,
774
+ sleepType: fn ? "dynamic" : "fixed"
775
+ },
776
+ tracingPolicy: this.options?.tracingPolicy
777
+ });
680
778
  if (fn) {
779
+ const stepCallId = randomUUID();
681
780
  duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
682
- return await fn({
683
- runId,
684
- mastra: this.mastra,
685
- runtimeContext,
686
- inputData: prevOutput,
687
- runCount: -1,
688
- getInitData: () => stepResults?.input,
689
- getStepResult: (step) => {
690
- if (!step?.id) {
691
- return null;
692
- }
693
- const result = stepResults[step.id];
694
- if (result?.status === "success") {
695
- return result.output;
781
+ return await fn(
782
+ createDeprecationProxy(
783
+ {
784
+ runId,
785
+ workflowId,
786
+ mastra: this.mastra,
787
+ runtimeContext,
788
+ inputData: prevOutput,
789
+ state: executionContext.state,
790
+ setState: (state) => {
791
+ executionContext.state = state;
792
+ },
793
+ runCount: -1,
794
+ retryCount: -1,
795
+ tracingContext: {
796
+ currentSpan: sleepSpan
797
+ },
798
+ getInitData: () => stepResults?.input,
799
+ getStepResult: 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
+ [EMITTER_SYMBOL]: emitter,
809
+ // TODO: add streamVNext support
810
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
811
+ engine: { step: this.inngestStep },
812
+ abortSignal: abortController?.signal,
813
+ writer: new ToolStream(
814
+ {
815
+ prefix: "workflow-step",
816
+ callId: stepCallId,
817
+ name: "sleep",
818
+ runId
819
+ },
820
+ writableStream
821
+ )
822
+ },
823
+ {
824
+ paramName: "runCount",
825
+ deprecationMessage: runCountDeprecationMessage,
826
+ logger: this.logger
696
827
  }
697
- return null;
698
- },
699
- // TODO: this function shouldn't have suspend probably?
700
- suspend: async (_suspendPayload) => {
701
- },
702
- bail: () => {
703
- },
704
- abort: () => {
705
- abortController?.abort();
706
- },
707
- [EMITTER_SYMBOL]: emitter,
708
- engine: { step: this.inngestStep },
709
- abortSignal: abortController?.signal
710
- });
828
+ )
829
+ );
711
830
  });
831
+ sleepSpan?.update({
832
+ attributes: {
833
+ durationMs: duration
834
+ }
835
+ });
836
+ }
837
+ try {
838
+ await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
839
+ sleepSpan?.end();
840
+ } catch (e) {
841
+ sleepSpan?.error({ error: e });
842
+ throw e;
712
843
  }
713
- await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
714
844
  }
715
845
  async executeSleepUntil({
716
846
  workflowId,
@@ -720,46 +850,96 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
720
850
  stepResults,
721
851
  emitter,
722
852
  abortController,
723
- runtimeContext
853
+ runtimeContext,
854
+ executionContext,
855
+ writableStream,
856
+ tracingContext
724
857
  }) {
725
858
  let { date, fn } = entry;
859
+ const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
860
+ type: AISpanType.WORKFLOW_SLEEP,
861
+ name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
862
+ attributes: {
863
+ untilDate: date,
864
+ durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
865
+ sleepType: fn ? "dynamic" : "fixed"
866
+ },
867
+ tracingPolicy: this.options?.tracingPolicy
868
+ });
726
869
  if (fn) {
727
870
  date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
728
- return await fn({
729
- runId,
730
- mastra: this.mastra,
731
- runtimeContext,
732
- inputData: prevOutput,
733
- runCount: -1,
734
- getInitData: () => stepResults?.input,
735
- getStepResult: (step) => {
736
- if (!step?.id) {
737
- return null;
738
- }
739
- const result = stepResults[step.id];
740
- if (result?.status === "success") {
741
- return result.output;
871
+ const stepCallId = randomUUID();
872
+ return await fn(
873
+ createDeprecationProxy(
874
+ {
875
+ runId,
876
+ workflowId,
877
+ mastra: this.mastra,
878
+ runtimeContext,
879
+ inputData: prevOutput,
880
+ state: executionContext.state,
881
+ setState: (state) => {
882
+ executionContext.state = state;
883
+ },
884
+ runCount: -1,
885
+ retryCount: -1,
886
+ tracingContext: {
887
+ currentSpan: sleepUntilSpan
888
+ },
889
+ getInitData: () => stepResults?.input,
890
+ getStepResult: getStepResult.bind(this, stepResults),
891
+ // TODO: this function shouldn't have suspend probably?
892
+ suspend: async (_suspendPayload) => {
893
+ },
894
+ bail: () => {
895
+ },
896
+ abort: () => {
897
+ abortController?.abort();
898
+ },
899
+ [EMITTER_SYMBOL]: emitter,
900
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
901
+ // TODO: add streamVNext support
902
+ engine: { step: this.inngestStep },
903
+ abortSignal: abortController?.signal,
904
+ writer: new ToolStream(
905
+ {
906
+ prefix: "workflow-step",
907
+ callId: stepCallId,
908
+ name: "sleep",
909
+ runId
910
+ },
911
+ writableStream
912
+ )
913
+ },
914
+ {
915
+ paramName: "runCount",
916
+ deprecationMessage: runCountDeprecationMessage,
917
+ logger: this.logger
742
918
  }
743
- return null;
744
- },
745
- // TODO: this function shouldn't have suspend probably?
746
- suspend: async (_suspendPayload) => {
747
- },
748
- bail: () => {
749
- },
750
- abort: () => {
751
- abortController?.abort();
752
- },
753
- [EMITTER_SYMBOL]: emitter,
754
- engine: { step: this.inngestStep },
755
- abortSignal: abortController?.signal
756
- });
919
+ )
920
+ );
921
+ });
922
+ if (date && !(date instanceof Date)) {
923
+ date = new Date(date);
924
+ }
925
+ const time = !date ? 0 : date.getTime() - Date.now();
926
+ sleepUntilSpan?.update({
927
+ attributes: {
928
+ durationMs: Math.max(0, time)
929
+ }
757
930
  });
758
931
  }
759
932
  if (!(date instanceof Date)) {
933
+ sleepUntilSpan?.end();
760
934
  return;
761
935
  }
762
- await this.inngestStep.sleepUntil(entry.id, date);
936
+ try {
937
+ await this.inngestStep.sleepUntil(entry.id, date);
938
+ sleepUntilSpan?.end();
939
+ } catch (e) {
940
+ sleepUntilSpan?.error({ error: e });
941
+ throw e;
942
+ }
763
943
  }
764
944
  async executeWaitForEvent({ event, timeout }) {
765
945
  const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
@@ -779,8 +959,25 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
779
959
  prevOutput,
780
960
  emitter,
781
961
  abortController,
782
- runtimeContext
962
+ runtimeContext,
963
+ tracingContext,
964
+ writableStream,
965
+ disableScorers
783
966
  }) {
967
+ const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
968
+ name: `workflow step: '${step.id}'`,
969
+ type: AISpanType.WORKFLOW_STEP,
970
+ input: prevOutput,
971
+ attributes: {
972
+ stepId: step.id
973
+ },
974
+ tracingPolicy: this.options?.tracingPolicy
975
+ });
976
+ const { inputData, validationError } = await validateStepInput({
977
+ prevOutput,
978
+ step,
979
+ validateInputs: this.options?.validateInputs ?? false
980
+ });
784
981
  const startedAt = await this.inngestStep.run(
785
982
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
786
983
  async () => {
@@ -807,11 +1004,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
807
1004
  eventTimestamp: Date.now()
808
1005
  });
809
1006
  await emitter.emit("watch-v2", {
810
- type: "step-start",
1007
+ type: "workflow-step-start",
811
1008
  payload: {
812
1009
  id: step.id,
813
1010
  status: "running",
814
- payload: prevOutput,
1011
+ payload: inputData,
815
1012
  startedAt: startedAt2
816
1013
  }
817
1014
  });
@@ -822,38 +1019,60 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
822
1019
  const isResume = !!resume?.steps?.length;
823
1020
  let result;
824
1021
  let runId;
825
- if (isResume) {
826
- runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? randomUUID();
827
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
828
- workflowName: step.id,
829
- runId
830
- });
831
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
832
- function: step.getFunction(),
833
- data: {
834
- inputData: prevOutput,
835
- runId,
836
- resume: {
1022
+ try {
1023
+ if (isResume) {
1024
+ runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
1025
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1026
+ workflowName: step.id,
1027
+ runId
1028
+ });
1029
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1030
+ function: step.getFunction(),
1031
+ data: {
1032
+ inputData,
1033
+ initialState: executionContext.state ?? snapshot?.value ?? {},
837
1034
  runId,
838
- steps: resume.steps.slice(1),
839
- stepResults: snapshot?.context,
840
- resumePayload: resume.resumePayload,
841
- // @ts-ignore
842
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1035
+ resume: {
1036
+ runId,
1037
+ steps: resume.steps.slice(1),
1038
+ stepResults: snapshot?.context,
1039
+ resumePayload: resume.resumePayload,
1040
+ // @ts-ignore
1041
+ resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
1042
+ },
1043
+ outputOptions: { includeState: true }
843
1044
  }
844
- }
845
- });
846
- result = invokeResp.result;
847
- runId = invokeResp.runId;
848
- } else {
849
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
850
- function: step.getFunction(),
851
- data: {
852
- inputData: prevOutput
853
- }
854
- });
855
- result = invokeResp.result;
856
- runId = invokeResp.runId;
1045
+ });
1046
+ result = invokeResp.result;
1047
+ runId = invokeResp.runId;
1048
+ executionContext.state = invokeResp.result.state;
1049
+ } else {
1050
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1051
+ function: step.getFunction(),
1052
+ data: {
1053
+ inputData,
1054
+ initialState: executionContext.state ?? {},
1055
+ outputOptions: { includeState: true }
1056
+ }
1057
+ });
1058
+ result = invokeResp.result;
1059
+ runId = invokeResp.runId;
1060
+ executionContext.state = invokeResp.result.state;
1061
+ }
1062
+ } catch (e) {
1063
+ const errorCause = e?.cause;
1064
+ if (errorCause && typeof errorCause === "object") {
1065
+ result = errorCause;
1066
+ runId = errorCause.runId || randomUUID();
1067
+ } else {
1068
+ runId = randomUUID();
1069
+ result = {
1070
+ status: "failed",
1071
+ error: e instanceof Error ? e : new Error(String(e)),
1072
+ steps: {},
1073
+ input: inputData
1074
+ };
1075
+ }
857
1076
  }
858
1077
  const res = await this.inngestStep.run(
859
1078
  `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
@@ -877,7 +1096,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
877
1096
  eventTimestamp: Date.now()
878
1097
  });
879
1098
  await emitter.emit("watch-v2", {
880
- type: "step-result",
1099
+ type: "workflow-step-result",
881
1100
  payload: {
882
1101
  id: step.id,
883
1102
  status: "failed",
@@ -892,7 +1111,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
892
1111
  return stepRes2?.status === "suspended";
893
1112
  });
894
1113
  for (const [stepName, stepResult] of suspendedSteps) {
895
- const suspendPath = [stepName, ...stepResult?.payload?.__workflow_meta?.path ?? []];
1114
+ const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
896
1115
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
897
1116
  await emitter.emit("watch", {
898
1117
  type: "watch",
@@ -900,7 +1119,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
900
1119
  currentStep: {
901
1120
  id: step.id,
902
1121
  status: "suspended",
903
- payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
1122
+ payload: stepResult.payload,
1123
+ suspendPayload: {
1124
+ ...stepResult?.suspendPayload,
1125
+ __workflow_meta: { runId, path: suspendPath }
1126
+ }
904
1127
  },
905
1128
  workflowState: {
906
1129
  status: "running",
@@ -912,7 +1135,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
912
1135
  eventTimestamp: Date.now()
913
1136
  });
914
1137
  await emitter.emit("watch-v2", {
915
- type: "step-suspended",
1138
+ type: "workflow-step-suspended",
916
1139
  payload: {
917
1140
  id: step.id,
918
1141
  status: "suspended"
@@ -922,7 +1145,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
922
1145
  executionContext,
923
1146
  result: {
924
1147
  status: "suspended",
925
- payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
1148
+ payload: stepResult.payload,
1149
+ suspendPayload: {
1150
+ ...stepResult?.suspendPayload,
1151
+ __workflow_meta: { runId, path: suspendPath }
1152
+ }
926
1153
  }
927
1154
  };
928
1155
  }
@@ -969,7 +1196,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
969
1196
  eventTimestamp: Date.now()
970
1197
  });
971
1198
  await emitter.emit("watch-v2", {
972
- type: "step-result",
1199
+ type: "workflow-step-result",
973
1200
  payload: {
974
1201
  id: step.id,
975
1202
  status: "success",
@@ -977,7 +1204,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
977
1204
  }
978
1205
  });
979
1206
  await emitter.emit("watch-v2", {
980
- type: "step-finish",
1207
+ type: "workflow-step-finish",
981
1208
  payload: {
982
1209
  id: step.id,
983
1210
  metadata: {}
@@ -987,135 +1214,202 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
987
1214
  }
988
1215
  );
989
1216
  Object.assign(executionContext, res.executionContext);
990
- return res.result;
1217
+ return {
1218
+ ...res.result,
1219
+ startedAt,
1220
+ endedAt: Date.now(),
1221
+ payload: inputData,
1222
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1223
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1224
+ };
991
1225
  }
992
- const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
993
- let execResults;
994
- let suspended;
995
- let bailed;
996
- try {
997
- const result = await step.execute({
998
- runId: executionContext.runId,
999
- mastra: this.mastra,
1000
- runtimeContext,
1001
- inputData: prevOutput,
1002
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1003
- getInitData: () => stepResults?.input,
1004
- getStepResult: (step2) => {
1005
- const result2 = stepResults[step2.id];
1006
- if (result2?.status === "success") {
1007
- return result2.output;
1226
+ let stepRes;
1227
+ try {
1228
+ stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1229
+ let execResults;
1230
+ let suspended;
1231
+ let bailed;
1232
+ try {
1233
+ if (validationError) {
1234
+ throw validationError;
1235
+ }
1236
+ const result = await step.execute({
1237
+ runId: executionContext.runId,
1238
+ mastra: this.mastra,
1239
+ runtimeContext,
1240
+ writableStream,
1241
+ state: executionContext?.state ?? {},
1242
+ setState: (state) => {
1243
+ executionContext.state = state;
1244
+ },
1245
+ inputData,
1246
+ resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1247
+ tracingContext: {
1248
+ currentSpan: stepAISpan
1249
+ },
1250
+ getInitData: () => stepResults?.input,
1251
+ getStepResult: getStepResult.bind(this, stepResults),
1252
+ suspend: async (suspendPayload, suspendOptions) => {
1253
+ executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1254
+ if (suspendOptions?.resumeLabel) {
1255
+ const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
1256
+ for (const label of resumeLabel) {
1257
+ executionContext.resumeLabels[label] = {
1258
+ stepId: step.id,
1259
+ foreachIndex: executionContext.foreachIndex
1260
+ };
1261
+ }
1262
+ }
1263
+ suspended = { payload: suspendPayload };
1264
+ },
1265
+ bail: (result2) => {
1266
+ bailed = { payload: result2 };
1267
+ },
1268
+ resume: {
1269
+ steps: resume?.steps?.slice(1) || [],
1270
+ resumePayload: resume?.resumePayload,
1271
+ // @ts-ignore
1272
+ runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1273
+ },
1274
+ [EMITTER_SYMBOL]: emitter,
1275
+ engine: {
1276
+ step: this.inngestStep
1277
+ },
1278
+ abortSignal: abortController.signal
1279
+ });
1280
+ const endedAt = Date.now();
1281
+ execResults = {
1282
+ status: "success",
1283
+ output: result,
1284
+ startedAt,
1285
+ endedAt,
1286
+ payload: inputData,
1287
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1288
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1289
+ };
1290
+ } catch (e) {
1291
+ const stepFailure = {
1292
+ status: "failed",
1293
+ payload: inputData,
1294
+ error: e instanceof Error ? e.message : String(e),
1295
+ endedAt: Date.now(),
1296
+ startedAt,
1297
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1298
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1299
+ };
1300
+ execResults = stepFailure;
1301
+ const fallbackErrorMessage = `Step ${step.id} failed`;
1302
+ stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1303
+ throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1304
+ cause: execResults
1305
+ });
1306
+ }
1307
+ if (suspended) {
1308
+ execResults = {
1309
+ status: "suspended",
1310
+ suspendPayload: suspended.payload,
1311
+ payload: inputData,
1312
+ suspendedAt: Date.now(),
1313
+ startedAt,
1314
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1315
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1316
+ };
1317
+ } else if (bailed) {
1318
+ execResults = {
1319
+ status: "bailed",
1320
+ output: bailed.payload,
1321
+ payload: inputData,
1322
+ endedAt: Date.now(),
1323
+ startedAt
1324
+ };
1325
+ }
1326
+ await emitter.emit("watch", {
1327
+ type: "watch",
1328
+ payload: {
1329
+ currentStep: {
1330
+ id: step.id,
1331
+ ...execResults
1332
+ },
1333
+ workflowState: {
1334
+ status: "running",
1335
+ steps: { ...stepResults, [step.id]: execResults },
1336
+ result: null,
1337
+ error: null
1008
1338
  }
1009
- return null;
1010
- },
1011
- suspend: async (suspendPayload) => {
1012
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1013
- suspended = { payload: suspendPayload };
1014
- },
1015
- bail: (result2) => {
1016
- bailed = { payload: result2 };
1017
- },
1018
- resume: {
1019
- steps: resume?.steps?.slice(1) || [],
1020
- resumePayload: resume?.resumePayload,
1021
- // @ts-ignore
1022
- runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
1023
1339
  },
1024
- [EMITTER_SYMBOL]: emitter,
1025
- engine: {
1026
- step: this.inngestStep
1027
- },
1028
- abortSignal: abortController.signal
1340
+ eventTimestamp: Date.now()
1029
1341
  });
1030
- const endedAt = Date.now();
1031
- execResults = {
1032
- status: "success",
1033
- output: result,
1034
- startedAt,
1035
- endedAt,
1036
- payload: prevOutput,
1037
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1038
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1039
- };
1040
- } catch (e) {
1041
- execResults = {
1042
- status: "failed",
1043
- payload: prevOutput,
1044
- error: e instanceof Error ? e.message : String(e),
1045
- endedAt: Date.now(),
1046
- startedAt,
1047
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1048
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1049
- };
1050
- }
1051
- if (suspended) {
1052
- execResults = {
1053
- status: "suspended",
1054
- suspendedPayload: suspended.payload,
1055
- payload: prevOutput,
1056
- suspendedAt: Date.now(),
1057
- startedAt,
1058
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1059
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1060
- };
1061
- } else if (bailed) {
1062
- execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
1063
- }
1064
- if (execResults.status === "failed") {
1065
- if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
1066
- throw execResults.error;
1342
+ if (execResults.status === "suspended") {
1343
+ await emitter.emit("watch-v2", {
1344
+ type: "workflow-step-suspended",
1345
+ payload: {
1346
+ id: step.id,
1347
+ ...execResults
1348
+ }
1349
+ });
1350
+ } else {
1351
+ await emitter.emit("watch-v2", {
1352
+ type: "workflow-step-result",
1353
+ payload: {
1354
+ id: step.id,
1355
+ ...execResults
1356
+ }
1357
+ });
1358
+ await emitter.emit("watch-v2", {
1359
+ type: "workflow-step-finish",
1360
+ payload: {
1361
+ id: step.id,
1362
+ metadata: {}
1363
+ }
1364
+ });
1067
1365
  }
1068
- }
1069
- await emitter.emit("watch", {
1070
- type: "watch",
1071
- payload: {
1072
- currentStep: {
1073
- id: step.id,
1074
- ...execResults
1075
- },
1076
- workflowState: {
1077
- status: "running",
1078
- steps: { ...stepResults, [step.id]: execResults },
1079
- result: null,
1080
- error: null
1081
- }
1082
- },
1083
- eventTimestamp: Date.now()
1366
+ stepAISpan?.end({ output: execResults });
1367
+ return { result: execResults, executionContext, stepResults };
1084
1368
  });
1085
- if (execResults.status === "suspended") {
1086
- await emitter.emit("watch-v2", {
1087
- type: "step-suspended",
1088
- payload: {
1089
- id: step.id,
1090
- ...execResults
1091
- }
1092
- });
1093
- } else {
1094
- await emitter.emit("watch-v2", {
1095
- type: "step-result",
1096
- payload: {
1097
- id: step.id,
1098
- ...execResults
1099
- }
1100
- });
1101
- await emitter.emit("watch-v2", {
1102
- type: "step-finish",
1103
- payload: {
1104
- id: step.id,
1105
- metadata: {}
1106
- }
1107
- });
1108
- }
1109
- return { result: execResults, executionContext, stepResults };
1110
- });
1369
+ } catch (e) {
1370
+ const stepFailure = e instanceof Error ? e?.cause : {
1371
+ status: "failed",
1372
+ error: e instanceof Error ? e.message : String(e),
1373
+ payload: inputData,
1374
+ startedAt,
1375
+ endedAt: Date.now()
1376
+ };
1377
+ stepRes = {
1378
+ result: stepFailure,
1379
+ executionContext,
1380
+ stepResults: {
1381
+ ...stepResults,
1382
+ [step.id]: stepFailure
1383
+ }
1384
+ };
1385
+ }
1386
+ if (disableScorers !== false && stepRes.result.status === "success") {
1387
+ await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1388
+ if (step.scorers) {
1389
+ await this.runScorers({
1390
+ scorers: step.scorers,
1391
+ runId: executionContext.runId,
1392
+ input: inputData,
1393
+ output: stepRes.result,
1394
+ workflowId: executionContext.workflowId,
1395
+ stepId: step.id,
1396
+ runtimeContext,
1397
+ disableScorers,
1398
+ tracingContext: { currentSpan: stepAISpan }
1399
+ });
1400
+ }
1401
+ });
1402
+ }
1111
1403
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1112
1404
  Object.assign(stepResults, stepRes.stepResults);
1405
+ executionContext.state = stepRes.executionContext.state;
1113
1406
  return stepRes.result;
1114
1407
  }
1115
1408
  async persistStepUpdate({
1116
1409
  workflowId,
1117
1410
  runId,
1118
1411
  stepResults,
1412
+ resourceId,
1119
1413
  executionContext,
1120
1414
  serializedStepGraph,
1121
1415
  workflowStatus,
@@ -1125,15 +1419,22 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1125
1419
  await this.inngestStep.run(
1126
1420
  `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
1127
1421
  async () => {
1422
+ const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
1423
+ if (!shouldPersistSnapshot) {
1424
+ return;
1425
+ }
1128
1426
  await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1129
1427
  workflowName: workflowId,
1130
1428
  runId,
1429
+ resourceId,
1131
1430
  snapshot: {
1132
1431
  runId,
1133
- value: {},
1432
+ value: executionContext.state,
1134
1433
  context: stepResults,
1135
1434
  activePaths: [],
1136
1435
  suspendedPaths: executionContext.suspendedPaths,
1436
+ resumeLabels: executionContext.resumeLabels,
1437
+ waitingPaths: {},
1137
1438
  serializedStepGraph,
1138
1439
  status: workflowStatus,
1139
1440
  result,
@@ -1150,102 +1451,179 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1150
1451
  runId,
1151
1452
  entry,
1152
1453
  prevOutput,
1153
- prevStep,
1154
1454
  stepResults,
1155
- serializedStepGraph,
1156
1455
  resume,
1157
1456
  executionContext,
1158
1457
  emitter,
1159
1458
  abortController,
1160
- runtimeContext
1459
+ runtimeContext,
1460
+ writableStream,
1461
+ disableScorers,
1462
+ tracingContext
1161
1463
  }) {
1464
+ const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1465
+ type: AISpanType.WORKFLOW_CONDITIONAL,
1466
+ name: `conditional: '${entry.conditions.length} conditions'`,
1467
+ input: prevOutput,
1468
+ attributes: {
1469
+ conditionCount: entry.conditions.length
1470
+ },
1471
+ tracingPolicy: this.options?.tracingPolicy
1472
+ });
1162
1473
  let execResults;
1163
1474
  const truthyIndexes = (await Promise.all(
1164
1475
  entry.conditions.map(
1165
1476
  (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1477
+ const evalSpan = conditionalSpan?.createChildSpan({
1478
+ type: AISpanType.WORKFLOW_CONDITIONAL_EVAL,
1479
+ name: `condition: '${index}'`,
1480
+ input: prevOutput,
1481
+ attributes: {
1482
+ conditionIndex: index
1483
+ },
1484
+ tracingPolicy: this.options?.tracingPolicy
1485
+ });
1166
1486
  try {
1167
- const result = await cond({
1168
- runId,
1169
- mastra: this.mastra,
1170
- runtimeContext,
1171
- runCount: -1,
1172
- inputData: prevOutput,
1173
- getInitData: () => stepResults?.input,
1174
- getStepResult: (step) => {
1175
- if (!step?.id) {
1176
- return null;
1177
- }
1178
- const result2 = stepResults[step.id];
1179
- if (result2?.status === "success") {
1180
- return result2.output;
1487
+ const result = await cond(
1488
+ createDeprecationProxy(
1489
+ {
1490
+ runId,
1491
+ workflowId,
1492
+ mastra: this.mastra,
1493
+ runtimeContext,
1494
+ runCount: -1,
1495
+ retryCount: -1,
1496
+ inputData: prevOutput,
1497
+ state: executionContext.state,
1498
+ setState: (state) => {
1499
+ executionContext.state = state;
1500
+ },
1501
+ tracingContext: {
1502
+ currentSpan: evalSpan
1503
+ },
1504
+ getInitData: () => stepResults?.input,
1505
+ getStepResult: getStepResult.bind(this, stepResults),
1506
+ // TODO: this function shouldn't have suspend probably?
1507
+ suspend: async (_suspendPayload) => {
1508
+ },
1509
+ bail: () => {
1510
+ },
1511
+ abort: () => {
1512
+ abortController.abort();
1513
+ },
1514
+ [EMITTER_SYMBOL]: emitter,
1515
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
1516
+ // TODO: add streamVNext support
1517
+ engine: {
1518
+ step: this.inngestStep
1519
+ },
1520
+ abortSignal: abortController.signal,
1521
+ writer: new ToolStream(
1522
+ {
1523
+ prefix: "workflow-step",
1524
+ callId: randomUUID(),
1525
+ name: "conditional",
1526
+ runId
1527
+ },
1528
+ writableStream
1529
+ )
1530
+ },
1531
+ {
1532
+ paramName: "runCount",
1533
+ deprecationMessage: runCountDeprecationMessage,
1534
+ logger: this.logger
1181
1535
  }
1182
- return null;
1183
- },
1184
- // TODO: this function shouldn't have suspend probably?
1185
- suspend: async (_suspendPayload) => {
1186
- },
1187
- bail: () => {
1188
- },
1189
- abort: () => {
1190
- abortController.abort();
1191
- },
1192
- [EMITTER_SYMBOL]: emitter,
1193
- engine: {
1194
- step: this.inngestStep
1195
- },
1196
- abortSignal: abortController.signal
1536
+ )
1537
+ );
1538
+ evalSpan?.end({
1539
+ output: result,
1540
+ attributes: {
1541
+ result: !!result
1542
+ }
1197
1543
  });
1198
1544
  return result ? index : null;
1199
1545
  } catch (e) {
1546
+ evalSpan?.error({
1547
+ error: e instanceof Error ? e : new Error(String(e)),
1548
+ attributes: {
1549
+ result: false
1550
+ }
1551
+ });
1200
1552
  return null;
1201
1553
  }
1202
1554
  })
1203
1555
  )
1204
1556
  )).filter((index) => index !== null);
1205
1557
  const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
1558
+ conditionalSpan?.update({
1559
+ attributes: {
1560
+ truthyIndexes,
1561
+ selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
1562
+ }
1563
+ });
1206
1564
  const results = await Promise.all(
1207
- stepsToRun.map(
1208
- (step, index) => this.executeEntry({
1209
- workflowId,
1210
- runId,
1211
- entry: step,
1212
- prevStep,
1565
+ stepsToRun.map(async (step, index) => {
1566
+ const currStepResult = stepResults[step.step.id];
1567
+ if (currStepResult && currStepResult.status === "success") {
1568
+ return currStepResult;
1569
+ }
1570
+ const result = await this.executeStep({
1571
+ step: step.step,
1572
+ prevOutput,
1213
1573
  stepResults,
1214
1574
  resume,
1215
- serializedStepGraph,
1216
1575
  executionContext: {
1217
1576
  workflowId,
1218
1577
  runId,
1219
1578
  executionPath: [...executionContext.executionPath, index],
1220
1579
  suspendedPaths: executionContext.suspendedPaths,
1580
+ resumeLabels: executionContext.resumeLabels,
1221
1581
  retryConfig: executionContext.retryConfig,
1222
- executionSpan: executionContext.executionSpan
1582
+ state: executionContext.state
1223
1583
  },
1224
1584
  emitter,
1225
1585
  abortController,
1226
- runtimeContext
1227
- })
1228
- )
1586
+ runtimeContext,
1587
+ writableStream,
1588
+ disableScorers,
1589
+ tracingContext: {
1590
+ currentSpan: conditionalSpan
1591
+ }
1592
+ });
1593
+ stepResults[step.step.id] = result;
1594
+ return result;
1595
+ })
1229
1596
  );
1230
- const hasFailed = results.find((result) => result.result.status === "failed");
1231
- const hasSuspended = results.find((result) => result.result.status === "suspended");
1597
+ const hasFailed = results.find((result) => result.status === "failed");
1598
+ const hasSuspended = results.find((result) => result.status === "suspended");
1232
1599
  if (hasFailed) {
1233
- execResults = { status: "failed", error: hasFailed.result.error };
1600
+ execResults = { status: "failed", error: hasFailed.error };
1234
1601
  } else if (hasSuspended) {
1235
- execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
1602
+ execResults = { status: "suspended", suspendPayload: hasSuspended.suspendPayload };
1236
1603
  } else {
1237
1604
  execResults = {
1238
1605
  status: "success",
1239
1606
  output: results.reduce((acc, result, index) => {
1240
- if (result.result.status === "success") {
1607
+ if (result.status === "success") {
1241
1608
  acc[stepsToRun[index].step.id] = result.output;
1242
1609
  }
1243
1610
  return acc;
1244
1611
  }, {})
1245
1612
  };
1246
1613
  }
1614
+ if (execResults.status === "failed") {
1615
+ conditionalSpan?.error({
1616
+ error: new Error(execResults.error)
1617
+ });
1618
+ } else {
1619
+ conditionalSpan?.end({
1620
+ output: execResults.output || execResults
1621
+ });
1622
+ }
1247
1623
  return execResults;
1248
1624
  }
1249
1625
  };
1250
1626
 
1251
1627
  export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
1628
+ //# sourceMappingURL=index.js.map
1629
+ //# sourceMappingURL=index.js.map