@mastra/inngest 0.15.0 → 0.15.1-alpha.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # @mastra/inngest
2
2
 
3
+ ## 0.15.1-alpha.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Mutable shared workflow run state ([#8545](https://github.com/mastra-ai/mastra/pull/8545))
8
+
9
+ - Updated dependencies [[`c621613`](https://github.com/mastra-ai/mastra/commit/c621613069173c69eb2c3ef19a5308894c6549f0), [`12b1189`](https://github.com/mastra-ai/mastra/commit/12b118942445e4de0dd916c593e33ec78dc3bc73), [`4783b30`](https://github.com/mastra-ai/mastra/commit/4783b3063efea887825514b783ba27f67912c26d), [`076b092`](https://github.com/mastra-ai/mastra/commit/076b0924902ff0f49d5712d2df24c4cca683713f), [`2aee9e7`](https://github.com/mastra-ai/mastra/commit/2aee9e7d188b8b256a4ddc203ccefb366b4867fa), [`c582906`](https://github.com/mastra-ai/mastra/commit/c5829065a346260f96c4beb8af131b94804ae3ad), [`fa2eb96`](https://github.com/mastra-ai/mastra/commit/fa2eb96af16c7d433891a73932764960d3235c1d), [`4783b30`](https://github.com/mastra-ai/mastra/commit/4783b3063efea887825514b783ba27f67912c26d), [`a739d0c`](https://github.com/mastra-ai/mastra/commit/a739d0c8b37cd89569e04a6ca0827083c6167e19), [`603e927`](https://github.com/mastra-ai/mastra/commit/603e9279db8bf8a46caf83881c6b7389ccffff7e), [`cd45982`](https://github.com/mastra-ai/mastra/commit/cd4598291cda128a88738734ae6cbef076ebdebd), [`874f74d`](https://github.com/mastra-ai/mastra/commit/874f74da4b1acf6517f18132d035612c3ecc394a), [`0baf2ba`](https://github.com/mastra-ai/mastra/commit/0baf2bab8420277072ef1f95df5ea7b0a2f61fe7), [`26e968d`](https://github.com/mastra-ai/mastra/commit/26e968db2171ded9e4d47aa1b4f19e1e771158d0), [`cbd3fb6`](https://github.com/mastra-ai/mastra/commit/cbd3fb65adb03a7c0df193cb998aed5ac56675ee)]:
10
+ - @mastra/core@0.20.1-alpha.1
11
+
12
+ ## 0.15.1-alpha.0
13
+
14
+ ### Patch Changes
15
+
16
+ - Handle workflow run failures (fix #8130) ([#8370](https://github.com/mastra-ai/mastra/pull/8370))
17
+
18
+ - Updated dependencies [[`10e633a`](https://github.com/mastra-ai/mastra/commit/10e633a07d333466d9734c97acfc3dbf757ad2d0)]:
19
+ - @mastra/core@0.20.1-alpha.0
20
+
3
21
  ## 0.15.0
4
22
 
5
23
  ### Minor Changes
package/dist/index.cjs CHANGED
@@ -7,6 +7,7 @@ var di = require('@mastra/core/di');
7
7
  var tools = require('@mastra/core/tools');
8
8
  var workflows = require('@mastra/core/workflows');
9
9
  var _constants = require('@mastra/core/workflows/_constants');
10
+ var inngest = require('inngest');
10
11
  var hono = require('inngest/hono');
11
12
  var zod = require('zod');
12
13
 
@@ -60,8 +61,15 @@ var InngestRun = class extends workflows.Run {
60
61
  await new Promise((resolve) => setTimeout(resolve, 1e3));
61
62
  runs = await this.getRuns(eventId);
62
63
  if (runs?.[0]?.status === "Failed") {
63
- throw new Error(`Function run ${runs?.[0]?.status}`);
64
- } else if (runs?.[0]?.status === "Cancelled") {
64
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
65
+ workflowName: this.workflowId,
66
+ runId: this.runId
67
+ });
68
+ return {
69
+ output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
70
+ };
71
+ }
72
+ if (runs?.[0]?.status === "Cancelled") {
65
73
  const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
66
74
  workflowName: this.workflowId,
67
75
  runId: this.runId
@@ -101,7 +109,8 @@ var InngestRun = class extends workflows.Run {
101
109
  }
102
110
  }
103
111
  async start({
104
- inputData
112
+ inputData,
113
+ initialState
105
114
  }) {
106
115
  await this.#mastra.getStorage()?.persistWorkflowSnapshot({
107
116
  workflowName: this.workflowId,
@@ -120,10 +129,12 @@ var InngestRun = class extends workflows.Run {
120
129
  }
121
130
  });
122
131
  const inputDataToUse = await this._validateInput(inputData);
132
+ const initialStateToUse = await this._validateInitialState(initialState ?? {});
123
133
  const eventOutput = await this.inngest.send({
124
134
  name: `workflow.${this.workflowId}`,
125
135
  data: {
126
136
  inputData: inputDataToUse,
137
+ initialState: initialStateToUse,
127
138
  runId: this.runId,
128
139
  resourceId: this.resourceId
129
140
  }
@@ -167,6 +178,7 @@ var InngestRun = class extends workflows.Run {
167
178
  name: `workflow.${this.workflowId}`,
168
179
  data: {
169
180
  inputData: resumeDataToUse,
181
+ initialState: snapshot?.value ?? {},
170
182
  runId: this.runId,
171
183
  workflowId: this.workflowId,
172
184
  stepResults: snapshot?.context,
@@ -365,7 +377,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
365
377
  },
366
378
  { event: `workflow.${this.id}` },
367
379
  async ({ event, step, attempt, publish }) => {
368
- let { inputData, runId, resourceId, resume } = event.data;
380
+ let { inputData, initialState, runId, resourceId, resume, outputOptions } = event.data;
369
381
  if (!runId) {
370
382
  runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
371
383
  return crypto.randomUUID();
@@ -401,14 +413,24 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
401
413
  graph: this.executionGraph,
402
414
  serializedStepGraph: this.serializedStepGraph,
403
415
  input: inputData,
416
+ initialState,
404
417
  emitter,
405
418
  retryConfig: this.retryConfig,
406
419
  runtimeContext: new di.RuntimeContext(),
407
420
  // TODO
408
421
  resume,
409
422
  abortController: new AbortController(),
410
- currentSpan: void 0
423
+ currentSpan: void 0,
411
424
  // TODO: Pass actual parent AI span from workflow execution context
425
+ outputOptions
426
+ });
427
+ await step.run(`workflow.${this.id}.finalize`, async () => {
428
+ if (result.status === "failed") {
429
+ throw new inngest.NonRetriableError(`Workflow failed`, {
430
+ cause: result
431
+ });
432
+ }
433
+ return result;
412
434
  });
413
435
  return { result, runId };
414
436
  }
@@ -560,7 +582,10 @@ function createStep(params) {
560
582
  function init(inngest) {
561
583
  return {
562
584
  createWorkflow(params) {
563
- return new InngestWorkflow(params, inngest);
585
+ return new InngestWorkflow(
586
+ params,
587
+ inngest
588
+ );
564
589
  },
565
590
  createStep,
566
591
  cloneStep(step, opts) {
@@ -569,6 +594,9 @@ function init(inngest) {
569
594
  description: step.description,
570
595
  inputSchema: step.inputSchema,
571
596
  outputSchema: step.outputSchema,
597
+ resumeSchema: step.resumeSchema,
598
+ suspendSchema: step.suspendSchema,
599
+ stateSchema: step.stateSchema,
572
600
  execute: step.execute,
573
601
  component: step.component
574
602
  };
@@ -654,7 +682,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
654
682
  });
655
683
  const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
656
684
  if (stepResult?.status === "suspended") {
657
- const nestedPath = stepResult?.payload?.__workflow_meta?.path;
685
+ const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
658
686
  return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
659
687
  }
660
688
  return [];
@@ -699,6 +727,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
699
727
  mastra: this.mastra,
700
728
  runtimeContext,
701
729
  inputData: prevOutput,
730
+ state: executionContext.state,
731
+ setState: (state) => {
732
+ executionContext.state = state;
733
+ },
702
734
  runCount: -1,
703
735
  tracingContext: {
704
736
  currentSpan: sleepSpan
@@ -776,6 +808,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
776
808
  mastra: this.mastra,
777
809
  runtimeContext,
778
810
  inputData: prevOutput,
811
+ state: executionContext.state,
812
+ setState: (state) => {
813
+ executionContext.state = state;
814
+ },
779
815
  runCount: -1,
780
816
  tracingContext: {
781
817
  currentSpan: sleepUntilSpan
@@ -906,38 +942,60 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
906
942
  const isResume = !!resume?.steps?.length;
907
943
  let result;
908
944
  let runId;
909
- if (isResume) {
910
- runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? crypto.randomUUID();
911
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
912
- workflowName: step.id,
913
- runId
914
- });
915
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
916
- function: step.getFunction(),
917
- data: {
918
- inputData,
919
- runId,
920
- resume: {
945
+ try {
946
+ if (isResume) {
947
+ runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
948
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
949
+ workflowName: step.id,
950
+ runId
951
+ });
952
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
953
+ function: step.getFunction(),
954
+ data: {
955
+ inputData,
956
+ initialState: executionContext.state ?? snapshot?.value ?? {},
921
957
  runId,
922
- steps: resume.steps.slice(1),
923
- stepResults: snapshot?.context,
924
- resumePayload: resume.resumePayload,
925
- // @ts-ignore
926
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
958
+ resume: {
959
+ runId,
960
+ steps: resume.steps.slice(1),
961
+ stepResults: snapshot?.context,
962
+ resumePayload: resume.resumePayload,
963
+ // @ts-ignore
964
+ resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
965
+ },
966
+ outputOptions: { includeState: true }
927
967
  }
928
- }
929
- });
930
- result = invokeResp.result;
931
- runId = invokeResp.runId;
932
- } else {
933
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
934
- function: step.getFunction(),
935
- data: {
936
- inputData
937
- }
938
- });
939
- result = invokeResp.result;
940
- runId = invokeResp.runId;
968
+ });
969
+ result = invokeResp.result;
970
+ runId = invokeResp.runId;
971
+ executionContext.state = invokeResp.result.state;
972
+ } else {
973
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
974
+ function: step.getFunction(),
975
+ data: {
976
+ inputData,
977
+ initialState: executionContext.state ?? {},
978
+ outputOptions: { includeState: true }
979
+ }
980
+ });
981
+ result = invokeResp.result;
982
+ runId = invokeResp.runId;
983
+ executionContext.state = invokeResp.result.state;
984
+ }
985
+ } catch (e) {
986
+ const errorCause = e?.cause;
987
+ if (errorCause && typeof errorCause === "object") {
988
+ result = errorCause;
989
+ runId = errorCause.runId || crypto.randomUUID();
990
+ } else {
991
+ runId = crypto.randomUUID();
992
+ result = {
993
+ status: "failed",
994
+ error: e instanceof Error ? e : new Error(String(e)),
995
+ steps: {},
996
+ input: inputData
997
+ };
998
+ }
941
999
  }
