@mastra/inngest 0.15.0-alpha.0 → 0.15.1-alpha.0

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,25 @@
1
1
  # @mastra/inngest
2
2
 
3
+ ## 0.15.1-alpha.0
4
+
5
+ ### Patch Changes
6
+
7
+ - Handle workflow run failures (fix #8130) ([#8370](https://github.com/mastra-ai/mastra/pull/8370))
8
+
9
+ - Updated dependencies [[`10e633a`](https://github.com/mastra-ai/mastra/commit/10e633a07d333466d9734c97acfc3dbf757ad2d0)]:
10
+ - @mastra/core@0.20.1-alpha.0
11
+
12
+ ## 0.15.0
13
+
14
+ ### Minor Changes
15
+
16
+ - Breaking change to move the agent.streamVNext/generateVNext implementation to the default stream/generate. The old stream/generate have now been moved to streamLegacy and generateLegacy ([#8097](https://github.com/mastra-ai/mastra/pull/8097))
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies [[`00cb6bd`](https://github.com/mastra-ai/mastra/commit/00cb6bdf78737c0fac14a5a0c7b532a11e38558a), [`869ba22`](https://github.com/mastra-ai/mastra/commit/869ba222e1d6b58fc1b65e7c9fd55ca4e01b8c2f), [`1b73665`](https://github.com/mastra-ai/mastra/commit/1b73665e8e23f5c09d49fcf3e7d709c75259259e), [`f7d7475`](https://github.com/mastra-ai/mastra/commit/f7d747507341aef60ed39e4b49318db1f86034a6), [`084b77b`](https://github.com/mastra-ai/mastra/commit/084b77b2955960e0190af8db3f77138aa83ed65c), [`a93ff84`](https://github.com/mastra-ai/mastra/commit/a93ff84b5e1af07ee236ac8873dac9b49aa5d501), [`bc5aacb`](https://github.com/mastra-ai/mastra/commit/bc5aacb646d468d325327e36117129f28cd13bf6), [`6b5af12`](https://github.com/mastra-ai/mastra/commit/6b5af12ce9e09066e0c32e821c203a6954498bea), [`bf60e4a`](https://github.com/mastra-ai/mastra/commit/bf60e4a89c515afd9570b7b79f33b95e7d07c397), [`d41aee5`](https://github.com/mastra-ai/mastra/commit/d41aee526d124e35f42720a08e64043229193679), [`e8fe13c`](https://github.com/mastra-ai/mastra/commit/e8fe13c4b4c255a42520127797ec394310f7c919), [`3ca833d`](https://github.com/mastra-ai/mastra/commit/3ca833dc994c38e3c9b4f9b4478a61cd8e07b32a), [`1edb8d1`](https://github.com/mastra-ai/mastra/commit/1edb8d1cfb963e72a12412990fb9170936c9904c), [`fbf6e32`](https://github.com/mastra-ai/mastra/commit/fbf6e324946332d0f5ed8930bf9d4d4479cefd7a), [`4753027`](https://github.com/mastra-ai/mastra/commit/4753027ee889288775c6958bdfeda03ff909af67)]:
21
+ - @mastra/core@0.20.0
22
+
3
23
  ## 0.15.0-alpha.0
4
24
 
5
25
  ### 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
@@ -410,6 +418,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
410
418
  currentSpan: void 0
411
419
  // TODO: Pass actual parent AI span from workflow execution context
412
420
  });
421
+ await step.run(`workflow.${this.id}.finalize`, async () => {
422
+ if (result.status === "failed") {
423
+ throw new inngest.NonRetriableError(`Workflow failed`, {
424
+ cause: result
425
+ });
426
+ }
427
+ return result;
428
+ });
413
429
  return { result, runId };
414
430
  }
415
431
  );
@@ -906,38 +922,54 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
906
922
  const isResume = !!resume?.steps?.length;
907
923
  let result;
908
924
  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: {
925
+ try {
926
+ if (isResume) {
927
+ runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? crypto.randomUUID();
928
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
929
+ workflowName: step.id,
930
+ runId
931
+ });
932
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
933
+ function: step.getFunction(),
934
+ data: {
935
+ inputData,
921
936
  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]]
937
+ resume: {
938
+ runId,
939
+ steps: resume.steps.slice(1),
940
+ stepResults: snapshot?.context,
941
+ resumePayload: resume.resumePayload,
942
+ // @ts-ignore
943
+ resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
944
+ }
927
945
  }
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;
946
+ });
947
+ result = invokeResp.result;
948
+ runId = invokeResp.runId;
949
+ } else {
950
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
951
+ function: step.getFunction(),
952
+ data: {
953
+ inputData
954
+ }
955
+ });
956
+ result = invokeResp.result;
957
+ runId = invokeResp.runId;
958
+ }
959
+ } catch (e) {
960
+ const errorCause = e?.cause;
961
+ if (errorCause && typeof errorCause === "object") {
962
+ result = errorCause;
963
+ runId = errorCause.runId || crypto.randomUUID();
964
+ } else {
965
+ runId = crypto.randomUUID();
966
+ result = {
967
+ status: "failed",
968
+ error: e instanceof Error ? e : new Error(String(e)),
969
+ steps: {},
970
+ input: inputData
971
+ };
972
+ }
941
973
  }
