@mastra/inngest 0.0.0-support-d1-client-20250701191943 → 0.0.0-suspendRuntimeContextTypeFix-20250930142630

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,22 @@
1
1
  import { randomUUID } from 'crypto';
2
2
  import { subscribe } from '@inngest/realtime';
3
+ import { wrapMastra, AISpanType } from '@mastra/core/ai-tracing';
3
4
  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';
5
+ import { ToolStream, Tool } from '@mastra/core/tools';
6
+ import { Run, Workflow, DefaultExecutionEngine, getStepResult, validateStepInput } from '@mastra/core/workflows';
7
+ import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
7
8
  import { serve as serve$1 } from 'inngest/hono';
8
9
  import { z } from 'zod';
9
10
 
10
11
  // src/index.ts
11
- function serve({ mastra, inngest }) {
12
+ function serve({
13
+ mastra,
14
+ inngest,
15
+ functions: userFunctions = [],
16
+ registerOptions
17
+ }) {
12
18
  const wfs = mastra.getWorkflows();
13
- const functions = Array.from(
19
+ const workflowFunctions = Array.from(
14
20
  new Set(
15
21
  Object.values(wfs).flatMap((wf) => {
16
22
  if (wf instanceof InngestWorkflow) {
@@ -22,8 +28,9 @@ function serve({ mastra, inngest }) {
22
28
  )
23
29
  );
24
30
  return serve$1({
31
+ ...registerOptions,
25
32
  client: inngest,
26
- functions
33
+ functions: [...workflowFunctions, ...userFunctions]
27
34
  });
28
35
  }
29
36
  var InngestRun = class extends Run {
@@ -83,6 +90,7 @@ var InngestRun = class extends Run {
83
90
  await this.#mastra?.storage?.persistWorkflowSnapshot({
84
91
  workflowName: this.workflowId,
85
92
  runId: this.runId,
93
+ resourceId: this.resourceId,
86
94
  snapshot: {
87
95
  ...snapshot,
88
96
  status: "canceled"
@@ -96,6 +104,7 @@ var InngestRun = class extends Run {
96
104
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
97
105
  workflowName: this.workflowId,
98
106
  runId: this.runId,
107
+ resourceId: this.resourceId,
99
108
  snapshot: {
100
109
  runId: this.runId,
101
110
  serializedStepGraph: this.serializedStepGraph,
@@ -103,15 +112,18 @@ var InngestRun = class extends Run {
103
112
  context: {},
104
113
  activePaths: [],
105
114
  suspendedPaths: {},
115
+ waitingPaths: {},
106
116
  timestamp: Date.now(),
107
117
  status: "running"
108
118
  }
109
119
  });
120
+ const inputDataToUse = await this._validateInput(inputData);
110
121
  const eventOutput = await this.inngest.send({
111
122
  name: `workflow.${this.workflowId}`,
112
123
  data: {
113
- inputData,
114
- runId: this.runId
124
+ inputData: inputDataToUse,
125
+ runId: this.runId,
126
+ resourceId: this.resourceId
115
127
  }
116
128
  });
117
129
  const eventId = eventOutput.ids[0];
@@ -147,16 +159,19 @@ var InngestRun = class extends Run {
147
159
  workflowName: this.workflowId,
148
160
  runId: this.runId
149
161
  });
162
+ const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
163
+ const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
150
164
  const eventOutput = await this.inngest.send({
151
165
  name: `workflow.${this.workflowId}`,
152
166
  data: {
153
- inputData: params.resumeData,
167
+ inputData: resumeDataToUse,
154
168
  runId: this.runId,
169
+ workflowId: this.workflowId,
155
170
  stepResults: snapshot?.context,
156
171
  resume: {
157
172
  steps,
158
173
  stepResults: snapshot?.context,
159
- resumePayload: params.resumeData,
174
+ resumePayload: resumeDataToUse,
160
175
  // @ts-ignore
161
176
  resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
162
177
  }
@@ -201,7 +216,11 @@ var InngestRun = class extends Run {
201
216
  const writer = writable.getWriter();
202
217
  const unwatch = this.watch(async (event) => {
203
218
  try {
204
- await writer.write(event);
219
+ const e = {
220
+ ...event,
221
+ type: event.type.replace("workflow-", "")
222
+ };
223
+ await writer.write(e);
205
224
  } catch {
206
225
  }
207
226
  }, "watch-v2");
@@ -232,8 +251,14 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
232
251
  #mastra;
233
252
  inngest;
234
253
  function;
254
+ flowControlConfig;
235
255
  constructor(params, inngest) {
236
- super(params);
256
+ const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
257
+ super(workflowParams);
258
+ const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
259
+ ([_, value]) => value !== void 0
260
+ );
261
+ this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
237
262
  this.#mastra = params.mastra;
238
263
  this.inngest = inngest;
239
264
  }
@@ -254,27 +279,6 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
254
279
  const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
255
280
  return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
256
281
  }
257
- async getWorkflowRunExecutionResult(runId) {
258
- const storage = this.#mastra?.getStorage();
259
- if (!storage) {
260
- this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
261
- return null;
262
- }
263
- const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
264
- if (!run?.snapshot) {
265
- return null;
266
- }
267
- if (typeof run.snapshot === "string") {
268
- return null;
269
- }
270
- return {
271
- status: run.snapshot.status,
272
- result: run.snapshot.result,
273
- error: run.snapshot.error,
274
- payload: run.snapshot.context?.input,
275
- steps: run.snapshot.context
276
- };
277
- }
278
282
  __registerMastra(mastra) {
279
283
  this.#mastra = mastra;
280
284
  this.executionEngine.__registerMastra(mastra);
@@ -293,23 +297,14 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
293
297
  }
294
298
  }
295
299
  }
296
- createRun(options) {
297
- const runIdToUse = options?.runId || randomUUID();
298
- const run = this.runs.get(runIdToUse) ?? new InngestRun(
299
- {
300
- workflowId: this.id,
301
- runId: runIdToUse,
302
- executionEngine: this.executionEngine,
303
- executionGraph: this.executionGraph,
304
- serializedStepGraph: this.serializedStepGraph,
305
- mastra: this.#mastra,
306
- retryConfig: this.retryConfig,
307
- cleanup: () => this.runs.delete(runIdToUse)
308
- },
309
- this.inngest
300
+ /**
301
+ * @deprecated Use createRunAsync() instead.
302
+ * @throws {Error} Always throws an error directing users to use createRunAsync()
303
+ */
304
+ createRun(_options) {
305
+ throw new Error(
306
+ "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."
310
307
  );
311
- this.runs.set(runIdToUse, run);
312
- return run;
313
308
  }
314
309
  async createRunAsync(options) {
315
310
  const runIdToUse = options?.runId || randomUUID();
@@ -317,27 +312,31 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
317
312
  {
318
313
  workflowId: this.id,
319
314
  runId: runIdToUse,
315
+ resourceId: options?.resourceId,
320
316
  executionEngine: this.executionEngine,
321
317
  executionGraph: this.executionGraph,
322
318
  serializedStepGraph: this.serializedStepGraph,
323
319
  mastra: this.#mastra,
324
320
  retryConfig: this.retryConfig,
325
- cleanup: () => this.runs.delete(runIdToUse)
321
+ cleanup: () => this.runs.delete(runIdToUse),
322
+ workflowSteps: this.steps
326
323
  },
327
324
  this.inngest
328
325
  );
329
326
  this.runs.set(runIdToUse, run);
330
- const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
327
+ const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
331
328
  if (!workflowSnapshotInStorage) {
332
329
  await this.mastra?.getStorage()?.persistWorkflowSnapshot({
333
330
  workflowName: this.id,
334
331
  runId: runIdToUse,
332
+ resourceId: options?.resourceId,
335
333
  snapshot: {
336
334
  runId: runIdToUse,
337
335
  status: "pending",
338
336
  value: {},
339
337
  context: {},
340
338
  activePaths: [],
339
+ waitingPaths: {},
341
340
  serializedStepGraph: this.serializedStepGraph,
342
341
  suspendedPaths: {},
343
342
  result: void 0,
@@ -358,11 +357,13 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
358
357
  id: `workflow.${this.id}`,
359
358
  // @ts-ignore
360
359
  retries: this.retryConfig?.attempts ?? 0,
361
- cancelOn: [{ event: `cancel.workflow.${this.id}` }]
360
+ cancelOn: [{ event: `cancel.workflow.${this.id}` }],
361
+ // Spread flow control configuration
362
+ ...this.flowControlConfig
362
363
  },
363
364
  { event: `workflow.${this.id}` },
364
365
  async ({ event, step, attempt, publish }) => {
365
- let { inputData, runId, resume } = event.data;
366
+ let { inputData, runId, resourceId, resume } = event.data;
366
367
  if (!runId) {
367
368
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
368
369
  return randomUUID();
@@ -394,6 +395,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
394
395
  const result = await engine.execute({
395
396
  workflowId: this.id,
396
397
  runId,
398
+ resourceId,
397
399
  graph: this.executionGraph,
398
400
  serializedStepGraph: this.serializedStepGraph,
399
401
  input: inputData,
@@ -402,7 +404,9 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
402
404
  runtimeContext: new RuntimeContext(),
403
405
  // TODO
404
406
  resume,
405
- abortController: new AbortController()
407
+ abortController: new AbortController(),
408
+ currentSpan: void 0
409
+ // TODO: Pass actual parent AI span from workflow execution context
406
410
  });
407
411
  return { result, runId };
408
412
  }
@@ -436,17 +440,16 @@ function createStep(params) {
436
440
  if (isAgent(params)) {
437
441
  return {
438
442
  id: params.name,
443
+ description: params.getDescription(),
439
444
  // @ts-ignore
440
445
  inputSchema: z.object({
441
446
  prompt: z.string()
442
- // resourceId: z.string().optional(),
443
- // threadId: z.string().optional(),
444
447
  }),
445
448
  // @ts-ignore
446
449
  outputSchema: z.object({
447
450
  text: z.string()
448
451
  }),
449
- execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
452
+ execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
450
453
  let streamPromise = {};
451
454
  streamPromise.promise = new Promise((resolve, reject) => {
452
455
  streamPromise.resolve = resolve;
@@ -456,14 +459,9 @@ function createStep(params) {
456
459
  name: params.name,
457
460
  args: inputData
458
461
  };
459
- await emitter.emit("watch-v2", {
460
- type: "tool-call-streaming-start",
461
- ...toolData
462
- });
463
462
  const { fullStream } = await params.stream(inputData.prompt, {
464
- // resourceId: inputData.resourceId,
465
- // threadId: inputData.threadId,
466
463
  runtimeContext,
464
+ tracingContext,
467
465
  onFinish: (result) => {
468
466
  streamPromise.resolve(result.text);
469
467
  },
@@ -472,34 +470,28 @@ function createStep(params) {
472
470
  if (abortSignal.aborted) {
473
471
  return abort();
474
472
  }
473
+ await emitter.emit("watch-v2", {
474
+ type: "tool-call-streaming-start",
475
+ ...toolData ?? {}
476
+ });
475
477
  for await (const chunk of fullStream) {
476
- switch (chunk.type) {
477
- case "text-delta":
478
- await emitter.emit("watch-v2", {
479
- type: "tool-call-delta",
480
- ...toolData,
481
- argsTextDelta: chunk.textDelta
482
- });
483
- break;
484
- case "step-start":
485
- case "step-finish":
486
- case "finish":
487
- break;
488
- case "tool-call":
489
- case "tool-result":
490
- case "tool-call-streaming-start":
491
- case "tool-call-delta":
492
- case "source":
493
- case "file":
494
- default:
495
- await emitter.emit("watch-v2", chunk);
496
- break;
478
+ if (chunk.type === "text-delta") {
479
+ await emitter.emit("watch-v2", {
480
+ type: "tool-call-delta",
481
+ ...toolData ?? {},
482
+ argsTextDelta: chunk.textDelta
483
+ });
497
484
  }
498
485
  }
486
+ await emitter.emit("watch-v2", {
487
+ type: "tool-call-streaming-finish",
488
+ ...toolData ?? {}
489
+ });
499
490
  return {
500
491
  text: await streamPromise.promise
501
492
  };
502
- }
493
+ },
494
+ component: params.component
503
495
  };
504
496
  }
505
497
  if (isTool(params)) {
@@ -510,15 +502,20 @@ function createStep(params) {
510
502
  // TODO: tool probably should have strong id type
511
503
  // @ts-ignore
512
504
  id: params.id,
505
+ description: params.description,
513
506
  inputSchema: params.inputSchema,
514
507
  outputSchema: params.outputSchema,
515
- execute: async ({ inputData, mastra, runtimeContext }) => {
508
+ execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
516
509
  return params.execute({
517
510
  context: inputData,
518
- mastra,
519
- runtimeContext
511
+ mastra: wrapMastra(mastra, tracingContext),
512
+ runtimeContext,
513
+ tracingContext,
514
+ suspend,
515
+ resumeData
520
516
  });
521
- }
517
+ },
518
+ component: "TOOL"
522
519
  };
523
520
  }
524
521
  return {
@@ -543,7 +540,8 @@ function init(inngest) {
543
540
  description: step.description,
544
541
  inputSchema: step.inputSchema,
545
542
  outputSchema: step.outputSchema,
546
- execute: step.execute
543
+ execute: step.execute,
544
+ component: step.component
547
545
  };
548
546
  },
549
547
  cloneWorkflow(workflow, opts) {
@@ -563,19 +561,19 @@ function init(inngest) {
563
561
  var InngestExecutionEngine = class extends DefaultExecutionEngine {
564
562
  inngestStep;
565
563
  inngestAttempts;
566
- constructor(mastra, inngestStep, inngestAttempts = 0) {
567
- super({ mastra });
564
+ constructor(mastra, inngestStep, inngestAttempts = 0, options) {
565
+ super({ mastra, options });
568
566
  this.inngestStep = inngestStep;
569
567
  this.inngestAttempts = inngestAttempts;
570
568
  }
571
569
  async execute(params) {
572
570
  await params.emitter.emit("watch-v2", {
573
- type: "start",
571
+ type: "workflow-start",
574
572
  payload: { runId: params.runId }
575
573
  });
576
574
  const result = await super.execute(params);
577
575
  await params.emitter.emit("watch-v2", {
578
- type: "finish",
576
+ type: "workflow-finish",
579
577
  payload: { runId: params.runId }
580
578
  });
581
579
  return result;
@@ -637,33 +635,169 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
637
635
  executionSpan?.end();
638
636
  return base;
639
637
  }
640
- async superExecuteStep({
638
+ // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
639
+ // await this.inngestStep.sleep(id, duration);
640
+ // }
641
+ async executeSleep({
641
642
  workflowId,
642
643
  runId,
643
- step,
644
+ entry,
645
+ prevOutput,
644
646
  stepResults,
647
+ emitter,
648
+ abortController,
649
+ runtimeContext,
645
650
  executionContext,
646
- resume,
651
+ writableStream,
652
+ tracingContext
653
+ }) {
654
+ let { duration, fn } = entry;
655
+ const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
656
+ type: AISpanType.WORKFLOW_SLEEP,
657
+ name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
658
+ attributes: {
659
+ durationMs: duration,
660
+ sleepType: fn ? "dynamic" : "fixed"
661
+ },
662
+ tracingPolicy: this.options?.tracingPolicy
663
+ });
664
+ if (fn) {
665
+ const stepCallId = randomUUID();
666
+ duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
667
+ return await fn({
668
+ runId,
669
+ workflowId,
670
+ mastra: this.mastra,
671
+ runtimeContext,
672
+ inputData: prevOutput,
673
+ runCount: -1,
674
+ tracingContext: {
675
+ currentSpan: sleepSpan
676
+ },
677
+ getInitData: () => stepResults?.input,
678
+ getStepResult: getStepResult.bind(this, stepResults),
679
+ // TODO: this function shouldn't have suspend probably?
680
+ suspend: async (_suspendPayload) => {
681
+ },
682
+ bail: () => {
683
+ },
684
+ abort: () => {
685
+ abortController?.abort();
686
+ },
687
+ [EMITTER_SYMBOL]: emitter,
688
+ // TODO: add streamVNext support
689
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
690
+ engine: { step: this.inngestStep },
691
+ abortSignal: abortController?.signal,
692
+ writer: new ToolStream(
693
+ {
694
+ prefix: "workflow-step",
695
+ callId: stepCallId,
696
+ name: "sleep",
697
+ runId
698
+ },
699
+ writableStream
700
+ )
701
+ });
702
+ });
703
+ sleepSpan?.update({
704
+ attributes: {
705
+ durationMs: duration
706
+ }
707
+ });
708
+ }
709
+ try {
710
+ await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
711
+ sleepSpan?.end();
712
+ } catch (e) {
713
+ sleepSpan?.error({ error: e });
714
+ throw e;
715
+ }
716
+ }
717
+ async executeSleepUntil({
718
+ workflowId,
719
+ runId,
720
+ entry,
647
721
  prevOutput,
722
+ stepResults,
648
723
  emitter,
649
724
  abortController,
650
- runtimeContext
725
+ runtimeContext,
726
+ executionContext,
727
+ writableStream,
728
+ tracingContext
651
729
  }) {
652
- return super.executeStep({
653
- workflowId,
654
- runId,
655
- step,
656
- stepResults,
657
- executionContext,
658
- resume,
659
- prevOutput,
660
- emitter,
661
- abortController,
662
- runtimeContext
730
+ let { date, fn } = entry;
731
+ const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
732
+ type: AISpanType.WORKFLOW_SLEEP,
733
+ name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
734
+ attributes: {
735
+ untilDate: date,
736
+ durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
737
+ sleepType: fn ? "dynamic" : "fixed"
738
+ },
739
+ tracingPolicy: this.options?.tracingPolicy
663
740
  });
664
- }
665
- async executeSleep({ id, duration }) {
666
- await this.inngestStep.sleep(id, duration);
741
+ if (fn) {
742
+ date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
743
+ const stepCallId = randomUUID();
744
+ return await fn({
745
+ runId,
746
+ workflowId,
747
+ mastra: this.mastra,
748
+ runtimeContext,
749
+ inputData: prevOutput,
750
+ runCount: -1,
751
+ tracingContext: {
752
+ currentSpan: sleepUntilSpan
753
+ },
754
+ getInitData: () => stepResults?.input,
755
+ getStepResult: getStepResult.bind(this, stepResults),
756
+ // TODO: this function shouldn't have suspend probably?
757
+ suspend: async (_suspendPayload) => {
758
+ },
759
+ bail: () => {
760
+ },
761
+ abort: () => {
762
+ abortController?.abort();
763
+ },
764
+ [EMITTER_SYMBOL]: emitter,
765
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
766
+ // TODO: add streamVNext support
767
+ engine: { step: this.inngestStep },
768
+ abortSignal: abortController?.signal,
769
+ writer: new ToolStream(
770
+ {
771
+ prefix: "workflow-step",
772
+ callId: stepCallId,
773
+ name: "sleep",
774
+ runId
775
+ },
776
+ writableStream
777
+ )
778
+ });
779
+ });
780
+ if (date && !(date instanceof Date)) {
781
+ date = new Date(date);
782
+ }
783
+ const time = !date ? 0 : date.getTime() - Date.now();
784
+ sleepUntilSpan?.update({
785
+ attributes: {
786
+ durationMs: Math.max(0, time)
787
+ }
788
+ });
789
+ }
790
+ if (!(date instanceof Date)) {
791
+ sleepUntilSpan?.end();
792
+ return;
793
+ }
794
+ try {
795
+ await this.inngestStep.sleepUntil(entry.id, date);
796
+ sleepUntilSpan?.end();
797
+ } catch (e) {
798
+ sleepUntilSpan?.error({ error: e });
799
+ throw e;
800
+ }
667
801
  }
668
802
  async executeWaitForEvent({ event, timeout }) {
669
803
  const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
@@ -683,8 +817,25 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
683
817
  prevOutput,
684
818
  emitter,
685
819
  abortController,
686
- runtimeContext
820
+ runtimeContext,
821
+ tracingContext,
822
+ writableStream,
823
+ disableScorers
687
824
  }) {
825
+ const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
826
+ name: `workflow step: '${step.id}'`,
827
+ type: AISpanType.WORKFLOW_STEP,
828
+ input: prevOutput,
829
+ attributes: {
830
+ stepId: step.id
831
+ },
832
+ tracingPolicy: this.options?.tracingPolicy
833
+ });
834
+ const { inputData, validationError } = await validateStepInput({
835
+ prevOutput,
836
+ step,
837
+ validateInputs: this.options?.validateInputs ?? false
838
+ });
688
839
  const startedAt = await this.inngestStep.run(
689
840
  `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
690
841
  async () => {
@@ -711,10 +862,12 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
711
862
  eventTimestamp: Date.now()
712
863
  });
713
864
  await emitter.emit("watch-v2", {
714
- type: "step-start",
865
+ type: "workflow-step-start",
715
866
  payload: {
716
867
  id: step.id,
717
- status: "running"
868
+ status: "running",
869
+ payload: inputData,
870
+ startedAt: startedAt2
718
871
  }
719
872
  });
720
873
  return startedAt2;
@@ -733,7 +886,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
733
886
  const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
734
887
  function: step.getFunction(),
735
888
  data: {
736
- inputData: prevOutput,
889
+ inputData,
737
890
  runId,
738
891
  resume: {
739
892
  runId,
@@ -751,7 +904,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
751
904
  const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
752
905
  function: step.getFunction(),
753
906
  data: {
754
- inputData: prevOutput
907
+ inputData
755
908
  }
756
909
  });
757
910
  result = invokeResp.result;
@@ -779,7 +932,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
779
932
  eventTimestamp: Date.now()
780
933
  });
781
934
  await emitter.emit("watch-v2", {
782
- type: "step-result",
935
+ type: "workflow-step-result",
783
936
  payload: {
784
937
  id: step.id,
785
938
  status: "failed",
@@ -814,7 +967,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
814
967
  eventTimestamp: Date.now()
815
968
  });
816
969
  await emitter.emit("watch-v2", {
817
- type: "step-suspended",
970
+ type: "workflow-step-suspended",
818
971
  payload: {
819
972
  id: step.id,
820
973
  status: "suspended"
@@ -871,7 +1024,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
871
1024
  eventTimestamp: Date.now()
872
1025
  });
873
1026
  await emitter.emit("watch-v2", {
874
- type: "step-result",
1027
+ type: "workflow-step-result",
875
1028
  payload: {
876
1029
  id: step.id,
877
1030
  status: "success",
@@ -879,7 +1032,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
879
1032
  }
880
1033
  });
881
1034
  await emitter.emit("watch-v2", {
882
- type: "step-finish",
1035
+ type: "workflow-step-finish",
883
1036
  payload: {
884
1037
  id: step.id,
885
1038
  metadata: {}
@@ -896,20 +1049,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
896
1049
  let suspended;
897
1050
  let bailed;
898
1051
  try {
1052
+ if (validationError) {
1053
+ throw validationError;
1054
+ }
899
1055
  const result = await step.execute({
900
1056
  runId: executionContext.runId,
901
1057
  mastra: this.mastra,
902
1058
  runtimeContext,
903
- inputData: prevOutput,
1059
+ writableStream,
1060
+ inputData,
904
1061
  resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
905
- getInitData: () => stepResults?.input,
906
- getStepResult: (step2) => {
907
- const result2 = stepResults[step2.id];
908
- if (result2?.status === "success") {
909
- return result2.output;
910
- }
911
- return null;
1062
+ tracingContext: {
1063
+ currentSpan: stepAISpan
912
1064
  },
1065
+ getInitData: () => stepResults?.input,
1066
+ getStepResult: getStepResult.bind(this, stepResults),
913
1067
  suspend: async (suspendPayload) => {
914
1068
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
915
1069
  suspended = { payload: suspendPayload };
@@ -935,14 +1089,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
935
1089
  output: result,
936
1090
  startedAt,
937
1091
  endedAt,
938
- payload: prevOutput,
1092
+ payload: inputData,
939
1093
  resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
940
1094
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
941
1095
  };
942
1096
  } catch (e) {
943
1097
  execResults = {
944
1098
  status: "failed",
945
- payload: prevOutput,
1099
+ payload: inputData,
946
1100
  error: e instanceof Error ? e.message : String(e),
947
1101
  endedAt: Date.now(),
948
1102
  startedAt,
@@ -954,18 +1108,20 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
954
1108
  execResults = {
955
1109
  status: "suspended",
956
1110
  suspendedPayload: suspended.payload,
957
- payload: prevOutput,
1111
+ payload: inputData,
958
1112
  suspendedAt: Date.now(),
959
1113
  startedAt,
960
1114
  resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
961
1115
  resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
962
1116
  };
963
1117
  } else if (bailed) {
964
- execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
1118
+ execResults = { status: "bailed", output: bailed.payload, payload: inputData, endedAt: Date.now(), startedAt };
965
1119
  }
966
1120
  if (execResults.status === "failed") {
967
1121
  if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
968
- throw execResults.error;
1122
+ const error = new Error(execResults.error);
1123
+ stepAISpan?.error({ error });
1124
+ throw error;
969
1125
  }
970
1126
  }
971
1127
  await emitter.emit("watch", {
@@ -986,7 +1142,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
986
1142
  });
987
1143
  if (execResults.status === "suspended") {
988
1144
  await emitter.emit("watch-v2", {
989
- type: "step-suspended",
1145
+ type: "workflow-step-suspended",
990
1146
  payload: {
991
1147
  id: step.id,
992
1148
  ...execResults
@@ -994,22 +1150,40 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
994
1150
  });
995
1151
  } else {
996
1152
  await emitter.emit("watch-v2", {
997
- type: "step-result",
1153
+ type: "workflow-step-result",
998
1154
  payload: {
999
1155
  id: step.id,
1000
1156
  ...execResults
1001
1157
  }
1002
1158
  });
1003
1159
  await emitter.emit("watch-v2", {
1004
- type: "step-finish",
1160
+ type: "workflow-step-finish",
1005
1161
  payload: {
1006
1162
  id: step.id,
1007
1163
  metadata: {}
1008
1164
  }
1009
1165
  });
1010
1166
  }
1167
+ stepAISpan?.end({ output: execResults });
1011
1168
  return { result: execResults, executionContext, stepResults };
1012
1169
  });
1170
+ if (disableScorers !== false) {
1171
+ await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1172
+ if (step.scorers) {
1173
+ await this.runScorers({
1174
+ scorers: step.scorers,
1175
+ runId: executionContext.runId,
1176
+ input: inputData,
1177
+ output: stepRes.result,
1178
+ workflowId: executionContext.workflowId,
1179
+ stepId: step.id,
1180
+ runtimeContext,
1181
+ disableScorers,
1182
+ tracingContext: { currentSpan: stepAISpan }
1183
+ });
1184
+ }
1185
+ });
1186
+ }
1013
1187
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1014
1188
  Object.assign(stepResults, stepRes.stepResults);
1015
1189
  return stepRes.result;
@@ -1018,6 +1192,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1018
1192
  workflowId,
1019
1193
  runId,
1020
1194
  stepResults,
1195
+ resourceId,
1021
1196
  executionContext,
1022
1197
  serializedStepGraph,
1023
1198
  workflowStatus,
@@ -1030,12 +1205,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1030
1205
  await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1031
1206
  workflowName: workflowId,
1032
1207
  runId,
1208
+ resourceId,
1033
1209
  snapshot: {
1034
1210
  runId,
1035
1211
  value: {},
1036
1212
  context: stepResults,
1037
1213
  activePaths: [],
1038
1214
  suspendedPaths: executionContext.suspendedPaths,
1215
+ waitingPaths: {},
1039
1216
  serializedStepGraph,
1040
1217
  status: workflowStatus,
1041
1218
  result,
@@ -1059,30 +1236,46 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1059
1236
  executionContext,
1060
1237
  emitter,
1061
1238
  abortController,
1062
- runtimeContext
1239
+ runtimeContext,
1240
+ writableStream,
1241
+ disableScorers,
1242
+ tracingContext
1063
1243
  }) {
1244
+ const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1245
+ type: AISpanType.WORKFLOW_CONDITIONAL,
1246
+ name: `conditional: '${entry.conditions.length} conditions'`,
1247
+ input: prevOutput,
1248
+ attributes: {
1249
+ conditionCount: entry.conditions.length
1250
+ },
1251
+ tracingPolicy: this.options?.tracingPolicy
1252
+ });
1064
1253
  let execResults;
1065
1254
  const truthyIndexes = (await Promise.all(
1066
1255
  entry.conditions.map(
1067
1256
  (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1257
+ const evalSpan = conditionalSpan?.createChildSpan({
1258
+ type: AISpanType.WORKFLOW_CONDITIONAL_EVAL,
1259
+ name: `condition: '${index}'`,
1260
+ input: prevOutput,
1261
+ attributes: {
1262
+ conditionIndex: index
1263
+ },
1264
+ tracingPolicy: this.options?.tracingPolicy
1265
+ });
1068
1266
  try {
1069
1267
  const result = await cond({
1070
1268
  runId,
1269
+ workflowId,
1071
1270
  mastra: this.mastra,
1072
1271
  runtimeContext,
1073
1272
  runCount: -1,
1074
1273
  inputData: prevOutput,
1075
- getInitData: () => stepResults?.input,
1076
- getStepResult: (step) => {
1077
- if (!step?.id) {
1078
- return null;
1079
- }
1080
- const result2 = stepResults[step.id];
1081
- if (result2?.status === "success") {
1082
- return result2.output;
1083
- }
1084
- return null;
1274
+ tracingContext: {
1275
+ currentSpan: evalSpan
1085
1276
  },
1277
+ getInitData: () => stepResults?.input,
1278
+ getStepResult: getStepResult.bind(this, stepResults),
1086
1279
  // TODO: this function shouldn't have suspend probably?
1087
1280
  suspend: async (_suspendPayload) => {
1088
1281
  },
@@ -1092,29 +1285,58 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1092
1285
  abortController.abort();
1093
1286
  },
1094
1287
  [EMITTER_SYMBOL]: emitter,
1288
+ [STREAM_FORMAT_SYMBOL]: executionContext.format,
1289
+ // TODO: add streamVNext support
1095
1290
  engine: {
1096
1291
  step: this.inngestStep
1097
1292
  },
1098
- abortSignal: abortController.signal
1293
+ abortSignal: abortController.signal,
1294
+ writer: new ToolStream(
1295
+ {
1296
+ prefix: "workflow-step",
1297
+ callId: randomUUID(),
1298
+ name: "conditional",
1299
+ runId
1300
+ },
1301
+ writableStream
1302
+ )
1303
+ });
1304
+ evalSpan?.end({
1305
+ output: result,
1306
+ attributes: {
1307
+ result: !!result
1308
+ }
1099
1309
  });
1100
1310
  return result ? index : null;
1101
1311
  } catch (e) {
1312
+ evalSpan?.error({
1313
+ error: e instanceof Error ? e : new Error(String(e)),
1314
+ attributes: {
1315
+ result: false
1316
+ }
1317
+ });
1102
1318
  return null;
1103
1319
  }
1104
1320
  })
1105
1321
  )
1106
1322
  )).filter((index) => index !== null);
1107
1323
  const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
1324
+ conditionalSpan?.update({
1325
+ attributes: {
1326
+ truthyIndexes,
1327
+ selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
1328
+ }
1329
+ });
1108
1330
  const results = await Promise.all(
1109
1331
  stepsToRun.map(
1110
1332
  (step, index) => this.executeEntry({
1111
1333
  workflowId,
1112
1334
  runId,
1113
1335
  entry: step,
1336
+ serializedStepGraph,
1114
1337
  prevStep,
1115
1338
  stepResults,
1116
1339
  resume,
1117
- serializedStepGraph,
1118
1340
  executionContext: {
1119
1341
  workflowId,
1120
1342
  runId,
@@ -1125,7 +1347,12 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1125
1347
  },
1126
1348
  emitter,
1127
1349
  abortController,
1128
- runtimeContext
1350
+ runtimeContext,
1351
+ writableStream,
1352
+ disableScorers,
1353
+ tracingContext: {
1354
+ currentSpan: conditionalSpan
1355
+ }
1129
1356
  })
1130
1357
  )
1131
1358
  );
@@ -1146,8 +1373,19 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1146
1373
  }, {})
1147
1374
  };
1148
1375
  }
1376
+ if (execResults.status === "failed") {
1377
+ conditionalSpan?.error({
1378
+ error: new Error(execResults.error)
1379
+ });
1380
+ } else {
1381
+ conditionalSpan?.end({
1382
+ output: execResults.output || execResults
1383
+ });
1384
+ }
1149
1385
  return execResults;
1150
1386
  }
1151
1387
  };
1152
1388
 
1153
1389
  export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
1390
+ //# sourceMappingURL=index.js.map
1391
+ //# sourceMappingURL=index.js.map