@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/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import { RuntimeContext } from '@mastra/core/di';
5
5
  import { ToolStream, Tool } from '@mastra/core/tools';
6
6
  import { Run, Workflow, DefaultExecutionEngine, getStepResult, validateStepInput } from '@mastra/core/workflows';
7
7
  import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
8
+ import { NonRetriableError, RetryAfterError } from 'inngest';
8
9
  import { serve as serve$1 } from 'inngest/hono';
9
10
  import { z } from 'zod';
10
11
 
@@ -58,8 +59,15 @@ var InngestRun = class extends Run {
58
59
  await new Promise((resolve) => setTimeout(resolve, 1e3));
59
60
  runs = await this.getRuns(eventId);
60
61
  if (runs?.[0]?.status === "Failed") {
61
- throw new Error(`Function run ${runs?.[0]?.status}`);
62
- } else if (runs?.[0]?.status === "Cancelled") {
62
+ const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
63
+ workflowName: this.workflowId,
64
+ runId: this.runId
65
+ });
66
+ return {
67
+ output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
68
+ };
69
+ }
70
+ if (runs?.[0]?.status === "Cancelled") {
63
71
  const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
64
72
  workflowName: this.workflowId,
65
73
  runId: this.runId
@@ -408,6 +416,14 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
408
416
  currentSpan: void 0
409
417
  // TODO: Pass actual parent AI span from workflow execution context
410
418
  });
419
+ await step.run(`workflow.${this.id}.finalize`, async () => {
420
+ if (result.status === "failed") {
421
+ throw new NonRetriableError(`Workflow failed`, {
422
+ cause: result
423
+ });
424
+ }
425
+ return result;
426
+ });
411
427
  return { result, runId };
412
428
  }
413
429
  );
@@ -904,38 +920,54 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
904
920
  const isResume = !!resume?.steps?.length;
905
921
  let result;
906
922
  let runId;
907
- if (isResume) {
908
- runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? randomUUID();
909
- const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
910
- workflowName: step.id,
911
- runId
912
- });
913
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
914
- function: step.getFunction(),
915
- data: {
916
- inputData,
917
- runId,
918
- resume: {
923
+ try {
924
+ if (isResume) {
925
+ runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? randomUUID();
926
+ const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
927
+ workflowName: step.id,
928
+ runId
929
+ });
930
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
931
+ function: step.getFunction(),
932
+ data: {
933
+ inputData,
919
934
  runId,
920
- steps: resume.steps.slice(1),
921
- stepResults: snapshot?.context,
922
- resumePayload: resume.resumePayload,
923
- // @ts-ignore
924
- resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
935
+ resume: {
936
+ runId,
937
+ steps: resume.steps.slice(1),
938
+ stepResults: snapshot?.context,
939
+ resumePayload: resume.resumePayload,
940
+ // @ts-ignore
941
+ resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
942
+ }
925
943
  }
926
- }
927
- });
928
- result = invokeResp.result;
929
- runId = invokeResp.runId;
930
- } else {
931
- const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
932
- function: step.getFunction(),
933
- data: {
934
- inputData
935
- }
936
- });
937
- result = invokeResp.result;
938
- runId = invokeResp.runId;
944
+ });
945
+ result = invokeResp.result;
946
+ runId = invokeResp.runId;
947
+ } else {
948
+ const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
949
+ function: step.getFunction(),
950
+ data: {
951
+ inputData
952
+ }
953
+ });
954
+ result = invokeResp.result;
955
+ runId = invokeResp.runId;
956
+ }
957
+ } catch (e) {
958
+ const errorCause = e?.cause;
959
+ if (errorCause && typeof errorCause === "object") {
960
+ result = errorCause;
961
+ runId = errorCause.runId || randomUUID();
962
+ } else {
963
+ runId = randomUUID();
964
+ result = {
965
+ status: "failed",
966
+ error: e instanceof Error ? e : new Error(String(e)),
967
+ steps: {},
968
+ input: inputData
969
+ };
970
+ }
939
971
  }
