@mastra/inngest 1.0.0-beta.3 → 1.0.0-beta.5

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 di = require('@mastra/core/di');
12
9
  var inngest = require('inngest');
10
+ var web = require('stream/web');
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,20 +948,17 @@ 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,
688
955
  abortController: new AbortController(),
689
956
  // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
690
957
  outputOptions,
691
- writableStream: new web.WritableStream({
692
- write(chunk) {
693
- void emitter.emit("watch", chunk).catch(() => {
694
- });
695
- }
696
- })
958
+ outputWriter: async (chunk) => {
959
+ void emitter.emit("watch", chunk).catch(() => {
960
+ });
961
+ }
697
962
  });
698
963
  await step.run(`workflow.${this.id}.finalize`, async () => {
699
964
  if (result.status === "failed") {
@@ -725,14 +990,50 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
725
990
  return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
726
991
  }
727
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 hono.serve({
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
728
1022
  function isAgent(params) {
729
1023
  return params?.component === "AGENT";
730
1024
  }
731
1025
  function isTool(params) {
732
1026
  return params instanceof tools.Tool;
733
1027
  }
1028
+ function isInngestWorkflow(params) {
1029
+ return params instanceof InngestWorkflow;
1030
+ }
734
1031
  function createStep(params, agentOptions) {
1032
+ if (isInngestWorkflow(params)) {
1033
+ return params;
1034
+ }
735
1035
  if (isAgent(params)) {
1036
+ const outputSchema = agentOptions?.structuredOutput?.schema ?? zod.z.object({ text: zod.z.string() });
736
1037
  return {
737
1038
  id: params.name,
738
1039
  description: params.getDescription(),
@@ -741,9 +1042,7 @@ function createStep(params, agentOptions) {
741
1042
  // resourceId: z.string().optional(),
742
1043
  // threadId: z.string().optional(),
743
1044
  }),
744
- outputSchema: zod.z.object({
745
- text: zod.z.string()
746
- }),
1045
+ outputSchema,
747
1046
  execute: async ({
748
1047
  inputData,
749
1048
  [_constants.EMITTER_SYMBOL]: emitter,
@@ -759,6 +1058,7 @@ function createStep(params, agentOptions) {
759
1058
  streamPromise.resolve = resolve;
760
1059
  streamPromise.reject = reject;
761
1060
  });
1061
+ let structuredResult = null;
762
1062
  const toolData = {
763
1063
  name: params.name,
764
1064
  args: inputData
@@ -772,6 +1072,10 @@ function createStep(params, agentOptions) {
772
1072
  requestContext,
773
1073
  tracingContext,
774
1074
  onFinish: (result) => {
1075
+ const resultWithObject = result;
1076
+ if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1077
+ structuredResult = resultWithObject.object;
1078
+ }
775
1079
  streamPromise.resolve(result.text);
776
1080
  void agentOptions?.onFinish?.(result);
777
1081
  },
@@ -784,6 +1088,10 @@ function createStep(params, agentOptions) {
784
1088
  requestContext,
785
1089
  tracingContext,
786
1090
  onFinish: (result) => {
1091
+ const resultWithObject = result;
1092
+ if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1093
+ structuredResult = resultWithObject.object;
1094
+ }
787
1095
  streamPromise.resolve(result.text);
788
1096
  void agentOptions?.onFinish?.(result);
789
1097
  },
@@ -817,6 +1125,9 @@ function createStep(params, agentOptions) {
817
1125
  if (abortSignal.aborted) {
818
1126
  return abort();
819
1127
  }
1128
+ if (structuredResult !== null) {
1129
+ return structuredResult;
1130
+ }
820
1131
  return {
821
1132
  text: await streamPromise.promise
822
1133
  };
@@ -906,7 +1217,8 @@ function init(inngest) {
906
1217
  inputSchema: workflow.inputSchema,
907
1218
  outputSchema: workflow.outputSchema,
908
1219
  steps: workflow.stepDefs,
909
- mastra: workflow.mastra
1220
+ mastra: workflow.mastra,
1221
+ options: workflow.options
910
1222
  });
911
1223
  wf.setStepFlow(workflow.stepGraph);
912
1224
  wf.commit();
@@ -914,856 +1226,11 @@ function init(inngest) {
914
1226
  }
915
1227
  };
916
1228
  }
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
1229
 
1764
1230
  exports.InngestExecutionEngine = InngestExecutionEngine;
1765
1231
  exports.InngestRun = InngestRun;
1766
1232
  exports.InngestWorkflow = InngestWorkflow;
1233
+ exports._compatibilityCheck = _compatibilityCheck;
1767
1234
  exports.createStep = createStep;
1768
1235
  exports.init = init;
1769
1236
  exports.serve = serve;