@mastra/inngest 0.0.0-fix-fetching-workflow-snapshots-20250625000954 → 0.0.0-http-transporter-20250702160118
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 +70 -2
- package/dist/_tsup-dts-rollup.d.cts +9 -13
- package/dist/_tsup-dts-rollup.d.ts +9 -13
- package/dist/index.cjs +109 -39
- package/dist/index.js +109 -39
- package/docker-compose.yaml +3 -3
- package/package.json +10 -9
- package/src/index.test.ts +501 -238
- package/src/index.ts +112 -39
- package/vitest.config.ts +6 -0
package/src/index.ts
CHANGED
|
@@ -33,13 +33,17 @@ export type InngestEngineType = {
|
|
|
33
33
|
|
|
34
34
|
export function serve({ mastra, inngest }: { mastra: Mastra; inngest: Inngest }): ReturnType<typeof inngestServe> {
|
|
35
35
|
const wfs = mastra.getWorkflows();
|
|
36
|
-
const functions =
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
const functions = Array.from(
|
|
37
|
+
new Set(
|
|
38
|
+
Object.values(wfs).flatMap(wf => {
|
|
39
|
+
if (wf instanceof InngestWorkflow) {
|
|
40
|
+
wf.__registerMastra(mastra);
|
|
41
|
+
return wf.getFunctions();
|
|
42
|
+
}
|
|
43
|
+
return [];
|
|
44
|
+
}),
|
|
45
|
+
),
|
|
46
|
+
);
|
|
43
47
|
return inngestServe({
|
|
44
48
|
client: inngest,
|
|
45
49
|
functions,
|
|
@@ -94,8 +98,15 @@ export class InngestRun<
|
|
|
94
98
|
while (runs?.[0]?.status !== 'Completed' || runs?.[0]?.event_id !== eventId) {
|
|
95
99
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
96
100
|
runs = await this.getRuns(eventId);
|
|
97
|
-
if (runs?.[0]?.status === 'Failed'
|
|
101
|
+
if (runs?.[0]?.status === 'Failed') {
|
|
102
|
+
console.log('run', runs?.[0]);
|
|
98
103
|
throw new Error(`Function run ${runs?.[0]?.status}`);
|
|
104
|
+
} else if (runs?.[0]?.status === 'Cancelled') {
|
|
105
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
106
|
+
workflowName: this.workflowId,
|
|
107
|
+
runId: this.runId,
|
|
108
|
+
});
|
|
109
|
+
return { output: { result: { steps: snapshot?.context, status: 'canceled' } } };
|
|
99
110
|
}
|
|
100
111
|
}
|
|
101
112
|
return runs?.[0];
|
|
@@ -108,6 +119,30 @@ export class InngestRun<
|
|
|
108
119
|
});
|
|
109
120
|
}
|
|
110
121
|
|
|
122
|
+
async cancel() {
|
|
123
|
+
await this.inngest.send({
|
|
124
|
+
name: `cancel.workflow.${this.workflowId}`,
|
|
125
|
+
data: {
|
|
126
|
+
runId: this.runId,
|
|
127
|
+
},
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
131
|
+
workflowName: this.workflowId,
|
|
132
|
+
runId: this.runId,
|
|
133
|
+
});
|
|
134
|
+
if (snapshot) {
|
|
135
|
+
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
136
|
+
workflowName: this.workflowId,
|
|
137
|
+
runId: this.runId,
|
|
138
|
+
snapshot: {
|
|
139
|
+
...snapshot,
|
|
140
|
+
status: 'canceled' as any,
|
|
141
|
+
},
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
111
146
|
async start({
|
|
112
147
|
inputData,
|
|
113
148
|
}: {
|
|
@@ -147,7 +182,9 @@ export class InngestRun<
|
|
|
147
182
|
result.error = new Error(result.error);
|
|
148
183
|
}
|
|
149
184
|
|
|
150
|
-
|
|
185
|
+
if (result.status !== 'suspended') {
|
|
186
|
+
this.cleanup?.();
|
|
187
|
+
}
|
|
151
188
|
return result;
|
|
152
189
|
}
|
|
153
190
|
|
|
@@ -432,23 +469,27 @@ export class InngestWorkflow<
|
|
|
432
469
|
|
|
433
470
|
this.runs.set(runIdToUse, run);
|
|
434
471
|
|
|
435
|
-
await this.
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
472
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
|
|
473
|
+
|
|
474
|
+
if (!workflowSnapshotInStorage) {
|
|
475
|
+
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
476
|
+
workflowName: this.id,
|
|
439
477
|
runId: runIdToUse,
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
478
|
+
snapshot: {
|
|
479
|
+
runId: runIdToUse,
|
|
480
|
+
status: 'pending',
|
|
481
|
+
value: {},
|
|
482
|
+
context: {},
|
|
483
|
+
activePaths: [],
|
|
484
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
485
|
+
suspendedPaths: {},
|
|
486
|
+
result: undefined,
|
|
487
|
+
error: undefined,
|
|
488
|
+
// @ts-ignore
|
|
489
|
+
timestamp: Date.now(),
|
|
490
|
+
},
|
|
491
|
+
});
|
|
492
|
+
}
|
|
452
493
|
|
|
453
494
|
return run;
|
|
454
495
|
}
|
|
@@ -458,8 +499,12 @@ export class InngestWorkflow<
|
|
|
458
499
|
return this.function;
|
|
459
500
|
}
|
|
460
501
|
this.function = this.inngest.createFunction(
|
|
461
|
-
|
|
462
|
-
|
|
502
|
+
{
|
|
503
|
+
id: `workflow.${this.id}`,
|
|
504
|
+
// @ts-ignore
|
|
505
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
506
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
507
|
+
},
|
|
463
508
|
{ event: `workflow.${this.id}` },
|
|
464
509
|
async ({ event, step, attempt, publish }) => {
|
|
465
510
|
let { inputData, runId, resume } = event.data;
|
|
@@ -508,6 +553,7 @@ export class InngestWorkflow<
|
|
|
508
553
|
retryConfig: this.retryConfig,
|
|
509
554
|
runtimeContext: new RuntimeContext(), // TODO
|
|
510
555
|
resume,
|
|
556
|
+
abortController: new AbortController(),
|
|
511
557
|
});
|
|
512
558
|
|
|
513
559
|
return { result, runId };
|
|
@@ -630,7 +676,7 @@ export function createStep<
|
|
|
630
676
|
outputSchema: z.object({
|
|
631
677
|
text: z.string(),
|
|
632
678
|
}),
|
|
633
|
-
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext }) => {
|
|
679
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
|
|
634
680
|
let streamPromise = {} as {
|
|
635
681
|
promise: Promise<string>;
|
|
636
682
|
resolve: (value: string) => void;
|
|
@@ -656,8 +702,13 @@ export function createStep<
|
|
|
656
702
|
onFinish: result => {
|
|
657
703
|
streamPromise.resolve(result.text);
|
|
658
704
|
},
|
|
705
|
+
abortSignal,
|
|
659
706
|
});
|
|
660
707
|
|
|
708
|
+
if (abortSignal.aborted) {
|
|
709
|
+
return abort();
|
|
710
|
+
}
|
|
711
|
+
|
|
661
712
|
for await (const chunk of fullStream) {
|
|
662
713
|
switch (chunk.type) {
|
|
663
714
|
case 'text-delta':
|
|
@@ -815,6 +866,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
815
866
|
delay?: number;
|
|
816
867
|
};
|
|
817
868
|
runtimeContext: RuntimeContext;
|
|
869
|
+
abortController: AbortController;
|
|
818
870
|
}): Promise<TOutput> {
|
|
819
871
|
await params.emitter.emit('watch-v2', {
|
|
820
872
|
type: 'start',
|
|
@@ -914,6 +966,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
914
966
|
resume,
|
|
915
967
|
prevOutput,
|
|
916
968
|
emitter,
|
|
969
|
+
abortController,
|
|
917
970
|
runtimeContext,
|
|
918
971
|
}: {
|
|
919
972
|
workflowId: string;
|
|
@@ -927,6 +980,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
927
980
|
};
|
|
928
981
|
prevOutput: any;
|
|
929
982
|
emitter: Emitter;
|
|
983
|
+
abortController: AbortController;
|
|
930
984
|
runtimeContext: RuntimeContext;
|
|
931
985
|
}): Promise<StepResult<any, any, any, any>> {
|
|
932
986
|
return super.executeStep({
|
|
@@ -938,6 +992,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
938
992
|
resume,
|
|
939
993
|
prevOutput,
|
|
940
994
|
emitter,
|
|
995
|
+
abortController,
|
|
941
996
|
runtimeContext,
|
|
942
997
|
});
|
|
943
998
|
}
|
|
@@ -966,17 +1021,12 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
966
1021
|
resume,
|
|
967
1022
|
prevOutput,
|
|
968
1023
|
emitter,
|
|
1024
|
+
abortController,
|
|
969
1025
|
runtimeContext,
|
|
970
1026
|
}: {
|
|
971
1027
|
step: Step<string, any, any>;
|
|
972
1028
|
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
973
|
-
executionContext:
|
|
974
|
-
workflowId: string;
|
|
975
|
-
runId: string;
|
|
976
|
-
executionPath: number[];
|
|
977
|
-
suspendedPaths: Record<string, number[]>;
|
|
978
|
-
retryConfig: { attempts: number; delay: number };
|
|
979
|
-
};
|
|
1029
|
+
executionContext: ExecutionContext;
|
|
980
1030
|
resume?: {
|
|
981
1031
|
steps: string[];
|
|
982
1032
|
resumePayload: any;
|
|
@@ -984,6 +1034,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
984
1034
|
};
|
|
985
1035
|
prevOutput: any;
|
|
986
1036
|
emitter: Emitter;
|
|
1037
|
+
abortController: AbortController;
|
|
987
1038
|
runtimeContext: RuntimeContext;
|
|
988
1039
|
}): Promise<StepResult<any, any, any, any>> {
|
|
989
1040
|
const startedAt = await this.inngestStep.run(
|
|
@@ -1016,6 +1067,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1016
1067
|
type: 'step-start',
|
|
1017
1068
|
payload: {
|
|
1018
1069
|
id: step.id,
|
|
1070
|
+
status: 'running',
|
|
1071
|
+
payload: prevOutput,
|
|
1072
|
+
startedAt,
|
|
1019
1073
|
},
|
|
1020
1074
|
});
|
|
1021
1075
|
|
|
@@ -1091,6 +1145,8 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1091
1145
|
payload: {
|
|
1092
1146
|
id: step.id,
|
|
1093
1147
|
status: 'failed',
|
|
1148
|
+
error: result?.error,
|
|
1149
|
+
payload: prevOutput,
|
|
1094
1150
|
},
|
|
1095
1151
|
});
|
|
1096
1152
|
|
|
@@ -1128,6 +1184,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1128
1184
|
type: 'step-suspended',
|
|
1129
1185
|
payload: {
|
|
1130
1186
|
id: step.id,
|
|
1187
|
+
status: 'suspended',
|
|
1131
1188
|
},
|
|
1132
1189
|
});
|
|
1133
1190
|
|
|
@@ -1187,6 +1244,15 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1187
1244
|
eventTimestamp: Date.now(),
|
|
1188
1245
|
});
|
|
1189
1246
|
|
|
1247
|
+
await emitter.emit('watch-v2', {
|
|
1248
|
+
type: 'step-result',
|
|
1249
|
+
payload: {
|
|
1250
|
+
id: step.id,
|
|
1251
|
+
status: 'success',
|
|
1252
|
+
output: result?.result,
|
|
1253
|
+
},
|
|
1254
|
+
});
|
|
1255
|
+
|
|
1190
1256
|
await emitter.emit('watch-v2', {
|
|
1191
1257
|
type: 'step-finish',
|
|
1192
1258
|
payload: {
|
|
@@ -1241,6 +1307,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1241
1307
|
engine: {
|
|
1242
1308
|
step: this.inngestStep,
|
|
1243
1309
|
},
|
|
1310
|
+
abortSignal: abortController.signal,
|
|
1244
1311
|
});
|
|
1245
1312
|
const endedAt = Date.now();
|
|
1246
1313
|
|
|
@@ -1307,8 +1374,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1307
1374
|
type: 'step-suspended',
|
|
1308
1375
|
payload: {
|
|
1309
1376
|
id: step.id,
|
|
1310
|
-
|
|
1311
|
-
output: execResults.status === 'success' ? execResults?.output : undefined,
|
|
1377
|
+
...execResults,
|
|
1312
1378
|
},
|
|
1313
1379
|
});
|
|
1314
1380
|
} else {
|
|
@@ -1316,8 +1382,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1316
1382
|
type: 'step-result',
|
|
1317
1383
|
payload: {
|
|
1318
1384
|
id: step.id,
|
|
1319
|
-
|
|
1320
|
-
output: execResults.status === 'success' ? execResults?.output : undefined,
|
|
1385
|
+
...execResults,
|
|
1321
1386
|
},
|
|
1322
1387
|
});
|
|
1323
1388
|
|
|
@@ -1396,6 +1461,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1396
1461
|
resume,
|
|
1397
1462
|
executionContext,
|
|
1398
1463
|
emitter,
|
|
1464
|
+
abortController,
|
|
1399
1465
|
runtimeContext,
|
|
1400
1466
|
}: {
|
|
1401
1467
|
workflowId: string;
|
|
@@ -1417,6 +1483,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1417
1483
|
};
|
|
1418
1484
|
executionContext: ExecutionContext;
|
|
1419
1485
|
emitter: Emitter;
|
|
1486
|
+
abortController: AbortController;
|
|
1420
1487
|
runtimeContext: RuntimeContext;
|
|
1421
1488
|
}): Promise<StepResult<any, any, any, any>> {
|
|
1422
1489
|
let execResults: any;
|
|
@@ -1429,6 +1496,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1429
1496
|
runId,
|
|
1430
1497
|
mastra: this.mastra!,
|
|
1431
1498
|
runtimeContext,
|
|
1499
|
+
runCount: -1,
|
|
1432
1500
|
inputData: prevOutput,
|
|
1433
1501
|
getInitData: () => stepResults?.input as any,
|
|
1434
1502
|
getStepResult: (step: any) => {
|
|
@@ -1447,10 +1515,14 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1447
1515
|
// TODO: this function shouldn't have suspend probably?
|
|
1448
1516
|
suspend: async (_suspendPayload: any) => {},
|
|
1449
1517
|
bail: () => {},
|
|
1518
|
+
abort: () => {
|
|
1519
|
+
abortController.abort();
|
|
1520
|
+
},
|
|
1450
1521
|
[EMITTER_SYMBOL]: emitter,
|
|
1451
1522
|
engine: {
|
|
1452
1523
|
step: this.inngestStep,
|
|
1453
1524
|
},
|
|
1525
|
+
abortSignal: abortController.signal,
|
|
1454
1526
|
});
|
|
1455
1527
|
return result ? index : null;
|
|
1456
1528
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -1482,6 +1554,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1482
1554
|
executionSpan: executionContext.executionSpan,
|
|
1483
1555
|
},
|
|
1484
1556
|
emitter,
|
|
1557
|
+
abortController,
|
|
1485
1558
|
runtimeContext,
|
|
1486
1559
|
}),
|
|
1487
1560
|
),
|