942
1000
  const res = await this.inngestStep.run(
943
1001
  `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
@@ -976,7 +1034,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
976
1034
  return stepRes2?.status === "suspended";
977
1035
  });
978
1036
  for (const [stepName, stepResult] of suspendedSteps) {
979
- const suspendPath = [stepName, ...stepResult?.payload?.__workflow_meta?.path ?? []];
1037
+ const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
980
1038
  executionContext.suspendedPaths[step.id] = executionContext.executionPath;
981
1039
  await emitter.emit("watch", {
982
1040
  type: "watch",
@@ -984,7 +1042,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
984
1042
  currentStep: {
985
1043
  id: step.id,
986
1044
  status: "suspended",
987
- payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
1045
+ payload: stepResult.payload,
1046
+ suspendPayload: {
1047
+ ...stepResult?.suspendPayload,
1048
+ __workflow_meta: { runId, path: suspendPath }
1049
+ }
988
1050
  },
989
1051
  workflowState: {
990
1052
  status: "running",
@@ -1006,7 +1068,11 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1006
1068
  executionContext,
1007
1069
  result: {
1008
1070
  status: "suspended",
1009
- payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
1071
+ payload: stepResult.payload,
1072
+ suspendPayload: {
1073
+ ...stepResult?.suspendPayload,
1074
+ __workflow_meta: { runId, path: suspendPath }
1075
+ }
1010
1076
  }
1011
1077
  };
1012
1078
  }
@@ -1071,132 +1137,167 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1071
1137
  }
1072
1138
  );
1073
1139
  Object.assign(executionContext, res.executionContext);
1074
- return res.result;
1140
+ return {
1141
+ ...res.result,
1142
+ startedAt,
1143
+ endedAt: Date.now(),
1144
+ payload: inputData,
1145
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1146
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1147
+ };
1075
1148
  }
1076
- const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1077
- let execResults;
1078
- let suspended;
1079
- let bailed;
1080
- try {
1081
- if (validationError) {
1082
- throw validationError;
1149
+ let stepRes;
1150
+ try {
1151
+ stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1152
+ let execResults;
1153
+ let suspended;
1154
+ let bailed;
1155
+ try {
1156
+ if (validationError) {
1157
+ throw validationError;
1158
+ }
1159
+ const result = await step.execute({
1160
+ runId: executionContext.runId,
1161
+ mastra: this.mastra,
1162
+ runtimeContext,
1163
+ writableStream,
1164
+ state: executionContext?.state ?? {},
1165
+ setState: (state) => {
1166
+ executionContext.state = state;
1167
+ },
1168
+ inputData,
1169
+ resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1170
+ tracingContext: {
1171
+ currentSpan: stepAISpan
1172
+ },
1173
+ getInitData: () => stepResults?.input,
1174
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1175
+ suspend: async (suspendPayload) => {
1176
+ executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1177
+ suspended = { payload: suspendPayload };
1178
+ },
1179
+ bail: (result2) => {
1180
+ bailed = { payload: result2 };
1181
+ },
1182
+ resume: {
1183
+ steps: resume?.steps?.slice(1) || [],
1184
+ resumePayload: resume?.resumePayload,
1185
+ // @ts-ignore
1186
+ runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
1187
+ },
1188
+ [_constants.EMITTER_SYMBOL]: emitter,
1189
+ engine: {
1190
+ step: this.inngestStep
1191
+ },
1192
+ abortSignal: abortController.signal
1193
+ });
1194
+ const endedAt = Date.now();
1195
+ execResults = {
1196
+ status: "success",
1197
+ output: result,
1198
+ startedAt,
1199
+ endedAt,
1200
+ payload: inputData,
1201
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1202
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1203
+ };
1204
+ } catch (e) {
1205
+ const stepFailure = {
1206
+ status: "failed",
1207
+ payload: inputData,
1208
+ error: e instanceof Error ? e.message : String(e),
1209
+ endedAt: Date.now(),
1210
+ startedAt,
1211
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1212
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1213
+ };
1214
+ execResults = stepFailure;
1215
+ const fallbackErrorMessage = `Step ${step.id} failed`;
1216
+ stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1217
+ throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1218
+ cause: execResults
1219
+ });
1083
1220
  }
1084
- const result = await step.execute({
1085
- runId: executionContext.runId,
1086
- mastra: this.mastra,
1087
- runtimeContext,
1088
- writableStream,
1089
- inputData,
1090
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1091
- tracingContext: {
1092
- currentSpan: stepAISpan
1093
- },
1094
- getInitData: () => stepResults?.input,
1095
- getStepResult: workflows.getStepResult.bind(this, stepResults),
1096
- suspend: async (suspendPayload) => {
1097
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1098
- suspended = { payload: suspendPayload };
1099
- },
1100
- bail: (result2) => {
1101
- bailed = { payload: result2 };
1102
- },
1103
- resume: {
1104
- steps: resume?.steps?.slice(1) || [],
1105
- resumePayload: resume?.resumePayload,
1106
- // @ts-ignore
1107
- runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
1108
- },
1109
- [_constants.EMITTER_SYMBOL]: emitter,
1110
- engine: {
1111
- step: this.inngestStep
1221
+ if (suspended) {
1222
+ execResults = {
1223
+ status: "suspended",
1224
+ suspendPayload: suspended.payload,
1225
+ payload: inputData,
1226
+ suspendedAt: Date.now(),
1227
+ startedAt,
1228
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1229
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1230
+ };
1231
+ } else if (bailed) {
1232
+ execResults = {
1233
+ status: "bailed",
1234
+ output: bailed.payload,
1235
+ payload: inputData,
1236
+ endedAt: Date.now(),
1237
+ startedAt
1238
+ };
1239
+ }
1240
+ await emitter.emit("watch", {
1241
+ type: "watch",
1242
+ payload: {
1243
+ currentStep: {
1244
+ id: step.id,
1245
+ ...execResults
1246
+ },
1247
+ workflowState: {
1248
+ status: "running",
1249
+ steps: { ...stepResults, [step.id]: execResults },
1250
+ result: null,
1251
+ error: null
1252
+ }
1112
1253
  },
1113
- abortSignal: abortController.signal
1254
+ eventTimestamp: Date.now()
1114
1255
  });
1115
- const endedAt = Date.now();
1116
- execResults = {
1117
- status: "success",
1118
- output: result,
1119
- startedAt,
1120
- endedAt,
1121
- payload: inputData,
1122
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1123
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1124
- };
1125
- } catch (e) {
1126
- execResults = {
1127
- status: "failed",
1128
- payload: inputData,
1129
- error: e instanceof Error ? e.message : String(e),
1130
- endedAt: Date.now(),
1131
- startedAt,
1132
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1133
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1134
- };
1135
- }
1136
- if (suspended) {
1137
- execResults = {
1138
- status: "suspended",
1139
- suspendedPayload: suspended.payload,
1140
- payload: inputData,
1141
- suspendedAt: Date.now(),
1142
- startedAt,
1143
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1144
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1145
- };
1146
- } else if (bailed) {
1147
- execResults = { status: "bailed", output: bailed.payload, payload: inputData, endedAt: Date.now(), startedAt };
1148
- }
1149
- if (execResults.status === "failed") {
1150
- if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
1151
- const error = new Error(execResults.error);
1152
- stepAISpan?.error({ error });
1153
- throw error;
1256
+ if (execResults.status === "suspended") {
1257
+ await emitter.emit("watch-v2", {
1258
+ type: "workflow-step-suspended",
1259
+ payload: {
1260
+ id: step.id,
1261
+ ...execResults
1262
+ }
1263
+ });
1264
+ } else {
1265
+ await emitter.emit("watch-v2", {
1266
+ type: "workflow-step-result",
1267
+ payload: {
1268
+ id: step.id,
1269
+ ...execResults
1270
+ }
1271
+ });
1272
+ await emitter.emit("watch-v2", {
1273
+ type: "workflow-step-finish",
1274
+ payload: {
1275
+ id: step.id,
1276
+ metadata: {}
1277
+ }
1278
+ });
1154
1279
  }
1155
- }
1156
- await emitter.emit("watch", {
1157
- type: "watch",
1158
- payload: {
1159
- currentStep: {
1160
- id: step.id,
1161
- ...execResults
1162
- },
1163
- workflowState: {
1164
- status: "running",
1165
- steps: { ...stepResults, [step.id]: execResults },
1166
- result: null,
1167
- error: null
1168
- }
1169
- },
1170
- eventTimestamp: Date.now()
1280
+ stepAISpan?.end({ output: execResults });
1281
+ return { result: execResults, executionContext, stepResults };
1171
1282
  });
1172
- if (execResults.status === "suspended") {
1173
- await emitter.emit("watch-v2", {
1174
- type: "workflow-step-suspended",
1175
- payload: {
1176
- id: step.id,
1177
- ...execResults
1178
- }
1179
- });
1180
- } else {
1181
- await emitter.emit("watch-v2", {
1182
- type: "workflow-step-result",
1183
- payload: {
1184
- id: step.id,
1185
- ...execResults
1186
- }
1187
- });
1188
- await emitter.emit("watch-v2", {
1189
- type: "workflow-step-finish",
1190
- payload: {
1191
- id: step.id,
1192
- metadata: {}
1193
- }
1194
- });
1195
- }
1196
- stepAISpan?.end({ output: execResults });
1197
- return { result: execResults, executionContext, stepResults };
1198
- });
1199
- if (disableScorers !== false) {
1283
+ } catch (e) {
1284
+ const stepFailure = e instanceof Error ? e?.cause : {
1285
+ status: "failed",
1286
+ error: e instanceof Error ? e.message : String(e),
1287
+ payload: inputData,
1288
+ startedAt,
1289
+ endedAt: Date.now()
1290
+ };
1291
+ stepRes = {
1292
+ result: stepFailure,
1293
+ executionContext,
1294
+ stepResults: {
1295
+ ...stepResults,
1296
+ [step.id]: stepFailure
1297
+ }
1298
+ };
1299
+ }
1300
+ if (disableScorers !== false && stepRes.result.status === "success") {
1200
1301
  await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1201
1302
  if (step.scorers) {
1202
1303
  await this.runScorers({
@@ -1215,6 +1316,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1215
1316
  }
1216
1317
  Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
1217
1318
  Object.assign(stepResults, stepRes.stepResults);
1319
+ executionContext.state = stepRes.executionContext.state;
1218
1320
  return stepRes.result;
1219
1321
  }
1220
1322
  async persistStepUpdate({
@@ -1237,7 +1339,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1237
1339
  resourceId,
1238
1340
  snapshot: {
1239
1341
  runId,
1240
- value: {},
1342
+ value: executionContext.state,
1241
1343
  context: stepResults,
1242
1344
  activePaths: [],
1243
1345
  suspendedPaths: executionContext.suspendedPaths,
@@ -1300,6 +1402,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1300
1402
  runtimeContext,
1301
1403
  runCount: -1,
1302
1404
  inputData: prevOutput,
1405
+ state: executionContext.state,
1406
+ setState: (state) => {
1407
+ executionContext.state = state;
1408
+ },
1303
1409
  tracingContext: {
1304
1410
  currentSpan: evalSpan
1305
1411
  },
@@ -1372,7 +1478,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1372
1478
  executionPath: [...executionContext.executionPath, index],
1373
1479
  suspendedPaths: executionContext.suspendedPaths,
1374
1480
  retryConfig: executionContext.retryConfig,
1375
- executionSpan: executionContext.executionSpan
1481
+ executionSpan: executionContext.executionSpan,
1482
+ state: executionContext.state
1376
1483
  },
1377
1484
  emitter,
1378
1485
  abortController,
@@ -1390,7 +1497,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1390
1497
  if (hasFailed) {
1391
1498
  execResults = { status: "failed", error: hasFailed.result.error };
1392
1499
  } else if (hasSuspended) {
1393
- execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
1500
+ execResults = { status: "suspended", suspendPayload: hasSuspended.result.suspendPayload };
1394
1501
  } else {
1395
1502
  execResults = {
1396
1503
  status: "success",