@mastra/inngest 0.0.0-generate-message-id-20250512171942 → 0.0.0-http-transporter-20250702160118
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 +431 -3
- package/dist/_tsup-dts-rollup.d.cts +136 -65
- package/dist/_tsup-dts-rollup.d.ts +136 -65
- package/dist/index.cjs +487 -59
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +484 -57
- package/docker-compose.yaml +3 -3
- package/package.json +22 -17
- package/src/index.test.ts +5026 -3333
- package/src/index.ts +733 -103
- package/vitest.config.ts +6 -0
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,50 @@ 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") {
|
|
56
|
+
console.log("run", runs?.[0]);
|
|
47
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" } } };
|
|
48
64
|
}
|
|
49
65
|
}
|
|
50
66
|
return runs?.[0];
|
|
51
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
|
+
}
|
|
52
96
|
async start({
|
|
53
97
|
inputData
|
|
54
98
|
}) {
|
|
@@ -57,11 +101,13 @@ var InngestRun = class extends vNext.Run {
|
|
|
57
101
|
runId: this.runId,
|
|
58
102
|
snapshot: {
|
|
59
103
|
runId: this.runId,
|
|
104
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
60
105
|
value: {},
|
|
61
106
|
context: {},
|
|
62
107
|
activePaths: [],
|
|
63
108
|
suspendedPaths: {},
|
|
64
|
-
timestamp: Date.now()
|
|
109
|
+
timestamp: Date.now(),
|
|
110
|
+
status: "running"
|
|
65
111
|
}
|
|
66
112
|
});
|
|
67
113
|
const eventOutput = await this.inngest.send({
|
|
@@ -80,10 +126,23 @@ var InngestRun = class extends vNext.Run {
|
|
|
80
126
|
if (result.status === "failed") {
|
|
81
127
|
result.error = new Error(result.error);
|
|
82
128
|
}
|
|
83
|
-
|
|
129
|
+
if (result.status !== "suspended") {
|
|
130
|
+
this.cleanup?.();
|
|
131
|
+
}
|
|
84
132
|
return result;
|
|
85
133
|
}
|
|
86
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) {
|
|
87
146
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
88
147
|
(step) => typeof step === "string" ? step : step?.id
|
|
89
148
|
);
|
|
@@ -117,27 +176,62 @@ var InngestRun = class extends vNext.Run {
|
|
|
117
176
|
}
|
|
118
177
|
return result;
|
|
119
178
|
}
|
|
120
|
-
watch(cb) {
|
|
179
|
+
watch(cb, type = "watch") {
|
|
180
|
+
let active = true;
|
|
121
181
|
const streamPromise = realtime.subscribe(
|
|
122
182
|
{
|
|
123
183
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
124
|
-
topics: [
|
|
184
|
+
topics: [type],
|
|
125
185
|
app: this.inngest
|
|
126
186
|
},
|
|
127
187
|
(message) => {
|
|
128
|
-
|
|
188
|
+
if (active) {
|
|
189
|
+
cb(message.data);
|
|
190
|
+
}
|
|
129
191
|
}
|
|
130
192
|
);
|
|
131
193
|
return () => {
|
|
132
|
-
|
|
133
|
-
|
|
194
|
+
active = false;
|
|
195
|
+
streamPromise.then(async (stream) => {
|
|
196
|
+
return stream.cancel();
|
|
134
197
|
}).catch((err) => {
|
|
135
198
|
console.error(err);
|
|
136
199
|
});
|
|
137
200
|
};
|
|
138
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
|
+
}
|
|
139
233
|
};
|
|
140
|
-
var InngestWorkflow = class _InngestWorkflow extends
|
|
234
|
+
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
141
235
|
#mastra;
|
|
142
236
|
inngest;
|
|
143
237
|
function;
|
|
@@ -158,11 +252,32 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
158
252
|
const storage = this.#mastra?.getStorage();
|
|
159
253
|
if (!storage) {
|
|
160
254
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
161
|
-
return null;
|
|
255
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
162
256
|
}
|
|
163
257
|
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
164
258
|
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
165
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
|
+
}
|
|
166
281
|
__registerMastra(mastra) {
|
|
167
282
|
this.#mastra = mastra;
|
|
168
283
|
this.executionEngine.__registerMastra(mastra);
|
|
@@ -189,6 +304,7 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
189
304
|
runId: runIdToUse,
|
|
190
305
|
executionEngine: this.executionEngine,
|
|
191
306
|
executionGraph: this.executionGraph,
|
|
307
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
192
308
|
mastra: this.#mastra,
|
|
193
309
|
retryConfig: this.retryConfig,
|
|
194
310
|
cleanup: () => this.runs.delete(runIdToUse)
|
|
@@ -198,13 +314,55 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
198
314
|
this.runs.set(runIdToUse, run);
|
|
199
315
|
return run;
|
|
200
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
|
+
}
|
|
201
355
|
getFunction() {
|
|
202
356
|
if (this.function) {
|
|
203
357
|
return this.function;
|
|
204
358
|
}
|
|
205
359
|
this.function = this.inngest.createFunction(
|
|
206
|
-
|
|
207
|
-
|
|
360
|
+
{
|
|
361
|
+
id: `workflow.${this.id}`,
|
|
362
|
+
// @ts-ignore
|
|
363
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
364
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }]
|
|
365
|
+
},
|
|
208
366
|
{ event: `workflow.${this.id}` },
|
|
209
367
|
async ({ event, step, attempt, publish }) => {
|
|
210
368
|
let { inputData, runId, resume } = event.data;
|
|
@@ -221,12 +379,18 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
221
379
|
try {
|
|
222
380
|
await publish({
|
|
223
381
|
channel: `workflow:${this.id}:${runId}`,
|
|
224
|
-
topic:
|
|
382
|
+
topic: event2,
|
|
225
383
|
data
|
|
226
384
|
});
|
|
227
385
|
} catch (err) {
|
|
228
386
|
this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
|
|
229
387
|
}
|
|
388
|
+
},
|
|
389
|
+
on: (_event, _callback) => {
|
|
390
|
+
},
|
|
391
|
+
off: (_event, _callback) => {
|
|
392
|
+
},
|
|
393
|
+
once: (_event, _callback) => {
|
|
230
394
|
}
|
|
231
395
|
};
|
|
232
396
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
@@ -234,12 +398,14 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
234
398
|
workflowId: this.id,
|
|
235
399
|
runId,
|
|
236
400
|
graph: this.executionGraph,
|
|
401
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
237
402
|
input: inputData,
|
|
238
403
|
emitter,
|
|
239
404
|
retryConfig: this.retryConfig,
|
|
240
405
|
runtimeContext: new di.RuntimeContext(),
|
|
241
406
|
// TODO
|
|
242
|
-
resume
|
|
407
|
+
resume,
|
|
408
|
+
abortController: new AbortController()
|
|
243
409
|
});
|
|
244
410
|
return { result, runId };
|
|
245
411
|
}
|
|
@@ -263,32 +429,141 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
263
429
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
264
430
|
}
|
|
265
431
|
};
|
|
266
|
-
function
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
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
|
+
};
|
|
280
536
|
}
|
|
281
537
|
function init(inngest) {
|
|
282
538
|
return {
|
|
283
539
|
createWorkflow(params) {
|
|
284
540
|
return new InngestWorkflow(params, inngest);
|
|
285
541
|
},
|
|
286
|
-
createStep
|
|
287
|
-
cloneStep
|
|
288
|
-
|
|
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
|
+
}
|
|
289
564
|
};
|
|
290
565
|
}
|
|
291
|
-
var InngestExecutionEngine = class extends
|
|
566
|
+
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
292
567
|
inngestStep;
|
|
293
568
|
inngestAttempts;
|
|
294
569
|
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
@@ -296,6 +571,18 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
296
571
|
this.inngestStep = inngestStep;
|
|
297
572
|
this.inngestAttempts = inngestAttempts;
|
|
298
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
|
+
}
|
|
299
586
|
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
300
587
|
const base = {
|
|
301
588
|
status: lastOutput.status,
|
|
@@ -362,6 +649,7 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
362
649
|
resume,
|
|
363
650
|
prevOutput,
|
|
364
651
|
emitter,
|
|
652
|
+
abortController,
|
|
365
653
|
runtimeContext
|
|
366
654
|
}) {
|
|
367
655
|
return super.executeStep({
|
|
@@ -373,9 +661,23 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
373
661
|
resume,
|
|
374
662
|
prevOutput,
|
|
375
663
|
emitter,
|
|
664
|
+
abortController,
|
|
376
665
|
runtimeContext
|
|
377
666
|
});
|
|
378
667
|
}
|
|
668
|
+
async executeSleep({ id, duration }) {
|
|
669
|
+
await this.inngestStep.sleep(id, duration);
|
|
670
|
+
}
|
|
671
|
+
async executeWaitForEvent({ event, timeout }) {
|
|
672
|
+
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
673
|
+
event: `user-event-${event}`,
|
|
674
|
+
timeout: timeout ?? 5e3
|
|
675
|
+
});
|
|
676
|
+
if (eventData === null) {
|
|
677
|
+
throw "Timeout waiting for event";
|
|
678
|
+
}
|
|
679
|
+
return eventData?.data;
|
|
680
|
+
}
|
|
379
681
|
async executeStep({
|
|
380
682
|
step,
|
|
381
683
|
stepResults,
|
|
@@ -383,11 +685,13 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
383
685
|
resume,
|
|
384
686
|
prevOutput,
|
|
385
687
|
emitter,
|
|
688
|
+
abortController,
|
|
386
689
|
runtimeContext
|
|
387
690
|
}) {
|
|
388
|
-
await this.inngestStep.run(
|
|
691
|
+
const startedAt = await this.inngestStep.run(
|
|
389
692
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
390
693
|
async () => {
|
|
694
|
+
const startedAt2 = Date.now();
|
|
391
695
|
await emitter.emit("watch", {
|
|
392
696
|
type: "watch",
|
|
393
697
|
payload: {
|
|
@@ -409,6 +713,16 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
409
713
|
},
|
|
410
714
|
eventTimestamp: Date.now()
|
|
411
715
|
});
|
|
716
|
+
await emitter.emit("watch-v2", {
|
|
717
|
+
type: "step-start",
|
|
718
|
+
payload: {
|
|
719
|
+
id: step.id,
|
|
720
|
+
status: "running",
|
|
721
|
+
payload: prevOutput,
|
|
722
|
+
startedAt: startedAt2
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
return startedAt2;
|
|
412
726
|
}
|
|
413
727
|
);
|
|
414
728
|
if (step instanceof InngestWorkflow) {
|
|
@@ -469,6 +783,15 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
469
783
|
},
|
|
470
784
|
eventTimestamp: Date.now()
|
|
471
785
|
});
|
|
786
|
+
await emitter.emit("watch-v2", {
|
|
787
|
+
type: "step-result",
|
|
788
|
+
payload: {
|
|
789
|
+
id: step.id,
|
|
790
|
+
status: "failed",
|
|
791
|
+
error: result?.error,
|
|
792
|
+
payload: prevOutput
|
|
793
|
+
}
|
|
794
|
+
});
|
|
472
795
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
473
796
|
} else if (result.status === "suspended") {
|
|
474
797
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
@@ -495,6 +818,13 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
495
818
|
},
|
|
496
819
|
eventTimestamp: Date.now()
|
|
497
820
|
});
|
|
821
|
+
await emitter.emit("watch-v2", {
|
|
822
|
+
type: "step-suspended",
|
|
823
|
+
payload: {
|
|
824
|
+
id: step.id,
|
|
825
|
+
status: "suspended"
|
|
826
|
+
}
|
|
827
|
+
});
|
|
498
828
|
return {
|
|
499
829
|
executionContext,
|
|
500
830
|
result: {
|
|
@@ -545,6 +875,21 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
545
875
|
},
|
|
546
876
|
eventTimestamp: Date.now()
|
|
547
877
|
});
|
|
878
|
+
await emitter.emit("watch-v2", {
|
|
879
|
+
type: "step-result",
|
|
880
|
+
payload: {
|
|
881
|
+
id: step.id,
|
|
882
|
+
status: "success",
|
|
883
|
+
output: result?.result
|
|
884
|
+
}
|
|
885
|
+
});
|
|
886
|
+
await emitter.emit("watch-v2", {
|
|
887
|
+
type: "step-finish",
|
|
888
|
+
payload: {
|
|
889
|
+
id: step.id,
|
|
890
|
+
metadata: {}
|
|
891
|
+
}
|
|
892
|
+
});
|
|
548
893
|
return { executionContext, result: { status: "success", output: result?.result } };
|
|
549
894
|
}
|
|
550
895
|
);
|
|
@@ -554,8 +899,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
554
899
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
555
900
|
let execResults;
|
|
556
901
|
let suspended;
|
|
902
|
+
let bailed;
|
|
557
903
|
try {
|
|
558
904
|
const result = await step.execute({
|
|
905
|
+
runId: executionContext.runId,
|
|
559
906
|
mastra: this.mastra,
|
|
560
907
|
runtimeContext,
|
|
561
908
|
inputData: prevOutput,
|
|
@@ -572,20 +919,54 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
572
919
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
573
920
|
suspended = { payload: suspendPayload };
|
|
574
921
|
},
|
|
922
|
+
bail: (result2) => {
|
|
923
|
+
bailed = { payload: result2 };
|
|
924
|
+
},
|
|
575
925
|
resume: {
|
|
576
926
|
steps: resume?.steps?.slice(1) || [],
|
|
577
927
|
resumePayload: resume?.resumePayload,
|
|
578
928
|
// @ts-ignore
|
|
579
929
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
580
930
|
},
|
|
581
|
-
emitter
|
|
931
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
932
|
+
engine: {
|
|
933
|
+
step: this.inngestStep
|
|
934
|
+
},
|
|
935
|
+
abortSignal: abortController.signal
|
|
582
936
|
});
|
|
583
|
-
|
|
937
|
+
const endedAt = Date.now();
|
|
938
|
+
execResults = {
|
|
939
|
+
status: "success",
|
|
940
|
+
output: result,
|
|
941
|
+
startedAt,
|
|
942
|
+
endedAt,
|
|
943
|
+
payload: prevOutput,
|
|
944
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
945
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
946
|
+
};
|
|
584
947
|
} catch (e) {
|
|
585
|
-
execResults = {
|
|
948
|
+
execResults = {
|
|
949
|
+
status: "failed",
|
|
950
|
+
payload: prevOutput,
|
|
951
|
+
error: e instanceof Error ? e.message : String(e),
|
|
952
|
+
endedAt: Date.now(),
|
|
953
|
+
startedAt,
|
|
954
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
955
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
956
|
+
};
|
|
586
957
|
}
|
|
587
958
|
if (suspended) {
|
|
588
|
-
execResults = {
|
|
959
|
+
execResults = {
|
|
960
|
+
status: "suspended",
|
|
961
|
+
suspendedPayload: suspended.payload,
|
|
962
|
+
payload: prevOutput,
|
|
963
|
+
suspendedAt: Date.now(),
|
|
964
|
+
startedAt,
|
|
965
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
966
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
967
|
+
};
|
|
968
|
+
} else if (bailed) {
|
|
969
|
+
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
589
970
|
}
|
|
590
971
|
if (execResults.status === "failed") {
|
|
591
972
|
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
@@ -597,18 +978,41 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
597
978
|
payload: {
|
|
598
979
|
currentStep: {
|
|
599
980
|
id: step.id,
|
|
600
|
-
|
|
601
|
-
output: execResults.output
|
|
981
|
+
...execResults
|
|
602
982
|
},
|
|
603
983
|
workflowState: {
|
|
604
984
|
status: "running",
|
|
605
|
-
steps: stepResults,
|
|
985
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
606
986
|
result: null,
|
|
607
987
|
error: null
|
|
608
988
|
}
|
|
609
989
|
},
|
|
610
990
|
eventTimestamp: Date.now()
|
|
611
991
|
});
|
|
992
|
+
if (execResults.status === "suspended") {
|
|
993
|
+
await emitter.emit("watch-v2", {
|
|
994
|
+
type: "step-suspended",
|
|
995
|
+
payload: {
|
|
996
|
+
id: step.id,
|
|
997
|
+
...execResults
|
|
998
|
+
}
|
|
999
|
+
});
|
|
1000
|
+
} else {
|
|
1001
|
+
await emitter.emit("watch-v2", {
|
|
1002
|
+
type: "step-result",
|
|
1003
|
+
payload: {
|
|
1004
|
+
id: step.id,
|
|
1005
|
+
...execResults
|
|
1006
|
+
}
|
|
1007
|
+
});
|
|
1008
|
+
await emitter.emit("watch-v2", {
|
|
1009
|
+
type: "step-finish",
|
|
1010
|
+
payload: {
|
|
1011
|
+
id: step.id,
|
|
1012
|
+
metadata: {}
|
|
1013
|
+
}
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
612
1016
|
return { result: execResults, executionContext, stepResults };
|
|
613
1017
|
});
|
|
614
1018
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
@@ -619,7 +1023,11 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
619
1023
|
workflowId,
|
|
620
1024
|
runId,
|
|
621
1025
|
stepResults,
|
|
622
|
-
executionContext
|
|
1026
|
+
executionContext,
|
|
1027
|
+
serializedStepGraph,
|
|
1028
|
+
workflowStatus,
|
|
1029
|
+
result,
|
|
1030
|
+
error
|
|
623
1031
|
}) {
|
|
624
1032
|
await this.inngestStep.run(
|
|
625
1033
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -633,6 +1041,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
633
1041
|
context: stepResults,
|
|
634
1042
|
activePaths: [],
|
|
635
1043
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1044
|
+
serializedStepGraph,
|
|
1045
|
+
status: workflowStatus,
|
|
1046
|
+
result,
|
|
1047
|
+
error,
|
|
636
1048
|
// @ts-ignore
|
|
637
1049
|
timestamp: Date.now()
|
|
638
1050
|
}
|
|
@@ -647,9 +1059,11 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
647
1059
|
prevOutput,
|
|
648
1060
|
prevStep,
|
|
649
1061
|
stepResults,
|
|
1062
|
+
serializedStepGraph,
|
|
650
1063
|
resume,
|
|
651
1064
|
executionContext,
|
|
652
1065
|
emitter,
|
|
1066
|
+
abortController,
|
|
653
1067
|
runtimeContext
|
|
654
1068
|
}) {
|
|
655
1069
|
let execResults;
|
|
@@ -658,8 +1072,10 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
658
1072
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
659
1073
|
try {
|
|
660
1074
|
const result = await cond({
|
|
1075
|
+
runId,
|
|
661
1076
|
mastra: this.mastra,
|
|
662
1077
|
runtimeContext,
|
|
1078
|
+
runCount: -1,
|
|
663
1079
|
inputData: prevOutput,
|
|
664
1080
|
getInitData: () => stepResults?.input,
|
|
665
1081
|
getStepResult: (step) => {
|
|
@@ -675,7 +1091,16 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
675
1091
|
// TODO: this function shouldn't have suspend probably?
|
|
676
1092
|
suspend: async (_suspendPayload) => {
|
|
677
1093
|
},
|
|
678
|
-
|
|
1094
|
+
bail: () => {
|
|
1095
|
+
},
|
|
1096
|
+
abort: () => {
|
|
1097
|
+
abortController.abort();
|
|
1098
|
+
},
|
|
1099
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1100
|
+
engine: {
|
|
1101
|
+
step: this.inngestStep
|
|
1102
|
+
},
|
|
1103
|
+
abortSignal: abortController.signal
|
|
679
1104
|
});
|
|
680
1105
|
return result ? index : null;
|
|
681
1106
|
} catch (e) {
|
|
@@ -694,6 +1119,7 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
694
1119
|
prevStep,
|
|
695
1120
|
stepResults,
|
|
696
1121
|
resume,
|
|
1122
|
+
serializedStepGraph,
|
|
697
1123
|
executionContext: {
|
|
698
1124
|
workflowId,
|
|
699
1125
|
runId,
|
|
@@ -703,21 +1129,22 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
703
1129
|
executionSpan: executionContext.executionSpan
|
|
704
1130
|
},
|
|
705
1131
|
emitter,
|
|
1132
|
+
abortController,
|
|
706
1133
|
runtimeContext
|
|
707
1134
|
})
|
|
708
1135
|
)
|
|
709
1136
|
);
|
|
710
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
711
|
-
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1137
|
+
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1138
|
+
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
712
1139
|
if (hasFailed) {
|
|
713
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1140
|
+
execResults = { status: "failed", error: hasFailed.result.error };
|
|
714
1141
|
} else if (hasSuspended) {
|
|
715
|
-
execResults = { status: "suspended", payload: hasSuspended.
|
|
1142
|
+
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
716
1143
|
} else {
|
|
717
1144
|
execResults = {
|
|
718
1145
|
status: "success",
|
|
719
1146
|
output: results.reduce((acc, result, index) => {
|
|
720
|
-
if (result.status === "success") {
|
|
1147
|
+
if (result.result.status === "success") {
|
|
721
1148
|
acc[stepsToRun[index].step.id] = result.output;
|
|
722
1149
|
}
|
|
723
1150
|
return acc;
|
|
@@ -731,5 +1158,6 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
731
1158
|
exports.InngestExecutionEngine = InngestExecutionEngine;
|
|
732
1159
|
exports.InngestRun = InngestRun;
|
|
733
1160
|
exports.InngestWorkflow = InngestWorkflow;
|
|
1161
|
+
exports.createStep = createStep;
|
|
734
1162
|
exports.init = init;
|
|
735
1163
|
exports.serve = serve;
|