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