@mastra/inngest 0.0.0-working-memory-per-user-20250620163010 → 0.0.0-zod-v4-compat-part-2-20250822105954
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 +364 -3
- package/LICENSE.md +11 -42
- package/dist/index.cjs +281 -30
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +282 -7
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +282 -31
- package/dist/index.js.map +1 -0
- package/docker-compose.yaml +3 -3
- package/package.json +15 -14
- package/src/index.test.ts +1371 -315
- package/src/index.ts +353 -30
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +1 -1
- package/tsup.config.ts +22 -0
- package/vitest.config.ts +6 -0
- package/dist/_tsup-dts-rollup.d.cts +0 -265
- package/dist/_tsup-dts-rollup.d.ts +0 -265
- package/dist/index.d.cts +0 -7
package/src/index.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
+
import type { ReadableStream } from 'node:stream/web';
|
|
2
3
|
import { subscribe } from '@inngest/realtime';
|
|
3
4
|
import type { Agent, Mastra, ToolExecutionContext, WorkflowRun, WorkflowRuns } from '@mastra/core';
|
|
4
5
|
import { RuntimeContext } from '@mastra/core/di';
|
|
5
|
-
import { Tool } from '@mastra/core/tools';
|
|
6
|
+
import { Tool, ToolStream } from '@mastra/core/tools';
|
|
6
7
|
import { Workflow, Run, DefaultExecutionEngine } from '@mastra/core/workflows';
|
|
7
8
|
import type {
|
|
8
9
|
ExecuteFunction,
|
|
@@ -19,6 +20,7 @@ import type {
|
|
|
19
20
|
Emitter,
|
|
20
21
|
WatchEvent,
|
|
21
22
|
StreamEvent,
|
|
23
|
+
ChunkType,
|
|
22
24
|
} from '@mastra/core/workflows';
|
|
23
25
|
import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
|
|
24
26
|
import type { Span } from '@opentelemetry/api';
|
|
@@ -32,13 +34,17 @@ export type InngestEngineType = {
|
|
|
32
34
|
|
|
33
35
|
export function serve({ mastra, inngest }: { mastra: Mastra; inngest: Inngest }): ReturnType<typeof inngestServe> {
|
|
34
36
|
const wfs = mastra.getWorkflows();
|
|
35
|
-
const functions =
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
const functions = Array.from(
|
|
38
|
+
new Set(
|
|
39
|
+
Object.values(wfs).flatMap(wf => {
|
|
40
|
+
if (wf instanceof InngestWorkflow) {
|
|
41
|
+
wf.__registerMastra(mastra);
|
|
42
|
+
return wf.getFunctions();
|
|
43
|
+
}
|
|
44
|
+
return [];
|
|
45
|
+
}),
|
|
46
|
+
),
|
|
47
|
+
);
|
|
42
48
|
return inngestServe({
|
|
43
49
|
client: inngest,
|
|
44
50
|
functions,
|
|
@@ -93,8 +99,15 @@ export class InngestRun<
|
|
|
93
99
|
while (runs?.[0]?.status !== 'Completed' || runs?.[0]?.event_id !== eventId) {
|
|
94
100
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
95
101
|
runs = await this.getRuns(eventId);
|
|
96
|
-
if (runs?.[0]?.status === 'Failed'
|
|
102
|
+
if (runs?.[0]?.status === 'Failed') {
|
|
103
|
+
console.log('run', runs?.[0]);
|
|
97
104
|
throw new Error(`Function run ${runs?.[0]?.status}`);
|
|
105
|
+
} else if (runs?.[0]?.status === 'Cancelled') {
|
|
106
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
107
|
+
workflowName: this.workflowId,
|
|
108
|
+
runId: this.runId,
|
|
109
|
+
});
|
|
110
|
+
return { output: { result: { steps: snapshot?.context, status: 'canceled' } } };
|
|
98
111
|
}
|
|
99
112
|
}
|
|
100
113
|
return runs?.[0];
|
|
@@ -107,6 +120,30 @@ export class InngestRun<
|
|
|
107
120
|
});
|
|
108
121
|
}
|
|
109
122
|
|
|
123
|
+
async cancel() {
|
|
124
|
+
await this.inngest.send({
|
|
125
|
+
name: `cancel.workflow.${this.workflowId}`,
|
|
126
|
+
data: {
|
|
127
|
+
runId: this.runId,
|
|
128
|
+
},
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
132
|
+
workflowName: this.workflowId,
|
|
133
|
+
runId: this.runId,
|
|
134
|
+
});
|
|
135
|
+
if (snapshot) {
|
|
136
|
+
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
137
|
+
workflowName: this.workflowId,
|
|
138
|
+
runId: this.runId,
|
|
139
|
+
snapshot: {
|
|
140
|
+
...snapshot,
|
|
141
|
+
status: 'canceled' as any,
|
|
142
|
+
},
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
110
147
|
async start({
|
|
111
148
|
inputData,
|
|
112
149
|
}: {
|
|
@@ -146,7 +183,9 @@ export class InngestRun<
|
|
|
146
183
|
result.error = new Error(result.error);
|
|
147
184
|
}
|
|
148
185
|
|
|
149
|
-
|
|
186
|
+
if (result.status !== 'suspended') {
|
|
187
|
+
this.cleanup?.();
|
|
188
|
+
}
|
|
150
189
|
return result;
|
|
151
190
|
}
|
|
152
191
|
|
|
@@ -193,6 +232,7 @@ export class InngestRun<
|
|
|
193
232
|
data: {
|
|
194
233
|
inputData: params.resumeData,
|
|
195
234
|
runId: this.runId,
|
|
235
|
+
workflowId: this.workflowId,
|
|
196
236
|
stepResults: snapshot?.context as any,
|
|
197
237
|
resume: {
|
|
198
238
|
steps,
|
|
@@ -278,7 +318,7 @@ export class InngestRun<
|
|
|
278
318
|
});
|
|
279
319
|
|
|
280
320
|
return {
|
|
281
|
-
stream: readable
|
|
321
|
+
stream: readable as ReadableStream<StreamEvent>,
|
|
282
322
|
getWorkflowState: () => this.executionResults!,
|
|
283
323
|
};
|
|
284
324
|
}
|
|
@@ -409,13 +449,64 @@ export class InngestWorkflow<
|
|
|
409
449
|
return run;
|
|
410
450
|
}
|
|
411
451
|
|
|
452
|
+
async createRunAsync(options?: { runId?: string }): Promise<Run<TEngineType, TSteps, TInput, TOutput>> {
|
|
453
|
+
const runIdToUse = options?.runId || randomUUID();
|
|
454
|
+
|
|
455
|
+
// Return a new Run instance with object parameters
|
|
456
|
+
const run: Run<TEngineType, TSteps, TInput, TOutput> =
|
|
457
|
+
this.runs.get(runIdToUse) ??
|
|
458
|
+
new InngestRun(
|
|
459
|
+
{
|
|
460
|
+
workflowId: this.id,
|
|
461
|
+
runId: runIdToUse,
|
|
462
|
+
executionEngine: this.executionEngine,
|
|
463
|
+
executionGraph: this.executionGraph,
|
|
464
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
465
|
+
mastra: this.#mastra,
|
|
466
|
+
retryConfig: this.retryConfig,
|
|
467
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
468
|
+
},
|
|
469
|
+
this.inngest,
|
|
470
|
+
);
|
|
471
|
+
|
|
472
|
+
this.runs.set(runIdToUse, run);
|
|
473
|
+
|
|
474
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
|
|
475
|
+
|
|
476
|
+
if (!workflowSnapshotInStorage) {
|
|
477
|
+
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
478
|
+
workflowName: this.id,
|
|
479
|
+
runId: runIdToUse,
|
|
480
|
+
snapshot: {
|
|
481
|
+
runId: runIdToUse,
|
|
482
|
+
status: 'pending',
|
|
483
|
+
value: {},
|
|
484
|
+
context: {},
|
|
485
|
+
activePaths: [],
|
|
486
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
487
|
+
suspendedPaths: {},
|
|
488
|
+
result: undefined,
|
|
489
|
+
error: undefined,
|
|
490
|
+
// @ts-ignore
|
|
491
|
+
timestamp: Date.now(),
|
|
492
|
+
},
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
return run;
|
|
497
|
+
}
|
|
498
|
+
|
|
412
499
|
getFunction() {
|
|
413
500
|
if (this.function) {
|
|
414
501
|
return this.function;
|
|
415
502
|
}
|
|
416
503
|
this.function = this.inngest.createFunction(
|
|
417
|
-
|
|
418
|
-
|
|
504
|
+
{
|
|
505
|
+
id: `workflow.${this.id}`,
|
|
506
|
+
// @ts-ignore
|
|
507
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
508
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
509
|
+
},
|
|
419
510
|
{ event: `workflow.${this.id}` },
|
|
420
511
|
async ({ event, step, attempt, publish }) => {
|
|
421
512
|
let { inputData, runId, resume } = event.data;
|
|
@@ -464,6 +555,7 @@ export class InngestWorkflow<
|
|
|
464
555
|
retryConfig: this.retryConfig,
|
|
465
556
|
runtimeContext: new RuntimeContext(), // TODO
|
|
466
557
|
resume,
|
|
558
|
+
abortController: new AbortController(),
|
|
467
559
|
});
|
|
468
560
|
|
|
469
561
|
return { result, runId };
|
|
@@ -586,7 +678,7 @@ export function createStep<
|
|
|
586
678
|
outputSchema: z.object({
|
|
587
679
|
text: z.string(),
|
|
588
680
|
}),
|
|
589
|
-
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext }) => {
|
|
681
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
|
|
590
682
|
let streamPromise = {} as {
|
|
591
683
|
promise: Promise<string>;
|
|
592
684
|
resolve: (value: string) => void;
|
|
@@ -612,8 +704,13 @@ export function createStep<
|
|
|
612
704
|
onFinish: result => {
|
|
613
705
|
streamPromise.resolve(result.text);
|
|
614
706
|
},
|
|
707
|
+
abortSignal,
|
|
615
708
|
});
|
|
616
709
|
|
|
710
|
+
if (abortSignal.aborted) {
|
|
711
|
+
return abort();
|
|
712
|
+
}
|
|
713
|
+
|
|
617
714
|
for await (const chunk of fullStream) {
|
|
618
715
|
switch (chunk.type) {
|
|
619
716
|
case 'text-delta':
|
|
@@ -722,11 +819,12 @@ export function init(inngest: Inngest) {
|
|
|
722
819
|
any,
|
|
723
820
|
InngestEngineType
|
|
724
821
|
>[],
|
|
822
|
+
TPrevSchema extends z.ZodType<any> = TInput,
|
|
725
823
|
>(
|
|
726
|
-
workflow: Workflow<InngestEngineType, TSteps, string, TInput, TOutput,
|
|
824
|
+
workflow: Workflow<InngestEngineType, TSteps, string, TInput, TOutput, TPrevSchema>,
|
|
727
825
|
opts: { id: TWorkflowId },
|
|
728
|
-
): Workflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput,
|
|
729
|
-
const wf = new Workflow({
|
|
826
|
+
): Workflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> {
|
|
827
|
+
const wf: Workflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> = new Workflow({
|
|
730
828
|
id: opts.id,
|
|
731
829
|
inputSchema: workflow.inputSchema,
|
|
732
830
|
outputSchema: workflow.outputSchema,
|
|
@@ -770,6 +868,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
770
868
|
delay?: number;
|
|
771
869
|
};
|
|
772
870
|
runtimeContext: RuntimeContext;
|
|
871
|
+
abortController: AbortController;
|
|
773
872
|
}): Promise<TOutput> {
|
|
774
873
|
await params.emitter.emit('watch-v2', {
|
|
775
874
|
type: 'start',
|
|
@@ -869,7 +968,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
869
968
|
resume,
|
|
870
969
|
prevOutput,
|
|
871
970
|
emitter,
|
|
971
|
+
abortController,
|
|
872
972
|
runtimeContext,
|
|
973
|
+
writableStream,
|
|
873
974
|
}: {
|
|
874
975
|
workflowId: string;
|
|
875
976
|
runId: string;
|
|
@@ -882,7 +983,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
882
983
|
};
|
|
883
984
|
prevOutput: any;
|
|
884
985
|
emitter: Emitter;
|
|
986
|
+
abortController: AbortController;
|
|
885
987
|
runtimeContext: RuntimeContext;
|
|
988
|
+
writableStream?: WritableStream<ChunkType>;
|
|
886
989
|
}): Promise<StepResult<any, any, any, any>> {
|
|
887
990
|
return super.executeStep({
|
|
888
991
|
workflowId,
|
|
@@ -893,12 +996,190 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
893
996
|
resume,
|
|
894
997
|
prevOutput,
|
|
895
998
|
emitter,
|
|
999
|
+
abortController,
|
|
896
1000
|
runtimeContext,
|
|
1001
|
+
writableStream,
|
|
897
1002
|
});
|
|
898
1003
|
}
|
|
899
1004
|
|
|
900
|
-
async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
901
|
-
|
|
1005
|
+
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
1006
|
+
// await this.inngestStep.sleep(id, duration);
|
|
1007
|
+
// }
|
|
1008
|
+
|
|
1009
|
+
async executeSleep({
|
|
1010
|
+
workflowId,
|
|
1011
|
+
runId,
|
|
1012
|
+
entry,
|
|
1013
|
+
prevOutput,
|
|
1014
|
+
stepResults,
|
|
1015
|
+
emitter,
|
|
1016
|
+
abortController,
|
|
1017
|
+
runtimeContext,
|
|
1018
|
+
writableStream,
|
|
1019
|
+
}: {
|
|
1020
|
+
workflowId: string;
|
|
1021
|
+
runId: string;
|
|
1022
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
1023
|
+
entry: {
|
|
1024
|
+
type: 'sleep';
|
|
1025
|
+
id: string;
|
|
1026
|
+
duration?: number;
|
|
1027
|
+
fn?: ExecuteFunction<any, any, any, any, InngestEngineType>;
|
|
1028
|
+
};
|
|
1029
|
+
prevStep: StepFlowEntry;
|
|
1030
|
+
prevOutput: any;
|
|
1031
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
1032
|
+
resume?: {
|
|
1033
|
+
steps: string[];
|
|
1034
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
1035
|
+
resumePayload: any;
|
|
1036
|
+
resumePath: number[];
|
|
1037
|
+
};
|
|
1038
|
+
executionContext: ExecutionContext;
|
|
1039
|
+
emitter: Emitter;
|
|
1040
|
+
abortController: AbortController;
|
|
1041
|
+
runtimeContext: RuntimeContext;
|
|
1042
|
+
writableStream?: WritableStream<ChunkType>;
|
|
1043
|
+
}): Promise<void> {
|
|
1044
|
+
let { duration, fn } = entry;
|
|
1045
|
+
|
|
1046
|
+
if (fn) {
|
|
1047
|
+
const stepCallId = randomUUID();
|
|
1048
|
+
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
1049
|
+
return await fn({
|
|
1050
|
+
runId,
|
|
1051
|
+
workflowId,
|
|
1052
|
+
mastra: this.mastra!,
|
|
1053
|
+
runtimeContext,
|
|
1054
|
+
inputData: prevOutput,
|
|
1055
|
+
runCount: -1,
|
|
1056
|
+
getInitData: () => stepResults?.input as any,
|
|
1057
|
+
getStepResult: (step: any) => {
|
|
1058
|
+
if (!step?.id) {
|
|
1059
|
+
return null;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
const result = stepResults[step.id];
|
|
1063
|
+
if (result?.status === 'success') {
|
|
1064
|
+
return result.output;
|
|
1065
|
+
}
|
|
1066
|
+
|
|
1067
|
+
return null;
|
|
1068
|
+
},
|
|
1069
|
+
|
|
1070
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1071
|
+
suspend: async (_suspendPayload: any): Promise<any> => {},
|
|
1072
|
+
bail: () => {},
|
|
1073
|
+
abort: () => {
|
|
1074
|
+
abortController?.abort();
|
|
1075
|
+
},
|
|
1076
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1077
|
+
engine: { step: this.inngestStep },
|
|
1078
|
+
abortSignal: abortController?.signal,
|
|
1079
|
+
writer: new ToolStream(
|
|
1080
|
+
{
|
|
1081
|
+
prefix: 'step',
|
|
1082
|
+
callId: stepCallId,
|
|
1083
|
+
name: 'sleep',
|
|
1084
|
+
runId,
|
|
1085
|
+
},
|
|
1086
|
+
writableStream,
|
|
1087
|
+
),
|
|
1088
|
+
});
|
|
1089
|
+
});
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
1093
|
+
}
|
|
1094
|
+
|
|
1095
|
+
async executeSleepUntil({
|
|
1096
|
+
workflowId,
|
|
1097
|
+
runId,
|
|
1098
|
+
entry,
|
|
1099
|
+
prevOutput,
|
|
1100
|
+
stepResults,
|
|
1101
|
+
emitter,
|
|
1102
|
+
abortController,
|
|
1103
|
+
runtimeContext,
|
|
1104
|
+
writableStream,
|
|
1105
|
+
}: {
|
|
1106
|
+
workflowId: string;
|
|
1107
|
+
runId: string;
|
|
1108
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
1109
|
+
entry: {
|
|
1110
|
+
type: 'sleepUntil';
|
|
1111
|
+
id: string;
|
|
1112
|
+
date?: Date;
|
|
1113
|
+
fn?: ExecuteFunction<any, any, any, any, InngestEngineType>;
|
|
1114
|
+
};
|
|
1115
|
+
prevStep: StepFlowEntry;
|
|
1116
|
+
prevOutput: any;
|
|
1117
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
1118
|
+
resume?: {
|
|
1119
|
+
steps: string[];
|
|
1120
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
1121
|
+
resumePayload: any;
|
|
1122
|
+
resumePath: number[];
|
|
1123
|
+
};
|
|
1124
|
+
executionContext: ExecutionContext;
|
|
1125
|
+
emitter: Emitter;
|
|
1126
|
+
abortController: AbortController;
|
|
1127
|
+
runtimeContext: RuntimeContext;
|
|
1128
|
+
writableStream?: WritableStream<ChunkType>;
|
|
1129
|
+
}): Promise<void> {
|
|
1130
|
+
let { date, fn } = entry;
|
|
1131
|
+
|
|
1132
|
+
if (fn) {
|
|
1133
|
+
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
1134
|
+
const stepCallId = randomUUID();
|
|
1135
|
+
return await fn({
|
|
1136
|
+
runId,
|
|
1137
|
+
workflowId,
|
|
1138
|
+
mastra: this.mastra!,
|
|
1139
|
+
runtimeContext,
|
|
1140
|
+
inputData: prevOutput,
|
|
1141
|
+
runCount: -1,
|
|
1142
|
+
getInitData: () => stepResults?.input as any,
|
|
1143
|
+
getStepResult: (step: any) => {
|
|
1144
|
+
if (!step?.id) {
|
|
1145
|
+
return null;
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
const result = stepResults[step.id];
|
|
1149
|
+
if (result?.status === 'success') {
|
|
1150
|
+
return result.output;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
return null;
|
|
1154
|
+
},
|
|
1155
|
+
|
|
1156
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1157
|
+
suspend: async (_suspendPayload: any): Promise<any> => {},
|
|
1158
|
+
bail: () => {},
|
|
1159
|
+
abort: () => {
|
|
1160
|
+
abortController?.abort();
|
|
1161
|
+
},
|
|
1162
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1163
|
+
engine: { step: this.inngestStep },
|
|
1164
|
+
abortSignal: abortController?.signal,
|
|
1165
|
+
writer: new ToolStream(
|
|
1166
|
+
{
|
|
1167
|
+
prefix: 'step',
|
|
1168
|
+
callId: stepCallId,
|
|
1169
|
+
name: 'sleep',
|
|
1170
|
+
runId,
|
|
1171
|
+
},
|
|
1172
|
+
writableStream,
|
|
1173
|
+
),
|
|
1174
|
+
});
|
|
1175
|
+
});
|
|
1176
|
+
}
|
|
1177
|
+
|
|
1178
|
+
if (!(date instanceof Date)) {
|
|
1179
|
+
return;
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
await this.inngestStep.sleepUntil(entry.id, date);
|
|
902
1183
|
}
|
|
903
1184
|
|
|
904
1185
|
async executeWaitForEvent({ event, timeout }: { event: string; timeout?: number }): Promise<any> {
|
|
@@ -921,17 +1202,13 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
921
1202
|
resume,
|
|
922
1203
|
prevOutput,
|
|
923
1204
|
emitter,
|
|
1205
|
+
abortController,
|
|
924
1206
|
runtimeContext,
|
|
1207
|
+
writableStream,
|
|
925
1208
|
}: {
|
|
926
1209
|
step: Step<string, any, any>;
|
|
927
1210
|
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
928
|
-
executionContext:
|
|
929
|
-
workflowId: string;
|
|
930
|
-
runId: string;
|
|
931
|
-
executionPath: number[];
|
|
932
|
-
suspendedPaths: Record<string, number[]>;
|
|
933
|
-
retryConfig: { attempts: number; delay: number };
|
|
934
|
-
};
|
|
1211
|
+
executionContext: ExecutionContext;
|
|
935
1212
|
resume?: {
|
|
936
1213
|
steps: string[];
|
|
937
1214
|
resumePayload: any;
|
|
@@ -939,7 +1216,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
939
1216
|
};
|
|
940
1217
|
prevOutput: any;
|
|
941
1218
|
emitter: Emitter;
|
|
1219
|
+
abortController: AbortController;
|
|
942
1220
|
runtimeContext: RuntimeContext;
|
|
1221
|
+
writableStream?: WritableStream<ChunkType>;
|
|
943
1222
|
}): Promise<StepResult<any, any, any, any>> {
|
|
944
1223
|
const startedAt = await this.inngestStep.run(
|
|
945
1224
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
@@ -971,6 +1250,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
971
1250
|
type: 'step-start',
|
|
972
1251
|
payload: {
|
|
973
1252
|
id: step.id,
|
|
1253
|
+
status: 'running',
|
|
1254
|
+
payload: prevOutput,
|
|
1255
|
+
startedAt,
|
|
974
1256
|
},
|
|
975
1257
|
});
|
|
976
1258
|
|
|
@@ -1046,6 +1328,8 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1046
1328
|
payload: {
|
|
1047
1329
|
id: step.id,
|
|
1048
1330
|
status: 'failed',
|
|
1331
|
+
error: result?.error,
|
|
1332
|
+
payload: prevOutput,
|
|
1049
1333
|
},
|
|
1050
1334
|
});
|
|
1051
1335
|
|
|
@@ -1083,6 +1367,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1083
1367
|
type: 'step-suspended',
|
|
1084
1368
|
payload: {
|
|
1085
1369
|
id: step.id,
|
|
1370
|
+
status: 'suspended',
|
|
1086
1371
|
},
|
|
1087
1372
|
});
|
|
1088
1373
|
|
|
@@ -1142,6 +1427,15 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1142
1427
|
eventTimestamp: Date.now(),
|
|
1143
1428
|
});
|
|
1144
1429
|
|
|
1430
|
+
await emitter.emit('watch-v2', {
|
|
1431
|
+
type: 'step-result',
|
|
1432
|
+
payload: {
|
|
1433
|
+
id: step.id,
|
|
1434
|
+
status: 'success',
|
|
1435
|
+
output: result?.result,
|
|
1436
|
+
},
|
|
1437
|
+
});
|
|
1438
|
+
|
|
1145
1439
|
await emitter.emit('watch-v2', {
|
|
1146
1440
|
type: 'step-finish',
|
|
1147
1441
|
payload: {
|
|
@@ -1161,12 +1455,14 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1161
1455
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1162
1456
|
let execResults: any;
|
|
1163
1457
|
let suspended: { payload: any } | undefined;
|
|
1458
|
+
let bailed: { payload: any } | undefined;
|
|
1164
1459
|
|
|
1165
1460
|
try {
|
|
1166
1461
|
const result = await step.execute({
|
|
1167
1462
|
runId: executionContext.runId,
|
|
1168
1463
|
mastra: this.mastra!,
|
|
1169
1464
|
runtimeContext,
|
|
1465
|
+
writableStream,
|
|
1170
1466
|
inputData: prevOutput,
|
|
1171
1467
|
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
|
|
1172
1468
|
getInitData: () => stepResults?.input as any,
|
|
@@ -1182,6 +1478,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1182
1478
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1183
1479
|
suspended = { payload: suspendPayload };
|
|
1184
1480
|
},
|
|
1481
|
+
bail: (result: any) => {
|
|
1482
|
+
bailed = { payload: result };
|
|
1483
|
+
},
|
|
1185
1484
|
resume: {
|
|
1186
1485
|
steps: resume?.steps?.slice(1) || [],
|
|
1187
1486
|
resumePayload: resume?.resumePayload,
|
|
@@ -1192,6 +1491,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1192
1491
|
engine: {
|
|
1193
1492
|
step: this.inngestStep,
|
|
1194
1493
|
},
|
|
1494
|
+
abortSignal: abortController.signal,
|
|
1195
1495
|
});
|
|
1196
1496
|
const endedAt = Date.now();
|
|
1197
1497
|
|
|
@@ -1226,6 +1526,8 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1226
1526
|
resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,
|
|
1227
1527
|
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
|
|
1228
1528
|
};
|
|
1529
|
+
} else if (bailed) {
|
|
1530
|
+
execResults = { status: 'bailed', output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
1229
1531
|
}
|
|
1230
1532
|
|
|
1231
1533
|
if (execResults.status === 'failed') {
|
|
@@ -1256,8 +1558,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1256
1558
|
type: 'step-suspended',
|
|
1257
1559
|
payload: {
|
|
1258
1560
|
id: step.id,
|
|
1259
|
-
|
|
1260
|
-
output: execResults.status === 'success' ? execResults?.output : undefined,
|
|
1561
|
+
...execResults,
|
|
1261
1562
|
},
|
|
1262
1563
|
});
|
|
1263
1564
|
} else {
|
|
@@ -1265,8 +1566,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1265
1566
|
type: 'step-result',
|
|
1266
1567
|
payload: {
|
|
1267
1568
|
id: step.id,
|
|
1268
|
-
|
|
1269
|
-
output: execResults.status === 'success' ? execResults?.output : undefined,
|
|
1569
|
+
...execResults,
|
|
1270
1570
|
},
|
|
1271
1571
|
});
|
|
1272
1572
|
|
|
@@ -1309,6 +1609,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1309
1609
|
workflowStatus: 'success' | 'failed' | 'suspended' | 'running';
|
|
1310
1610
|
result?: Record<string, any>;
|
|
1311
1611
|
error?: string | Error;
|
|
1612
|
+
runtimeContext: RuntimeContext;
|
|
1312
1613
|
}) {
|
|
1313
1614
|
await this.inngestStep.run(
|
|
1314
1615
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -1345,7 +1646,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1345
1646
|
resume,
|
|
1346
1647
|
executionContext,
|
|
1347
1648
|
emitter,
|
|
1649
|
+
abortController,
|
|
1348
1650
|
runtimeContext,
|
|
1651
|
+
writableStream,
|
|
1349
1652
|
}: {
|
|
1350
1653
|
workflowId: string;
|
|
1351
1654
|
runId: string;
|
|
@@ -1366,7 +1669,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1366
1669
|
};
|
|
1367
1670
|
executionContext: ExecutionContext;
|
|
1368
1671
|
emitter: Emitter;
|
|
1672
|
+
abortController: AbortController;
|
|
1369
1673
|
runtimeContext: RuntimeContext;
|
|
1674
|
+
writableStream?: WritableStream<ChunkType>;
|
|
1370
1675
|
}): Promise<StepResult<any, any, any, any>> {
|
|
1371
1676
|
let execResults: any;
|
|
1372
1677
|
const truthyIndexes = (
|
|
@@ -1376,8 +1681,10 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1376
1681
|
try {
|
|
1377
1682
|
const result = await cond({
|
|
1378
1683
|
runId,
|
|
1684
|
+
workflowId,
|
|
1379
1685
|
mastra: this.mastra!,
|
|
1380
1686
|
runtimeContext,
|
|
1687
|
+
runCount: -1,
|
|
1381
1688
|
inputData: prevOutput,
|
|
1382
1689
|
getInitData: () => stepResults?.input as any,
|
|
1383
1690
|
getStepResult: (step: any) => {
|
|
@@ -1395,10 +1702,24 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1395
1702
|
|
|
1396
1703
|
// TODO: this function shouldn't have suspend probably?
|
|
1397
1704
|
suspend: async (_suspendPayload: any) => {},
|
|
1705
|
+
bail: () => {},
|
|
1706
|
+
abort: () => {
|
|
1707
|
+
abortController.abort();
|
|
1708
|
+
},
|
|
1398
1709
|
[EMITTER_SYMBOL]: emitter,
|
|
1399
1710
|
engine: {
|
|
1400
1711
|
step: this.inngestStep,
|
|
1401
1712
|
},
|
|
1713
|
+
abortSignal: abortController.signal,
|
|
1714
|
+
writer: new ToolStream(
|
|
1715
|
+
{
|
|
1716
|
+
prefix: 'step',
|
|
1717
|
+
callId: randomUUID(),
|
|
1718
|
+
name: 'conditional',
|
|
1719
|
+
runId,
|
|
1720
|
+
},
|
|
1721
|
+
writableStream,
|
|
1722
|
+
),
|
|
1402
1723
|
});
|
|
1403
1724
|
return result ? index : null;
|
|
1404
1725
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -1430,7 +1751,9 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
1430
1751
|
executionSpan: executionContext.executionSpan,
|
|
1431
1752
|
},
|
|
1432
1753
|
emitter,
|
|
1754
|
+
abortController,
|
|
1433
1755
|
runtimeContext,
|
|
1756
|
+
writableStream,
|
|
1434
1757
|
}),
|
|
1435
1758
|
),
|
|
1436
1759
|
);
|
package/tsconfig.json
CHANGED
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
import { defineConfig } from 'tsup';
|
|
4
|
+
|
|
5
|
+
const exec = promisify(spawn);
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
entry: ['src/index.ts'],
|
|
9
|
+
format: ['esm', 'cjs'],
|
|
10
|
+
clean: true,
|
|
11
|
+
dts: false,
|
|
12
|
+
splitting: true,
|
|
13
|
+
treeshake: {
|
|
14
|
+
preset: 'smallest',
|
|
15
|
+
},
|
|
16
|
+
sourcemap: true,
|
|
17
|
+
onSuccess: async () => {
|
|
18
|
+
await exec('pnpm', ['tsc', '-p', 'tsconfig.build.json'], {
|
|
19
|
+
stdio: 'inherit',
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
});
|