942
974
  const res = await this.inngestStep.run(
943
975
  `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
@@ -1073,130 +1105,154 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
1073
1105
  Object.assign(executionContext, res.executionContext);
1074
1106
  return res.result;
1075
1107
  }
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;
1108
+ let stepRes;
1109
+ try {
1110
+ stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1111
+ let execResults;
1112
+ let suspended;
1113
+ let bailed;
1114
+ try {
1115
+ if (validationError) {
1116
+ throw validationError;
1117
+ }
1118
+ const result = await step.execute({
1119
+ runId: executionContext.runId,
1120
+ mastra: this.mastra,
1121
+ runtimeContext,
1122
+ writableStream,
1123
+ inputData,
1124
+ resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1125
+ tracingContext: {
1126
+ currentSpan: stepAISpan
1127
+ },
1128
+ getInitData: () => stepResults?.input,
1129
+ getStepResult: workflows.getStepResult.bind(this, stepResults),
1130
+ suspend: async (suspendPayload) => {
1131
+ executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1132
+ suspended = { payload: suspendPayload };
1133
+ },
1134
+ bail: (result2) => {
1135
+ bailed = { payload: result2 };
1136
+ },
1137
+ resume: {
1138
+ steps: resume?.steps?.slice(1) || [],
1139
+ resumePayload: resume?.resumePayload,
1140
+ // @ts-ignore
1141
+ runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
1142
+ },
1143
+ [_constants.EMITTER_SYMBOL]: emitter,
1144
+ engine: {
1145
+ step: this.inngestStep
1146
+ },
1147
+ abortSignal: abortController.signal
1148
+ });
1149
+ const endedAt = Date.now();
1150
+ execResults = {
1151
+ status: "success",
1152
+ output: result,
1153
+ startedAt,
1154
+ endedAt,
1155
+ payload: inputData,
1156
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1157
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1158
+ };
1159
+ } catch (e) {
1160
+ const stepFailure = {
1161
+ status: "failed",
1162
+ payload: inputData,
1163
+ error: e instanceof Error ? e.message : String(e),
1164
+ endedAt: Date.now(),
1165
+ startedAt,
1166
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1167
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1168
+ };
1169
+ execResults = stepFailure;
1170
+ const fallbackErrorMessage = `Step ${step.id} failed`;
1171
+ stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1172
+ throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1173
+ cause: execResults
1174
+ });
1083
1175
  }
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
1176
+ if (suspended) {
1177
+ execResults = {
1178
+ status: "suspended",
1179
+ suspendedPayload: suspended.payload,
1180
+ payload: inputData,
1181
+ suspendedAt: Date.now(),
1182
+ startedAt,
1183
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1184
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1185
+ };
1186
+ } else if (bailed) {
1187
+ execResults = {
1188
+ status: "bailed",
1189
+ output: bailed.payload,
1190
+ payload: inputData,
1191
+ endedAt: Date.now(),
1192
+ startedAt
1193
+ };
1194
+ }
1195
+ await emitter.emit("watch", {
1196
+ type: "watch",
1197
+ payload: {
1198
+ currentStep: {
1199
+ id: step.id,
1200
+ ...execResults
1201
+ },
1202
+ workflowState: {
1203
+ status: "running",
1204
+ steps: { ...stepResults, [step.id]: execResults },
1205
+ result: null,
1206
+ error: null
1207
+ }
1112
1208
  },
1113
- abortSignal: abortController.signal
1209
+ eventTimestamp: Date.now()
1114
1210
  });
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;
1211
+ if (execResults.status === "suspended") {
1212
+ await emitter.emit("watch-v2", {
1213
+ type: "workflow-step-suspended",
1214
+ payload: {
1215
+ id: step.id,
1216
+ ...execResults
1217
+ }
1218
+ });
1219
+ } else {
1220
+ await emitter.emit("watch-v2", {
1221
+ type: "workflow-step-result",
1222
+ payload: {
1223
+ id: step.id,
1224
+ ...execResults
1225
+ }
1226
+ });
1227
+ await emitter.emit("watch-v2", {
1228
+ type: "workflow-step-finish",
1229
+ payload: {
1230
+ id: step.id,
1231
+ metadata: {}
1232
+ }
1233
+ });
1154
1234
  }
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()
1235
+ stepAISpan?.end({ output: execResults });
1236
+ return { result: execResults, executionContext, stepResults };
1171
1237
  });
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) {
1238
+ } catch (e) {
1239
+ const stepFailure = e instanceof Error ? e?.cause : {
1240
+ status: "failed",
1241
+ error: e instanceof Error ? e.message : String(e),
1242
+ payload: inputData,
1243
+ startedAt,
1244
+ endedAt: Date.now()
1245
+ };
1246
+ stepRes = {
1247
+ result: stepFailure,
1248
+ executionContext,
1249
+ stepResults: {
1250
+ ...stepResults,
1251
+ [step.id]: stepFailure
1252
+ }
1253
+ };
1254
+ }
1255
+ if (disableScorers !== false && stepRes.result.status === "success") {
1200
1256
  await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1201
1257
  if (step.scorers) {
1202
1258
  await this.runScorers({