@mastra/inngest 0.0.0-redis-cloud-transporter-20250508194049 → 0.0.0-support-d1-client-20250701191943
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 +440 -2
- package/dist/_tsup-dts-rollup.d.cts +136 -65
- package/dist/_tsup-dts-rollup.d.ts +136 -65
- package/dist/index.cjs +484 -59
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +481 -57
- package/package.json +21 -17
- package/src/index.test.ts +4983 -3348
- package/src/index.ts +730 -103
package/dist/index.cjs
CHANGED
|
@@ -3,34 +3,43 @@
|
|
|
3
3
|
var crypto = require('crypto');
|
|
4
4
|
var realtime = require('@inngest/realtime');
|
|
5
5
|
var di = require('@mastra/core/di');
|
|
6
|
-
var
|
|
6
|
+
var tools = require('@mastra/core/tools');
|
|
7
|
+
var workflows = require('@mastra/core/workflows');
|
|
8
|
+
var _constants = require('@mastra/core/workflows/_constants');
|
|
7
9
|
var hono = require('inngest/hono');
|
|
10
|
+
var zod = require('zod');
|
|
8
11
|
|
|
9
12
|
// src/index.ts
|
|
10
13
|
function serve({ mastra, inngest }) {
|
|
11
|
-
const wfs = mastra.
|
|
12
|
-
const functions =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
const wfs = mastra.getWorkflows();
|
|
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
|
+
);
|
|
19
26
|
return hono.serve({
|
|
20
27
|
client: inngest,
|
|
21
28
|
functions
|
|
22
29
|
});
|
|
23
30
|
}
|
|
24
|
-
var InngestRun = class extends
|
|
31
|
+
var InngestRun = class extends workflows.Run {
|
|
25
32
|
inngest;
|
|
33
|
+
serializedStepGraph;
|
|
26
34
|
#mastra;
|
|
27
35
|
constructor(params, inngest) {
|
|
28
36
|
super(params);
|
|
29
37
|
this.inngest = inngest;
|
|
38
|
+
this.serializedStepGraph = params.serializedStepGraph;
|
|
30
39
|
this.#mastra = params.mastra;
|
|
31
40
|
}
|
|
32
41
|
async getRuns(eventId) {
|
|
33
|
-
const response = await fetch(`${this.inngest.apiBaseUrl}/v1/events/${eventId}/runs`, {
|
|
42
|
+
const response = await fetch(`${this.inngest.apiBaseUrl ?? "https://api.inngest.com"}/v1/events/${eventId}/runs`, {
|
|
34
43
|
headers: {
|
|
35
44
|
Authorization: `Bearer ${process.env.INNGEST_SIGNING_KEY}`
|
|
36
45
|
}
|
|
@@ -40,15 +49,49 @@ var InngestRun = class extends vNext.Run {
|
|
|
40
49
|
}
|
|
41
50
|
async getRunOutput(eventId) {
|
|
42
51
|
let runs = await this.getRuns(eventId);
|
|
43
|
-
while (runs?.[0]?.status !== "Completed") {
|
|
52
|
+
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
44
53
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
45
54
|
runs = await this.getRuns(eventId);
|
|
46
|
-
if (runs?.[0]?.status === "Failed"
|
|
55
|
+
if (runs?.[0]?.status === "Failed") {
|
|
47
56
|
throw new Error(`Function run ${runs?.[0]?.status}`);
|
|
57
|
+
} else if (runs?.[0]?.status === "Cancelled") {
|
|
58
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
59
|
+
workflowName: this.workflowId,
|
|
60
|
+
runId: this.runId
|
|
61
|
+
});
|
|
62
|
+
return { output: { result: { steps: snapshot?.context, status: "canceled" } } };
|
|
48
63
|
}
|
|
49
64
|
}
|
|
50
65
|
return runs?.[0];
|
|
51
66
|
}
|
|
67
|
+
async sendEvent(event, data) {
|
|
68
|
+
await this.inngest.send({
|
|
69
|
+
name: `user-event-${event}`,
|
|
70
|
+
data
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
async cancel() {
|
|
74
|
+
await this.inngest.send({
|
|
75
|
+
name: `cancel.workflow.${this.workflowId}`,
|
|
76
|
+
data: {
|
|
77
|
+
runId: this.runId
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
81
|
+
workflowName: this.workflowId,
|
|
82
|
+
runId: this.runId
|
|
83
|
+
});
|
|
84
|
+
if (snapshot) {
|
|
85
|
+
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
86
|
+
workflowName: this.workflowId,
|
|
87
|
+
runId: this.runId,
|
|
88
|
+
snapshot: {
|
|
89
|
+
...snapshot,
|
|
90
|
+
status: "canceled"
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
52
95
|
async start({
|
|
53
96
|
inputData
|
|
54
97
|
}) {
|
|
@@ -57,11 +100,13 @@ var InngestRun = class extends vNext.Run {
|
|
|
57
100
|
runId: this.runId,
|
|
58
101
|
snapshot: {
|
|
59
102
|
runId: this.runId,
|
|
103
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
60
104
|
value: {},
|
|
61
105
|
context: {},
|
|
62
106
|
activePaths: [],
|
|
63
107
|
suspendedPaths: {},
|
|
64
|
-
timestamp: Date.now()
|
|
108
|
+
timestamp: Date.now(),
|
|
109
|
+
status: "running"
|
|
65
110
|
}
|
|
66
111
|
});
|
|
67
112
|
const eventOutput = await this.inngest.send({
|
|
@@ -80,10 +125,23 @@ var InngestRun = class extends vNext.Run {
|
|
|
80
125
|
if (result.status === "failed") {
|
|
81
126
|
result.error = new Error(result.error);
|
|
82
127
|
}
|
|
83
|
-
|
|
128
|
+
if (result.status !== "suspended") {
|
|
129
|
+
this.cleanup?.();
|
|
130
|
+
}
|
|
84
131
|
return result;
|
|
85
132
|
}
|
|
86
133
|
async resume(params) {
|
|
134
|
+
const p = this._resume(params).then((result) => {
|
|
135
|
+
if (result.status !== "suspended") {
|
|
136
|
+
this.closeStreamAction?.().catch(() => {
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return result;
|
|
140
|
+
});
|
|
141
|
+
this.executionResults = p;
|
|
142
|
+
return p;
|
|
143
|
+
}
|
|
144
|
+
async _resume(params) {
|
|
87
145
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
88
146
|
(step) => typeof step === "string" ? step : step?.id
|
|
89
147
|
);
|
|
@@ -117,27 +175,62 @@ var InngestRun = class extends vNext.Run {
|
|
|
117
175
|
}
|
|
118
176
|
return result;
|
|
119
177
|
}
|
|
120
|
-
watch(cb) {
|
|
178
|
+
watch(cb, type = "watch") {
|
|
179
|
+
let active = true;
|
|
121
180
|
const streamPromise = realtime.subscribe(
|
|
122
181
|
{
|
|
123
182
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
124
|
-
topics: [
|
|
183
|
+
topics: [type],
|
|
125
184
|
app: this.inngest
|
|
126
185
|
},
|
|
127
186
|
(message) => {
|
|
128
|
-
|
|
187
|
+
if (active) {
|
|
188
|
+
cb(message.data);
|
|
189
|
+
}
|
|
129
190
|
}
|
|
130
191
|
);
|
|
131
192
|
return () => {
|
|
132
|
-
|
|
133
|
-
|
|
193
|
+
active = false;
|
|
194
|
+
streamPromise.then(async (stream) => {
|
|
195
|
+
return stream.cancel();
|
|
134
196
|
}).catch((err) => {
|
|
135
197
|
console.error(err);
|
|
136
198
|
});
|
|
137
199
|
};
|
|
138
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
|
+
}
|
|
139
232
|
};
|
|
140
|
-
var InngestWorkflow = class _InngestWorkflow extends
|
|
233
|
+
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
141
234
|
#mastra;
|
|
142
235
|
inngest;
|
|
143
236
|
function;
|
|
@@ -158,11 +251,32 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
158
251
|
const storage = this.#mastra?.getStorage();
|
|
159
252
|
if (!storage) {
|
|
160
253
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
161
|
-
return null;
|
|
254
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
162
255
|
}
|
|
163
256
|
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
164
257
|
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
165
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
|
+
}
|
|
166
280
|
__registerMastra(mastra) {
|
|
167
281
|
this.#mastra = mastra;
|
|
168
282
|
this.executionEngine.__registerMastra(mastra);
|
|
@@ -189,6 +303,7 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
189
303
|
runId: runIdToUse,
|
|
190
304
|
executionEngine: this.executionEngine,
|
|
191
305
|
executionGraph: this.executionGraph,
|
|
306
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
192
307
|
mastra: this.#mastra,
|
|
193
308
|
retryConfig: this.retryConfig,
|
|
194
309
|
cleanup: () => this.runs.delete(runIdToUse)
|
|
@@ -198,13 +313,55 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
198
313
|
this.runs.set(runIdToUse, run);
|
|
199
314
|
return run;
|
|
200
315
|
}
|
|
316
|
+
async createRunAsync(options) {
|
|
317
|
+
const runIdToUse = options?.runId || crypto.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
|
+
}
|
|
201
354
|
getFunction() {
|
|
202
355
|
if (this.function) {
|
|
203
356
|
return this.function;
|
|
204
357
|
}
|
|
205
358
|
this.function = this.inngest.createFunction(
|
|
206
|
-
|
|
207
|
-
|
|
359
|
+
{
|
|
360
|
+
id: `workflow.${this.id}`,
|
|
361
|
+
// @ts-ignore
|
|
362
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
363
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }]
|
|
364
|
+
},
|
|
208
365
|
{ event: `workflow.${this.id}` },
|
|
209
366
|
async ({ event, step, attempt, publish }) => {
|
|
210
367
|
let { inputData, runId, resume } = event.data;
|
|
@@ -221,12 +378,18 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
221
378
|
try {
|
|
222
379
|
await publish({
|
|
223
380
|
channel: `workflow:${this.id}:${runId}`,
|
|
224
|
-
topic:
|
|
381
|
+
topic: event2,
|
|
225
382
|
data
|
|
226
383
|
});
|
|
227
384
|
} catch (err) {
|
|
228
385
|
this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
|
|
229
386
|
}
|
|
387
|
+
},
|
|
388
|
+
on: (_event, _callback) => {
|
|
389
|
+
},
|
|
390
|
+
off: (_event, _callback) => {
|
|
391
|
+
},
|
|
392
|
+
once: (_event, _callback) => {
|
|
230
393
|
}
|
|
231
394
|
};
|
|
232
395
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
@@ -234,12 +397,14 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
234
397
|
workflowId: this.id,
|
|
235
398
|
runId,
|
|
236
399
|
graph: this.executionGraph,
|
|
400
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
237
401
|
input: inputData,
|
|
238
402
|
emitter,
|
|
239
403
|
retryConfig: this.retryConfig,
|
|
240
404
|
runtimeContext: new di.RuntimeContext(),
|
|
241
405
|
// TODO
|
|
242
|
-
resume
|
|
406
|
+
resume,
|
|
407
|
+
abortController: new AbortController()
|
|
243
408
|
});
|
|
244
409
|
return { result, runId };
|
|
245
410
|
}
|
|
@@ -263,32 +428,141 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
263
428
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
264
429
|
}
|
|
265
430
|
};
|
|
266
|
-
function
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
431
|
+
function isAgent(params) {
|
|
432
|
+
return params?.component === "AGENT";
|
|
433
|
+
}
|
|
434
|
+
function isTool(params) {
|
|
435
|
+
return params instanceof tools.Tool;
|
|
436
|
+
}
|
|
437
|
+
function createStep(params) {
|
|
438
|
+
if (isAgent(params)) {
|
|
439
|
+
return {
|
|
440
|
+
id: params.name,
|
|
441
|
+
// @ts-ignore
|
|
442
|
+
inputSchema: zod.z.object({
|
|
443
|
+
prompt: zod.z.string()
|
|
444
|
+
// resourceId: z.string().optional(),
|
|
445
|
+
// threadId: z.string().optional(),
|
|
446
|
+
}),
|
|
447
|
+
// @ts-ignore
|
|
448
|
+
outputSchema: zod.z.object({
|
|
449
|
+
text: zod.z.string()
|
|
450
|
+
}),
|
|
451
|
+
execute: async ({ inputData, [_constants.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
|
+
};
|
|
280
535
|
}
|
|
281
536
|
function init(inngest) {
|
|
282
537
|
return {
|
|
283
538
|
createWorkflow(params) {
|
|
284
539
|
return new InngestWorkflow(params, inngest);
|
|
285
540
|
},
|
|
286
|
-
createStep
|
|
287
|
-
cloneStep
|
|
288
|
-
|
|
541
|
+
createStep,
|
|
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 workflows.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
|
+
}
|
|
289
563
|
};
|
|
290
564
|
}
|
|
291
|
-
var InngestExecutionEngine = class extends
|
|
565
|
+
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
292
566
|
inngestStep;
|
|
293
567
|
inngestAttempts;
|
|
294
568
|
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
@@ -296,6 +570,18 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
296
570
|
this.inngestStep = inngestStep;
|
|
297
571
|
this.inngestAttempts = inngestAttempts;
|
|
298
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
|
+
}
|
|
299
585
|
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
300
586
|
const base = {
|
|
301
587
|
status: lastOutput.status,
|
|
@@ -362,6 +648,7 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
362
648
|
resume,
|
|
363
649
|
prevOutput,
|
|
364
650
|
emitter,
|
|
651
|
+
abortController,
|
|
365
652
|
runtimeContext
|
|
366
653
|
}) {
|
|
367
654
|
return super.executeStep({
|
|
@@ -373,9 +660,23 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
373
660
|
resume,
|
|
374
661
|
prevOutput,
|
|
375
662
|
emitter,
|
|
663
|
+
abortController,
|
|
376
664
|
runtimeContext
|
|
377
665
|
});
|
|
378
666
|
}
|
|
667
|
+
async executeSleep({ id, duration }) {
|
|
668
|
+
await this.inngestStep.sleep(id, duration);
|
|
669
|
+
}
|
|
670
|
+
async executeWaitForEvent({ event, timeout }) {
|
|
671
|
+
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
672
|
+
event: `user-event-${event}`,
|
|
673
|
+
timeout: timeout ?? 5e3
|
|
674
|
+
});
|
|
675
|
+
if (eventData === null) {
|
|
676
|
+
throw "Timeout waiting for event";
|
|
677
|
+
}
|
|
678
|
+
return eventData?.data;
|
|
679
|
+
}
|
|
379
680
|
async executeStep({
|
|
380
681
|
step,
|
|
381
682
|
stepResults,
|
|
@@ -383,11 +684,13 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
383
684
|
resume,
|
|
384
685
|
prevOutput,
|
|
385
686
|
emitter,
|
|
687
|
+
abortController,
|
|
386
688
|
runtimeContext
|
|
387
689
|
}) {
|
|
388
|
-
await this.inngestStep.run(
|
|
690
|
+
const startedAt = await this.inngestStep.run(
|
|
389
691
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
390
692
|
async () => {
|
|
693
|
+
const startedAt2 = Date.now();
|
|
391
694
|
await emitter.emit("watch", {
|
|
392
695
|
type: "watch",
|
|
393
696
|
payload: {
|
|
@@ -409,6 +712,14 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
409
712
|
},
|
|
410
713
|
eventTimestamp: Date.now()
|
|
411
714
|
});
|
|
715
|
+
await emitter.emit("watch-v2", {
|
|
716
|
+
type: "step-start",
|
|
717
|
+
payload: {
|
|
718
|
+
id: step.id,
|
|
719
|
+
status: "running"
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
return startedAt2;
|
|
412
723
|
}
|
|
413
724
|
);
|
|
414
725
|
if (step instanceof InngestWorkflow) {
|
|
@@ -469,6 +780,15 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
469
780
|
},
|
|
470
781
|
eventTimestamp: Date.now()
|
|
471
782
|
});
|
|
783
|
+
await emitter.emit("watch-v2", {
|
|
784
|
+
type: "step-result",
|
|
785
|
+
payload: {
|
|
786
|
+
id: step.id,
|
|
787
|
+
status: "failed",
|
|
788
|
+
error: result?.error,
|
|
789
|
+
payload: prevOutput
|
|
790
|
+
}
|
|
791
|
+
});
|
|
472
792
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
473
793
|
} else if (result.status === "suspended") {
|
|
474
794
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
@@ -495,6 +815,13 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
495
815
|
},
|
|
496
816
|
eventTimestamp: Date.now()
|
|
497
817
|
});
|
|
818
|
+
await emitter.emit("watch-v2", {
|
|
819
|
+
type: "step-suspended",
|
|
820
|
+
payload: {
|
|
821
|
+
id: step.id,
|
|
822
|
+
status: "suspended"
|
|
823
|
+
}
|
|
824
|
+
});
|
|
498
825
|
return {
|
|
499
826
|
executionContext,
|
|
500
827
|
result: {
|
|
@@ -545,6 +872,21 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
545
872
|
},
|
|
546
873
|
eventTimestamp: Date.now()
|
|
547
874
|
});
|
|
875
|
+
await emitter.emit("watch-v2", {
|
|
876
|
+
type: "step-result",
|
|
877
|
+
payload: {
|
|
878
|
+
id: step.id,
|
|
879
|
+
status: "success",
|
|
880
|
+
output: result?.result
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
await emitter.emit("watch-v2", {
|
|
884
|
+
type: "step-finish",
|
|
885
|
+
payload: {
|
|
886
|
+
id: step.id,
|
|
887
|
+
metadata: {}
|
|
888
|
+
}
|
|
889
|
+
});
|
|
548
890
|
return { executionContext, result: { status: "success", output: result?.result } };
|
|
549
891
|
}
|
|
550
892
|
);
|
|
@@ -554,8 +896,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
554
896
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
555
897
|
let execResults;
|
|
556
898
|
let suspended;
|
|
899
|
+
let bailed;
|
|
557
900
|
try {
|
|
558
901
|
const result = await step.execute({
|
|
902
|
+
runId: executionContext.runId,
|
|
559
903
|
mastra: this.mastra,
|
|
560
904
|
runtimeContext,
|
|
561
905
|
inputData: prevOutput,
|
|
@@ -572,20 +916,54 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
572
916
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
573
917
|
suspended = { payload: suspendPayload };
|
|
574
918
|
},
|
|
919
|
+
bail: (result2) => {
|
|
920
|
+
bailed = { payload: result2 };
|
|
921
|
+
},
|
|
575
922
|
resume: {
|
|
576
923
|
steps: resume?.steps?.slice(1) || [],
|
|
577
924
|
resumePayload: resume?.resumePayload,
|
|
578
925
|
// @ts-ignore
|
|
579
926
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
580
927
|
},
|
|
581
|
-
emitter
|
|
928
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
929
|
+
engine: {
|
|
930
|
+
step: this.inngestStep
|
|
931
|
+
},
|
|
932
|
+
abortSignal: abortController.signal
|
|
582
933
|
});
|
|
583
|
-
|
|
934
|
+
const endedAt = Date.now();
|
|
935
|
+
execResults = {
|
|
936
|
+
status: "success",
|
|
937
|
+
output: result,
|
|
938
|
+
startedAt,
|
|
939
|
+
endedAt,
|
|
940
|
+
payload: prevOutput,
|
|
941
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
942
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
943
|
+
};
|
|
584
944
|
} catch (e) {
|
|
585
|
-
execResults = {
|
|
945
|
+
execResults = {
|
|
946
|
+
status: "failed",
|
|
947
|
+
payload: prevOutput,
|
|
948
|
+
error: e instanceof Error ? e.message : String(e),
|
|
949
|
+
endedAt: Date.now(),
|
|
950
|
+
startedAt,
|
|
951
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
952
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
953
|
+
};
|
|
586
954
|
}
|
|
587
955
|
if (suspended) {
|
|
588
|
-
execResults = {
|
|
956
|
+
execResults = {
|
|
957
|
+
status: "suspended",
|
|
958
|
+
suspendedPayload: suspended.payload,
|
|
959
|
+
payload: prevOutput,
|
|
960
|
+
suspendedAt: Date.now(),
|
|
961
|
+
startedAt,
|
|
962
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
963
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
964
|
+
};
|
|
965
|
+
} else if (bailed) {
|
|
966
|
+
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
589
967
|
}
|
|
590
968
|
if (execResults.status === "failed") {
|
|
591
969
|
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
@@ -597,18 +975,41 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
597
975
|
payload: {
|
|
598
976
|
currentStep: {
|
|
599
977
|
id: step.id,
|
|
600
|
-
|
|
601
|
-
output: execResults.output
|
|
978
|
+
...execResults
|
|
602
979
|
},
|
|
603
980
|
workflowState: {
|
|
604
981
|
status: "running",
|
|
605
|
-
steps: stepResults,
|
|
982
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
606
983
|
result: null,
|
|
607
984
|
error: null
|
|
608
985
|
}
|
|
609
986
|
},
|
|
610
987
|
eventTimestamp: Date.now()
|
|
611
988
|
});
|
|
989
|
+
if (execResults.status === "suspended") {
|
|
990
|
+
await emitter.emit("watch-v2", {
|
|
991
|
+
type: "step-suspended",
|
|
992
|
+
payload: {
|
|
993
|
+
id: step.id,
|
|
994
|
+
...execResults
|
|
995
|
+
}
|
|
996
|
+
});
|
|
997
|
+
} else {
|
|
998
|
+
await emitter.emit("watch-v2", {
|
|
999
|
+
type: "step-result",
|
|
1000
|
+
payload: {
|
|
1001
|
+
id: step.id,
|
|
1002
|
+
...execResults
|
|
1003
|
+
}
|
|
1004
|
+
});
|
|
1005
|
+
await emitter.emit("watch-v2", {
|
|
1006
|
+
type: "step-finish",
|
|
1007
|
+
payload: {
|
|
1008
|
+
id: step.id,
|
|
1009
|
+
metadata: {}
|
|
1010
|
+
}
|
|
1011
|
+
});
|
|
1012
|
+
}
|
|
612
1013
|
return { result: execResults, executionContext, stepResults };
|
|
613
1014
|
});
|
|
614
1015
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
@@ -619,7 +1020,11 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
619
1020
|
workflowId,
|
|
620
1021
|
runId,
|
|
621
1022
|
stepResults,
|
|
622
|
-
executionContext
|
|
1023
|
+
executionContext,
|
|
1024
|
+
serializedStepGraph,
|
|
1025
|
+
workflowStatus,
|
|
1026
|
+
result,
|
|
1027
|
+
error
|
|
623
1028
|
}) {
|
|
624
1029
|
await this.inngestStep.run(
|
|
625
1030
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -633,6 +1038,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
633
1038
|
context: stepResults,
|
|
634
1039
|
activePaths: [],
|
|
635
1040
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1041
|
+
serializedStepGraph,
|
|
1042
|
+
status: workflowStatus,
|
|
1043
|
+
result,
|
|
1044
|
+
error,
|
|
636
1045
|
// @ts-ignore
|
|
637
1046
|
timestamp: Date.now()
|
|
638
1047
|
}
|
|
@@ -647,9 +1056,11 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
647
1056
|
prevOutput,
|
|
648
1057
|
prevStep,
|
|
649
1058
|
stepResults,
|
|
1059
|
+
serializedStepGraph,
|
|
650
1060
|
resume,
|
|
651
1061
|
executionContext,
|
|
652
1062
|
emitter,
|
|
1063
|
+
abortController,
|
|
653
1064
|
runtimeContext
|
|
654
1065
|
}) {
|
|
655
1066
|
let execResults;
|
|
@@ -658,8 +1069,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
658
1069
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
659
1070
|
try {
|
|
660
1071
|
const result = await cond({
|
|
1072
|
+
runId,
|
|
661
1073
|
mastra: this.mastra,
|
|
662
1074
|
runtimeContext,
|
|
1075
|
+
runCount: -1,
|
|
663
1076
|
inputData: prevOutput,
|
|
664
1077
|
getInitData: () => stepResults?.input,
|
|
665
1078
|
getStepResult: (step) => {
|
|
@@ -675,7 +1088,16 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
675
1088
|
// TODO: this function shouldn't have suspend probably?
|
|
676
1089
|
suspend: async (_suspendPayload) => {
|
|
677
1090
|
},
|
|
678
|
-
|
|
1091
|
+
bail: () => {
|
|
1092
|
+
},
|
|
1093
|
+
abort: () => {
|
|
1094
|
+
abortController.abort();
|
|
1095
|
+
},
|
|
1096
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1097
|
+
engine: {
|
|
1098
|
+
step: this.inngestStep
|
|
1099
|
+
},
|
|
1100
|
+
abortSignal: abortController.signal
|
|
679
1101
|
});
|
|
680
1102
|
return result ? index : null;
|
|
681
1103
|
} catch (e) {
|
|
@@ -694,6 +1116,7 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
694
1116
|
prevStep,
|
|
695
1117
|
stepResults,
|
|
696
1118
|
resume,
|
|
1119
|
+
serializedStepGraph,
|
|
697
1120
|
executionContext: {
|
|
698
1121
|
workflowId,
|
|
699
1122
|
runId,
|
|
@@ -703,21 +1126,22 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
703
1126
|
executionSpan: executionContext.executionSpan
|
|
704
1127
|
},
|
|
705
1128
|
emitter,
|
|
1129
|
+
abortController,
|
|
706
1130
|
runtimeContext
|
|
707
1131
|
})
|
|
708
1132
|
)
|
|
709
1133
|
);
|
|
710
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
711
|
-
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1134
|
+
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1135
|
+
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
712
1136
|
if (hasFailed) {
|
|
713
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1137
|
+
execResults = { status: "failed", error: hasFailed.result.error };
|
|
714
1138
|
} else if (hasSuspended) {
|
|
715
|
-
execResults = { status: "suspended", payload: hasSuspended.
|
|
1139
|
+
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
716
1140
|
} else {
|
|
717
1141
|
execResults = {
|
|
718
1142
|
status: "success",
|
|
719
1143
|
output: results.reduce((acc, result, index) => {
|
|
720
|
-
if (result.status === "success") {
|
|
1144
|
+
if (result.result.status === "success") {
|
|
721
1145
|
acc[stepsToRun[index].step.id] = result.output;
|
|
722
1146
|
}
|
|
723
1147
|
return acc;
|
|
@@ -731,5 +1155,6 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
731
1155
|
exports.InngestExecutionEngine = InngestExecutionEngine;
|
|
732
1156
|
exports.InngestRun = InngestRun;
|
|
733
1157
|
exports.InngestWorkflow = InngestWorkflow;
|
|
1158
|
+
exports.createStep = createStep;
|
|
734
1159
|
exports.init = init;
|
|
735
1160
|
exports.serve = serve;
|