@mastra/inngest 0.0.0-redis-cloud-transporter-20250508203756 → 0.0.0-scorers-api-v2-20250801171841
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 +715 -2
- package/LICENSE.md +11 -42
- package/dist/index.cjs +630 -64
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +282 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +627 -62
- package/dist/index.js.map +1 -0
- package/docker-compose.yaml +3 -3
- package/package.json +24 -19
- package/src/index.test.ts +5927 -3549
- package/src/index.ts +931 -103
- 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 -194
- package/dist/_tsup-dts-rollup.d.ts +0 -194
- package/dist/index.d.cts +0 -5
package/src/index.ts
CHANGED
|
@@ -1,34 +1,50 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
+
import type { ReadableStream } from 'node:stream/web';
|
|
2
3
|
import { subscribe } from '@inngest/realtime';
|
|
3
|
-
import type { Mastra, WorkflowRun } from '@mastra/core';
|
|
4
|
+
import type { Agent, Mastra, ToolExecutionContext, WorkflowRun, WorkflowRuns } from '@mastra/core';
|
|
4
5
|
import { RuntimeContext } from '@mastra/core/di';
|
|
5
|
-
import {
|
|
6
|
+
import { Tool, ToolStream } from '@mastra/core/tools';
|
|
7
|
+
import { Workflow, Run, DefaultExecutionEngine } from '@mastra/core/workflows';
|
|
6
8
|
import type {
|
|
7
9
|
ExecuteFunction,
|
|
8
10
|
ExecutionContext,
|
|
9
11
|
ExecutionEngine,
|
|
10
12
|
ExecutionGraph,
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
NewWorkflowConfig,
|
|
13
|
+
Step,
|
|
14
|
+
WorkflowConfig,
|
|
14
15
|
StepFlowEntry,
|
|
15
16
|
StepResult,
|
|
16
17
|
WorkflowResult,
|
|
17
|
-
|
|
18
|
+
SerializedStepFlowEntry,
|
|
19
|
+
StepFailure,
|
|
20
|
+
Emitter,
|
|
21
|
+
WatchEvent,
|
|
22
|
+
StreamEvent,
|
|
23
|
+
ChunkType,
|
|
24
|
+
} from '@mastra/core/workflows';
|
|
25
|
+
import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
|
|
18
26
|
import type { Span } from '@opentelemetry/api';
|
|
19
27
|
import type { Inngest, BaseContext } from 'inngest';
|
|
20
28
|
import { serve as inngestServe } from 'inngest/hono';
|
|
21
|
-
import
|
|
29
|
+
import { z } from 'zod';
|
|
30
|
+
|
|
31
|
+
export type InngestEngineType = {
|
|
32
|
+
step: any;
|
|
33
|
+
};
|
|
22
34
|
|
|
23
35
|
export function serve({ mastra, inngest }: { mastra: Mastra; inngest: Inngest }): ReturnType<typeof inngestServe> {
|
|
24
|
-
const wfs = mastra.
|
|
25
|
-
const functions =
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
const wfs = mastra.getWorkflows();
|
|
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
|
+
);
|
|
32
48
|
return inngestServe({
|
|
33
49
|
client: inngest,
|
|
34
50
|
functions,
|
|
@@ -36,11 +52,13 @@ export function serve({ mastra, inngest }: { mastra: Mastra; inngest: Inngest })
|
|
|
36
52
|
}
|
|
37
53
|
|
|
38
54
|
export class InngestRun<
|
|
39
|
-
|
|
55
|
+
TEngineType = InngestEngineType,
|
|
56
|
+
TSteps extends Step<string, any, any>[] = Step<string, any, any>[],
|
|
40
57
|
TInput extends z.ZodType<any> = z.ZodType<any>,
|
|
41
58
|
TOutput extends z.ZodType<any> = z.ZodType<any>,
|
|
42
|
-
> extends Run<TSteps, TInput, TOutput> {
|
|
59
|
+
> extends Run<TEngineType, TSteps, TInput, TOutput> {
|
|
43
60
|
private inngest: Inngest;
|
|
61
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
44
62
|
#mastra: Mastra;
|
|
45
63
|
|
|
46
64
|
constructor(
|
|
@@ -49,6 +67,7 @@ export class InngestRun<
|
|
|
49
67
|
runId: string;
|
|
50
68
|
executionEngine: ExecutionEngine;
|
|
51
69
|
executionGraph: ExecutionGraph;
|
|
70
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
52
71
|
mastra?: Mastra;
|
|
53
72
|
retryConfig?: {
|
|
54
73
|
attempts?: number;
|
|
@@ -60,11 +79,12 @@ export class InngestRun<
|
|
|
60
79
|
) {
|
|
61
80
|
super(params);
|
|
62
81
|
this.inngest = inngest;
|
|
82
|
+
this.serializedStepGraph = params.serializedStepGraph;
|
|
63
83
|
this.#mastra = params.mastra!;
|
|
64
84
|
}
|
|
65
85
|
|
|
66
86
|
async getRuns(eventId: string) {
|
|
67
|
-
const response = await fetch(`${this.inngest.apiBaseUrl}/v1/events/${eventId}/runs`, {
|
|
87
|
+
const response = await fetch(`${this.inngest.apiBaseUrl ?? 'https://api.inngest.com'}/v1/events/${eventId}/runs`, {
|
|
68
88
|
headers: {
|
|
69
89
|
Authorization: `Bearer ${process.env.INNGEST_SIGNING_KEY}`,
|
|
70
90
|
},
|
|
@@ -75,16 +95,55 @@ export class InngestRun<
|
|
|
75
95
|
|
|
76
96
|
async getRunOutput(eventId: string) {
|
|
77
97
|
let runs = await this.getRuns(eventId);
|
|
78
|
-
|
|
98
|
+
|
|
99
|
+
while (runs?.[0]?.status !== 'Completed' || runs?.[0]?.event_id !== eventId) {
|
|
79
100
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
80
101
|
runs = await this.getRuns(eventId);
|
|
81
|
-
if (runs?.[0]?.status === 'Failed'
|
|
102
|
+
if (runs?.[0]?.status === 'Failed') {
|
|
103
|
+
console.log('run', runs?.[0]);
|
|
82
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' } } };
|
|
83
111
|
}
|
|
84
112
|
}
|
|
85
113
|
return runs?.[0];
|
|
86
114
|
}
|
|
87
115
|
|
|
116
|
+
async sendEvent(event: string, data: any) {
|
|
117
|
+
await this.inngest.send({
|
|
118
|
+
name: `user-event-${event}`,
|
|
119
|
+
data,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
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
|
+
|
|
88
147
|
async start({
|
|
89
148
|
inputData,
|
|
90
149
|
}: {
|
|
@@ -96,11 +155,13 @@ export class InngestRun<
|
|
|
96
155
|
runId: this.runId,
|
|
97
156
|
snapshot: {
|
|
98
157
|
runId: this.runId,
|
|
158
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
99
159
|
value: {},
|
|
100
160
|
context: {} as any,
|
|
101
161
|
activePaths: [],
|
|
102
162
|
suspendedPaths: {},
|
|
103
163
|
timestamp: Date.now(),
|
|
164
|
+
status: 'running',
|
|
104
165
|
},
|
|
105
166
|
});
|
|
106
167
|
|
|
@@ -122,7 +183,9 @@ export class InngestRun<
|
|
|
122
183
|
result.error = new Error(result.error);
|
|
123
184
|
}
|
|
124
185
|
|
|
125
|
-
|
|
186
|
+
if (result.status !== 'suspended') {
|
|
187
|
+
this.cleanup?.();
|
|
188
|
+
}
|
|
126
189
|
return result;
|
|
127
190
|
}
|
|
128
191
|
|
|
@@ -134,6 +197,27 @@ export class InngestRun<
|
|
|
134
197
|
| string
|
|
135
198
|
| string[];
|
|
136
199
|
runtimeContext?: RuntimeContext;
|
|
200
|
+
}): Promise<WorkflowResult<TOutput, TSteps>> {
|
|
201
|
+
const p = this._resume(params).then(result => {
|
|
202
|
+
if (result.status !== 'suspended') {
|
|
203
|
+
this.closeStreamAction?.().catch(() => {});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return result;
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
this.executionResults = p;
|
|
210
|
+
return p;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
async _resume<TResumeSchema extends z.ZodType<any>>(params: {
|
|
214
|
+
resumeData?: z.infer<TResumeSchema>;
|
|
215
|
+
step:
|
|
216
|
+
| Step<string, any, any, TResumeSchema, any>
|
|
217
|
+
| [...Step<string, any, any, any, any>[], Step<string, any, any, TResumeSchema, any>]
|
|
218
|
+
| string
|
|
219
|
+
| string[];
|
|
220
|
+
runtimeContext?: RuntimeContext;
|
|
137
221
|
}): Promise<WorkflowResult<TOutput, TSteps>> {
|
|
138
222
|
const steps: string[] = (Array.isArray(params.step) ? params.step : [params.step]).map(step =>
|
|
139
223
|
typeof step === 'string' ? step : step?.id,
|
|
@@ -148,6 +232,7 @@ export class InngestRun<
|
|
|
148
232
|
data: {
|
|
149
233
|
inputData: params.resumeData,
|
|
150
234
|
runId: this.runId,
|
|
235
|
+
workflowId: this.workflowId,
|
|
151
236
|
stepResults: snapshot?.context as any,
|
|
152
237
|
resume: {
|
|
153
238
|
steps,
|
|
@@ -171,43 +256,88 @@ export class InngestRun<
|
|
|
171
256
|
return result;
|
|
172
257
|
}
|
|
173
258
|
|
|
174
|
-
watch(cb: (event:
|
|
259
|
+
watch(cb: (event: WatchEvent) => void, type: 'watch' | 'watch-v2' = 'watch'): () => void {
|
|
260
|
+
let active = true;
|
|
175
261
|
const streamPromise = subscribe(
|
|
176
262
|
{
|
|
177
263
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
178
|
-
topics: [
|
|
264
|
+
topics: [type],
|
|
179
265
|
app: this.inngest,
|
|
180
266
|
},
|
|
181
267
|
(message: any) => {
|
|
182
|
-
|
|
268
|
+
if (active) {
|
|
269
|
+
cb(message.data);
|
|
270
|
+
}
|
|
183
271
|
},
|
|
184
272
|
);
|
|
185
273
|
|
|
186
274
|
return () => {
|
|
275
|
+
active = false;
|
|
187
276
|
streamPromise
|
|
188
|
-
.then((stream:
|
|
189
|
-
stream.cancel();
|
|
277
|
+
.then(async (stream: Awaited<typeof streamPromise>) => {
|
|
278
|
+
return stream.cancel();
|
|
190
279
|
})
|
|
191
280
|
.catch(err => {
|
|
192
281
|
console.error(err);
|
|
193
282
|
});
|
|
194
283
|
};
|
|
195
284
|
}
|
|
285
|
+
|
|
286
|
+
stream({ inputData, runtimeContext }: { inputData?: z.infer<TInput>; runtimeContext?: RuntimeContext } = {}): {
|
|
287
|
+
stream: ReadableStream<StreamEvent>;
|
|
288
|
+
getWorkflowState: () => Promise<WorkflowResult<TOutput, TSteps>>;
|
|
289
|
+
} {
|
|
290
|
+
const { readable, writable } = new TransformStream<StreamEvent, StreamEvent>();
|
|
291
|
+
|
|
292
|
+
const writer = writable.getWriter();
|
|
293
|
+
const unwatch = this.watch(async event => {
|
|
294
|
+
try {
|
|
295
|
+
// watch-v2 events are data stream events, so we need to cast them to the correct type
|
|
296
|
+
await writer.write(event as any);
|
|
297
|
+
} catch {}
|
|
298
|
+
}, 'watch-v2');
|
|
299
|
+
|
|
300
|
+
this.closeStreamAction = async () => {
|
|
301
|
+
unwatch();
|
|
302
|
+
|
|
303
|
+
try {
|
|
304
|
+
await writer.close();
|
|
305
|
+
} catch (err) {
|
|
306
|
+
console.error('Error closing stream:', err);
|
|
307
|
+
} finally {
|
|
308
|
+
writer.releaseLock();
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
this.executionResults = this.start({ inputData, runtimeContext }).then(result => {
|
|
313
|
+
if (result.status !== 'suspended') {
|
|
314
|
+
this.closeStreamAction?.().catch(() => {});
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
return result;
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
return {
|
|
321
|
+
stream: readable as ReadableStream<StreamEvent>,
|
|
322
|
+
getWorkflowState: () => this.executionResults!,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
196
325
|
}
|
|
197
326
|
|
|
198
327
|
export class InngestWorkflow<
|
|
199
|
-
|
|
328
|
+
TEngineType = InngestEngineType,
|
|
329
|
+
TSteps extends Step<string, any, any>[] = Step<string, any, any>[],
|
|
200
330
|
TWorkflowId extends string = string,
|
|
201
331
|
TInput extends z.ZodType<any> = z.ZodType<any>,
|
|
202
332
|
TOutput extends z.ZodType<any> = z.ZodType<any>,
|
|
203
333
|
TPrevSchema extends z.ZodType<any> = TInput,
|
|
204
|
-
> extends
|
|
334
|
+
> extends Workflow<TEngineType, TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> {
|
|
205
335
|
#mastra: Mastra;
|
|
206
336
|
public inngest: Inngest;
|
|
207
337
|
|
|
208
338
|
private function: ReturnType<Inngest['createFunction']> | undefined;
|
|
209
339
|
|
|
210
|
-
constructor(params:
|
|
340
|
+
constructor(params: WorkflowConfig<TWorkflowId, TInput, TOutput, TSteps>, inngest: Inngest) {
|
|
211
341
|
super(params);
|
|
212
342
|
this.#mastra = params.mastra!;
|
|
213
343
|
this.inngest = inngest;
|
|
@@ -226,16 +356,19 @@ export class InngestWorkflow<
|
|
|
226
356
|
return { runs: [], total: 0 };
|
|
227
357
|
}
|
|
228
358
|
|
|
229
|
-
return storage.getWorkflowRuns({ workflowName: this.id, ...(args ?? {}) });
|
|
359
|
+
return storage.getWorkflowRuns({ workflowName: this.id, ...(args ?? {}) }) as unknown as WorkflowRuns;
|
|
230
360
|
}
|
|
231
361
|
|
|
232
362
|
async getWorkflowRunById(runId: string): Promise<WorkflowRun | null> {
|
|
233
363
|
const storage = this.#mastra?.getStorage();
|
|
234
364
|
if (!storage) {
|
|
235
365
|
this.logger.debug('Cannot get workflow runs. Mastra engine is not initialized');
|
|
236
|
-
|
|
366
|
+
//returning in memory run if no storage is initialized
|
|
367
|
+
return this.runs.get(runId)
|
|
368
|
+
? ({ ...this.runs.get(runId), workflowName: this.id } as unknown as WorkflowRun)
|
|
369
|
+
: null;
|
|
237
370
|
}
|
|
238
|
-
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
371
|
+
const run = (await storage.getWorkflowRunById({ runId, workflowName: this.id })) as unknown as WorkflowRun;
|
|
239
372
|
|
|
240
373
|
return (
|
|
241
374
|
run ??
|
|
@@ -243,6 +376,32 @@ export class InngestWorkflow<
|
|
|
243
376
|
);
|
|
244
377
|
}
|
|
245
378
|
|
|
379
|
+
async getWorkflowRunExecutionResult(runId: string): Promise<WatchEvent['payload']['workflowState'] | null> {
|
|
380
|
+
const storage = this.#mastra?.getStorage();
|
|
381
|
+
if (!storage) {
|
|
382
|
+
this.logger.debug('Cannot get workflow run execution result. Mastra storage is not initialized');
|
|
383
|
+
return null;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
387
|
+
|
|
388
|
+
if (!run?.snapshot) {
|
|
389
|
+
return null;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
if (typeof run.snapshot === 'string') {
|
|
393
|
+
return null;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
return {
|
|
397
|
+
status: run.snapshot.status,
|
|
398
|
+
result: run.snapshot.result,
|
|
399
|
+
error: run.snapshot.error,
|
|
400
|
+
payload: run.snapshot.context?.input,
|
|
401
|
+
steps: run.snapshot.context as any,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
246
405
|
__registerMastra(mastra: Mastra) {
|
|
247
406
|
this.#mastra = mastra;
|
|
248
407
|
this.executionEngine.__registerMastra(mastra);
|
|
@@ -266,11 +425,11 @@ export class InngestWorkflow<
|
|
|
266
425
|
}
|
|
267
426
|
}
|
|
268
427
|
|
|
269
|
-
createRun(options?: { runId?: string }): Run<TSteps, TInput, TOutput> {
|
|
428
|
+
createRun(options?: { runId?: string }): Run<TEngineType, TSteps, TInput, TOutput> {
|
|
270
429
|
const runIdToUse = options?.runId || randomUUID();
|
|
271
430
|
|
|
272
431
|
// Return a new Run instance with object parameters
|
|
273
|
-
const run: Run<TSteps, TInput, TOutput> =
|
|
432
|
+
const run: Run<TEngineType, TSteps, TInput, TOutput> =
|
|
274
433
|
this.runs.get(runIdToUse) ??
|
|
275
434
|
new InngestRun(
|
|
276
435
|
{
|
|
@@ -278,6 +437,7 @@ export class InngestWorkflow<
|
|
|
278
437
|
runId: runIdToUse,
|
|
279
438
|
executionEngine: this.executionEngine,
|
|
280
439
|
executionGraph: this.executionGraph,
|
|
440
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
281
441
|
mastra: this.#mastra,
|
|
282
442
|
retryConfig: this.retryConfig,
|
|
283
443
|
cleanup: () => this.runs.delete(runIdToUse),
|
|
@@ -289,13 +449,64 @@ export class InngestWorkflow<
|
|
|
289
449
|
return run;
|
|
290
450
|
}
|
|
291
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
|
+
|
|
292
499
|
getFunction() {
|
|
293
500
|
if (this.function) {
|
|
294
501
|
return this.function;
|
|
295
502
|
}
|
|
296
503
|
this.function = this.inngest.createFunction(
|
|
297
|
-
|
|
298
|
-
|
|
504
|
+
{
|
|
505
|
+
id: `workflow.${this.id}`,
|
|
506
|
+
// @ts-ignore
|
|
507
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
508
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
509
|
+
},
|
|
299
510
|
{ event: `workflow.${this.id}` },
|
|
300
511
|
async ({ event, step, attempt, publish }) => {
|
|
301
512
|
let { inputData, runId, resume } = event.data;
|
|
@@ -315,13 +526,22 @@ export class InngestWorkflow<
|
|
|
315
526
|
try {
|
|
316
527
|
await publish({
|
|
317
528
|
channel: `workflow:${this.id}:${runId}`,
|
|
318
|
-
topic:
|
|
529
|
+
topic: event,
|
|
319
530
|
data,
|
|
320
531
|
});
|
|
321
532
|
} catch (err: any) {
|
|
322
533
|
this.logger.error('Error emitting event: ' + (err?.stack ?? err?.message ?? err));
|
|
323
534
|
}
|
|
324
535
|
},
|
|
536
|
+
on: (_event: string, _callback: (data: any) => void) => {
|
|
537
|
+
// no-op
|
|
538
|
+
},
|
|
539
|
+
off: (_event: string, _callback: (data: any) => void) => {
|
|
540
|
+
// no-op
|
|
541
|
+
},
|
|
542
|
+
once: (_event: string, _callback: (data: any) => void) => {
|
|
543
|
+
// no-op
|
|
544
|
+
},
|
|
325
545
|
};
|
|
326
546
|
|
|
327
547
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
@@ -329,11 +549,13 @@ export class InngestWorkflow<
|
|
|
329
549
|
workflowId: this.id,
|
|
330
550
|
runId,
|
|
331
551
|
graph: this.executionGraph,
|
|
552
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
332
553
|
input: inputData,
|
|
333
554
|
emitter,
|
|
334
555
|
retryConfig: this.retryConfig,
|
|
335
556
|
runtimeContext: new RuntimeContext(), // TODO
|
|
336
557
|
resume,
|
|
558
|
+
abortController: new AbortController(),
|
|
337
559
|
});
|
|
338
560
|
|
|
339
561
|
return { result, runId };
|
|
@@ -362,29 +584,197 @@ export class InngestWorkflow<
|
|
|
362
584
|
}
|
|
363
585
|
}
|
|
364
586
|
|
|
365
|
-
function
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
587
|
+
function isAgent(params: any): params is Agent<any, any, any> {
|
|
588
|
+
return params?.component === 'AGENT';
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
function isTool(params: any): params is Tool<any, any, any> {
|
|
592
|
+
return params instanceof Tool;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
export function createStep<
|
|
596
|
+
TStepId extends string,
|
|
597
|
+
TStepInput extends z.ZodType<any>,
|
|
598
|
+
TStepOutput extends z.ZodType<any>,
|
|
599
|
+
TResumeSchema extends z.ZodType<any>,
|
|
600
|
+
TSuspendSchema extends z.ZodType<any>,
|
|
601
|
+
>(params: {
|
|
602
|
+
id: TStepId;
|
|
603
|
+
description?: string;
|
|
604
|
+
inputSchema: TStepInput;
|
|
605
|
+
outputSchema: TStepOutput;
|
|
606
|
+
resumeSchema?: TResumeSchema;
|
|
607
|
+
suspendSchema?: TSuspendSchema;
|
|
608
|
+
execute: ExecuteFunction<
|
|
609
|
+
z.infer<TStepInput>,
|
|
610
|
+
z.infer<TStepOutput>,
|
|
611
|
+
z.infer<TResumeSchema>,
|
|
612
|
+
z.infer<TSuspendSchema>,
|
|
613
|
+
InngestEngineType
|
|
614
|
+
>;
|
|
615
|
+
}): Step<TStepId, TStepInput, TStepOutput, TResumeSchema, TSuspendSchema, InngestEngineType>;
|
|
616
|
+
|
|
617
|
+
export function createStep<
|
|
618
|
+
TStepId extends string,
|
|
619
|
+
TStepInput extends z.ZodObject<{ prompt: z.ZodString }>,
|
|
620
|
+
TStepOutput extends z.ZodObject<{ text: z.ZodString }>,
|
|
621
|
+
TResumeSchema extends z.ZodType<any>,
|
|
622
|
+
TSuspendSchema extends z.ZodType<any>,
|
|
370
623
|
>(
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
624
|
+
agent: Agent<TStepId, any, any>,
|
|
625
|
+
): Step<TStepId, TStepInput, TStepOutput, TResumeSchema, TSuspendSchema, InngestEngineType>;
|
|
626
|
+
|
|
627
|
+
export function createStep<
|
|
628
|
+
TSchemaIn extends z.ZodType<any>,
|
|
629
|
+
TSchemaOut extends z.ZodType<any>,
|
|
630
|
+
TContext extends ToolExecutionContext<TSchemaIn>,
|
|
631
|
+
>(
|
|
632
|
+
tool: Tool<TSchemaIn, TSchemaOut, TContext> & {
|
|
633
|
+
inputSchema: TSchemaIn;
|
|
634
|
+
outputSchema: TSchemaOut;
|
|
635
|
+
execute: (context: TContext) => Promise<any>;
|
|
636
|
+
},
|
|
637
|
+
): Step<string, TSchemaIn, TSchemaOut, z.ZodType<any>, z.ZodType<any>, InngestEngineType>;
|
|
638
|
+
export function createStep<
|
|
639
|
+
TStepId extends string,
|
|
640
|
+
TStepInput extends z.ZodType<any>,
|
|
641
|
+
TStepOutput extends z.ZodType<any>,
|
|
642
|
+
TResumeSchema extends z.ZodType<any>,
|
|
643
|
+
TSuspendSchema extends z.ZodType<any>,
|
|
644
|
+
>(
|
|
645
|
+
params:
|
|
646
|
+
| {
|
|
647
|
+
id: TStepId;
|
|
648
|
+
description?: string;
|
|
649
|
+
inputSchema: TStepInput;
|
|
650
|
+
outputSchema: TStepOutput;
|
|
651
|
+
resumeSchema?: TResumeSchema;
|
|
652
|
+
suspendSchema?: TSuspendSchema;
|
|
653
|
+
execute: ExecuteFunction<
|
|
654
|
+
z.infer<TStepInput>,
|
|
655
|
+
z.infer<TStepOutput>,
|
|
656
|
+
z.infer<TResumeSchema>,
|
|
657
|
+
z.infer<TSuspendSchema>,
|
|
658
|
+
InngestEngineType
|
|
659
|
+
>;
|
|
660
|
+
}
|
|
661
|
+
| Agent<any, any, any>
|
|
662
|
+
| (Tool<TStepInput, TStepOutput, any> & {
|
|
663
|
+
inputSchema: TStepInput;
|
|
664
|
+
outputSchema: TStepOutput;
|
|
665
|
+
execute: (context: ToolExecutionContext<TStepInput>) => Promise<any>;
|
|
666
|
+
}),
|
|
667
|
+
): Step<TStepId, TStepInput, TStepOutput, TResumeSchema, TSuspendSchema, InngestEngineType> {
|
|
668
|
+
if (isAgent(params)) {
|
|
669
|
+
return {
|
|
670
|
+
id: params.name,
|
|
671
|
+
// @ts-ignore
|
|
672
|
+
inputSchema: z.object({
|
|
673
|
+
prompt: z.string(),
|
|
674
|
+
// resourceId: z.string().optional(),
|
|
675
|
+
// threadId: z.string().optional(),
|
|
676
|
+
}),
|
|
677
|
+
// @ts-ignore
|
|
678
|
+
outputSchema: z.object({
|
|
679
|
+
text: z.string(),
|
|
680
|
+
}),
|
|
681
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
|
|
682
|
+
let streamPromise = {} as {
|
|
683
|
+
promise: Promise<string>;
|
|
684
|
+
resolve: (value: string) => void;
|
|
685
|
+
reject: (reason?: any) => void;
|
|
686
|
+
};
|
|
687
|
+
|
|
688
|
+
streamPromise.promise = new Promise((resolve, reject) => {
|
|
689
|
+
streamPromise.resolve = resolve;
|
|
690
|
+
streamPromise.reject = reject;
|
|
691
|
+
});
|
|
692
|
+
const toolData = {
|
|
693
|
+
name: params.name,
|
|
694
|
+
args: inputData,
|
|
695
|
+
};
|
|
696
|
+
await emitter.emit('watch-v2', {
|
|
697
|
+
type: 'tool-call-streaming-start',
|
|
698
|
+
...toolData,
|
|
699
|
+
});
|
|
700
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
701
|
+
// resourceId: inputData.resourceId,
|
|
702
|
+
// threadId: inputData.threadId,
|
|
703
|
+
runtimeContext,
|
|
704
|
+
onFinish: result => {
|
|
705
|
+
streamPromise.resolve(result.text);
|
|
706
|
+
},
|
|
707
|
+
abortSignal,
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
if (abortSignal.aborted) {
|
|
711
|
+
return abort();
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
for await (const chunk of fullStream) {
|
|
715
|
+
switch (chunk.type) {
|
|
716
|
+
case 'text-delta':
|
|
717
|
+
await emitter.emit('watch-v2', {
|
|
718
|
+
type: 'tool-call-delta',
|
|
719
|
+
...toolData,
|
|
720
|
+
argsTextDelta: chunk.textDelta,
|
|
721
|
+
});
|
|
722
|
+
break;
|
|
723
|
+
|
|
724
|
+
case 'step-start':
|
|
725
|
+
case 'step-finish':
|
|
726
|
+
case 'finish':
|
|
727
|
+
break;
|
|
728
|
+
|
|
729
|
+
case 'tool-call':
|
|
730
|
+
case 'tool-result':
|
|
731
|
+
case 'tool-call-streaming-start':
|
|
732
|
+
case 'tool-call-delta':
|
|
733
|
+
case 'source':
|
|
734
|
+
case 'file':
|
|
735
|
+
default:
|
|
736
|
+
await emitter.emit('watch-v2', chunk);
|
|
737
|
+
break;
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
return {
|
|
742
|
+
text: await streamPromise.promise,
|
|
743
|
+
};
|
|
744
|
+
},
|
|
745
|
+
};
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
if (isTool(params)) {
|
|
749
|
+
if (!params.inputSchema || !params.outputSchema) {
|
|
750
|
+
throw new Error('Tool must have input and output schemas defined');
|
|
751
|
+
}
|
|
384
752
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
753
|
+
return {
|
|
754
|
+
// TODO: tool probably should have strong id type
|
|
755
|
+
// @ts-ignore
|
|
756
|
+
id: params.id,
|
|
757
|
+
inputSchema: params.inputSchema,
|
|
758
|
+
outputSchema: params.outputSchema,
|
|
759
|
+
execute: async ({ inputData, mastra, runtimeContext }) => {
|
|
760
|
+
return params.execute({
|
|
761
|
+
context: inputData,
|
|
762
|
+
mastra,
|
|
763
|
+
runtimeContext,
|
|
764
|
+
});
|
|
765
|
+
},
|
|
766
|
+
};
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
return {
|
|
770
|
+
id: params.id,
|
|
771
|
+
description: params.description,
|
|
772
|
+
inputSchema: params.inputSchema,
|
|
773
|
+
outputSchema: params.outputSchema,
|
|
774
|
+
resumeSchema: params.resumeSchema,
|
|
775
|
+
suspendSchema: params.suspendSchema,
|
|
776
|
+
execute: params.execute,
|
|
777
|
+
};
|
|
388
778
|
}
|
|
389
779
|
|
|
390
780
|
export function init(inngest: Inngest) {
|
|
@@ -393,13 +783,59 @@ export function init(inngest: Inngest) {
|
|
|
393
783
|
TWorkflowId extends string = string,
|
|
394
784
|
TInput extends z.ZodType<any> = z.ZodType<any>,
|
|
395
785
|
TOutput extends z.ZodType<any> = z.ZodType<any>,
|
|
396
|
-
TSteps extends Step<string, any, any
|
|
397
|
-
|
|
398
|
-
|
|
786
|
+
TSteps extends Step<string, any, any, any, any, InngestEngineType>[] = Step<
|
|
787
|
+
string,
|
|
788
|
+
any,
|
|
789
|
+
any,
|
|
790
|
+
any,
|
|
791
|
+
any,
|
|
792
|
+
InngestEngineType
|
|
793
|
+
>[],
|
|
794
|
+
>(params: WorkflowConfig<TWorkflowId, TInput, TOutput, TSteps>) {
|
|
795
|
+
return new InngestWorkflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput, TInput>(params, inngest);
|
|
399
796
|
},
|
|
400
797
|
createStep,
|
|
401
|
-
cloneStep
|
|
402
|
-
|
|
798
|
+
cloneStep<TStepId extends string>(
|
|
799
|
+
step: Step<string, any, any, any, any, InngestEngineType>,
|
|
800
|
+
opts: { id: TStepId },
|
|
801
|
+
): Step<TStepId, any, any, any, any, InngestEngineType> {
|
|
802
|
+
return {
|
|
803
|
+
id: opts.id,
|
|
804
|
+
description: step.description,
|
|
805
|
+
inputSchema: step.inputSchema,
|
|
806
|
+
outputSchema: step.outputSchema,
|
|
807
|
+
execute: step.execute,
|
|
808
|
+
};
|
|
809
|
+
},
|
|
810
|
+
cloneWorkflow<
|
|
811
|
+
TWorkflowId extends string = string,
|
|
812
|
+
TInput extends z.ZodType<any> = z.ZodType<any>,
|
|
813
|
+
TOutput extends z.ZodType<any> = z.ZodType<any>,
|
|
814
|
+
TSteps extends Step<string, any, any, any, any, InngestEngineType>[] = Step<
|
|
815
|
+
string,
|
|
816
|
+
any,
|
|
817
|
+
any,
|
|
818
|
+
any,
|
|
819
|
+
any,
|
|
820
|
+
InngestEngineType
|
|
821
|
+
>[],
|
|
822
|
+
TPrevSchema extends z.ZodType<any> = TInput,
|
|
823
|
+
>(
|
|
824
|
+
workflow: Workflow<InngestEngineType, TSteps, string, TInput, TOutput, TPrevSchema>,
|
|
825
|
+
opts: { id: TWorkflowId },
|
|
826
|
+
): Workflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> {
|
|
827
|
+
const wf: Workflow<InngestEngineType, TSteps, TWorkflowId, TInput, TOutput, TPrevSchema> = new Workflow({
|
|
828
|
+
id: opts.id,
|
|
829
|
+
inputSchema: workflow.inputSchema,
|
|
830
|
+
outputSchema: workflow.outputSchema,
|
|
831
|
+
steps: workflow.stepDefs,
|
|
832
|
+
mastra: workflow.mastra,
|
|
833
|
+
});
|
|
834
|
+
|
|
835
|
+
wf.setStepFlow(workflow.stepGraph);
|
|
836
|
+
wf.commit();
|
|
837
|
+
return wf;
|
|
838
|
+
},
|
|
403
839
|
};
|
|
404
840
|
}
|
|
405
841
|
|
|
@@ -413,11 +849,47 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
413
849
|
this.inngestAttempts = inngestAttempts;
|
|
414
850
|
}
|
|
415
851
|
|
|
852
|
+
async execute<TInput, TOutput>(params: {
|
|
853
|
+
workflowId: string;
|
|
854
|
+
runId: string;
|
|
855
|
+
graph: ExecutionGraph;
|
|
856
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
857
|
+
input?: TInput;
|
|
858
|
+
resume?: {
|
|
859
|
+
// TODO: add execute path
|
|
860
|
+
steps: string[];
|
|
861
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
862
|
+
resumePayload: any;
|
|
863
|
+
resumePath: number[];
|
|
864
|
+
};
|
|
865
|
+
emitter: Emitter;
|
|
866
|
+
retryConfig?: {
|
|
867
|
+
attempts?: number;
|
|
868
|
+
delay?: number;
|
|
869
|
+
};
|
|
870
|
+
runtimeContext: RuntimeContext;
|
|
871
|
+
abortController: AbortController;
|
|
872
|
+
}): Promise<TOutput> {
|
|
873
|
+
await params.emitter.emit('watch-v2', {
|
|
874
|
+
type: 'start',
|
|
875
|
+
payload: { runId: params.runId },
|
|
876
|
+
});
|
|
877
|
+
|
|
878
|
+
const result = await super.execute<TInput, TOutput>(params);
|
|
879
|
+
|
|
880
|
+
await params.emitter.emit('watch-v2', {
|
|
881
|
+
type: 'finish',
|
|
882
|
+
payload: { runId: params.runId },
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
return result;
|
|
886
|
+
}
|
|
887
|
+
|
|
416
888
|
protected async fmtReturnValue<TOutput>(
|
|
417
889
|
executionSpan: Span | undefined,
|
|
418
|
-
emitter:
|
|
419
|
-
stepResults: Record<string, StepResult<any>>,
|
|
420
|
-
lastOutput: StepResult<any>,
|
|
890
|
+
emitter: Emitter,
|
|
891
|
+
stepResults: Record<string, StepResult<any, any, any, any>>,
|
|
892
|
+
lastOutput: StepResult<any, any, any, any>,
|
|
421
893
|
error?: Error | string,
|
|
422
894
|
): Promise<TOutput> {
|
|
423
895
|
const base: any = {
|
|
@@ -496,21 +968,25 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
496
968
|
resume,
|
|
497
969
|
prevOutput,
|
|
498
970
|
emitter,
|
|
971
|
+
abortController,
|
|
499
972
|
runtimeContext,
|
|
973
|
+
writableStream,
|
|
500
974
|
}: {
|
|
501
975
|
workflowId: string;
|
|
502
976
|
runId: string;
|
|
503
977
|
step: Step<string, any, any>;
|
|
504
|
-
stepResults: Record<string, StepResult<any>>;
|
|
978
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
505
979
|
executionContext: ExecutionContext;
|
|
506
980
|
resume?: {
|
|
507
981
|
steps: string[];
|
|
508
982
|
resumePayload: any;
|
|
509
983
|
};
|
|
510
984
|
prevOutput: any;
|
|
511
|
-
emitter:
|
|
985
|
+
emitter: Emitter;
|
|
986
|
+
abortController: AbortController;
|
|
512
987
|
runtimeContext: RuntimeContext;
|
|
513
|
-
|
|
988
|
+
writableStream?: WritableStream<ChunkType>;
|
|
989
|
+
}): Promise<StepResult<any, any, any, any>> {
|
|
514
990
|
return super.executeStep({
|
|
515
991
|
workflowId,
|
|
516
992
|
runId,
|
|
@@ -520,10 +996,205 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
520
996
|
resume,
|
|
521
997
|
prevOutput,
|
|
522
998
|
emitter,
|
|
999
|
+
abortController,
|
|
523
1000
|
runtimeContext,
|
|
1001
|
+
writableStream,
|
|
524
1002
|
});
|
|
525
1003
|
}
|
|
526
1004
|
|
|
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);
|
|
1183
|
+
}
|
|
1184
|
+
|
|
1185
|
+
async executeWaitForEvent({ event, timeout }: { event: string; timeout?: number }): Promise<any> {
|
|
1186
|
+
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
1187
|
+
event: `user-event-${event}`,
|
|
1188
|
+
timeout: timeout ?? 5e3,
|
|
1189
|
+
});
|
|
1190
|
+
|
|
1191
|
+
if (eventData === null) {
|
|
1192
|
+
throw 'Timeout waiting for event';
|
|
1193
|
+
}
|
|
1194
|
+
|
|
1195
|
+
return eventData?.data;
|
|
1196
|
+
}
|
|
1197
|
+
|
|
527
1198
|
async executeStep({
|
|
528
1199
|
step,
|
|
529
1200
|
stepResults,
|
|
@@ -531,29 +1202,28 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
531
1202
|
resume,
|
|
532
1203
|
prevOutput,
|
|
533
1204
|
emitter,
|
|
1205
|
+
abortController,
|
|
534
1206
|
runtimeContext,
|
|
1207
|
+
writableStream,
|
|
535
1208
|
}: {
|
|
536
1209
|
step: Step<string, any, any>;
|
|
537
|
-
stepResults: Record<string, StepResult<any>>;
|
|
538
|
-
executionContext:
|
|
539
|
-
workflowId: string;
|
|
540
|
-
runId: string;
|
|
541
|
-
executionPath: number[];
|
|
542
|
-
suspendedPaths: Record<string, number[]>;
|
|
543
|
-
retryConfig: { attempts: number; delay: number };
|
|
544
|
-
};
|
|
1210
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
1211
|
+
executionContext: ExecutionContext;
|
|
545
1212
|
resume?: {
|
|
546
1213
|
steps: string[];
|
|
547
1214
|
resumePayload: any;
|
|
548
1215
|
runId?: string;
|
|
549
1216
|
};
|
|
550
1217
|
prevOutput: any;
|
|
551
|
-
emitter:
|
|
1218
|
+
emitter: Emitter;
|
|
1219
|
+
abortController: AbortController;
|
|
552
1220
|
runtimeContext: RuntimeContext;
|
|
553
|
-
|
|
554
|
-
|
|
1221
|
+
writableStream?: WritableStream<ChunkType>;
|
|
1222
|
+
}): Promise<StepResult<any, any, any, any>> {
|
|
1223
|
+
const startedAt = await this.inngestStep.run(
|
|
555
1224
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
556
1225
|
async () => {
|
|
1226
|
+
const startedAt = Date.now();
|
|
557
1227
|
await emitter.emit('watch', {
|
|
558
1228
|
type: 'watch',
|
|
559
1229
|
payload: {
|
|
@@ -575,6 +1245,18 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
575
1245
|
},
|
|
576
1246
|
eventTimestamp: Date.now(),
|
|
577
1247
|
});
|
|
1248
|
+
|
|
1249
|
+
await emitter.emit('watch-v2', {
|
|
1250
|
+
type: 'step-start',
|
|
1251
|
+
payload: {
|
|
1252
|
+
id: step.id,
|
|
1253
|
+
status: 'running',
|
|
1254
|
+
payload: prevOutput,
|
|
1255
|
+
startedAt,
|
|
1256
|
+
},
|
|
1257
|
+
});
|
|
1258
|
+
|
|
1259
|
+
return startedAt;
|
|
578
1260
|
},
|
|
579
1261
|
);
|
|
580
1262
|
|
|
@@ -641,10 +1323,20 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
641
1323
|
eventTimestamp: Date.now(),
|
|
642
1324
|
});
|
|
643
1325
|
|
|
1326
|
+
await emitter.emit('watch-v2', {
|
|
1327
|
+
type: 'step-result',
|
|
1328
|
+
payload: {
|
|
1329
|
+
id: step.id,
|
|
1330
|
+
status: 'failed',
|
|
1331
|
+
error: result?.error,
|
|
1332
|
+
payload: prevOutput,
|
|
1333
|
+
},
|
|
1334
|
+
});
|
|
1335
|
+
|
|
644
1336
|
return { executionContext, result: { status: 'failed', error: result?.error } };
|
|
645
1337
|
} else if (result.status === 'suspended') {
|
|
646
1338
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
647
|
-
const stepRes: StepResult<any> = stepResult as StepResult<any>;
|
|
1339
|
+
const stepRes: StepResult<any, any, any, any> = stepResult as StepResult<any, any, any, any>;
|
|
648
1340
|
return stepRes?.status === 'suspended';
|
|
649
1341
|
});
|
|
650
1342
|
|
|
@@ -671,6 +1363,14 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
671
1363
|
eventTimestamp: Date.now(),
|
|
672
1364
|
});
|
|
673
1365
|
|
|
1366
|
+
await emitter.emit('watch-v2', {
|
|
1367
|
+
type: 'step-suspended',
|
|
1368
|
+
payload: {
|
|
1369
|
+
id: step.id,
|
|
1370
|
+
status: 'suspended',
|
|
1371
|
+
},
|
|
1372
|
+
});
|
|
1373
|
+
|
|
674
1374
|
return {
|
|
675
1375
|
executionContext,
|
|
676
1376
|
result: {
|
|
@@ -727,21 +1427,42 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
727
1427
|
eventTimestamp: Date.now(),
|
|
728
1428
|
});
|
|
729
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
|
+
|
|
1439
|
+
await emitter.emit('watch-v2', {
|
|
1440
|
+
type: 'step-finish',
|
|
1441
|
+
payload: {
|
|
1442
|
+
id: step.id,
|
|
1443
|
+
metadata: {},
|
|
1444
|
+
},
|
|
1445
|
+
});
|
|
1446
|
+
|
|
730
1447
|
return { executionContext, result: { status: 'success', output: result?.result } };
|
|
731
1448
|
},
|
|
732
1449
|
);
|
|
733
1450
|
|
|
734
1451
|
Object.assign(executionContext, res.executionContext);
|
|
735
|
-
return res.result as StepResult<any>;
|
|
1452
|
+
return res.result as StepResult<any, any, any, any>;
|
|
736
1453
|
}
|
|
737
1454
|
|
|
738
1455
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
739
1456
|
let execResults: any;
|
|
740
1457
|
let suspended: { payload: any } | undefined;
|
|
1458
|
+
let bailed: { payload: any } | undefined;
|
|
1459
|
+
|
|
741
1460
|
try {
|
|
742
1461
|
const result = await step.execute({
|
|
1462
|
+
runId: executionContext.runId,
|
|
743
1463
|
mastra: this.mastra!,
|
|
744
1464
|
runtimeContext,
|
|
1465
|
+
writableStream,
|
|
745
1466
|
inputData: prevOutput,
|
|
746
1467
|
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
|
|
747
1468
|
getInitData: () => stepResults?.input as any,
|
|
@@ -757,22 +1478,56 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
757
1478
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
758
1479
|
suspended = { payload: suspendPayload };
|
|
759
1480
|
},
|
|
1481
|
+
bail: (result: any) => {
|
|
1482
|
+
bailed = { payload: result };
|
|
1483
|
+
},
|
|
760
1484
|
resume: {
|
|
761
1485
|
steps: resume?.steps?.slice(1) || [],
|
|
762
1486
|
resumePayload: resume?.resumePayload,
|
|
763
1487
|
// @ts-ignore
|
|
764
1488
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId,
|
|
765
1489
|
},
|
|
766
|
-
emitter,
|
|
1490
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1491
|
+
engine: {
|
|
1492
|
+
step: this.inngestStep,
|
|
1493
|
+
},
|
|
1494
|
+
abortSignal: abortController.signal,
|
|
767
1495
|
});
|
|
768
|
-
|
|
769
|
-
|
|
1496
|
+
const endedAt = Date.now();
|
|
1497
|
+
|
|
1498
|
+
execResults = {
|
|
1499
|
+
status: 'success',
|
|
1500
|
+
output: result,
|
|
1501
|
+
startedAt,
|
|
1502
|
+
endedAt,
|
|
1503
|
+
payload: prevOutput,
|
|
1504
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,
|
|
1505
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
|
|
1506
|
+
};
|
|
770
1507
|
} catch (e) {
|
|
771
|
-
execResults = {
|
|
1508
|
+
execResults = {
|
|
1509
|
+
status: 'failed',
|
|
1510
|
+
payload: prevOutput,
|
|
1511
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1512
|
+
endedAt: Date.now(),
|
|
1513
|
+
startedAt,
|
|
1514
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,
|
|
1515
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
|
|
1516
|
+
};
|
|
772
1517
|
}
|
|
773
1518
|
|
|
774
1519
|
if (suspended) {
|
|
775
|
-
execResults = {
|
|
1520
|
+
execResults = {
|
|
1521
|
+
status: 'suspended',
|
|
1522
|
+
suspendedPayload: suspended.payload,
|
|
1523
|
+
payload: prevOutput,
|
|
1524
|
+
suspendedAt: Date.now(),
|
|
1525
|
+
startedAt,
|
|
1526
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,
|
|
1527
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,
|
|
1528
|
+
};
|
|
1529
|
+
} else if (bailed) {
|
|
1530
|
+
execResults = { status: 'bailed', output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
776
1531
|
}
|
|
777
1532
|
|
|
778
1533
|
if (execResults.status === 'failed') {
|
|
@@ -786,12 +1541,11 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
786
1541
|
payload: {
|
|
787
1542
|
currentStep: {
|
|
788
1543
|
id: step.id,
|
|
789
|
-
|
|
790
|
-
output: execResults.output,
|
|
1544
|
+
...execResults,
|
|
791
1545
|
},
|
|
792
1546
|
workflowState: {
|
|
793
1547
|
status: 'running',
|
|
794
|
-
steps: stepResults,
|
|
1548
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
795
1549
|
result: null,
|
|
796
1550
|
error: null,
|
|
797
1551
|
},
|
|
@@ -799,6 +1553,32 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
799
1553
|
eventTimestamp: Date.now(),
|
|
800
1554
|
});
|
|
801
1555
|
|
|
1556
|
+
if (execResults.status === 'suspended') {
|
|
1557
|
+
await emitter.emit('watch-v2', {
|
|
1558
|
+
type: 'step-suspended',
|
|
1559
|
+
payload: {
|
|
1560
|
+
id: step.id,
|
|
1561
|
+
...execResults,
|
|
1562
|
+
},
|
|
1563
|
+
});
|
|
1564
|
+
} else {
|
|
1565
|
+
await emitter.emit('watch-v2', {
|
|
1566
|
+
type: 'step-result',
|
|
1567
|
+
payload: {
|
|
1568
|
+
id: step.id,
|
|
1569
|
+
...execResults,
|
|
1570
|
+
},
|
|
1571
|
+
});
|
|
1572
|
+
|
|
1573
|
+
await emitter.emit('watch-v2', {
|
|
1574
|
+
type: 'step-finish',
|
|
1575
|
+
payload: {
|
|
1576
|
+
id: step.id,
|
|
1577
|
+
metadata: {},
|
|
1578
|
+
},
|
|
1579
|
+
});
|
|
1580
|
+
}
|
|
1581
|
+
|
|
802
1582
|
return { result: execResults, executionContext, stepResults };
|
|
803
1583
|
});
|
|
804
1584
|
|
|
@@ -816,11 +1596,20 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
816
1596
|
runId,
|
|
817
1597
|
stepResults,
|
|
818
1598
|
executionContext,
|
|
1599
|
+
serializedStepGraph,
|
|
1600
|
+
workflowStatus,
|
|
1601
|
+
result,
|
|
1602
|
+
error,
|
|
819
1603
|
}: {
|
|
820
1604
|
workflowId: string;
|
|
821
1605
|
runId: string;
|
|
822
|
-
stepResults: Record<string, StepResult<any>>;
|
|
1606
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
1607
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
823
1608
|
executionContext: ExecutionContext;
|
|
1609
|
+
workflowStatus: 'success' | 'failed' | 'suspended' | 'running';
|
|
1610
|
+
result?: Record<string, any>;
|
|
1611
|
+
error?: string | Error;
|
|
1612
|
+
runtimeContext: RuntimeContext;
|
|
824
1613
|
}) {
|
|
825
1614
|
await this.inngestStep.run(
|
|
826
1615
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -834,6 +1623,10 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
834
1623
|
context: stepResults as any,
|
|
835
1624
|
activePaths: [],
|
|
836
1625
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1626
|
+
serializedStepGraph,
|
|
1627
|
+
status: workflowStatus,
|
|
1628
|
+
result,
|
|
1629
|
+
error,
|
|
837
1630
|
// @ts-ignore
|
|
838
1631
|
timestamp: Date.now(),
|
|
839
1632
|
},
|
|
@@ -849,27 +1642,37 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
849
1642
|
prevOutput,
|
|
850
1643
|
prevStep,
|
|
851
1644
|
stepResults,
|
|
1645
|
+
serializedStepGraph,
|
|
852
1646
|
resume,
|
|
853
1647
|
executionContext,
|
|
854
1648
|
emitter,
|
|
1649
|
+
abortController,
|
|
855
1650
|
runtimeContext,
|
|
1651
|
+
writableStream,
|
|
856
1652
|
}: {
|
|
857
1653
|
workflowId: string;
|
|
858
1654
|
runId: string;
|
|
859
|
-
entry: {
|
|
1655
|
+
entry: {
|
|
1656
|
+
type: 'conditional';
|
|
1657
|
+
steps: StepFlowEntry[];
|
|
1658
|
+
conditions: ExecuteFunction<any, any, any, any, InngestEngineType>[];
|
|
1659
|
+
};
|
|
860
1660
|
prevStep: StepFlowEntry;
|
|
1661
|
+
serializedStepGraph: SerializedStepFlowEntry[];
|
|
861
1662
|
prevOutput: any;
|
|
862
|
-
stepResults: Record<string, StepResult<any>>;
|
|
1663
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
863
1664
|
resume?: {
|
|
864
1665
|
steps: string[];
|
|
865
|
-
stepResults: Record<string, StepResult<any>>;
|
|
1666
|
+
stepResults: Record<string, StepResult<any, any, any, any>>;
|
|
866
1667
|
resumePayload: any;
|
|
867
1668
|
resumePath: number[];
|
|
868
1669
|
};
|
|
869
1670
|
executionContext: ExecutionContext;
|
|
870
|
-
emitter:
|
|
1671
|
+
emitter: Emitter;
|
|
1672
|
+
abortController: AbortController;
|
|
871
1673
|
runtimeContext: RuntimeContext;
|
|
872
|
-
|
|
1674
|
+
writableStream?: WritableStream<ChunkType>;
|
|
1675
|
+
}): Promise<StepResult<any, any, any, any>> {
|
|
873
1676
|
let execResults: any;
|
|
874
1677
|
const truthyIndexes = (
|
|
875
1678
|
await Promise.all(
|
|
@@ -877,8 +1680,11 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
877
1680
|
this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
878
1681
|
try {
|
|
879
1682
|
const result = await cond({
|
|
1683
|
+
runId,
|
|
1684
|
+
workflowId,
|
|
880
1685
|
mastra: this.mastra!,
|
|
881
1686
|
runtimeContext,
|
|
1687
|
+
runCount: -1,
|
|
882
1688
|
inputData: prevOutput,
|
|
883
1689
|
getInitData: () => stepResults?.input as any,
|
|
884
1690
|
getStepResult: (step: any) => {
|
|
@@ -896,7 +1702,24 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
896
1702
|
|
|
897
1703
|
// TODO: this function shouldn't have suspend probably?
|
|
898
1704
|
suspend: async (_suspendPayload: any) => {},
|
|
899
|
-
|
|
1705
|
+
bail: () => {},
|
|
1706
|
+
abort: () => {
|
|
1707
|
+
abortController.abort();
|
|
1708
|
+
},
|
|
1709
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1710
|
+
engine: {
|
|
1711
|
+
step: this.inngestStep,
|
|
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
|
+
),
|
|
900
1723
|
});
|
|
901
1724
|
return result ? index : null;
|
|
902
1725
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -909,7 +1732,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
909
1732
|
).filter((index: any): index is number => index !== null);
|
|
910
1733
|
|
|
911
1734
|
const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
|
|
912
|
-
const results: StepResult<any>[] = await Promise.all(
|
|
1735
|
+
const results: { result: StepResult<any, any, any, any> }[] = await Promise.all(
|
|
913
1736
|
stepsToRun.map((step, index) =>
|
|
914
1737
|
this.executeEntry({
|
|
915
1738
|
workflowId,
|
|
@@ -918,6 +1741,7 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
918
1741
|
prevStep,
|
|
919
1742
|
stepResults,
|
|
920
1743
|
resume,
|
|
1744
|
+
serializedStepGraph,
|
|
921
1745
|
executionContext: {
|
|
922
1746
|
workflowId,
|
|
923
1747
|
runId,
|
|
@@ -927,21 +1751,25 @@ export class InngestExecutionEngine extends DefaultExecutionEngine {
|
|
|
927
1751
|
executionSpan: executionContext.executionSpan,
|
|
928
1752
|
},
|
|
929
1753
|
emitter,
|
|
1754
|
+
abortController,
|
|
930
1755
|
runtimeContext,
|
|
1756
|
+
writableStream,
|
|
931
1757
|
}),
|
|
932
1758
|
),
|
|
933
1759
|
);
|
|
934
|
-
const hasFailed = results.find(result => result.status === 'failed')
|
|
935
|
-
|
|
1760
|
+
const hasFailed = results.find(result => result.result.status === 'failed') as {
|
|
1761
|
+
result: StepFailure<any, any, any>;
|
|
1762
|
+
};
|
|
1763
|
+
const hasSuspended = results.find(result => result.result.status === 'suspended');
|
|
936
1764
|
if (hasFailed) {
|
|
937
|
-
execResults = { status: 'failed', error: hasFailed.error };
|
|
1765
|
+
execResults = { status: 'failed', error: hasFailed.result.error };
|
|
938
1766
|
} else if (hasSuspended) {
|
|
939
|
-
execResults = { status: 'suspended', payload: hasSuspended.
|
|
1767
|
+
execResults = { status: 'suspended', payload: hasSuspended.result.suspendPayload };
|
|
940
1768
|
} else {
|
|
941
1769
|
execResults = {
|
|
942
1770
|
status: 'success',
|
|
943
1771
|
output: results.reduce((acc: Record<string, any>, result, index) => {
|
|
944
|
-
if (result.status === 'success') {
|
|
1772
|
+
if (result.result.status === 'success') {
|
|
945
1773
|
// @ts-ignore
|
|
946
1774
|
acc[stepsToRun[index]!.step.id] = result.output;
|
|
947
1775
|
}
|