940
972
  const res = await this.inngestStep.run(
941
973
  `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
@@ -1071,130 +1103,154 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
1071
1103
  Object.assign(executionContext, res.executionContext);
1072
1104
  return res.result;
1073
1105
  }
1074
- const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1075
- let execResults;
1076
- let suspended;
1077
- let bailed;
1078
- try {
1079
- if (validationError) {
1080
- throw validationError;
1106
+ let stepRes;
1107
+ try {
1108
+ stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
1109
+ let execResults;
1110
+ let suspended;
1111
+ let bailed;
1112
+ try {
1113
+ if (validationError) {
1114
+ throw validationError;
1115
+ }
1116
+ const result = await step.execute({
1117
+ runId: executionContext.runId,
1118
+ mastra: this.mastra,
1119
+ runtimeContext,
1120
+ writableStream,
1121
+ inputData,
1122
+ resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1123
+ tracingContext: {
1124
+ currentSpan: stepAISpan
1125
+ },
1126
+ getInitData: () => stepResults?.input,
1127
+ getStepResult: getStepResult.bind(this, stepResults),
1128
+ suspend: async (suspendPayload) => {
1129
+ executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1130
+ suspended = { payload: suspendPayload };
1131
+ },
1132
+ bail: (result2) => {
1133
+ bailed = { payload: result2 };
1134
+ },
1135
+ resume: {
1136
+ steps: resume?.steps?.slice(1) || [],
1137
+ resumePayload: resume?.resumePayload,
1138
+ // @ts-ignore
1139
+ runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
1140
+ },
1141
+ [EMITTER_SYMBOL]: emitter,
1142
+ engine: {
1143
+ step: this.inngestStep
1144
+ },
1145
+ abortSignal: abortController.signal
1146
+ });
1147
+ const endedAt = Date.now();
1148
+ execResults = {
1149
+ status: "success",
1150
+ output: result,
1151
+ startedAt,
1152
+ endedAt,
1153
+ payload: inputData,
1154
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1155
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1156
+ };
1157
+ } catch (e) {
1158
+ const stepFailure = {
1159
+ status: "failed",
1160
+ payload: inputData,
1161
+ error: e instanceof Error ? e.message : String(e),
1162
+ endedAt: Date.now(),
1163
+ startedAt,
1164
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1165
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1166
+ };
1167
+ execResults = stepFailure;
1168
+ const fallbackErrorMessage = `Step ${step.id} failed`;
1169
+ stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
1170
+ throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
1171
+ cause: execResults
1172
+ });
1081
1173
  }
1082
- const result = await step.execute({
1083
- runId: executionContext.runId,
1084
- mastra: this.mastra,
1085
- runtimeContext,
1086
- writableStream,
1087
- inputData,
1088
- resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
1089
- tracingContext: {
1090
- currentSpan: stepAISpan
1091
- },
1092
- getInitData: () => stepResults?.input,
1093
- getStepResult: getStepResult.bind(this, stepResults),
1094
- suspend: async (suspendPayload) => {
1095
- executionContext.suspendedPaths[step.id] = executionContext.executionPath;
1096
- suspended = { payload: suspendPayload };
1097
- },
1098
- bail: (result2) => {
1099
- bailed = { payload: result2 };
1100
- },
1101
- resume: {
1102
- steps: resume?.steps?.slice(1) || [],
1103
- resumePayload: resume?.resumePayload,
1104
- // @ts-ignore
1105
- runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
1106
- },
1107
- [EMITTER_SYMBOL]: emitter,
1108
- engine: {
1109
- step: this.inngestStep
1174
+ if (suspended) {
1175
+ execResults = {
1176
+ status: "suspended",
1177
+ suspendedPayload: suspended.payload,
1178
+ payload: inputData,
1179
+ suspendedAt: Date.now(),
1180
+ startedAt,
1181
+ resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1182
+ resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1183
+ };
1184
+ } else if (bailed) {
1185
+ execResults = {
1186
+ status: "bailed",
1187
+ output: bailed.payload,
1188
+ payload: inputData,
1189
+ endedAt: Date.now(),
1190
+ startedAt
1191
+ };
1192
+ }
1193
+ await emitter.emit("watch", {
1194
+ type: "watch",
1195
+ payload: {
1196
+ currentStep: {
1197
+ id: step.id,
1198
+ ...execResults
1199
+ },
1200
+ workflowState: {
1201
+ status: "running",
1202
+ steps: { ...stepResults, [step.id]: execResults },
1203
+ result: null,
1204
+ error: null
1205
+ }
1110
1206
  },
1111
- abortSignal: abortController.signal
1207
+ eventTimestamp: Date.now()
1112
1208
  });
1113
- const endedAt = Date.now();
1114
- execResults = {
1115
- status: "success",
1116
- output: result,
1117
- startedAt,
1118
- endedAt,
1119
- payload: inputData,
1120
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1121
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1122
- };
1123
- } catch (e) {
1124
- execResults = {
1125
- status: "failed",
1126
- payload: inputData,
1127
- error: e instanceof Error ? e.message : String(e),
1128
- endedAt: Date.now(),
1129
- startedAt,
1130
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1131
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1132
- };
1133
- }
1134
- if (suspended) {
1135
- execResults = {
1136
- status: "suspended",
1137
- suspendedPayload: suspended.payload,
1138
- payload: inputData,
1139
- suspendedAt: Date.now(),
1140
- startedAt,
1141
- resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
1142
- resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
1143
- };
1144
- } else if (bailed) {
1145
- execResults = { status: "bailed", output: bailed.payload, payload: inputData, endedAt: Date.now(), startedAt };
1146
- }
1147
- if (execResults.status === "failed") {
1148
- if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
1149
- const error = new Error(execResults.error);
1150
- stepAISpan?.error({ error });
1151
- throw error;
1209
+ if (execResults.status === "suspended") {
1210
+ await emitter.emit("watch-v2", {
1211
+ type: "workflow-step-suspended",
1212
+ payload: {
1213
+ id: step.id,
1214
+ ...execResults
1215
+ }
1216
+ });
1217
+ } else {
1218
+ await emitter.emit("watch-v2", {
1219
+ type: "workflow-step-result",
1220
+ payload: {
1221
+ id: step.id,
1222
+ ...execResults
1223
+ }
1224
+ });
1225
+ await emitter.emit("watch-v2", {
1226
+ type: "workflow-step-finish",
1227
+ payload: {
1228
+ id: step.id,
1229
+ metadata: {}
1230
+ }
1231
+ });
1152
1232
  }
1153
- }
1154
- await emitter.emit("watch", {
1155
- type: "watch",
1156
- payload: {
1157
- currentStep: {
1158
- id: step.id,
1159
- ...execResults
1160
- },
1161
- workflowState: {
1162
- status: "running",
1163
- steps: { ...stepResults, [step.id]: execResults },
1164
- result: null,
1165
- error: null
1166
- }
1167
- },
1168
- eventTimestamp: Date.now()
1233
+ stepAISpan?.end({ output: execResults });
1234
+ return { result: execResults, executionContext, stepResults };
1169
1235
  });
1170
- if (execResults.status === "suspended") {
1171
- await emitter.emit("watch-v2", {
1172
- type: "workflow-step-suspended",
1173
- payload: {
1174
- id: step.id,
1175
- ...execResults
1176
- }
1177
- });
1178
- } else {
1179
- await emitter.emit("watch-v2", {
1180
- type: "workflow-step-result",
1181
- payload: {
1182
- id: step.id,
1183
- ...execResults
1184
- }
1185
- });
1186
- await emitter.emit("watch-v2", {
1187
- type: "workflow-step-finish",
1188
- payload: {
1189
- id: step.id,
1190
- metadata: {}
1191
- }
1192
- });
1193
- }
1194
- stepAISpan?.end({ output: execResults });
1195
- return { result: execResults, executionContext, stepResults };
1196
- });
1197
- if (disableScorers !== false) {
1236
+ } catch (e) {
1237
+ const stepFailure = e instanceof Error ? e?.cause : {
1238
+ status: "failed",
1239
+ error: e instanceof Error ? e.message : String(e),
1240
+ payload: inputData,
1241
+ startedAt,
1242
+ endedAt: Date.now()
1243
+ };
1244
+ stepRes = {
1245
+ result: stepFailure,
1246
+ executionContext,
1247
+ stepResults: {
1248
+ ...stepResults,
1249
+ [step.id]: stepFailure
1250
+ }
1251
+ };
1252
+ }
1253
+ if (disableScorers !== false && stepRes.result.status === "success") {
1198
1254
  await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
1199
1255
  if (step.scorers) {
1200
1256
  await this.runScorers({