@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.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
- import { ReadableStream, WritableStream } from 'stream/web';
3
- import { subscribe } from '@inngest/realtime';
4
6
  import { RequestContext } from '@mastra/core/di';
5
- import { SpanType } from '@mastra/core/observability';
7
+ import { RetryAfterError, NonRetriableError } from 'inngest';
8
+ import { ReadableStream } from 'stream/web';
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, validateStepSuspendData } 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,20 +946,17 @@ 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,
686
953
  abortController: new AbortController(),
687
954
  // currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
688
955
  outputOptions,
689
- writableStream: new WritableStream({
690
- write(chunk) {
691
- void emitter.emit("watch", chunk).catch(() => {
692
- });
693
- }
694
- })
956
+ outputWriter: async (chunk) => {
957
+ void emitter.emit("watch", chunk).catch(() => {
958
+ });
959
+ }
695
960
  });
696
961
  await step.run(`workflow.${this.id}.finalize`, async () => {
697
962
  if (result.status === "failed") {
@@ -723,14 +988,50 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
723
988
  return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
724
989
  }
725
990
  };
991
+ function serve({
992
+ mastra,
993
+ inngest,
994
+ functions: userFunctions = [],
995
+ registerOptions
996
+ }) {
997
+ const wfs = mastra.listWorkflows();
998
+ const workflowFunctions = Array.from(
999
+ new Set(
1000
+ Object.values(wfs).flatMap((wf) => {
1001
+ if (wf instanceof InngestWorkflow) {
1002
+ wf.__registerMastra(mastra);
1003
+ return wf.getFunctions();
1004
+ }
1005
+ return [];
1006
+ })
1007
+ )
1008
+ );
1009
+ return serve$1({
1010
+ ...registerOptions,
1011
+ client: inngest,
1012
+ functions: [...workflowFunctions, ...userFunctions]
1013
+ });
1014
+ }
1015
+
1016
+ // src/types.ts
1017
+ var _compatibilityCheck = true;
1018
+
1019
+ // src/index.ts
726
1020
  function isAgent(params) {
727
1021
  return params?.component === "AGENT";
728
1022
  }
729
1023
  function isTool(params) {
730
1024
  return params instanceof Tool;
731
1025
  }
1026
+ function isInngestWorkflow(params) {
1027
+ return params instanceof InngestWorkflow;
1028
+ }
732
1029
  function createStep(params, agentOptions) {
1030
+ if (isInngestWorkflow(params)) {
1031
+ return params;
1032
+ }
733
1033
  if (isAgent(params)) {
1034
+ const outputSchema = agentOptions?.structuredOutput?.schema ?? z.object({ text: z.string() });
734
1035
  return {
735
1036
  id: params.name,
736
1037
  description: params.getDescription(),
@@ -739,9 +1040,7 @@ function createStep(params, agentOptions) {
739
1040
  // resourceId: z.string().optional(),
740
1041
  // threadId: z.string().optional(),
741
1042
  }),
742
- outputSchema: z.object({
743
- text: z.string()
744
- }),
1043
+ outputSchema,
745
1044
  execute: async ({
746
1045
  inputData,
747
1046
  [EMITTER_SYMBOL]: emitter,
@@ -757,6 +1056,7 @@ function createStep(params, agentOptions) {
757
1056
  streamPromise.resolve = resolve;
758
1057
  streamPromise.reject = reject;
759
1058
  });
1059
+ let structuredResult = null;
760
1060
  const toolData = {
761
1061
  name: params.name,
762
1062
  args: inputData
@@ -770,6 +1070,10 @@ function createStep(params, agentOptions) {
770
1070
  requestContext,
771
1071
  tracingContext,
772
1072
  onFinish: (result) => {
1073
+ const resultWithObject = result;
1074
+ if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1075
+ structuredResult = resultWithObject.object;
1076
+ }
773
1077
  streamPromise.resolve(result.text);
774
1078
  void agentOptions?.onFinish?.(result);
775
1079
  },
@@ -782,6 +1086,10 @@ function createStep(params, agentOptions) {
782
1086
  requestContext,
783
1087
  tracingContext,
784
1088
  onFinish: (result) => {
1089
+ const resultWithObject = result;
1090
+ if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
1091
+ structuredResult = resultWithObject.object;
1092
+ }
785
1093
  streamPromise.resolve(result.text);
786
1094
  void agentOptions?.onFinish?.(result);
787
1095
  },
@@ -815,6 +1123,9 @@ function createStep(params, agentOptions) {
815
1123
  if (abortSignal.aborted) {
816
1124
  return abort();
817
1125
  }
1126
+ if (structuredResult !== null) {
1127
+ return structuredResult;
1128
+ }
818
1129
  return {
819
1130
  text: await streamPromise.promise
820
1131
  };
@@ -904,7 +1215,8 @@ function init(inngest) {
904
1215
  inputSchema: workflow.inputSchema,
905
1216
  outputSchema: workflow.outputSchema,
906
1217
  steps: workflow.stepDefs,
907
- mastra: workflow.mastra
1218
+ mastra: workflow.mastra,
1219
+ options: workflow.options
908
1220
  });
909
1221
  wf.setStepFlow(workflow.stepGraph);
910
1222
  wf.commit();
@@ -912,853 +1224,7 @@ function init(inngest) {
912
1224
  }
913
1225
  };
914
1226
  }
915
- var InngestExecutionEngine = class extends DefaultExecutionEngine {
916
- inngestStep;
917
- inngestAttempts;
918
- constructor(mastra, inngestStep, inngestAttempts = 0, options) {
919
- super({ mastra, options });
920
- this.inngestStep = inngestStep;
921
- this.inngestAttempts = inngestAttempts;
922
- }
923
- async fmtReturnValue(emitter, stepResults, lastOutput, error) {
924
- const base = {
925
- status: lastOutput.status,
926
- steps: stepResults
927
- };
928
- if (lastOutput.status === "success") {
929
- base.result = lastOutput.output;
930
- } else if (lastOutput.status === "failed") {
931
- base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
932
- } else if (lastOutput.status === "suspended") {
933
- const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
934
- if (stepResult?.status === "suspended") {
935
- const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
936
- return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
937
- }
938
- return [];
939
- });
940
- base.suspended = suspendedStepIds;
941
- }
942
- return base;
943
- }
944
- // async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
945
- // await this.inngestStep.sleep(id, duration);
946
- // }
947
- async executeSleep({
948
- workflowId,
949
- runId,
950
- entry,
951
- prevOutput,
952
- stepResults,
953
- emitter,
954
- abortController,
955
- requestContext,
956
- executionContext,
957
- writableStream,
958
- tracingContext
959
- }) {
960
- let { duration, fn } = entry;
961
- const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
962
- type: SpanType.WORKFLOW_SLEEP,
963
- name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
964
- attributes: {
965
- durationMs: duration,
966
- sleepType: fn ? "dynamic" : "fixed"
967
- },
968
- tracingPolicy: this.options?.tracingPolicy
969
- });
970
- if (fn) {
971
- const stepCallId = randomUUID();
972
- duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
973
- return await fn(
974
- createDeprecationProxy(
975
- {
976
- runId,
977
- workflowId,
978
- mastra: this.mastra,
979
- requestContext,
980
- inputData: prevOutput,
981
- state: executionContext.state,
982
- setState: (state) => {
983
- executionContext.state = state;
984
- },
985
- retryCount: -1,
986
- tracingContext: {
987
- currentSpan: sleepSpan
988
- },
989
- getInitData: () => stepResults?.input,
990
- getStepResult: getStepResult.bind(this, stepResults),
991
- // TODO: this function shouldn't have suspend probably?
992
- suspend: async (_suspendPayload) => {
993
- },
994
- bail: () => {
995
- },
996
- abort: () => {
997
- abortController?.abort();
998
- },
999
- [EMITTER_SYMBOL]: emitter,
1000
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
1001
- engine: { step: this.inngestStep },
1002
- abortSignal: abortController?.signal,
1003
- writer: new ToolStream(
1004
- {
1005
- prefix: "workflow-step",
1006
- callId: stepCallId,
1007
- name: "sleep",
1008
- runId
1009
- },
1010
- writableStream
1011
- )
1012
- },
1013
- {
1014
- paramName: "runCount",
1015
- deprecationMessage: runCountDeprecationMessage,
1016
- logger: this.logger
1017
- }
1018
- )
1019
- );
1020
- });
1021
- sleepSpan?.update({
1022
- attributes: {
1023
- durationMs: duration
1024
- }
1025
- });
1026
- }
1027
- try {
1028
- await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
1029
- sleepSpan?.end();
1030
- } catch (e) {
1031
- sleepSpan?.error({ error: e });
1032
- throw e;
1033
- }
1034
- }
1035
- async executeSleepUntil({
1036
- workflowId,
1037
- runId,
1038
- entry,
1039
- prevOutput,
1040
- stepResults,
1041
- emitter,
1042
- abortController,
1043
- requestContext,
1044
- executionContext,
1045
- writableStream,
1046
- tracingContext
1047
- }) {
1048
- let { date, fn } = entry;
1049
- const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
1050
- type: SpanType.WORKFLOW_SLEEP,
1051
- name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
1052
- attributes: {
1053
- untilDate: date,
1054
- durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
1055
- sleepType: fn ? "dynamic" : "fixed"
1056
- },
1057
- tracingPolicy: this.options?.tracingPolicy
1058
- });
1059
- if (fn) {
1060
- date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
1061
- const stepCallId = randomUUID();
1062
- return await fn(
1063
- createDeprecationProxy(
1064
- {
1065
- runId,
1066
- workflowId,
1067
- mastra: this.mastra,
1068
- requestContext,
1069
- inputData: prevOutput,
1070
- state: executionContext.state,
1071
- setState: (state) => {
1072
- executionContext.state = state;
1073
- },
1074
- retryCount: -1,
1075
- tracingContext: {
1076
- currentSpan: sleepUntilSpan
1077
- },
1078
- getInitData: () => stepResults?.input,
1079
- getStepResult: getStepResult.bind(this, stepResults),
1080
- // TODO: this function shouldn't have suspend probably?
1081
- suspend: async (_suspendPayload) => {
1082
- },
1083
- bail: () => {
1084
- },
1085
- abort: () => {
1086
- abortController?.abort();
1087
- },
1088
- [EMITTER_SYMBOL]: emitter,
1089
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
1090
- engine: { step: this.inngestStep },
1091
- abortSignal: abortController?.signal,
1092
- writer: new ToolStream(
1093
- {
1094
- prefix: "workflow-step",
1095
- callId: stepCallId,
1096
- name: "sleep",
1097
- runId
1098
- },
1099
- writableStream
1100
- )
1101
- },
1102
- {
1103
- paramName: "runCount",
1104
- deprecationMessage: runCountDeprecationMessage,
1105
- logger: this.logger
1106
- }
1107
- )
1108
- );
1109
- });
1110
- if (date && !(date instanceof Date)) {
1111
- date = new Date(date);
1112
- }
1113
- const time = !date ? 0 : date.getTime() - Date.now();
1114
- sleepUntilSpan?.update({
1115
- attributes: {
1116
- durationMs: Math.max(0, time)
1117
- }
1118
- });
1119
- }
1120
- if (!(date instanceof Date)) {
1121
- sleepUntilSpan?.end();
1122
- return;
1123
- }
1124
- try {
1125
- await this.inngestStep.sleepUntil(entry.id, date);
1126
- sleepUntilSpan?.end();
1127
- } catch (e) {
1128
- sleepUntilSpan?.error({ error: e });
1129
- throw e;
1130
- }
1131
- }
1132
- async executeStep({
1133
- step,
1134
- stepResults,
1135
- executionContext,
1136
- resume,
1137
- timeTravel,
1138
- prevOutput,
1139
- emitter,
1140
- abortController,
1141
- requestContext,
1142
- tracingContext,
1143
- writableStream,
1144
- disableScorers
1145
- }) {
1146
- const stepSpan = tracingContext?.currentSpan?.createChildSpan({
1147
- name: `workflow step: '${step.id}'`,
1148
- type: SpanType.WORKFLOW_STEP,
1149
- input: prevOutput,
1150
- attributes: {
1151
- stepId: step.id
1152
- },
1153
- tracingPolicy: this.options?.tracingPolicy
1154
- });
1155
- const { inputData, validationError } = await validateStepInput({
1156
- prevOutput,
1157
- step,
1158
- validateInputs: this.options?.validateInputs ?? true
1159
- });
1160
- const startedAt = await this.inngestStep.run(
1161
- `workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
1162
- async () => {
1163
- const startedAt2 = Date.now();
1164
- await emitter.emit("watch", {
1165
- type: "workflow-step-start",
1166
- payload: {
1167
- id: step.id,
1168
- status: "running",
1169
- payload: inputData,
1170
- startedAt: startedAt2
1171
- }
1172
- });
1173
- return startedAt2;
1174
- }
1175
- );
1176
- if (step instanceof InngestWorkflow) {
1177
- const isResume = !!resume?.steps?.length;
1178
- let result;
1179
- let runId;
1180
- const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
1181
- try {
1182
- if (isResume) {
1183
- runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
1184
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1185
- workflowName: step.id,
1186
- runId
1187
- });
1188
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1189
- function: step.getFunction(),
1190
- data: {
1191
- inputData,
1192
- initialState: executionContext.state ?? snapshot?.value ?? {},
1193
- runId,
1194
- resume: {
1195
- runId,
1196
- steps: resume.steps.slice(1),
1197
- stepResults: snapshot?.context,
1198
- resumePayload: resume.resumePayload,
1199
- resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
1200
- },
1201
- outputOptions: { includeState: true }
1202
- }
1203
- });
1204
- result = invokeResp.result;
1205
- runId = invokeResp.runId;
1206
- executionContext.state = invokeResp.result.state;
1207
- } else if (isTimeTravel) {
1208
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
1209
- workflowName: step.id,
1210
- runId: executionContext.runId
1211
- }) ?? { context: {} };
1212
- const timeTravelParams = createTimeTravelExecutionParams({
1213
- steps: timeTravel.steps.slice(1),
1214
- inputData: timeTravel.inputData,
1215
- resumeData: timeTravel.resumeData,
1216
- context: timeTravel.nestedStepResults?.[step.id] ?? {},
1217
- nestedStepsContext: timeTravel.nestedStepResults ?? {},
1218
- snapshot,
1219
- graph: step.buildExecutionGraph()
1220
- });
1221
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1222
- function: step.getFunction(),
1223
- data: {
1224
- timeTravel: timeTravelParams,
1225
- initialState: executionContext.state ?? {},
1226
- runId: executionContext.runId,
1227
- outputOptions: { includeState: true }
1228
- }
1229
- });
1230
- result = invokeResp.result;
1231
- runId = invokeResp.runId;
1232
- executionContext.state = invokeResp.result.state;
1233
- } else {
1234
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
1235
- function: step.getFunction(),
1236
- data: {
1237
- inputData,
1238
- initialState: executionContext.state ?? {},
1239
- outputOptions: { includeState: true }
1240
- }
1241
- });
1242
- result = invokeResp.result;
1243
- runId = invokeResp.runId;
1244
- executionContext.state = invokeResp.result.state;
1245
- }
1246
- } catch (e) {
1247
- const errorCause = e?.cause;
1248
- if (errorCause && typeof errorCause === "object") {
1249
- result = errorCause;
1250
- runId = errorCause.runId || randomUUID();
1251
- } else {
1252
- runId = randomUUID();
1253
- result = {
1254
- status: "failed",
1255
- error: e instanceof Error ? e : new Error(String(e)),
1256
- steps: {},
1257
- input: inputData
1258
- };
1259
- }
1260
- }
1261
- const res = await this.inngestStep.run(
1262
- `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
1263
- async () => {
1264
- if (result.status === "failed") {
1265
- await emitter.emit("watch", {
1266
- type: "workflow-step-result",
1267
- payload: {
1268
- id: step.id,
1269
- status: "failed",
1270
- error: result?.error,
1271
- payload: prevOutput
1272
- }
1273
- });
1274
- return { executionContext, result: { status: "failed", error: result?.error } };
1275
- } else if (result.status === "suspended") {
1276
- const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
1277
- const stepRes2 = stepResult;
1278
- return stepRes2?.status === "suspended";
1279
- });
1280
- for (const [stepName, stepResult] of suspendedSteps) {
1281
- const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
1282
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1283
- await emitter.emit("watch", {
1284
- type: "workflow-step-suspended",
1285
- payload: {
1286
- id: step.id,
1287
- status: "suspended"
1288
- }
1289
- });
1290
- return {
1291
- executionContext,
1292
- result: {
1293
- status: "suspended",
1294
- payload: stepResult.payload,
1295
- suspendPayload: {
1296
- ...stepResult?.suspendPayload,
1297
- __workflow_meta: { runId, path: suspendPath }
1298
- }
1299
- }
1300
- };
1301
- }
1302
- return {
1303
- executionContext,
1304
- result: {
1305
- status: "suspended",
1306
- payload: {}
1307
- }
1308
- };
1309
- }
1310
- await emitter.emit("watch", {
1311
- type: "workflow-step-result",
1312
- payload: {
1313
- id: step.id,
1314
- status: "success",
1315
- output: result?.result
1316
- }
1317
- });
1318
- await emitter.emit("watch", {
1319
- type: "workflow-step-finish",
1320
- payload: {
1321
- id: step.id,
1322
- metadata: {}
1323
- }
1324
- });
1325
- return { executionContext, result: { status: "success", output: result?.result } };
1326
- }
1327
- );
1328
- Object.assign(executionContext, res.executionContext);
1329
- return {
1330
- ...res.result,
1331
- startedAt,
1332
- endedAt: Date.now(),
1333
- payload: inputData,
1334
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1335
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1336
- };
1337
- }
1338
- const stepCallId = randomUUID();
1339
- let stepRes;
1340
- try {
1341
- stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1342
- let execResults;
1343
- let suspended;
1344
- let bailed;
1345
- const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await validateStepResumeData({
1346
- resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
1347
- step
1348
- });
1349
- let resumeDataToUse;
1350
- if (timeTravelResumeData && !timeTravelResumeValidationError) {
1351
- resumeDataToUse = timeTravelResumeData;
1352
- } else if (timeTravelResumeData && timeTravelResumeValidationError) {
1353
- this.logger.warn("Time travel resume data validation failed", {
1354
- stepId: step.id,
1355
- error: timeTravelResumeValidationError.message
1356
- });
1357
- } else if (resume?.steps[0] === step.id) {
1358
- resumeDataToUse = resume?.resumePayload;
1359
- }
1360
- try {
1361
- if (validationError) {
1362
- throw validationError;
1363
- }
1364
- const retryCount = this.getOrGenerateRetryCount(step.id);
1365
- const result = await step.execute({
1366
- runId: executionContext.runId,
1367
- workflowId: executionContext.workflowId,
1368
- mastra: this.mastra,
1369
- requestContext,
1370
- retryCount,
1371
- writer: new ToolStream(
1372
- {
1373
- prefix: "workflow-step",
1374
- callId: stepCallId,
1375
- name: step.id,
1376
- runId: executionContext.runId
1377
- },
1378
- writableStream
1379
- ),
1380
- state: executionContext?.state ?? {},
1381
- setState: (state) => {
1382
- executionContext.state = state;
1383
- },
1384
- inputData,
1385
- resumeData: resumeDataToUse,
1386
- tracingContext: {
1387
- currentSpan: stepSpan
1388
- },
1389
- getInitData: () => stepResults?.input,
1390
- getStepResult: getStepResult.bind(this, stepResults),
1391
- suspend: async (suspendPayload, suspendOptions) => {
1392
- const { suspendData, validationError: validationError2 } = await validateStepSuspendData({
1393
- suspendData: suspendPayload,
1394
- step
1395
- });
1396
- if (validationError2) {
1397
- throw validationError2;
1398
- }
1399
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1400
- if (suspendOptions?.resumeLabel) {
1401
- const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
1402
- for (const label of resumeLabel) {
1403
- executionContext.resumeLabels[label] = {
1404
- stepId: step.id,
1405
- foreachIndex: executionContext.foreachIndex
1406
- };
1407
- }
1408
- }
1409
- suspended = { payload: suspendData };
1410
- },
1411
- bail: (result2) => {
1412
- bailed = { payload: result2 };
1413
- },
1414
- abort: () => {
1415
- abortController?.abort();
1416
- },
1417
- [EMITTER_SYMBOL]: emitter,
1418
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
1419
- engine: {
1420
- step: this.inngestStep
1421
- },
1422
- abortSignal: abortController.signal
1423
- });
1424
- const endedAt = Date.now();
1425
- execResults = {
1426
- status: "success",
1427
- output: result,
1428
- startedAt,
1429
- endedAt,
1430
- payload: inputData,
1431
- resumedAt: resumeDataToUse ? startedAt : void 0,
1432
- resumePayload: resumeDataToUse
1433
- };
1434
- } catch (e) {
1435
- const stepFailure = {
1436
- status: "failed",
1437
- payload: inputData,
1438
- error: e instanceof Error ? e.message : String(e),
1439
- endedAt: Date.now(),
1440
- startedAt,
1441
- resumedAt: resumeDataToUse ? startedAt : void 0,
1442
- resumePayload: resumeDataToUse
1443
- };
1444
- execResults = stepFailure;
1445
- const fallbackErrorMessage = `Step ${step.id} failed`;
1446
- stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1447
- throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1448
- cause: execResults
1449
- });
1450
- }
1451
- if (suspended) {
1452
- execResults = {
1453
- status: "suspended",
1454
- suspendPayload: suspended.payload,
1455
- ...execResults.output ? { suspendOutput: execResults.output } : {},
1456
- payload: inputData,
1457
- suspendedAt: Date.now(),
1458
- startedAt,
1459
- resumedAt: resumeDataToUse ? startedAt : void 0,
1460
- resumePayload: resumeDataToUse
1461
- };
1462
- } else if (bailed) {
1463
- execResults = {
1464
- status: "bailed",
1465
- output: bailed.payload,
1466
- payload: inputData,
1467
- endedAt: Date.now(),
1468
- startedAt
1469
- };
1470
- }
1471
- if (execResults.status === "suspended") {
1472
- await emitter.emit("watch", {
1473
- type: "workflow-step-suspended",
1474
- payload: {
1475
- id: step.id,
1476
- ...execResults
1477
- }
1478
- });
1479
- } else {
1480
- await emitter.emit("watch", {
1481
- type: "workflow-step-result",
1482
- payload: {
1483
- id: step.id,
1484
- ...execResults
1485
- }
1486
- });
1487
- await emitter.emit("watch", {
1488
- type: "workflow-step-finish",
1489
- payload: {
1490
- id: step.id,
1491
- metadata: {}
1492
- }
1493
- });
1494
- }
1495
- stepSpan?.end({ output: execResults });
1496
- return { result: execResults, executionContext, stepResults };
1497
- });
1498
- } catch (e) {
1499
- const stepFailure = e instanceof Error ? e?.cause : {
1500
- status: "failed",
1501
- error: e instanceof Error ? e.message : String(e),
1502
- payload: inputData,
1503
- startedAt,
1504
- endedAt: Date.now()
1505
- };
1506
- stepRes = {
1507
- result: stepFailure,
1508
- executionContext,
1509
- stepResults: {
1510
- ...stepResults,
1511
- [step.id]: stepFailure
1512
- }
1513
- };
1514
- }
1515
- if (disableScorers !== false && stepRes.result.status === "success") {
1516
- await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1517
- if (step.scorers) {
1518
- await this.runScorers({
1519
- scorers: step.scorers,
1520
- runId: executionContext.runId,
1521
- input: inputData,
1522
- output: stepRes.result,
1523
- workflowId: executionContext.workflowId,
1524
- stepId: step.id,
1525
- requestContext,
1526
- disableScorers,
1527
- tracingContext: { currentSpan: stepSpan }
1528
- });
1529
- }
1530
- });
1531
- }
1532
- Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1533
- executionContext.state = stepRes.executionContext.state;
1534
- return stepRes.result;
1535
- }
1536
- async persistStepUpdate({
1537
- workflowId,
1538
- runId,
1539
- stepResults,
1540
- resourceId,
1541
- executionContext,
1542
- serializedStepGraph,
1543
- workflowStatus,
1544
- result,
1545
- error
1546
- }) {
1547
- await this.inngestStep.run(
1548
- `workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
1549
- async () => {
1550
- const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
1551
- if (!shouldPersistSnapshot) {
1552
- return;
1553
- }
1554
- await this.mastra?.getStorage()?.persistWorkflowSnapshot({
1555
- workflowName: workflowId,
1556
- runId,
1557
- resourceId,
1558
- snapshot: {
1559
- runId,
1560
- status: workflowStatus,
1561
- value: executionContext.state,
1562
- context: stepResults,
1563
- activePaths: executionContext.executionPath,
1564
- activeStepsPath: executionContext.activeStepsPath,
1565
- suspendedPaths: executionContext.suspendedPaths,
1566
- resumeLabels: executionContext.resumeLabels,
1567
- waitingPaths: {},
1568
- serializedStepGraph,
1569
- result,
1570
- error,
1571
- timestamp: Date.now()
1572
- }
1573
- });
1574
- }
1575
- );
1576
- }
1577
- async executeConditional({
1578
- workflowId,
1579
- runId,
1580
- entry,
1581
- prevOutput,
1582
- stepResults,
1583
- timeTravel,
1584
- resume,
1585
- executionContext,
1586
- emitter,
1587
- abortController,
1588
- requestContext,
1589
- writableStream,
1590
- disableScorers,
1591
- tracingContext
1592
- }) {
1593
- const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
1594
- type: SpanType.WORKFLOW_CONDITIONAL,
1595
- name: `conditional: '${entry.conditions.length} conditions'`,
1596
- input: prevOutput,
1597
- attributes: {
1598
- conditionCount: entry.conditions.length
1599
- },
1600
- tracingPolicy: this.options?.tracingPolicy
1601
- });
1602
- let execResults;
1603
- const truthyIndexes = (await Promise.all(
1604
- entry.conditions.map(
1605
- (cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
1606
- const evalSpan = conditionalSpan?.createChildSpan({
1607
- type: SpanType.WORKFLOW_CONDITIONAL_EVAL,
1608
- name: `condition: '${index}'`,
1609
- input: prevOutput,
1610
- attributes: {
1611
- conditionIndex: index
1612
- },
1613
- tracingPolicy: this.options?.tracingPolicy
1614
- });
1615
- try {
1616
- const result = await cond(
1617
- createDeprecationProxy(
1618
- {
1619
- runId,
1620
- workflowId,
1621
- mastra: this.mastra,
1622
- requestContext,
1623
- retryCount: -1,
1624
- inputData: prevOutput,
1625
- state: executionContext.state,
1626
- setState: (state) => {
1627
- executionContext.state = state;
1628
- },
1629
- tracingContext: {
1630
- currentSpan: evalSpan
1631
- },
1632
- getInitData: () => stepResults?.input,
1633
- getStepResult: getStepResult.bind(this, stepResults),
1634
- // TODO: this function shouldn't have suspend probably?
1635
- suspend: async (_suspendPayload) => {
1636
- },
1637
- bail: () => {
1638
- },
1639
- abort: () => {
1640
- abortController.abort();
1641
- },
1642
- [EMITTER_SYMBOL]: emitter,
1643
- [STREAM_FORMAT_SYMBOL]: executionContext.format,
1644
- engine: {
1645
- step: this.inngestStep
1646
- },
1647
- abortSignal: abortController.signal,
1648
- writer: new ToolStream(
1649
- {
1650
- prefix: "workflow-step",
1651
- callId: randomUUID(),
1652
- name: "conditional",
1653
- runId
1654
- },
1655
- writableStream
1656
- )
1657
- },
1658
- {
1659
- paramName: "runCount",
1660
- deprecationMessage: runCountDeprecationMessage,
1661
- logger: this.logger
1662
- }
1663
- )
1664
- );
1665
- evalSpan?.end({
1666
- output: result,
1667
- attributes: {
1668
- result: !!result
1669
- }
1670
- });
1671
- return result ? index : null;
1672
- } catch (e) {
1673
- evalSpan?.error({
1674
- error: e instanceof Error ? e : new Error(String(e)),
1675
- attributes: {
1676
- result: false
1677
- }
1678
- });
1679
- return null;
1680
- }
1681
- })
1682
- )
1683
- )).filter((index) => index !== null);
1684
- const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
1685
- conditionalSpan?.update({
1686
- attributes: {
1687
- truthyIndexes,
1688
- selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
1689
- }
1690
- });
1691
- const results = await Promise.all(
1692
- stepsToRun.map(async (step, index) => {
1693
- const currStepResult = stepResults[step.step.id];
1694
- if (currStepResult && currStepResult.status === "success") {
1695
- return currStepResult;
1696
- }
1697
- const result = await this.executeStep({
1698
- step: step.step,
1699
- prevOutput,
1700
- stepResults,
1701
- resume,
1702
- timeTravel,
1703
- executionContext: {
1704
- workflowId,
1705
- runId,
1706
- executionPath: [...executionContext.executionPath, index],
1707
- activeStepsPath: executionContext.activeStepsPath,
1708
- suspendedPaths: executionContext.suspendedPaths,
1709
- resumeLabels: executionContext.resumeLabels,
1710
- retryConfig: executionContext.retryConfig,
1711
- state: executionContext.state
1712
- },
1713
- emitter,
1714
- abortController,
1715
- requestContext,
1716
- writableStream,
1717
- disableScorers,
1718
- tracingContext: {
1719
- currentSpan: conditionalSpan
1720
- }
1721
- });
1722
- stepResults[step.step.id] = result;
1723
- return result;
1724
- })
1725
- );
1726
- const hasFailed = results.find((result) => result.status === "failed");
1727
- const hasSuspended = results.find((result) => result.status === "suspended");
1728
- if (hasFailed) {
1729
- execResults = { status: "failed", error: hasFailed.error };
1730
- } else if (hasSuspended) {
1731
- execResults = {
1732
- status: "suspended",
1733
- suspendPayload: hasSuspended.suspendPayload,
1734
- ...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
1735
- };
1736
- } else {
1737
- execResults = {
1738
- status: "success",
1739
- output: results.reduce((acc, result, index) => {
1740
- if (result.status === "success") {
1741
- if ("step" in stepsToRun[index]) {
1742
- acc[stepsToRun[index].step.id] = result.output;
1743
- }
1744
- }
1745
- return acc;
1746
- }, {})
1747
- };
1748
- }
1749
- if (execResults.status === "failed") {
1750
- conditionalSpan?.error({
1751
- error: new Error(execResults.error)
1752
- });
1753
- } else {
1754
- conditionalSpan?.end({
1755
- output: execResults.output || execResults
1756
- });
1757
- }
1758
- return execResults;
1759
- }
1760
- };
1761
1227
 
1762
- export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
1228
+ export { InngestExecutionEngine, InngestRun, InngestWorkflow, _compatibilityCheck, createStep, init, serve };
1763
1229
  //# sourceMappingURL=index.js.map
1764
1230
  //# sourceMappingURL=index.js.map