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