@mastra/inngest 1.0.0-beta.2 → 1.0.0-beta.4

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,41 +1,300 @@
1
+ import { Tool } from '@mastra/core/tools';
2
+ import { DefaultExecutionEngine, createTimeTravelExecutionParams, Run, Workflow } from '@mastra/core/workflows';
3
+ import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
4
+ import { z } from 'zod';
1
5
  import { randomUUID } from 'crypto';
2
6
  import { ReadableStream, WritableStream } from 'stream/web';
3
- import { subscribe } from '@inngest/realtime';
4
7
  import { RequestContext } from '@mastra/core/di';
5
- import { SpanType } from '@mastra/core/observability';
8
+ import { RetryAfterError, NonRetriableError } from 'inngest';
9
+ import { subscribe } from '@inngest/realtime';
6
10
  import { ChunkFrom, WorkflowRunOutput } from '@mastra/core/stream';
7
- import { ToolStream, Tool } from '@mastra/core/tools';
8
- import { Run, createTimeTravelExecutionParams, Workflow, DefaultExecutionEngine, createDeprecationProxy, getStepResult, runCountDeprecationMessage, validateStepInput, validateStepResumeData } from '@mastra/core/workflows';
9
- import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
10
- import { NonRetriableError, RetryAfterError } from 'inngest';
11
11
  import { serve as serve$1 } from 'inngest/hono';
12
- import { z } from 'zod';
13
12
 
14
13
  // src/index.ts
