@mastra/inngest 0.0.0-taofeeqInngest-20250603090617 → 0.0.0-transpile-packages-20250724123433
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 +388 -2
- package/LICENSE.md +11 -42
- package/dist/_tsup-dts-rollup.d.cts +151 -40
- package/dist/_tsup-dts-rollup.d.ts +151 -40
- package/dist/index.cjs +568 -53
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +568 -54
- package/docker-compose.yaml +3 -3
- package/package.json +21 -19
- package/src/index.test.ts +5702 -3435
- package/src/index.ts +848 -78
- package/vitest.config.ts +6 -0
package/dist/index.js
CHANGED
|
@@ -1,20 +1,26 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
2
|
import { subscribe } from '@inngest/realtime';
|
|
3
3
|
import { RuntimeContext } from '@mastra/core/di';
|
|
4
|
-
import {
|
|
4
|
+
import { Tool } from '@mastra/core/tools';
|
|
5
|
+
import { Run, Workflow, DefaultExecutionEngine } from '@mastra/core/workflows';
|
|
5
6
|
import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
|
|
6
7
|
import { serve as serve$1 } from 'inngest/hono';
|
|
8
|
+
import { z } from 'zod';
|
|
7
9
|
|
|
8
10
|
// src/index.ts
|
|
9
11
|
function serve({ mastra, inngest }) {
|
|
10
12
|
const wfs = mastra.getWorkflows();
|
|
11
|
-
const functions =
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
const functions = Array.from(
|
|
14
|
+
new Set(
|
|
15
|
+
Object.values(wfs).flatMap((wf) => {
|
|
16
|
+
if (wf instanceof InngestWorkflow) {
|
|
17
|
+
wf.__registerMastra(mastra);
|
|
18
|
+
return wf.getFunctions();
|
|
19
|
+
}
|
|
20
|
+
return [];
|
|
21
|
+
})
|
|
22
|
+
)
|
|
23
|
+
);
|
|
18
24
|
return serve$1({
|
|
19
25
|
client: inngest,
|
|
20
26
|
functions
|
|
@@ -41,15 +47,50 @@ var InngestRun = class extends Run {
|
|
|
41
47
|
}
|
|
42
48
|
async getRunOutput(eventId) {
|
|
43
49
|
let runs = await this.getRuns(eventId);
|
|
44
|
-
while (runs?.[0]?.status !== "Completed") {
|
|
50
|
+
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
45
51
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
46
52
|
runs = await this.getRuns(eventId);
|
|
47
|
-
if (runs?.[0]?.status === "Failed"
|
|
53
|
+
if (runs?.[0]?.status === "Failed") {
|
|
54
|
+
console.log("run", runs?.[0]);
|
|
48
55
|
throw new Error(`Function run ${runs?.[0]?.status}`);
|
|
56
|
+
} else if (runs?.[0]?.status === "Cancelled") {
|
|
57
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
58
|
+
workflowName: this.workflowId,
|
|
59
|
+
runId: this.runId
|
|
60
|
+
});
|
|
61
|
+
return { output: { result: { steps: snapshot?.context, status: "canceled" } } };
|
|
49
62
|
}
|
|
50
63
|
}
|
|
51
64
|
return runs?.[0];
|
|
52
65
|
}
|
|
66
|
+
async sendEvent(event, data) {
|
|
67
|
+
await this.inngest.send({
|
|
68
|
+
name: `user-event-${event}`,
|
|
69
|
+
data
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
async cancel() {
|
|
73
|
+
await this.inngest.send({
|
|
74
|
+
name: `cancel.workflow.${this.workflowId}`,
|
|
75
|
+
data: {
|
|
76
|
+
runId: this.runId
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
80
|
+
workflowName: this.workflowId,
|
|
81
|
+
runId: this.runId
|
|
82
|
+
});
|
|
83
|
+
if (snapshot) {
|
|
84
|
+
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
85
|
+
workflowName: this.workflowId,
|
|
86
|
+
runId: this.runId,
|
|
87
|
+
snapshot: {
|
|
88
|
+
...snapshot,
|
|
89
|
+
status: "canceled"
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
53
94
|
async start({
|
|
54
95
|
inputData
|
|
55
96
|
}) {
|
|
@@ -63,7 +104,8 @@ var InngestRun = class extends Run {
|
|
|
63
104
|
context: {},
|
|
64
105
|
activePaths: [],
|
|
65
106
|
suspendedPaths: {},
|
|
66
|
-
timestamp: Date.now()
|
|
107
|
+
timestamp: Date.now(),
|
|
108
|
+
status: "running"
|
|
67
109
|
}
|
|
68
110
|
});
|
|
69
111
|
const eventOutput = await this.inngest.send({
|
|
@@ -82,10 +124,23 @@ var InngestRun = class extends Run {
|
|
|
82
124
|
if (result.status === "failed") {
|
|
83
125
|
result.error = new Error(result.error);
|
|
84
126
|
}
|
|
85
|
-
|
|
127
|
+
if (result.status !== "suspended") {
|
|
128
|
+
this.cleanup?.();
|
|
129
|
+
}
|
|
86
130
|
return result;
|
|
87
131
|
}
|
|
88
132
|
async resume(params) {
|
|
133
|
+
const p = this._resume(params).then((result) => {
|
|
134
|
+
if (result.status !== "suspended") {
|
|
135
|
+
this.closeStreamAction?.().catch(() => {
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
139
|
+
});
|
|
140
|
+
this.executionResults = p;
|
|
141
|
+
return p;
|
|
142
|
+
}
|
|
143
|
+
async _resume(params) {
|
|
89
144
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
90
145
|
(step) => typeof step === "string" ? step : step?.id
|
|
91
146
|
);
|
|
@@ -98,6 +153,7 @@ var InngestRun = class extends Run {
|
|
|
98
153
|
data: {
|
|
99
154
|
inputData: params.resumeData,
|
|
100
155
|
runId: this.runId,
|
|
156
|
+
workflowId: this.workflowId,
|
|
101
157
|
stepResults: snapshot?.context,
|
|
102
158
|
resume: {
|
|
103
159
|
steps,
|
|
@@ -119,25 +175,60 @@ var InngestRun = class extends Run {
|
|
|
119
175
|
}
|
|
120
176
|
return result;
|
|
121
177
|
}
|
|
122
|
-
watch(cb) {
|
|
178
|
+
watch(cb, type = "watch") {
|
|
179
|
+
let active = true;
|
|
123
180
|
const streamPromise = subscribe(
|
|
124
181
|
{
|
|
125
182
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
126
|
-
topics: [
|
|
183
|
+
topics: [type],
|
|
127
184
|
app: this.inngest
|
|
128
185
|
},
|
|
129
186
|
(message) => {
|
|
130
|
-
|
|
187
|
+
if (active) {
|
|
188
|
+
cb(message.data);
|
|
189
|
+
}
|
|
131
190
|
}
|
|
132
191
|
);
|
|
133
192
|
return () => {
|
|
134
|
-
|
|
135
|
-
|
|
193
|
+
active = false;
|
|
194
|
+
streamPromise.then(async (stream) => {
|
|
195
|
+
return stream.cancel();
|
|
136
196
|
}).catch((err) => {
|
|
137
197
|
console.error(err);
|
|
138
198
|
});
|
|
139
199
|
};
|
|
140
200
|
}
|
|
201
|
+
stream({ inputData, runtimeContext } = {}) {
|
|
202
|
+
const { readable, writable } = new TransformStream();
|
|
203
|
+
const writer = writable.getWriter();
|
|
204
|
+
const unwatch = this.watch(async (event) => {
|
|
205
|
+
try {
|
|
206
|
+
await writer.write(event);
|
|
207
|
+
} catch {
|
|
208
|
+
}
|
|
209
|
+
}, "watch-v2");
|
|
210
|
+
this.closeStreamAction = async () => {
|
|
211
|
+
unwatch();
|
|
212
|
+
try {
|
|
213
|
+
await writer.close();
|
|
214
|
+
} catch (err) {
|
|
215
|
+
console.error("Error closing stream:", err);
|
|
216
|
+
} finally {
|
|
217
|
+
writer.releaseLock();
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
|
|
221
|
+
if (result.status !== "suspended") {
|
|
222
|
+
this.closeStreamAction?.().catch(() => {
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
return result;
|
|
226
|
+
});
|
|
227
|
+
return {
|
|
228
|
+
stream: readable,
|
|
229
|
+
getWorkflowState: () => this.executionResults
|
|
230
|
+
};
|
|
231
|
+
}
|
|
141
232
|
};
|
|
142
233
|
var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
143
234
|
#mastra;
|
|
@@ -160,11 +251,32 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
160
251
|
const storage = this.#mastra?.getStorage();
|
|
161
252
|
if (!storage) {
|
|
162
253
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
163
|
-
return null;
|
|
254
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
164
255
|
}
|
|
165
256
|
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
166
257
|
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
167
258
|
}
|
|
259
|
+
async getWorkflowRunExecutionResult(runId) {
|
|
260
|
+
const storage = this.#mastra?.getStorage();
|
|
261
|
+
if (!storage) {
|
|
262
|
+
this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
266
|
+
if (!run?.snapshot) {
|
|
267
|
+
return null;
|
|
268
|
+
}
|
|
269
|
+
if (typeof run.snapshot === "string") {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
return {
|
|
273
|
+
status: run.snapshot.status,
|
|
274
|
+
result: run.snapshot.result,
|
|
275
|
+
error: run.snapshot.error,
|
|
276
|
+
payload: run.snapshot.context?.input,
|
|
277
|
+
steps: run.snapshot.context
|
|
278
|
+
};
|
|
279
|
+
}
|
|
168
280
|
__registerMastra(mastra) {
|
|
169
281
|
this.#mastra = mastra;
|
|
170
282
|
this.executionEngine.__registerMastra(mastra);
|
|
@@ -201,13 +313,55 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
201
313
|
this.runs.set(runIdToUse, run);
|
|
202
314
|
return run;
|
|
203
315
|
}
|
|
316
|
+
async createRunAsync(options) {
|
|
317
|
+
const runIdToUse = options?.runId || randomUUID();
|
|
318
|
+
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
319
|
+
{
|
|
320
|
+
workflowId: this.id,
|
|
321
|
+
runId: runIdToUse,
|
|
322
|
+
executionEngine: this.executionEngine,
|
|
323
|
+
executionGraph: this.executionGraph,
|
|
324
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
325
|
+
mastra: this.#mastra,
|
|
326
|
+
retryConfig: this.retryConfig,
|
|
327
|
+
cleanup: () => this.runs.delete(runIdToUse)
|
|
328
|
+
},
|
|
329
|
+
this.inngest
|
|
330
|
+
);
|
|
331
|
+
this.runs.set(runIdToUse, run);
|
|
332
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
|
|
333
|
+
if (!workflowSnapshotInStorage) {
|
|
334
|
+
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
335
|
+
workflowName: this.id,
|
|
336
|
+
runId: runIdToUse,
|
|
337
|
+
snapshot: {
|
|
338
|
+
runId: runIdToUse,
|
|
339
|
+
status: "pending",
|
|
340
|
+
value: {},
|
|
341
|
+
context: {},
|
|
342
|
+
activePaths: [],
|
|
343
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
344
|
+
suspendedPaths: {},
|
|
345
|
+
result: void 0,
|
|
346
|
+
error: void 0,
|
|
347
|
+
// @ts-ignore
|
|
348
|
+
timestamp: Date.now()
|
|
349
|
+
}
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
return run;
|
|
353
|
+
}
|
|
204
354
|
getFunction() {
|
|
205
355
|
if (this.function) {
|
|
206
356
|
return this.function;
|
|
207
357
|
}
|
|
208
358
|
this.function = this.inngest.createFunction(
|
|
209
|
-
|
|
210
|
-
|
|
359
|
+
{
|
|
360
|
+
id: `workflow.${this.id}`,
|
|
361
|
+
// @ts-ignore
|
|
362
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
363
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }]
|
|
364
|
+
},
|
|
211
365
|
{ event: `workflow.${this.id}` },
|
|
212
366
|
async ({ event, step, attempt, publish }) => {
|
|
213
367
|
let { inputData, runId, resume } = event.data;
|
|
@@ -224,12 +378,18 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
224
378
|
try {
|
|
225
379
|
await publish({
|
|
226
380
|
channel: `workflow:${this.id}:${runId}`,
|
|
227
|
-
topic:
|
|
381
|
+
topic: event2,
|
|
228
382
|
data
|
|
229
383
|
});
|
|
230
384
|
} catch (err) {
|
|
231
385
|
this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
|
|
232
386
|
}
|
|
387
|
+
},
|
|
388
|
+
on: (_event, _callback) => {
|
|
389
|
+
},
|
|
390
|
+
off: (_event, _callback) => {
|
|
391
|
+
},
|
|
392
|
+
once: (_event, _callback) => {
|
|
233
393
|
}
|
|
234
394
|
};
|
|
235
395
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
@@ -243,7 +403,8 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
243
403
|
retryConfig: this.retryConfig,
|
|
244
404
|
runtimeContext: new RuntimeContext(),
|
|
245
405
|
// TODO
|
|
246
|
-
resume
|
|
406
|
+
resume,
|
|
407
|
+
abortController: new AbortController()
|
|
247
408
|
});
|
|
248
409
|
return { result, runId };
|
|
249
410
|
}
|
|
@@ -267,20 +428,110 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
267
428
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
268
429
|
}
|
|
269
430
|
};
|
|
270
|
-
function
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
431
|
+
function isAgent(params) {
|
|
432
|
+
return params?.component === "AGENT";
|
|
433
|
+
}
|
|
434
|
+
function isTool(params) {
|
|
435
|
+
return params instanceof Tool;
|
|
436
|
+
}
|
|
437
|
+
function createStep(params) {
|
|
438
|
+
if (isAgent(params)) {
|
|
439
|
+
return {
|
|
440
|
+
id: params.name,
|
|
441
|
+
// @ts-ignore
|
|
442
|
+
inputSchema: z.object({
|
|
443
|
+
prompt: z.string()
|
|
444
|
+
// resourceId: z.string().optional(),
|
|
445
|
+
// threadId: z.string().optional(),
|
|
446
|
+
}),
|
|
447
|
+
// @ts-ignore
|
|
448
|
+
outputSchema: z.object({
|
|
449
|
+
text: z.string()
|
|
450
|
+
}),
|
|
451
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort }) => {
|
|
452
|
+
let streamPromise = {};
|
|
453
|
+
streamPromise.promise = new Promise((resolve, reject) => {
|
|
454
|
+
streamPromise.resolve = resolve;
|
|
455
|
+
streamPromise.reject = reject;
|
|
456
|
+
});
|
|
457
|
+
const toolData = {
|
|
458
|
+
name: params.name,
|
|
459
|
+
args: inputData
|
|
460
|
+
};
|
|
461
|
+
await emitter.emit("watch-v2", {
|
|
462
|
+
type: "tool-call-streaming-start",
|
|
463
|
+
...toolData
|
|
464
|
+
});
|
|
465
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
466
|
+
// resourceId: inputData.resourceId,
|
|
467
|
+
// threadId: inputData.threadId,
|
|
468
|
+
runtimeContext,
|
|
469
|
+
onFinish: (result) => {
|
|
470
|
+
streamPromise.resolve(result.text);
|
|
471
|
+
},
|
|
472
|
+
abortSignal
|
|
473
|
+
});
|
|
474
|
+
if (abortSignal.aborted) {
|
|
475
|
+
return abort();
|
|
476
|
+
}
|
|
477
|
+
for await (const chunk of fullStream) {
|
|
478
|
+
switch (chunk.type) {
|
|
479
|
+
case "text-delta":
|
|
480
|
+
await emitter.emit("watch-v2", {
|
|
481
|
+
type: "tool-call-delta",
|
|
482
|
+
...toolData,
|
|
483
|
+
argsTextDelta: chunk.textDelta
|
|
484
|
+
});
|
|
485
|
+
break;
|
|
486
|
+
case "step-start":
|
|
487
|
+
case "step-finish":
|
|
488
|
+
case "finish":
|
|
489
|
+
break;
|
|
490
|
+
case "tool-call":
|
|
491
|
+
case "tool-result":
|
|
492
|
+
case "tool-call-streaming-start":
|
|
493
|
+
case "tool-call-delta":
|
|
494
|
+
case "source":
|
|
495
|
+
case "file":
|
|
496
|
+
default:
|
|
497
|
+
await emitter.emit("watch-v2", chunk);
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
return {
|
|
502
|
+
text: await streamPromise.promise
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
if (isTool(params)) {
|
|
508
|
+
if (!params.inputSchema || !params.outputSchema) {
|
|
509
|
+
throw new Error("Tool must have input and output schemas defined");
|
|
510
|
+
}
|
|
511
|
+
return {
|
|
512
|
+
// TODO: tool probably should have strong id type
|
|
513
|
+
// @ts-ignore
|
|
514
|
+
id: params.id,
|
|
515
|
+
inputSchema: params.inputSchema,
|
|
516
|
+
outputSchema: params.outputSchema,
|
|
517
|
+
execute: async ({ inputData, mastra, runtimeContext }) => {
|
|
518
|
+
return params.execute({
|
|
519
|
+
context: inputData,
|
|
520
|
+
mastra,
|
|
521
|
+
runtimeContext
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
};
|
|
525
|
+
}
|
|
526
|
+
return {
|
|
527
|
+
id: params.id,
|
|
528
|
+
description: params.description,
|
|
529
|
+
inputSchema: params.inputSchema,
|
|
530
|
+
outputSchema: params.outputSchema,
|
|
531
|
+
resumeSchema: params.resumeSchema,
|
|
532
|
+
suspendSchema: params.suspendSchema,
|
|
533
|
+
execute: params.execute
|
|
534
|
+
};
|
|
284
535
|
}
|
|
285
536
|
function init(inngest) {
|
|
286
537
|
return {
|
|
@@ -288,8 +539,27 @@ function init(inngest) {
|
|
|
288
539
|
return new InngestWorkflow(params, inngest);
|
|
289
540
|
},
|
|
290
541
|
createStep,
|
|
291
|
-
cloneStep,
|
|
292
|
-
|
|
542
|
+
cloneStep(step, opts) {
|
|
543
|
+
return {
|
|
544
|
+
id: opts.id,
|
|
545
|
+
description: step.description,
|
|
546
|
+
inputSchema: step.inputSchema,
|
|
547
|
+
outputSchema: step.outputSchema,
|
|
548
|
+
execute: step.execute
|
|
549
|
+
};
|
|
550
|
+
},
|
|
551
|
+
cloneWorkflow(workflow, opts) {
|
|
552
|
+
const wf = new Workflow({
|
|
553
|
+
id: opts.id,
|
|
554
|
+
inputSchema: workflow.inputSchema,
|
|
555
|
+
outputSchema: workflow.outputSchema,
|
|
556
|
+
steps: workflow.stepDefs,
|
|
557
|
+
mastra: workflow.mastra
|
|
558
|
+
});
|
|
559
|
+
wf.setStepFlow(workflow.stepGraph);
|
|
560
|
+
wf.commit();
|
|
561
|
+
return wf;
|
|
562
|
+
}
|
|
293
563
|
};
|
|
294
564
|
}
|
|
295
565
|
var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
@@ -300,6 +570,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
300
570
|
this.inngestStep = inngestStep;
|
|
301
571
|
this.inngestAttempts = inngestAttempts;
|
|
302
572
|
}
|
|
573
|
+
async execute(params) {
|
|
574
|
+
await params.emitter.emit("watch-v2", {
|
|
575
|
+
type: "start",
|
|
576
|
+
payload: { runId: params.runId }
|
|
577
|
+
});
|
|
578
|
+
const result = await super.execute(params);
|
|
579
|
+
await params.emitter.emit("watch-v2", {
|
|
580
|
+
type: "finish",
|
|
581
|
+
payload: { runId: params.runId }
|
|
582
|
+
});
|
|
583
|
+
return result;
|
|
584
|
+
}
|
|
303
585
|
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
304
586
|
const base = {
|
|
305
587
|
status: lastOutput.status,
|
|
@@ -366,6 +648,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
366
648
|
resume,
|
|
367
649
|
prevOutput,
|
|
368
650
|
emitter,
|
|
651
|
+
abortController,
|
|
369
652
|
runtimeContext
|
|
370
653
|
}) {
|
|
371
654
|
return super.executeStep({
|
|
@@ -377,9 +660,120 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
377
660
|
resume,
|
|
378
661
|
prevOutput,
|
|
379
662
|
emitter,
|
|
663
|
+
abortController,
|
|
380
664
|
runtimeContext
|
|
381
665
|
});
|
|
382
666
|
}
|
|
667
|
+
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
668
|
+
// await this.inngestStep.sleep(id, duration);
|
|
669
|
+
// }
|
|
670
|
+
async executeSleep({
|
|
671
|
+
workflowId,
|
|
672
|
+
runId,
|
|
673
|
+
entry,
|
|
674
|
+
prevOutput,
|
|
675
|
+
stepResults,
|
|
676
|
+
emitter,
|
|
677
|
+
abortController,
|
|
678
|
+
runtimeContext
|
|
679
|
+
}) {
|
|
680
|
+
let { duration, fn } = entry;
|
|
681
|
+
if (fn) {
|
|
682
|
+
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
683
|
+
return await fn({
|
|
684
|
+
runId,
|
|
685
|
+
workflowId,
|
|
686
|
+
mastra: this.mastra,
|
|
687
|
+
runtimeContext,
|
|
688
|
+
inputData: prevOutput,
|
|
689
|
+
runCount: -1,
|
|
690
|
+
getInitData: () => stepResults?.input,
|
|
691
|
+
getStepResult: (step) => {
|
|
692
|
+
if (!step?.id) {
|
|
693
|
+
return null;
|
|
694
|
+
}
|
|
695
|
+
const result = stepResults[step.id];
|
|
696
|
+
if (result?.status === "success") {
|
|
697
|
+
return result.output;
|
|
698
|
+
}
|
|
699
|
+
return null;
|
|
700
|
+
},
|
|
701
|
+
// TODO: this function shouldn't have suspend probably?
|
|
702
|
+
suspend: async (_suspendPayload) => {
|
|
703
|
+
},
|
|
704
|
+
bail: () => {
|
|
705
|
+
},
|
|
706
|
+
abort: () => {
|
|
707
|
+
abortController?.abort();
|
|
708
|
+
},
|
|
709
|
+
[EMITTER_SYMBOL]: emitter,
|
|
710
|
+
engine: { step: this.inngestStep },
|
|
711
|
+
abortSignal: abortController?.signal
|
|
712
|
+
});
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
716
|
+
}
|
|
717
|
+
async executeSleepUntil({
|
|
718
|
+
workflowId,
|
|
719
|
+
runId,
|
|
720
|
+
entry,
|
|
721
|
+
prevOutput,
|
|
722
|
+
stepResults,
|
|
723
|
+
emitter,
|
|
724
|
+
abortController,
|
|
725
|
+
runtimeContext
|
|
726
|
+
}) {
|
|
727
|
+
let { date, fn } = entry;
|
|
728
|
+
if (fn) {
|
|
729
|
+
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
730
|
+
return await fn({
|
|
731
|
+
runId,
|
|
732
|
+
workflowId,
|
|
733
|
+
mastra: this.mastra,
|
|
734
|
+
runtimeContext,
|
|
735
|
+
inputData: prevOutput,
|
|
736
|
+
runCount: -1,
|
|
737
|
+
getInitData: () => stepResults?.input,
|
|
738
|
+
getStepResult: (step) => {
|
|
739
|
+
if (!step?.id) {
|
|
740
|
+
return null;
|
|
741
|
+
}
|
|
742
|
+
const result = stepResults[step.id];
|
|
743
|
+
if (result?.status === "success") {
|
|
744
|
+
return result.output;
|
|
745
|
+
}
|
|
746
|
+
return null;
|
|
747
|
+
},
|
|
748
|
+
// TODO: this function shouldn't have suspend probably?
|
|
749
|
+
suspend: async (_suspendPayload) => {
|
|
750
|
+
},
|
|
751
|
+
bail: () => {
|
|
752
|
+
},
|
|
753
|
+
abort: () => {
|
|
754
|
+
abortController?.abort();
|
|
755
|
+
},
|
|
756
|
+
[EMITTER_SYMBOL]: emitter,
|
|
757
|
+
engine: { step: this.inngestStep },
|
|
758
|
+
abortSignal: abortController?.signal
|
|
759
|
+
});
|
|
760
|
+
});
|
|
761
|
+
}
|
|
762
|
+
if (!(date instanceof Date)) {
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
await this.inngestStep.sleepUntil(entry.id, date);
|
|
766
|
+
}
|
|
767
|
+
async executeWaitForEvent({ event, timeout }) {
|
|
768
|
+
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
769
|
+
event: `user-event-${event}`,
|
|
770
|
+
timeout: timeout ?? 5e3
|
|
771
|
+
});
|
|
772
|
+
if (eventData === null) {
|
|
773
|
+
throw "Timeout waiting for event";
|
|
774
|
+
}
|
|
775
|
+
return eventData?.data;
|
|
776
|
+
}
|
|
383
777
|
async executeStep({
|
|
384
778
|
step,
|
|
385
779
|
stepResults,
|
|
@@ -387,11 +781,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
387
781
|
resume,
|
|
388
782
|
prevOutput,
|
|
389
783
|
emitter,
|
|
784
|
+
abortController,
|
|
390
785
|
runtimeContext
|
|
391
786
|
}) {
|
|
392
|
-
await this.inngestStep.run(
|
|
787
|
+
const startedAt = await this.inngestStep.run(
|
|
393
788
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
394
789
|
async () => {
|
|
790
|
+
const startedAt2 = Date.now();
|
|
395
791
|
await emitter.emit("watch", {
|
|
396
792
|
type: "watch",
|
|
397
793
|
payload: {
|
|
@@ -413,6 +809,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
413
809
|
},
|
|
414
810
|
eventTimestamp: Date.now()
|
|
415
811
|
});
|
|
812
|
+
await emitter.emit("watch-v2", {
|
|
813
|
+
type: "step-start",
|
|
814
|
+
payload: {
|
|
815
|
+
id: step.id,
|
|
816
|
+
status: "running",
|
|
817
|
+
payload: prevOutput,
|
|
818
|
+
startedAt: startedAt2
|
|
819
|
+
}
|
|
820
|
+
});
|
|
821
|
+
return startedAt2;
|
|
416
822
|
}
|
|
417
823
|
);
|
|
418
824
|
if (step instanceof InngestWorkflow) {
|
|
@@ -473,6 +879,15 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
473
879
|
},
|
|
474
880
|
eventTimestamp: Date.now()
|
|
475
881
|
});
|
|
882
|
+
await emitter.emit("watch-v2", {
|
|
883
|
+
type: "step-result",
|
|
884
|
+
payload: {
|
|
885
|
+
id: step.id,
|
|
886
|
+
status: "failed",
|
|
887
|
+
error: result?.error,
|
|
888
|
+
payload: prevOutput
|
|
889
|
+
}
|
|
890
|
+
});
|
|
476
891
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
477
892
|
} else if (result.status === "suspended") {
|
|
478
893
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
@@ -499,6 +914,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
499
914
|
},
|
|
500
915
|
eventTimestamp: Date.now()
|
|
501
916
|
});
|
|
917
|
+
await emitter.emit("watch-v2", {
|
|
918
|
+
type: "step-suspended",
|
|
919
|
+
payload: {
|
|
920
|
+
id: step.id,
|
|
921
|
+
status: "suspended"
|
|
922
|
+
}
|
|
923
|
+
});
|
|
502
924
|
return {
|
|
503
925
|
executionContext,
|
|
504
926
|
result: {
|
|
@@ -549,6 +971,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
549
971
|
},
|
|
550
972
|
eventTimestamp: Date.now()
|
|
551
973
|
});
|
|
974
|
+
await emitter.emit("watch-v2", {
|
|
975
|
+
type: "step-result",
|
|
976
|
+
payload: {
|
|
977
|
+
id: step.id,
|
|
978
|
+
status: "success",
|
|
979
|
+
output: result?.result
|
|
980
|
+
}
|
|
981
|
+
});
|
|
982
|
+
await emitter.emit("watch-v2", {
|
|
983
|
+
type: "step-finish",
|
|
984
|
+
payload: {
|
|
985
|
+
id: step.id,
|
|
986
|
+
metadata: {}
|
|
987
|
+
}
|
|
988
|
+
});
|
|
552
989
|
return { executionContext, result: { status: "success", output: result?.result } };
|
|
553
990
|
}
|
|
554
991
|
);
|
|
@@ -558,6 +995,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
558
995
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
559
996
|
let execResults;
|
|
560
997
|
let suspended;
|
|
998
|
+
let bailed;
|
|
561
999
|
try {
|
|
562
1000
|
const result = await step.execute({
|
|
563
1001
|
runId: executionContext.runId,
|
|
@@ -577,20 +1015,54 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
577
1015
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
578
1016
|
suspended = { payload: suspendPayload };
|
|
579
1017
|
},
|
|
1018
|
+
bail: (result2) => {
|
|
1019
|
+
bailed = { payload: result2 };
|
|
1020
|
+
},
|
|
580
1021
|
resume: {
|
|
581
1022
|
steps: resume?.steps?.slice(1) || [],
|
|
582
1023
|
resumePayload: resume?.resumePayload,
|
|
583
1024
|
// @ts-ignore
|
|
584
1025
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
585
1026
|
},
|
|
586
|
-
emitter
|
|
1027
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1028
|
+
engine: {
|
|
1029
|
+
step: this.inngestStep
|
|
1030
|
+
},
|
|
1031
|
+
abortSignal: abortController.signal
|
|
587
1032
|
});
|
|
588
|
-
|
|
1033
|
+
const endedAt = Date.now();
|
|
1034
|
+
execResults = {
|
|
1035
|
+
status: "success",
|
|
1036
|
+
output: result,
|
|
1037
|
+
startedAt,
|
|
1038
|
+
endedAt,
|
|
1039
|
+
payload: prevOutput,
|
|
1040
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1041
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1042
|
+
};
|
|
589
1043
|
} catch (e) {
|
|
590
|
-
execResults = {
|
|
1044
|
+
execResults = {
|
|
1045
|
+
status: "failed",
|
|
1046
|
+
payload: prevOutput,
|
|
1047
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1048
|
+
endedAt: Date.now(),
|
|
1049
|
+
startedAt,
|
|
1050
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1051
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1052
|
+
};
|
|
591
1053
|
}
|
|
592
1054
|
if (suspended) {
|
|
593
|
-
execResults = {
|
|
1055
|
+
execResults = {
|
|
1056
|
+
status: "suspended",
|
|
1057
|
+
suspendedPayload: suspended.payload,
|
|
1058
|
+
payload: prevOutput,
|
|
1059
|
+
suspendedAt: Date.now(),
|
|
1060
|
+
startedAt,
|
|
1061
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1062
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1063
|
+
};
|
|
1064
|
+
} else if (bailed) {
|
|
1065
|
+
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
594
1066
|
}
|
|
595
1067
|
if (execResults.status === "failed") {
|
|
596
1068
|
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
@@ -602,18 +1074,41 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
602
1074
|
payload: {
|
|
603
1075
|
currentStep: {
|
|
604
1076
|
id: step.id,
|
|
605
|
-
|
|
606
|
-
output: execResults.output
|
|
1077
|
+
...execResults
|
|
607
1078
|
},
|
|
608
1079
|
workflowState: {
|
|
609
1080
|
status: "running",
|
|
610
|
-
steps: stepResults,
|
|
1081
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
611
1082
|
result: null,
|
|
612
1083
|
error: null
|
|
613
1084
|
}
|
|
614
1085
|
},
|
|
615
1086
|
eventTimestamp: Date.now()
|
|
616
1087
|
});
|
|
1088
|
+
if (execResults.status === "suspended") {
|
|
1089
|
+
await emitter.emit("watch-v2", {
|
|
1090
|
+
type: "step-suspended",
|
|
1091
|
+
payload: {
|
|
1092
|
+
id: step.id,
|
|
1093
|
+
...execResults
|
|
1094
|
+
}
|
|
1095
|
+
});
|
|
1096
|
+
} else {
|
|
1097
|
+
await emitter.emit("watch-v2", {
|
|
1098
|
+
type: "step-result",
|
|
1099
|
+
payload: {
|
|
1100
|
+
id: step.id,
|
|
1101
|
+
...execResults
|
|
1102
|
+
}
|
|
1103
|
+
});
|
|
1104
|
+
await emitter.emit("watch-v2", {
|
|
1105
|
+
type: "step-finish",
|
|
1106
|
+
payload: {
|
|
1107
|
+
id: step.id,
|
|
1108
|
+
metadata: {}
|
|
1109
|
+
}
|
|
1110
|
+
});
|
|
1111
|
+
}
|
|
617
1112
|
return { result: execResults, executionContext, stepResults };
|
|
618
1113
|
});
|
|
619
1114
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
@@ -625,7 +1120,10 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
625
1120
|
runId,
|
|
626
1121
|
stepResults,
|
|
627
1122
|
executionContext,
|
|
628
|
-
serializedStepGraph
|
|
1123
|
+
serializedStepGraph,
|
|
1124
|
+
workflowStatus,
|
|
1125
|
+
result,
|
|
1126
|
+
error
|
|
629
1127
|
}) {
|
|
630
1128
|
await this.inngestStep.run(
|
|
631
1129
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -640,6 +1138,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
640
1138
|
activePaths: [],
|
|
641
1139
|
suspendedPaths: executionContext.suspendedPaths,
|
|
642
1140
|
serializedStepGraph,
|
|
1141
|
+
status: workflowStatus,
|
|
1142
|
+
result,
|
|
1143
|
+
error,
|
|
643
1144
|
// @ts-ignore
|
|
644
1145
|
timestamp: Date.now()
|
|
645
1146
|
}
|
|
@@ -658,6 +1159,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
658
1159
|
resume,
|
|
659
1160
|
executionContext,
|
|
660
1161
|
emitter,
|
|
1162
|
+
abortController,
|
|
661
1163
|
runtimeContext
|
|
662
1164
|
}) {
|
|
663
1165
|
let execResults;
|
|
@@ -667,8 +1169,10 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
667
1169
|
try {
|
|
668
1170
|
const result = await cond({
|
|
669
1171
|
runId,
|
|
1172
|
+
workflowId,
|
|
670
1173
|
mastra: this.mastra,
|
|
671
1174
|
runtimeContext,
|
|
1175
|
+
runCount: -1,
|
|
672
1176
|
inputData: prevOutput,
|
|
673
1177
|
getInitData: () => stepResults?.input,
|
|
674
1178
|
getStepResult: (step) => {
|
|
@@ -684,7 +1188,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
684
1188
|
// TODO: this function shouldn't have suspend probably?
|
|
685
1189
|
suspend: async (_suspendPayload) => {
|
|
686
1190
|
},
|
|
687
|
-
|
|
1191
|
+
bail: () => {
|
|
1192
|
+
},
|
|
1193
|
+
abort: () => {
|
|
1194
|
+
abortController.abort();
|
|
1195
|
+
},
|
|
1196
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1197
|
+
engine: {
|
|
1198
|
+
step: this.inngestStep
|
|
1199
|
+
},
|
|
1200
|
+
abortSignal: abortController.signal
|
|
688
1201
|
});
|
|
689
1202
|
return result ? index : null;
|
|
690
1203
|
} catch (e) {
|
|
@@ -713,21 +1226,22 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
713
1226
|
executionSpan: executionContext.executionSpan
|
|
714
1227
|
},
|
|
715
1228
|
emitter,
|
|
1229
|
+
abortController,
|
|
716
1230
|
runtimeContext
|
|
717
1231
|
})
|
|
718
1232
|
)
|
|
719
1233
|
);
|
|
720
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
721
|
-
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1234
|
+
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1235
|
+
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
722
1236
|
if (hasFailed) {
|
|
723
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1237
|
+
execResults = { status: "failed", error: hasFailed.result.error };
|
|
724
1238
|
} else if (hasSuspended) {
|
|
725
|
-
execResults = { status: "suspended", payload: hasSuspended.
|
|
1239
|
+
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
726
1240
|
} else {
|
|
727
1241
|
execResults = {
|
|
728
1242
|
status: "success",
|
|
729
1243
|
output: results.reduce((acc, result, index) => {
|
|
730
|
-
if (result.status === "success") {
|
|
1244
|
+
if (result.result.status === "success") {
|
|
731
1245
|
acc[stepsToRun[index].step.id] = result.output;
|
|
732
1246
|
}
|
|
733
1247
|
return acc;
|
|
@@ -738,4 +1252,4 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
738
1252
|
}
|
|
739
1253
|
};
|
|
740
1254
|
|
|
741
|
-
export { InngestExecutionEngine, InngestRun, InngestWorkflow, init, serve };
|
|
1255
|
+
export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
|