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