15
- function serve({
16
- mastra,
17
- inngest,
18
- functions: userFunctions = [],
19
- registerOptions
20
- }) {
21
- const wfs = mastra.listWorkflows();
22
- const workflowFunctions = Array.from(
23
- new Set(
24
- Object.values(wfs).flatMap((wf) => {
25
- if (wf instanceof InngestWorkflow) {
26
- wf.__registerMastra(mastra);
27
- return wf.getFunctions();
14
+ var InngestExecutionEngine = class extends DefaultExecutionEngine {
15
+ inngestStep;
16
+ inngestAttempts;
17
+ constructor(mastra, inngestStep, inngestAttempts = 0, options) {
18
+ super({ mastra, options });
19
+ this.inngestStep = inngestStep;
20
+ this.inngestAttempts = inngestAttempts;
21
+ }
22
+ // =============================================================================
23
+ // Hook Overrides
24
+ // =============================================================================
25
+ /**
26
+ * Format errors with stack traces for better debugging in Inngest
27
+ */
28
+ formatResultError(error, lastOutput) {
29
+ if (error instanceof Error) {
30
+ return error.stack ?? error.message;
31
+ }
32
+ const outputError = lastOutput?.error;
33
+ if (outputError instanceof Error) {
34
+ return outputError.message;
35
+ }
36
+ return outputError ?? error ?? "Unknown error";
37
+ }
38
+ /**
39
+ * Detect InngestWorkflow instances for special nested workflow handling
40
+ */
41
+ isNestedWorkflowStep(step) {
42
+ return step instanceof InngestWorkflow;
43
+ }
44
+ /**
45
+ * Inngest requires requestContext serialization for memoization.
46
+ * When steps are replayed, the original function doesn't re-execute,
47
+ * so requestContext modifications must be captured and restored.
48
+ */
49
+ requiresDurableContextSerialization() {
50
+ return true;
51
+ }
52
+ /**
53
+ * Execute a step with retry logic for Inngest.
54
+ * Retries are handled via step-level retry (RetryAfterError thrown INSIDE step.run()).
55
+ * After retries exhausted, error propagates here and we return a failed result.
56
+ */
57
+ async executeStepWithRetry(stepId, runStep, params) {
58
+ try {
59
+ const result = await this.wrapDurableOperation(stepId, runStep, { delay: params.delay });
60
+ return { ok: true, result };
61
+ } catch (e) {
62
+ const cause = e?.cause;
63
+ if (cause?.status === "failed") {
64
+ params.stepSpan?.error({
65
+ error: e,
66
+ attributes: { status: "failed" }
67
+ });
68
+ return { ok: false, error: cause };
69
+ }
70
+ const errorMessage = e instanceof Error ? e.message : String(e);
71
+ params.stepSpan?.error({
72
+ error: e,
73
+ attributes: { status: "failed" }
74
+ });
75
+ return {
76
+ ok: false,
77
+ error: {
78
+ status: "failed",
79
+ error: `Error: ${errorMessage}`,
80
+ endedAt: Date.now()
28
81
  }
29
- return [];
30
- })
31
- )
32
- );
33
- return serve$1({
34
- ...registerOptions,
35
- client: inngest,
36
- functions: [...workflowFunctions, ...userFunctions]
37
- });
38
- }
82
+ };
83
+ }
84
+ }
85
+ /**
86
+ * Use Inngest's sleep primitive for durability
87
+ */
88
+ async executeSleepDuration(duration, sleepId, workflowId) {
89
+ await this.inngestStep.sleep(`workflow.${workflowId}.sleep.${sleepId}`, duration < 0 ? 0 : duration);
90
+ }
91
+ /**
92
+ * Use Inngest's sleepUntil primitive for durability
93
+ */
94
+ async executeSleepUntilDate(date, sleepUntilId, workflowId) {
95
+ await this.inngestStep.sleepUntil(`workflow.${workflowId}.sleepUntil.${sleepUntilId}`, date);
96
+ }
97
+ /**
98
+ * Wrap durable operations in Inngest step.run() for durability.
99
+ * If retryConfig is provided, throws RetryAfterError INSIDE step.run() to trigger
100
+ * Inngest's step-level retry mechanism (not function-level retry).
101
+ */
102
+ async wrapDurableOperation(operationId, operationFn, retryConfig) {
103
+ return this.inngestStep.run(operationId, async () => {
104
+ try {
105
+ return await operationFn();
106
+ } catch (e) {
107
+ if (retryConfig) {
108
+ const errorMessage = e instanceof Error ? e.message : String(e);
109
+ throw new RetryAfterError(errorMessage, retryConfig.delay, {
110
+ cause: {
111
+ status: "failed",
112
+ error: `Error: ${errorMessage}`,
113
+ endedAt: Date.now()
114
+ }
115
+ });
116
+ }
117
+ throw e;
118
+ }
119
+ });
120
+ }
121
+ /**
122
+ * Provide Inngest step primitive in engine context
123
+ */
124
+ getEngineContext() {
125
+ return { step: this.inngestStep };
126
+ }
127
+ /**
128
+ * Execute nested InngestWorkflow using inngestStep.invoke() for durability.
129
+ * This MUST be called directly (not inside step.run()) due to Inngest constraints.
130
+ */
131
+ async executeWorkflowStep(params) {
132
+ if (!(params.step instanceof InngestWorkflow)) {
133
+ return null;
134
+ }
135
+ const { step, stepResults, executionContext, resume, timeTravel, prevOutput, inputData, emitter, startedAt } = params;
136
+ const isResume = !!resume?.steps?.length;
137
+ let result;
138
+ let runId;
139
+ const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
140
+ try {
141
+ if (isResume) {
142
+ runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
143
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
144
+ workflowName: step.id,
145
+ runId
146
+ });
147
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
148
+ function: step.getFunction(),
149
+ data: {
150
+ inputData,
151
+ initialState: executionContext.state ?? snapshot?.value ?? {},
152
+ runId,
153
+ resume: {
154
+ runId,
155
+ steps: resume.steps.slice(1),
156
+ stepResults: snapshot?.context,
157
+ resumePayload: resume.resumePayload,
158
+ resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
159
+ },
160
+ outputOptions: { includeState: true }
161
+ }
162
+ });
163
+ result = invokeResp.result;
164
+ runId = invokeResp.runId;
165
+ executionContext.state = invokeResp.result.state;
166
+ } else if (isTimeTravel) {
167
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
168
+ workflowName: step.id,
169
+ runId: executionContext.runId
170
+ }) ?? { context: {} };
171
+ const timeTravelParams = createTimeTravelExecutionParams({
172
+ steps: timeTravel.steps.slice(1),
173
+ inputData: timeTravel.inputData,
174
+ resumeData: timeTravel.resumeData,
175
+ context: timeTravel.nestedStepResults?.[step.id] ?? {},
176
+ nestedStepsContext: timeTravel.nestedStepResults ?? {},
177
+ snapshot,
178
+ graph: step.buildExecutionGraph()
179
+ });
180
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
181
+ function: step.getFunction(),
182
+ data: {
183
+ timeTravel: timeTravelParams,
184
+ initialState: executionContext.state ?? {},
185
+ runId: executionContext.runId,
186
+ outputOptions: { includeState: true }
187
+ }
188
+ });
189
+ result = invokeResp.result;
190
+ runId = invokeResp.runId;
191
+ executionContext.state = invokeResp.result.state;
192
+ } else {
193
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
194
+ function: step.getFunction(),
195
+ data: {
196
+ inputData,
197
+ initialState: executionContext.state ?? {},
198
+ outputOptions: { includeState: true }
199
+ }
200
+ });
201
+ result = invokeResp.result;
202
+ runId = invokeResp.runId;
203
+ executionContext.state = invokeResp.result.state;
204
+ }
205
+ } catch (e) {
206
+ const errorCause = e?.cause;
207
+ if (errorCause && typeof errorCause === "object") {
208
+ result = errorCause;
209
+ runId = errorCause.runId || randomUUID();
210
+ } else {
211
+ runId = randomUUID();
212
+ result = {
213
+ status: "failed",
214
+ error: e instanceof Error ? e : new Error(String(e)),
215
+ steps: {},
216
+ input: inputData
217
+ };
218
+ }
219
+ }
220
+ const res = await this.inngestStep.run(
221
+ `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
222
+ async () => {
223
+ if (result.status === "failed") {
224
+ await emitter.emit("watch", {
225
+ type: "workflow-step-result",
226
+ payload: {
227
+ id: step.id,
228
+ status: "failed",
229
+ error: result?.error,
230
+ payload: prevOutput
231
+ }
232
+ });
233
+ return { executionContext, result: { status: "failed", error: result?.error } };
234
+ } else if (result.status === "suspended") {
235
+ const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
236
+ const stepRes = stepResult;
237
+ return stepRes?.status === "suspended";
238
+ });
239
+ for (const [stepName, stepResult] of suspendedSteps) {
240
+ const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
241
+ executionContext.suspendedPaths[step.id] = executionContext.executionPath;
242
+ await emitter.emit("watch", {
243
+ type: "workflow-step-suspended",
244
+ payload: {
245
+ id: step.id,
246
+ status: "suspended"
247
+ }
248
+ });
249
+ return {
250
+ executionContext,
251
+ result: {
252
+ status: "suspended",
253
+ payload: stepResult.payload,
254
+ suspendPayload: {
255
+ ...stepResult?.suspendPayload,
256
+ __workflow_meta: { runId, path: suspendPath }
257
+ }
258
+ }
259
+ };
260
+ }
261
+ return {
262
+ executionContext,
263
+ result: {
264
+ status: "suspended",
265
+ payload: {}
266
+ }
267
+ };
268
+ }
269
+ await emitter.emit("watch", {
270
+ type: "workflow-step-result",
271
+ payload: {
272
+ id: step.id,
273
+ status: "success",
274
+ output: result?.result
275
+ }
276
+ });
277
+ await emitter.emit("watch", {
278
+ type: "workflow-step-finish",
279
+ payload: {
280
+ id: step.id,
281
+ metadata: {}
282
+ }
283
+ });
284
+ return { executionContext, result: { status: "success", output: result?.result } };
285
+ }
286
+ );
287
+ Object.assign(executionContext, res.executionContext);
288
+ return {
289
+ ...res.result,
290
+ startedAt,
291
+ endedAt: Date.now(),
292
+ payload: inputData,
293
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
294
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
295
+ };
296
+ }
297
+ };
39
298
  var InngestRun = class extends Run {
40
299
  inngest;
41
300
  serializedStepGraph;
@@ -113,7 +372,8 @@ var InngestRun = class extends Run {
113
372
  initialState,
114
373
  outputOptions,
115
374
  tracingOptions,
116
- format
375
+ format,
376
+ requestContext
117
377
  }) {
118
378
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
119
379
  workflowName: this.workflowId,
@@ -144,7 +404,8 @@ var InngestRun = class extends Run {
144
404
  resourceId: this.resourceId,
145
405
  outputOptions,
146
406
  tracingOptions,
147
- format
407
+ format,
408
+ requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {}
148
409
  }
149
410
  });
150
411
  const eventId = eventOutput.ids[0];
@@ -188,6 +449,9 @@ var InngestRun = class extends Run {
188
449
  });
189
450
  const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
190
451
  const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
452
+ const persistedRequestContext = snapshot?.requestContext ?? {};
453
+ const newRequestContext = params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {};
454
+ const mergedRequestContext = { ...persistedRequestContext, ...newRequestContext };
191
455
  const eventOutput = await this.inngest.send({
192
456
  name: `workflow.${this.workflowId}`,
193
457
  data: {
@@ -201,7 +465,8 @@ var InngestRun = class extends Run {
201
465
  stepResults: snapshot?.context,
202
466
  resumePayload: resumeDataToUse,
203
467
  resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
204
- }
468
+ },
469
+ requestContext: mergedRequestContext
205
470
  }
206
471
  });
207
472
  const eventId = eventOutput.ids[0];
@@ -292,7 +557,8 @@ var InngestRun = class extends Run {
292
557
  stepResults: timeTravelData.stepResults,
293
558
  timeTravel: timeTravelData,
294
559
  tracingOptions: params.tracingOptions,
295
- outputOptions: params.outputOptions
560
+ outputOptions: params.outputOptions,
561
+ requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
296
562
  }
297
563
  });
298
564
  const eventId = eventOutput.ids[0];
@@ -332,14 +598,14 @@ var InngestRun = class extends Run {
332
598
  streamLegacy({ inputData, requestContext } = {}) {
333
599
  const { readable, writable } = new TransformStream();
334
600
  const writer = writable.getWriter();
601
+ void writer.write({
602
+ // @ts-ignore
603
+ type: "start",
604
+ // @ts-ignore
605
+ payload: { runId: this.runId }
606
+ });
335
607
  const unwatch = this.watch(async (event) => {
336
608
  try {
337
- await writer.write({
338
- // @ts-ignore
339
- type: "start",
340
- // @ts-ignore
341
- payload: { runId: this.runId }
342
- });
343
609
  const e = {
344
610
  ...event,
345
611
  type: event.type.replace("workflow-", "")
@@ -485,7 +751,7 @@ var InngestRun = class extends Run {
485
751
  self.closeStreamAction = async () => {
486
752
  unwatch();
487
753
  try {
488
- await controller.close();
754
+ controller.close();
489
755
  } catch (err) {
490
756
  console.error("Error closing stream:", err);
491
757
  }
@@ -525,6 +791,8 @@ var InngestRun = class extends Run {
525
791
  return this.streamOutput;
526
792
  }
527
793
  };
794
+
795
+ // src/workflow.ts
528
796
  var InngestWorkflow = class _InngestWorkflow extends Workflow {
529
797
  #mastra;
530
798
  inngest;
@@ -678,8 +946,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
678
946
  initialState,
679
947
  emitter,
680
948
  retryConfig: this.retryConfig,
681
- requestContext: new RequestContext(),
682
- // TODO
949
+ requestContext: new RequestContext(Object.entries(event.data.requestContext ?? {})),
683
950
  resume,
684
951
  timeTravel,
685
952
  format,
@@ -723,13 +990,48 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
723
990
  return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
724
991
  }
725
992
  };
993
+ function serve({
994
+ mastra,
995
+ inngest,
996
+ functions: userFunctions = [],
997
+ registerOptions
998
+ }) {
999
+ const wfs = mastra.listWorkflows();
1000
+ const workflowFunctions = Array.from(
1001
+ new Set(
1002
+ Object.values(wfs).flatMap((wf) => {
1003
+ if (wf instanceof InngestWorkflow) {
1004
+ wf.__registerMastra(mastra);
1005
+ return wf.getFunctions();
1006
+ }
1007
+ return [];
1008
+ })
1009
+ )
1010
+ );
1011
+ return serve$1({
1012
+ ...registerOptions,
1013
+ client: inngest,
1014
+ functions: [...workflowFunctions, ...userFunctions]
1015
+ });
1016
+ }
1017
+
1018
+ // src/types.ts
1019
+ var _compatibilityCheck = true;
1020
+
1021
+ // src/index.ts
726
1022
  function isAgent(params) {
727
1023
  return params?.component === "AGENT";
728
1024
  }
729
1025
  function isTool(params) {
730
1026
  return params instanceof Tool;
731
1027
  }
1028
+ function isInngestWorkflow(params) {
1029
+ return params instanceof InngestWorkflow;
1030
+ }
732
1031
  function createStep(params, agentOptions) {
1032
+ if (isInngestWorkflow(params)) {
1033
+ return params;
1034
+ }
733
1035
  if (isAgent(params)) {
734
1036
  return {
735
1037
  id: params.name,
@@ -832,6 +1134,8 @@ function createStep(params, agentOptions) {
832
1134
  description: params.description,
833
1135
  inputSchema: params.inputSchema,
834
1136
  outputSchema: params.outputSchema,
1137
+ suspendSchema: params.suspendSchema,
1138
+ resumeSchema: params.resumeSchema,
835
1139
  execute: async ({
836
1140
  inputData,
837
1141
  mastra,
@@ -848,9 +1152,9 @@ function createStep(params, agentOptions) {
848
1152
  mastra,
849
1153
  requestContext,
850
1154
  tracingContext,
851
- resumeData,
852
1155
  workflow: {
853
1156
  runId,
1157
+ resumeData,
854
1158
  suspend,
855
1159
  workflowId,
856
1160
  state,
@@ -902,7 +1206,8 @@ function init(inngest) {
902
1206
  inputSchema: workflow.inputSchema,
903
1207
  outputSchema: workflow.outputSchema,
904
1208
  steps: workflow.stepDefs,
905
- mastra: workflow.mastra
1209
+ mastra: workflow.mastra,
1210
+ options: workflow.options
906
1211
  });
907
1212
  wf.setStepFlow(workflow.stepGraph);
908
1213
  wf.commit();
@@ -910,846 +1215,7 @@ function init(inngest) {
910
1215
  }
911
1216
  };
912
1217
  }
913
- var InngestExecutionEngine = class extends DefaultExecutionEngine {
914
- inngestStep;
915
- inngestAttempts;
916
- constructor(mastra, inngestStep, inngestAttempts = 0, options) {
917
- super({ mastra, options });
918
- this.inngestStep = inngestStep;
919
- this.inngestAttempts = inngestAttempts;
920
- }
921
- async fmtReturnValue(emitter, stepResults, lastOutput, error) {
922
- const base = {
923
- status: lastOutput.status,
924
- steps: stepResults
925
- };
926
- if (lastOutput.status === "success") {
927
- base.result = lastOutput.output;
928
- } else if (lastOutput.status === "failed") {
929
- base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
930
- } else if (lastOutput.status === "suspended") {
931
- const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
932
- if (stepResult?.status === "suspended") {
933
- const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
934
- return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
935
- }
936
- return [];
937
- });
938
- base.suspended = suspendedStepIds;
939
- }
940
- return base;
941
- }
942
- // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
943
- // await this.inngestStep.sleep(id, duration);
944
- // }
945
- async executeSleep({
946
- workflowId,
947
- runId,
948
- entry,
949
- prevOutput,
950
- stepResults,
951
- emitter,
952
- abortController,
953
- requestContext,
954
- executionContext,
955
- writableStream,
956
- tracingContext
957
- }) {
958
- let { duration, fn } = entry;
959
- const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
960
- type: SpanType.WORKFLOW_SLEEP,
961
- name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
962
- attributes: {
963
- durationMs: duration,
964
- sleepType: fn ? "dynamic" : "fixed"
965
- },
966
- tracingPolicy: this.options?.tracingPolicy
967
- });
968
- if (fn) {
969
- const stepCallId = randomUUID();
970
- duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
971
- return await fn(
972
- createDeprecationProxy(
973
- {
974
- runId,
975
- workflowId,
976
- mastra: this.mastra,
977
- requestContext,
978
- inputData: prevOutput,
979
- state: executionContext.state,
980
- setState: (state) => {
981
- executionContext.state = state;
982
- },
983
- retryCount: -1,
984
- tracingContext: {
985
- currentSpan: sleepSpan
986
- },
987
- getInitData: () => stepResults?.input,
988
- getStepResult: getStepResult.bind(this, stepResults),
989
- // TODO: this function shouldn't have suspend probably?
990
- suspend: async (_suspendPayload) => {
991
- },
992
- bail: () => {
993
- },
994
- abort: () => {
995
- abortController?.abort();
996
- },
997
- [EMITTER_SYMBOL]: emitter,
998
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
999
- engine: { step: this.inngestStep },
1000
- abortSignal: abortController?.signal,
1001
- writer: new ToolStream(
1002
- {
1003
- prefix: "workflow-step",
1004
- callId: stepCallId,
1005
- name: "sleep",
1006
- runId
1007
- },
1008
- writableStream
1009
- )
1010
- },
1011
- {
1012
- paramName: "runCount",
1013
- deprecationMessage: runCountDeprecationMessage,
1014
- logger: this.logger
1015
- }
1016
- )
1017
- );
1018
- });
1019
- sleepSpan?.update({
1020
- attributes: {
1021
- durationMs: duration
1022
- }
1023
- });
1024
- }
1025
- try {
1026
- await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
1027
- sleepSpan?.end();
1028
- } catch (e) {
1029
- sleepSpan?.error({ error: e });
1030
- throw e;
1031
- }
1032
- }
1033
- async executeSleepUntil({
1034
- workflowId,
1035
- runId,
1036
- entry,
1037
- prevOutput,
1038
- stepResults,
1039
- emitter,
1040
- abortController,
1041
- requestContext,
1042
- executionContext,
1043
- writableStream,
1044
- tracingContext
1045
- }) {
1046
- let { date, fn } = entry;
1047
- const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
1048
- type: SpanType.WORKFLOW_SLEEP,
1049
- name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
1050
- attributes: {
1051
- untilDate: date,
1052
- durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
1053
- sleepType: fn ? "dynamic" : "fixed"
1054
- },
1055
- tracingPolicy: this.options?.tracingPolicy
1056
- });
1057
- if (fn) {
1058
- date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
1059
- const stepCallId = randomUUID();
1060
- return await fn(
1061
- createDeprecationProxy(
1062
- {
1063
- runId,
1064
- workflowId,
1065
- mastra: this.mastra,
1066
- requestContext,
1067
- inputData: prevOutput,
1068
- state: executionContext.state,
1069
- setState: (state) => {
1070
- executionContext.state = state;
1071
- },
1072
- retryCount: -1,
1073
- tracingContext: {
1074
- currentSpan: sleepUntilSpan
1075
- },
1076
- getInitData: () => stepResults?.input,
1077
- getStepResult: getStepResult.bind(this, stepResults),
1078
- // TODO: this function shouldn't have suspend probably?
1079
- suspend: async (_suspendPayload) => {
1080
- },
1081
- bail: () => {
1082
- },
1083
- abort: () => {
1084
- abortController?.abort();
1085
- },
1086
- [EMITTER_SYMBOL]: emitter,
1087
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
1088
- engine: { step: this.inngestStep },
1089
- abortSignal: abortController?.signal,
1090
- writer: new ToolStream(
1091
- {
1092
- prefix: "workflow-step",
1093
- callId: stepCallId,
1094
- name: "sleep",
1095
- runId
1096
- },
1097
- writableStream
1098
- )
1099
- },
1100
- {
1101
- paramName: "runCount",
1102
- deprecationMessage: runCountDeprecationMessage,
1103
- logger: this.logger
1104
- }
1105
- )
1106
- );
1107
- });
1108
- if (date && !(date instanceof Date)) {
1109
- date = new Date(date);
1110
- }
1111
- const time = !date ? 0 : date.getTime() - Date.now();
1112
- sleepUntilSpan?.update({
1113
- attributes: {
1114
- durationMs: Math.max(0, time)
1115
- }
1116
- });
1117
- }
1118
- if (!(date instanceof Date)) {
1119
- sleepUntilSpan?.end();
1120
- return;
1121
- }
1122
- try {
1123
- await this.inngestStep.sleepUntil(entry.id, date);
1124
- sleepUntilSpan?.end();
1125
- } catch (e) {
1126
- sleepUntilSpan?.error({ error: e });
1127
- throw e;
1128
- }
1129
- }
1130
- async executeStep({
1131
- step,
1132
- stepResults,
1133
- executionContext,
1134
- resume,
1135
- timeTravel,
1136
- prevOutput,
1137
- emitter,
1138
- abortController,
1139
- requestContext,
1140
- tracingContext,
1141
- writableStream,
1142
- disableScorers
1143
- }) {
1144
- const stepSpan = tracingContext?.currentSpan?.createChildSpan({
1145
- name: `workflow step: '${step.id}'`,
1146
- type: SpanType.WORKFLOW_STEP,
1147
- input: prevOutput,
1148
- attributes: {
1149
- stepId: step.id
1150
- },
1151
- tracingPolicy: this.options?.tracingPolicy
1152
- });
1153
- const { inputData, validationError } = await validateStepInput({
1154
- prevOutput,
1155
- step,
1156
- validateInputs: this.options?.validateInputs ?? true
1157
- });
1158
- const startedAt = await this.inngestStep.run(
1159
- `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
1160
- async () => {
1161
- const startedAt2 = Date.now();
1162
- await emitter.emit("watch", {
1163
- type: "workflow-step-start",
1164
- payload: {
1165
- id: step.id,
1166
- status: "running",
1167
- payload: inputData,
1168
- startedAt: startedAt2
1169
- }
1170
- });
1171
- return startedAt2;
1172
- }
1173
- );
1174
- if (step instanceof InngestWorkflow) {
1175
- const isResume = !!resume?.steps?.length;
1176
- let result;
1177
- let runId;
1178
- const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
1179
- try {
1180
- if (isResume) {
1181
- runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
1182
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1183
- workflowName: step.id,
1184
- runId
1185
- });
1186
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1187
- function: step.getFunction(),
1188
- data: {
1189
- inputData,
1190
- initialState: executionContext.state ?? snapshot?.value ?? {},
1191
- runId,
1192
- resume: {
1193
- runId,
1194
- steps: resume.steps.slice(1),
1195
- stepResults: snapshot?.context,
1196
- resumePayload: resume.resumePayload,
1197
- resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
1198
- },
1199
- outputOptions: { includeState: true }
1200
- }
1201
- });
1202
- result = invokeResp.result;
1203
- runId = invokeResp.runId;
1204
- executionContext.state = invokeResp.result.state;
1205
- } else if (isTimeTravel) {
1206
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1207
- workflowName: step.id,
1208
- runId: executionContext.runId
1209
- }) ?? { context: {} };
1210
- const timeTravelParams = createTimeTravelExecutionParams({
1211
- steps: timeTravel.steps.slice(1),
1212
- inputData: timeTravel.inputData,
1213
- resumeData: timeTravel.resumeData,
1214
- context: timeTravel.nestedStepResults?.[step.id] ?? {},
1215
- nestedStepsContext: timeTravel.nestedStepResults ?? {},
1216
- snapshot,
1217
- graph: step.buildExecutionGraph()
1218
- });
1219
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1220
- function: step.getFunction(),
1221
- data: {
1222
- timeTravel: timeTravelParams,
1223
- initialState: executionContext.state ?? {},
1224
- runId: executionContext.runId,
1225
- outputOptions: { includeState: true }
1226
- }
1227
- });
1228
- result = invokeResp.result;
1229
- runId = invokeResp.runId;
1230
- executionContext.state = invokeResp.result.state;
1231
- } else {
1232
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1233
- function: step.getFunction(),
1234
- data: {
1235
- inputData,
1236
- initialState: executionContext.state ?? {},
1237
- outputOptions: { includeState: true }
1238
- }
1239
- });
1240
- result = invokeResp.result;
1241
- runId = invokeResp.runId;
1242
- executionContext.state = invokeResp.result.state;
1243
- }
1244
- } catch (e) {
1245
- const errorCause = e?.cause;
1246
- if (errorCause && typeof errorCause === "object") {
1247
- result = errorCause;
1248
- runId = errorCause.runId || randomUUID();
1249
- } else {
1250
- runId = randomUUID();
1251
- result = {
1252
- status: "failed",
1253
- error: e instanceof Error ? e : new Error(String(e)),
1254
- steps: {},
1255
- input: inputData
1256
- };
1257
- }
1258
- }
1259
- const res = await this.inngestStep.run(
1260
- `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
1261
- async () => {
1262
- if (result.status === "failed") {
1263
- await emitter.emit("watch", {
1264
- type: "workflow-step-result",
1265
- payload: {
1266
- id: step.id,
1267
- status: "failed",
1268
- error: result?.error,
1269
- payload: prevOutput
1270
- }
1271
- });
1272
- return { executionContext, result: { status: "failed", error: result?.error } };
1273
- } else if (result.status === "suspended") {
1274
- const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
1275
- const stepRes2 = stepResult;
1276
- return stepRes2?.status === "suspended";
1277
- });
1278
- for (const [stepName, stepResult] of suspendedSteps) {
1279
- const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
1280
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1281
- await emitter.emit("watch", {
1282
- type: "workflow-step-suspended",
1283
- payload: {
1284
- id: step.id,
1285
- status: "suspended"
1286
- }
1287
- });
1288
- return {
1289
- executionContext,
1290
- result: {
1291
- status: "suspended",
1292
- payload: stepResult.payload,
1293
- suspendPayload: {
1294
- ...stepResult?.suspendPayload,
1295
- __workflow_meta: { runId, path: suspendPath }
1296
- }
1297
- }
1298
- };
1299
- }
1300
- return {
1301
- executionContext,
1302
- result: {
1303
- status: "suspended",
1304
- payload: {}
1305
- }
1306
- };
1307
- }
1308
- await emitter.emit("watch", {
1309
- type: "workflow-step-result",
1310
- payload: {
1311
- id: step.id,
1312
- status: "success",
1313
- output: result?.result
1314
- }
1315
- });
1316
- await emitter.emit("watch", {
1317
- type: "workflow-step-finish",
1318
- payload: {
1319
- id: step.id,
1320
- metadata: {}
1321
- }
1322
- });
1323
- return { executionContext, result: { status: "success", output: result?.result } };
1324
- }
1325
- );
1326
- Object.assign(executionContext, res.executionContext);
1327
- return {
1328
- ...res.result,
1329
- startedAt,
1330
- endedAt: Date.now(),
1331
- payload: inputData,
1332
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1333
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1334
- };
1335
- }
1336
- const stepCallId = randomUUID();
1337
- let stepRes;
1338
- try {
1339
- stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1340
- let execResults;
1341
- let suspended;
1342
- let bailed;
1343
- const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await validateStepResumeData({
1344
- resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
1345
- step
1346
- });
1347
- let resumeDataToUse;
1348
- if (timeTravelResumeData && !timeTravelResumeValidationError) {
1349
- resumeDataToUse = timeTravelResumeData;
1350
- } else if (timeTravelResumeData && timeTravelResumeValidationError) {
1351
- this.logger.warn("Time travel resume data validation failed", {
1352
- stepId: step.id,
1353
- error: timeTravelResumeValidationError.message
1354
- });
1355
- } else if (resume?.steps[0] === step.id) {
1356
- resumeDataToUse = resume?.resumePayload;
1357
- }
1358
- try {
1359
- if (validationError) {
1360
- throw validationError;
1361
- }
1362
- const retryCount = this.getOrGenerateRetryCount(step.id);
1363
- const result = await step.execute({
1364
- runId: executionContext.runId,
1365
- workflowId: executionContext.workflowId,
1366
- mastra: this.mastra,
1367
- requestContext,
1368
- retryCount,
1369
- writer: new ToolStream(
1370
- {
1371
- prefix: "workflow-step",
1372
- callId: stepCallId,
1373
- name: step.id,
1374
- runId: executionContext.runId
1375
- },
1376
- writableStream
1377
- ),
1378
- state: executionContext?.state ?? {},
1379
- setState: (state) => {
1380
- executionContext.state = state;
1381
- },
1382
- inputData,
1383
- resumeData: resumeDataToUse,
1384
- tracingContext: {
1385
- currentSpan: stepSpan
1386
- },
1387
- getInitData: () => stepResults?.input,
1388
- getStepResult: getStepResult.bind(this, stepResults),
1389
- suspend: async (suspendPayload, suspendOptions) => {
1390
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1391
- if (suspendOptions?.resumeLabel) {
1392
- const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
1393
- for (const label of resumeLabel) {
1394
- executionContext.resumeLabels[label] = {
1395
- stepId: step.id,
1396
- foreachIndex: executionContext.foreachIndex
1397
- };
1398
- }
1399
- }
1400
- suspended = { payload: suspendPayload };
1401
- },
1402
- bail: (result2) => {
1403
- bailed = { payload: result2 };
1404
- },
1405
- abort: () => {
1406
- abortController?.abort();
1407
- },
1408
- [EMITTER_SYMBOL]: emitter,
1409
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
1410
- engine: {
1411
- step: this.inngestStep
1412
- },
1413
- abortSignal: abortController.signal
1414
- });
1415
- const endedAt = Date.now();
1416
- execResults = {
1417
- status: "success",
1418
- output: result,
1419
- startedAt,
1420
- endedAt,
1421
- payload: inputData,
1422
- resumedAt: resumeDataToUse ? startedAt : void 0,
1423
- resumePayload: resumeDataToUse
1424
- };
1425
- } catch (e) {
1426
- const stepFailure = {
1427
- status: "failed",
1428
- payload: inputData,
1429
- error: e instanceof Error ? e.message : String(e),
1430
- endedAt: Date.now(),
1431
- startedAt,
1432
- resumedAt: resumeDataToUse ? startedAt : void 0,
1433
- resumePayload: resumeDataToUse
1434
- };
1435
- execResults = stepFailure;
1436
- const fallbackErrorMessage = `Step ${step.id} failed`;
1437
- stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1438
- throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1439
- cause: execResults
1440
- });
1441
- }
1442
- if (suspended) {
1443
- execResults = {
1444
- status: "suspended",
1445
- suspendPayload: suspended.payload,
1446
- ...execResults.output ? { suspendOutput: execResults.output } : {},
1447
- payload: inputData,
1448
- suspendedAt: Date.now(),
1449
- startedAt,
1450
- resumedAt: resumeDataToUse ? startedAt : void 0,
1451
- resumePayload: resumeDataToUse
1452
- };
1453
- } else if (bailed) {
1454
- execResults = {
1455
- status: "bailed",
1456
- output: bailed.payload,
1457
- payload: inputData,
1458
- endedAt: Date.now(),
1459
- startedAt
1460
- };
1461
- }
1462
- if (execResults.status === "suspended") {
1463
- await emitter.emit("watch", {
1464
- type: "workflow-step-suspended",
1465
- payload: {
1466
- id: step.id,
1467
- ...execResults
1468
- }
1469
- });
1470
- } else {
1471
- await emitter.emit("watch", {
1472
- type: "workflow-step-result",
1473
- payload: {
1474
- id: step.id,
1475
- ...execResults
1476
- }
1477
- });
1478
- await emitter.emit("watch", {
1479
- type: "workflow-step-finish",
1480
- payload: {
1481
- id: step.id,
1482
- metadata: {}
1483
- }
1484
- });
1485
- }
1486
- stepSpan?.end({ output: execResults });
1487
- return { result: execResults, executionContext, stepResults };
1488
- });
1489
- } catch (e) {
1490
- const stepFailure = e instanceof Error ? e?.cause : {
1491
- status: "failed",
1492
- error: e instanceof Error ? e.message : String(e),
1493
- payload: inputData,
1494
- startedAt,
1495
- endedAt: Date.now()
1496
- };
1497
- stepRes = {
1498
- result: stepFailure,
1499
- executionContext,
1500
- stepResults: {
1501
- ...stepResults,
1502
- [step.id]: stepFailure
1503
- }
1504
- };
1505
- }
1506
- if (disableScorers !== false && stepRes.result.status === "success") {
1507
- await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1508
- if (step.scorers) {
1509
- await this.runScorers({
1510
- scorers: step.scorers,
1511
- runId: executionContext.runId,
1512
- input: inputData,
1513
- output: stepRes.result,
1514
- workflowId: executionContext.workflowId,
1515
- stepId: step.id,
1516
- requestContext,
1517
- disableScorers,
1518
- tracingContext: { currentSpan: stepSpan }
1519
- });
1520
- }
1521
- });
1522
- }
1523
- Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1524
- executionContext.state = stepRes.executionContext.state;
1525
- return stepRes.result;
1526
- }
1527
- async persistStepUpdate({
1528
- workflowId,
1529
- runId,
1530
- stepResults,
1531
- resourceId,
1532
- executionContext,
1533
- serializedStepGraph,
1534
- workflowStatus,
1535
- result,
1536
- error
1537
- }) {
1538
- await this.inngestStep.run(
1539
- `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
1540
- async () => {
1541
- const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
1542
- if (!shouldPersistSnapshot) {
1543
- return;
1544
- }
1545
- await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1546
- workflowName: workflowId,
1547
- runId,
1548
- resourceId,
1549
- snapshot: {
1550
- runId,
1551
- status: workflowStatus,
1552
- value: executionContext.state,
1553
- context: stepResults,
1554
- activePaths: executionContext.executionPath,
1555
- activeStepsPath: executionContext.activeStepsPath,
1556
- suspendedPaths: executionContext.suspendedPaths,
1557
- resumeLabels: executionContext.resumeLabels,
1558
- waitingPaths: {},
1559
- serializedStepGraph,
1560
- result,
1561
- error,
1562
- timestamp: Date.now()
1563
- }
1564
- });
1565
- }
1566
- );
1567
- }
1568
- async executeConditional({
1569
- workflowId,
1570
- runId,
1571
- entry,
1572
- prevOutput,
1573
- stepResults,
1574
- timeTravel,
1575
- resume,
1576
- executionContext,
1577
- emitter,
1578
- abortController,
1579
- requestContext,
1580
- writableStream,
1581
- disableScorers,
1582
- tracingContext
1583
- }) {
1584
- const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1585
- type: SpanType.WORKFLOW_CONDITIONAL,
1586
- name: `conditional: '${entry.conditions.length} conditions'`,
1587
- input: prevOutput,
1588
- attributes: {
1589
- conditionCount: entry.conditions.length
1590
- },
1591
- tracingPolicy: this.options?.tracingPolicy
1592
- });
1593
- let execResults;
1594
- const truthyIndexes = (await Promise.all(
1595
- entry.conditions.map(
1596
- (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1597
- const evalSpan = conditionalSpan?.createChildSpan({
1598
- type: SpanType.WORKFLOW_CONDITIONAL_EVAL,
1599
- name: `condition: '${index}'`,
1600
- input: prevOutput,
1601
- attributes: {
1602
- conditionIndex: index
1603
- },
1604
- tracingPolicy: this.options?.tracingPolicy
1605
- });
1606
- try {
1607
- const result = await cond(
1608
- createDeprecationProxy(
1609
- {
1610
- runId,
1611
- workflowId,
1612
- mastra: this.mastra,
1613
- requestContext,
1614
- retryCount: -1,
1615
- inputData: prevOutput,
1616
- state: executionContext.state,
1617
- setState: (state) => {
1618
- executionContext.state = state;
1619
- },
1620
- tracingContext: {
1621
- currentSpan: evalSpan
1622
- },
1623
- getInitData: () => stepResults?.input,
1624
- getStepResult: getStepResult.bind(this, stepResults),
1625
- // TODO: this function shouldn't have suspend probably?
1626
- suspend: async (_suspendPayload) => {
1627
- },
1628
- bail: () => {
1629
- },
1630
- abort: () => {
1631
- abortController.abort();
1632
- },
1633
- [EMITTER_SYMBOL]: emitter,
1634
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
1635
- engine: {
1636
- step: this.inngestStep
1637
- },
1638
- abortSignal: abortController.signal,
1639
- writer: new ToolStream(
1640
- {
1641
- prefix: "workflow-step",
1642
- callId: randomUUID(),
1643
- name: "conditional",
1644
- runId
1645
- },
1646
- writableStream
1647
- )
1648
- },
1649
- {
1650
- paramName: "runCount",
1651
- deprecationMessage: runCountDeprecationMessage,
1652
- logger: this.logger
1653
- }
1654
- )
1655
- );
1656
- evalSpan?.end({
1657
- output: result,
1658
- attributes: {
1659
- result: !!result
1660
- }
1661
- });
1662
- return result ? index : null;
1663
- } catch (e) {
1664
- evalSpan?.error({
1665
- error: e instanceof Error ? e : new Error(String(e)),
1666
- attributes: {
1667
- result: false
1668
- }
1669
- });
1670
- return null;
1671
- }
1672
- })
1673
- )
1674
- )).filter((index) => index !== null);
1675
- const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
1676
- conditionalSpan?.update({
1677
- attributes: {
1678
- truthyIndexes,
1679
- selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
1680
- }
1681
- });
1682
- const results = await Promise.all(
1683
- stepsToRun.map(async (step, index) => {
1684
- const currStepResult = stepResults[step.step.id];
1685
- if (currStepResult && currStepResult.status === "success") {
1686
- return currStepResult;
1687
- }
1688
- const result = await this.executeStep({
1689
- step: step.step,
1690
- prevOutput,
1691
- stepResults,
1692
- resume,
1693
- timeTravel,
1694
- executionContext: {
1695
- workflowId,
1696
- runId,
1697
- executionPath: [...executionContext.executionPath, index],
1698
- activeStepsPath: executionContext.activeStepsPath,
1699
- suspendedPaths: executionContext.suspendedPaths,
1700
- resumeLabels: executionContext.resumeLabels,
1701
- retryConfig: executionContext.retryConfig,
1702
- state: executionContext.state
1703
- },
1704
- emitter,
1705
- abortController,
1706
- requestContext,
1707
- writableStream,
1708
- disableScorers,
1709
- tracingContext: {
1710
- currentSpan: conditionalSpan
1711
- }
1712
- });
1713
- stepResults[step.step.id] = result;
1714
- return result;
1715
- })
1716
- );
1717
- const hasFailed = results.find((result) => result.status === "failed");
1718
- const hasSuspended = results.find((result) => result.status === "suspended");
1719
- if (hasFailed) {
1720
- execResults = { status: "failed", error: hasFailed.error };
1721
- } else if (hasSuspended) {
1722
- execResults = {
1723
- status: "suspended",
1724
- suspendPayload: hasSuspended.suspendPayload,
1725
- ...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
1726
- };
1727
- } else {
1728
- execResults = {
1729
- status: "success",
1730
- output: results.reduce((acc, result, index) => {
1731
- if (result.status === "success") {
1732
- if ("step" in stepsToRun[index]) {
1733
- acc[stepsToRun[index].step.id] = result.output;
1734
- }
1735
- }
1736
- return acc;
1737
- }, {})
1738
- };
1739
- }
1740
- if (execResults.status === "failed") {
1741
- conditionalSpan?.error({
1742
- error: new Error(execResults.error)
1743
- });
1744
- } else {
1745
- conditionalSpan?.end({
1746
- output: execResults.output || execResults
1747
- });
1748
- }
1749
- return execResults;
1750
- }
1751
- };
1752
1218
 
1753
- export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
1219
+ export { InngestExecutionEngine, InngestRun, InngestWorkflow, _compatibilityCheck, createStep, init, serve };
1754
1220
  //# sourceMappingURL=index.js.map
1755
1221
  //# sourceMappingURL=index.js.map