@mastra/inngest 0.0.0-vector-sources-20250516175436 → 0.0.0-vector-query-tool-provider-options-20250828222356
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 +769 -2
- package/LICENSE.md +11 -42
- package/dist/index.cjs +758 -78
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +277 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +755 -76
- package/dist/index.js.map +1 -0
- package/docker-compose.yaml +3 -3
- package/package.json +26 -20
- package/src/index.test.ts +5998 -3528
- package/src/index.ts +1089 -127
- package/tsconfig.build.json +9 -0
- package/tsconfig.json +1 -1
- package/tsup.config.ts +17 -0
- package/vitest.config.ts +6 -0
- package/dist/_tsup-dts-rollup.d.cts +0 -194
- package/dist/_tsup-dts-rollup.d.ts +0 -194
- package/dist/index.d.cts +0 -5
package/dist/index.js
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
2
|
import { subscribe } from '@inngest/realtime';
|
|
3
|
+
import { wrapMastra, AISpanType } from '@mastra/core/ai-tracing';
|
|
3
4
|
import { RuntimeContext } from '@mastra/core/di';
|
|
4
|
-
import {
|
|
5
|
+
import { ToolStream, Tool } from '@mastra/core/tools';
|
|
6
|
+
import { Run, Workflow, DefaultExecutionEngine } from '@mastra/core/workflows';
|
|
7
|
+
import { EMITTER_SYMBOL } from '@mastra/core/workflows/_constants';
|
|
5
8
|
import { serve as serve$1 } from 'inngest/hono';
|
|
9
|
+
import { z } from 'zod';
|
|
6
10
|
|
|
7
11
|
// src/index.ts
|
|
8
12
|
function serve({ mastra, inngest }) {
|
|
9
|
-
const wfs = mastra.
|
|
10
|
-
const functions =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
const wfs = mastra.getWorkflows();
|
|
14
|
+
const functions = Array.from(
|
|
15
|
+
new Set(
|
|
16
|
+
Object.values(wfs).flatMap((wf) => {
|
|
17
|
+
if (wf instanceof InngestWorkflow) {
|
|
18
|
+
wf.__registerMastra(mastra);
|
|
19
|
+
return wf.getFunctions();
|
|
20
|
+
}
|
|
21
|
+
return [];
|
|
22
|
+
})
|
|
23
|
+
)
|
|
24
|
+
);
|
|
17
25
|
return serve$1({
|
|
18
26
|
client: inngest,
|
|
19
27
|
functions
|
|
@@ -21,14 +29,16 @@ function serve({ mastra, inngest }) {
|
|
|
21
29
|
}
|
|
22
30
|
var InngestRun = class extends Run {
|
|
23
31
|
inngest;
|
|
32
|
+
serializedStepGraph;
|
|
24
33
|
#mastra;
|
|
25
34
|
constructor(params, inngest) {
|
|
26
35
|
super(params);
|
|
27
36
|
this.inngest = inngest;
|
|
37
|
+
this.serializedStepGraph = params.serializedStepGraph;
|
|
28
38
|
this.#mastra = params.mastra;
|
|
29
39
|
}
|
|
30
40
|
async getRuns(eventId) {
|
|
31
|
-
const response = await fetch(`${this.inngest.apiBaseUrl}/v1/events/${eventId}/runs`, {
|
|
41
|
+
const response = await fetch(`${this.inngest.apiBaseUrl ?? "https://api.inngest.com"}/v1/events/${eventId}/runs`, {
|
|
32
42
|
headers: {
|
|
33
43
|
Authorization: `Bearer ${process.env.INNGEST_SIGNING_KEY}`
|
|
34
44
|
}
|
|
@@ -38,15 +48,50 @@ var InngestRun = class extends Run {
|
|
|
38
48
|
}
|
|
39
49
|
async getRunOutput(eventId) {
|
|
40
50
|
let runs = await this.getRuns(eventId);
|
|
41
|
-
while (runs?.[0]?.status !== "Completed") {
|
|
51
|
+
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
42
52
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
43
53
|
runs = await this.getRuns(eventId);
|
|
44
|
-
if (runs?.[0]?.status === "Failed"
|
|
54
|
+
if (runs?.[0]?.status === "Failed") {
|
|
55
|
+
console.log("run", runs?.[0]);
|
|
45
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" } } };
|
|
46
63
|
}
|
|
47
64
|
}
|
|
48
65
|
return runs?.[0];
|
|
49
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
|
+
}
|
|
50
95
|
async start({
|
|
51
96
|
inputData
|
|
52
97
|
}) {
|
|
@@ -55,11 +100,14 @@ var InngestRun = class extends Run {
|
|
|
55
100
|
runId: this.runId,
|
|
56
101
|
snapshot: {
|
|
57
102
|
runId: this.runId,
|
|
103
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
58
104
|
value: {},
|
|
59
105
|
context: {},
|
|
60
106
|
activePaths: [],
|
|
61
107
|
suspendedPaths: {},
|
|
62
|
-
|
|
108
|
+
waitingPaths: {},
|
|
109
|
+
timestamp: Date.now(),
|
|
110
|
+
status: "running"
|
|
63
111
|
}
|
|
64
112
|
});
|
|
65
113
|
const eventOutput = await this.inngest.send({
|
|
@@ -78,10 +126,23 @@ var InngestRun = class extends Run {
|
|
|
78
126
|
if (result.status === "failed") {
|
|
79
127
|
result.error = new Error(result.error);
|
|
80
128
|
}
|
|
81
|
-
|
|
129
|
+
if (result.status !== "suspended") {
|
|
130
|
+
this.cleanup?.();
|
|
131
|
+
}
|
|
82
132
|
return result;
|
|
83
133
|
}
|
|
84
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) {
|
|
85
146
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
86
147
|
(step) => typeof step === "string" ? step : step?.id
|
|
87
148
|
);
|
|
@@ -94,6 +155,7 @@ var InngestRun = class extends Run {
|
|
|
94
155
|
data: {
|
|
95
156
|
inputData: params.resumeData,
|
|
96
157
|
runId: this.runId,
|
|
158
|
+
workflowId: this.workflowId,
|
|
97
159
|
stepResults: snapshot?.context,
|
|
98
160
|
resume: {
|
|
99
161
|
steps,
|
|
@@ -115,27 +177,62 @@ var InngestRun = class extends Run {
|
|
|
115
177
|
}
|
|
116
178
|
return result;
|
|
117
179
|
}
|
|
118
|
-
watch(cb) {
|
|
180
|
+
watch(cb, type = "watch") {
|
|
181
|
+
let active = true;
|
|
119
182
|
const streamPromise = subscribe(
|
|
120
183
|
{
|
|
121
184
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
122
|
-
topics: [
|
|
185
|
+
topics: [type],
|
|
123
186
|
app: this.inngest
|
|
124
187
|
},
|
|
125
188
|
(message) => {
|
|
126
|
-
|
|
189
|
+
if (active) {
|
|
190
|
+
cb(message.data);
|
|
191
|
+
}
|
|
127
192
|
}
|
|
128
193
|
);
|
|
129
194
|
return () => {
|
|
130
|
-
|
|
131
|
-
|
|
195
|
+
active = false;
|
|
196
|
+
streamPromise.then(async (stream) => {
|
|
197
|
+
return stream.cancel();
|
|
132
198
|
}).catch((err) => {
|
|
133
199
|
console.error(err);
|
|
134
200
|
});
|
|
135
201
|
};
|
|
136
202
|
}
|
|
203
|
+
stream({ inputData, runtimeContext } = {}) {
|
|
204
|
+
const { readable, writable } = new TransformStream();
|
|
205
|
+
const writer = writable.getWriter();
|
|
206
|
+
const unwatch = this.watch(async (event) => {
|
|
207
|
+
try {
|
|
208
|
+
await writer.write(event);
|
|
209
|
+
} catch {
|
|
210
|
+
}
|
|
211
|
+
}, "watch-v2");
|
|
212
|
+
this.closeStreamAction = async () => {
|
|
213
|
+
unwatch();
|
|
214
|
+
try {
|
|
215
|
+
await writer.close();
|
|
216
|
+
} catch (err) {
|
|
217
|
+
console.error("Error closing stream:", err);
|
|
218
|
+
} finally {
|
|
219
|
+
writer.releaseLock();
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
|
|
223
|
+
if (result.status !== "suspended") {
|
|
224
|
+
this.closeStreamAction?.().catch(() => {
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
return result;
|
|
228
|
+
});
|
|
229
|
+
return {
|
|
230
|
+
stream: readable,
|
|
231
|
+
getWorkflowState: () => this.executionResults
|
|
232
|
+
};
|
|
233
|
+
}
|
|
137
234
|
};
|
|
138
|
-
var InngestWorkflow = class _InngestWorkflow extends
|
|
235
|
+
var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
139
236
|
#mastra;
|
|
140
237
|
inngest;
|
|
141
238
|
function;
|
|
@@ -156,11 +253,32 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
156
253
|
const storage = this.#mastra?.getStorage();
|
|
157
254
|
if (!storage) {
|
|
158
255
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
159
|
-
return null;
|
|
256
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
160
257
|
}
|
|
161
258
|
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
162
259
|
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
163
260
|
}
|
|
261
|
+
async getWorkflowRunExecutionResult(runId) {
|
|
262
|
+
const storage = this.#mastra?.getStorage();
|
|
263
|
+
if (!storage) {
|
|
264
|
+
this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
268
|
+
if (!run?.snapshot) {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
if (typeof run.snapshot === "string") {
|
|
272
|
+
return null;
|
|
273
|
+
}
|
|
274
|
+
return {
|
|
275
|
+
status: run.snapshot.status,
|
|
276
|
+
result: run.snapshot.result,
|
|
277
|
+
error: run.snapshot.error,
|
|
278
|
+
payload: run.snapshot.context?.input,
|
|
279
|
+
steps: run.snapshot.context
|
|
280
|
+
};
|
|
281
|
+
}
|
|
164
282
|
__registerMastra(mastra) {
|
|
165
283
|
this.#mastra = mastra;
|
|
166
284
|
this.executionEngine.__registerMastra(mastra);
|
|
@@ -187,6 +305,25 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
187
305
|
runId: runIdToUse,
|
|
188
306
|
executionEngine: this.executionEngine,
|
|
189
307
|
executionGraph: this.executionGraph,
|
|
308
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
309
|
+
mastra: this.#mastra,
|
|
310
|
+
retryConfig: this.retryConfig,
|
|
311
|
+
cleanup: () => this.runs.delete(runIdToUse)
|
|
312
|
+
},
|
|
313
|
+
this.inngest
|
|
314
|
+
);
|
|
315
|
+
this.runs.set(runIdToUse, run);
|
|
316
|
+
return run;
|
|
317
|
+
}
|
|
318
|
+
async createRunAsync(options) {
|
|
319
|
+
const runIdToUse = options?.runId || randomUUID();
|
|
320
|
+
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
321
|
+
{
|
|
322
|
+
workflowId: this.id,
|
|
323
|
+
runId: runIdToUse,
|
|
324
|
+
executionEngine: this.executionEngine,
|
|
325
|
+
executionGraph: this.executionGraph,
|
|
326
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
190
327
|
mastra: this.#mastra,
|
|
191
328
|
retryConfig: this.retryConfig,
|
|
192
329
|
cleanup: () => this.runs.delete(runIdToUse)
|
|
@@ -194,6 +331,27 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
194
331
|
this.inngest
|
|
195
332
|
);
|
|
196
333
|
this.runs.set(runIdToUse, run);
|
|
334
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
|
|
335
|
+
if (!workflowSnapshotInStorage) {
|
|
336
|
+
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
337
|
+
workflowName: this.id,
|
|
338
|
+
runId: runIdToUse,
|
|
339
|
+
snapshot: {
|
|
340
|
+
runId: runIdToUse,
|
|
341
|
+
status: "pending",
|
|
342
|
+
value: {},
|
|
343
|
+
context: {},
|
|
344
|
+
activePaths: [],
|
|
345
|
+
waitingPaths: {},
|
|
346
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
347
|
+
suspendedPaths: {},
|
|
348
|
+
result: void 0,
|
|
349
|
+
error: void 0,
|
|
350
|
+
// @ts-ignore
|
|
351
|
+
timestamp: Date.now()
|
|
352
|
+
}
|
|
353
|
+
});
|
|
354
|
+
}
|
|
197
355
|
return run;
|
|
198
356
|
}
|
|
199
357
|
getFunction() {
|
|
@@ -201,8 +359,12 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
201
359
|
return this.function;
|
|
202
360
|
}
|
|
203
361
|
this.function = this.inngest.createFunction(
|
|
204
|
-
|
|
205
|
-
|
|
362
|
+
{
|
|
363
|
+
id: `workflow.${this.id}`,
|
|
364
|
+
// @ts-ignore
|
|
365
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
366
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }]
|
|
367
|
+
},
|
|
206
368
|
{ event: `workflow.${this.id}` },
|
|
207
369
|
async ({ event, step, attempt, publish }) => {
|
|
208
370
|
let { inputData, runId, resume } = event.data;
|
|
@@ -219,12 +381,18 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
219
381
|
try {
|
|
220
382
|
await publish({
|
|
221
383
|
channel: `workflow:${this.id}:${runId}`,
|
|
222
|
-
topic:
|
|
384
|
+
topic: event2,
|
|
223
385
|
data
|
|
224
386
|
});
|
|
225
387
|
} catch (err) {
|
|
226
388
|
this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
|
|
227
389
|
}
|
|
390
|
+
},
|
|
391
|
+
on: (_event, _callback) => {
|
|
392
|
+
},
|
|
393
|
+
off: (_event, _callback) => {
|
|
394
|
+
},
|
|
395
|
+
once: (_event, _callback) => {
|
|
228
396
|
}
|
|
229
397
|
};
|
|
230
398
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
@@ -232,12 +400,16 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
232
400
|
workflowId: this.id,
|
|
233
401
|
runId,
|
|
234
402
|
graph: this.executionGraph,
|
|
403
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
235
404
|
input: inputData,
|
|
236
405
|
emitter,
|
|
237
406
|
retryConfig: this.retryConfig,
|
|
238
407
|
runtimeContext: new RuntimeContext(),
|
|
239
408
|
// TODO
|
|
240
|
-
resume
|
|
409
|
+
resume,
|
|
410
|
+
abortController: new AbortController(),
|
|
411
|
+
currentSpan: void 0
|
|
412
|
+
// TODO: Pass actual parent AI span from workflow execution context
|
|
241
413
|
});
|
|
242
414
|
return { result, runId };
|
|
243
415
|
}
|
|
@@ -261,20 +433,112 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
261
433
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
262
434
|
}
|
|
263
435
|
};
|
|
264
|
-
function
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
436
|
+
function isAgent(params) {
|
|
437
|
+
return params?.component === "AGENT";
|
|
438
|
+
}
|
|
439
|
+
function isTool(params) {
|
|
440
|
+
return params instanceof Tool;
|
|
441
|
+
}
|
|
442
|
+
function createStep(params) {
|
|
443
|
+
if (isAgent(params)) {
|
|
444
|
+
return {
|
|
445
|
+
id: params.name,
|
|
446
|
+
// @ts-ignore
|
|
447
|
+
inputSchema: z.object({
|
|
448
|
+
prompt: z.string()
|
|
449
|
+
// resourceId: z.string().optional(),
|
|
450
|
+
// threadId: z.string().optional(),
|
|
451
|
+
}),
|
|
452
|
+
// @ts-ignore
|
|
453
|
+
outputSchema: z.object({
|
|
454
|
+
text: z.string()
|
|
455
|
+
}),
|
|
456
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
|
|
457
|
+
let streamPromise = {};
|
|
458
|
+
streamPromise.promise = new Promise((resolve, reject) => {
|
|
459
|
+
streamPromise.resolve = resolve;
|
|
460
|
+
streamPromise.reject = reject;
|
|
461
|
+
});
|
|
462
|
+
const toolData = {
|
|
463
|
+
name: params.name,
|
|
464
|
+
args: inputData
|
|
465
|
+
};
|
|
466
|
+
await emitter.emit("watch-v2", {
|
|
467
|
+
type: "tool-call-streaming-start",
|
|
468
|
+
...toolData
|
|
469
|
+
});
|
|
470
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
471
|
+
// resourceId: inputData.resourceId,
|
|
472
|
+
// threadId: inputData.threadId,
|
|
473
|
+
runtimeContext,
|
|
474
|
+
tracingContext,
|
|
475
|
+
onFinish: (result) => {
|
|
476
|
+
streamPromise.resolve(result.text);
|
|
477
|
+
},
|
|
478
|
+
abortSignal
|
|
479
|
+
});
|
|
480
|
+
if (abortSignal.aborted) {
|
|
481
|
+
return abort();
|
|
482
|
+
}
|
|
483
|
+
for await (const chunk of fullStream) {
|
|
484
|
+
switch (chunk.type) {
|
|
485
|
+
case "text-delta":
|
|
486
|
+
await emitter.emit("watch-v2", {
|
|
487
|
+
type: "tool-call-delta",
|
|
488
|
+
...toolData,
|
|
489
|
+
argsTextDelta: chunk.textDelta
|
|
490
|
+
});
|
|
491
|
+
break;
|
|
492
|
+
case "step-start":
|
|
493
|
+
case "step-finish":
|
|
494
|
+
case "finish":
|
|
495
|
+
break;
|
|
496
|
+
case "tool-call":
|
|
497
|
+
case "tool-result":
|
|
498
|
+
case "tool-call-streaming-start":
|
|
499
|
+
case "tool-call-delta":
|
|
500
|
+
case "source":
|
|
501
|
+
case "file":
|
|
502
|
+
default:
|
|
503
|
+
await emitter.emit("watch-v2", chunk);
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
return {
|
|
508
|
+
text: await streamPromise.promise
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
if (isTool(params)) {
|
|
514
|
+
if (!params.inputSchema || !params.outputSchema) {
|
|
515
|
+
throw new Error("Tool must have input and output schemas defined");
|
|
516
|
+
}
|
|
517
|
+
return {
|
|
518
|
+
// TODO: tool probably should have strong id type
|
|
519
|
+
// @ts-ignore
|
|
520
|
+
id: params.id,
|
|
521
|
+
inputSchema: params.inputSchema,
|
|
522
|
+
outputSchema: params.outputSchema,
|
|
523
|
+
execute: async ({ inputData, mastra, runtimeContext, tracingContext }) => {
|
|
524
|
+
return params.execute({
|
|
525
|
+
context: inputData,
|
|
526
|
+
mastra: wrapMastra(mastra, tracingContext),
|
|
527
|
+
runtimeContext,
|
|
528
|
+
tracingContext
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
};
|
|
532
|
+
}
|
|
533
|
+
return {
|
|
534
|
+
id: params.id,
|
|
535
|
+
description: params.description,
|
|
536
|
+
inputSchema: params.inputSchema,
|
|
537
|
+
outputSchema: params.outputSchema,
|
|
538
|
+
resumeSchema: params.resumeSchema,
|
|
539
|
+
suspendSchema: params.suspendSchema,
|
|
540
|
+
execute: params.execute
|
|
541
|
+
};
|
|
278
542
|
}
|
|
279
543
|
function init(inngest) {
|
|
280
544
|
return {
|
|
@@ -282,8 +546,27 @@ function init(inngest) {
|
|
|
282
546
|
return new InngestWorkflow(params, inngest);
|
|
283
547
|
},
|
|
284
548
|
createStep,
|
|
285
|
-
cloneStep,
|
|
286
|
-
|
|
549
|
+
cloneStep(step, opts) {
|
|
550
|
+
return {
|
|
551
|
+
id: opts.id,
|
|
552
|
+
description: step.description,
|
|
553
|
+
inputSchema: step.inputSchema,
|
|
554
|
+
outputSchema: step.outputSchema,
|
|
555
|
+
execute: step.execute
|
|
556
|
+
};
|
|
557
|
+
},
|
|
558
|
+
cloneWorkflow(workflow, opts) {
|
|
559
|
+
const wf = new Workflow({
|
|
560
|
+
id: opts.id,
|
|
561
|
+
inputSchema: workflow.inputSchema,
|
|
562
|
+
outputSchema: workflow.outputSchema,
|
|
563
|
+
steps: workflow.stepDefs,
|
|
564
|
+
mastra: workflow.mastra
|
|
565
|
+
});
|
|
566
|
+
wf.setStepFlow(workflow.stepGraph);
|
|
567
|
+
wf.commit();
|
|
568
|
+
return wf;
|
|
569
|
+
}
|
|
287
570
|
};
|
|
288
571
|
}
|
|
289
572
|
var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
@@ -294,6 +577,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
294
577
|
this.inngestStep = inngestStep;
|
|
295
578
|
this.inngestAttempts = inngestAttempts;
|
|
296
579
|
}
|
|
580
|
+
async execute(params) {
|
|
581
|
+
await params.emitter.emit("watch-v2", {
|
|
582
|
+
type: "start",
|
|
583
|
+
payload: { runId: params.runId }
|
|
584
|
+
});
|
|
585
|
+
const result = await super.execute(params);
|
|
586
|
+
await params.emitter.emit("watch-v2", {
|
|
587
|
+
type: "finish",
|
|
588
|
+
payload: { runId: params.runId }
|
|
589
|
+
});
|
|
590
|
+
return result;
|
|
591
|
+
}
|
|
297
592
|
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
298
593
|
const base = {
|
|
299
594
|
status: lastOutput.status,
|
|
@@ -351,28 +646,186 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
351
646
|
executionSpan?.end();
|
|
352
647
|
return base;
|
|
353
648
|
}
|
|
354
|
-
async
|
|
649
|
+
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
650
|
+
// await this.inngestStep.sleep(id, duration);
|
|
651
|
+
// }
|
|
652
|
+
async executeSleep({
|
|
355
653
|
workflowId,
|
|
356
654
|
runId,
|
|
357
|
-
|
|
655
|
+
entry,
|
|
656
|
+
prevOutput,
|
|
358
657
|
stepResults,
|
|
359
|
-
|
|
360
|
-
|
|
658
|
+
emitter,
|
|
659
|
+
abortController,
|
|
660
|
+
runtimeContext,
|
|
661
|
+
writableStream,
|
|
662
|
+
tracingContext
|
|
663
|
+
}) {
|
|
664
|
+
let { duration, fn } = entry;
|
|
665
|
+
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
666
|
+
type: AISpanType.WORKFLOW_SLEEP,
|
|
667
|
+
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
668
|
+
attributes: {
|
|
669
|
+
durationMs: duration,
|
|
670
|
+
sleepType: fn ? "dynamic" : "fixed"
|
|
671
|
+
}
|
|
672
|
+
});
|
|
673
|
+
if (fn) {
|
|
674
|
+
const stepCallId = randomUUID();
|
|
675
|
+
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
676
|
+
return await fn({
|
|
677
|
+
runId,
|
|
678
|
+
workflowId,
|
|
679
|
+
mastra: this.mastra,
|
|
680
|
+
runtimeContext,
|
|
681
|
+
inputData: prevOutput,
|
|
682
|
+
runCount: -1,
|
|
683
|
+
tracingContext: {
|
|
684
|
+
currentSpan: sleepSpan
|
|
685
|
+
},
|
|
686
|
+
getInitData: () => stepResults?.input,
|
|
687
|
+
getStepResult: (step) => {
|
|
688
|
+
if (!step?.id) {
|
|
689
|
+
return null;
|
|
690
|
+
}
|
|
691
|
+
const result = stepResults[step.id];
|
|
692
|
+
if (result?.status === "success") {
|
|
693
|
+
return result.output;
|
|
694
|
+
}
|
|
695
|
+
return null;
|
|
696
|
+
},
|
|
697
|
+
// TODO: this function shouldn't have suspend probably?
|
|
698
|
+
suspend: async (_suspendPayload) => {
|
|
699
|
+
},
|
|
700
|
+
bail: () => {
|
|
701
|
+
},
|
|
702
|
+
abort: () => {
|
|
703
|
+
abortController?.abort();
|
|
704
|
+
},
|
|
705
|
+
[EMITTER_SYMBOL]: emitter,
|
|
706
|
+
engine: { step: this.inngestStep },
|
|
707
|
+
abortSignal: abortController?.signal,
|
|
708
|
+
writer: new ToolStream(
|
|
709
|
+
{
|
|
710
|
+
prefix: "step",
|
|
711
|
+
callId: stepCallId,
|
|
712
|
+
name: "sleep",
|
|
713
|
+
runId
|
|
714
|
+
},
|
|
715
|
+
writableStream
|
|
716
|
+
)
|
|
717
|
+
});
|
|
718
|
+
});
|
|
719
|
+
sleepSpan?.update({
|
|
720
|
+
attributes: {
|
|
721
|
+
durationMs: duration
|
|
722
|
+
}
|
|
723
|
+
});
|
|
724
|
+
}
|
|
725
|
+
try {
|
|
726
|
+
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
727
|
+
sleepSpan?.end();
|
|
728
|
+
} catch (e) {
|
|
729
|
+
sleepSpan?.error({ error: e });
|
|
730
|
+
throw e;
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
async executeSleepUntil({
|
|
734
|
+
workflowId,
|
|
735
|
+
runId,
|
|
736
|
+
entry,
|
|
361
737
|
prevOutput,
|
|
738
|
+
stepResults,
|
|
362
739
|
emitter,
|
|
363
|
-
|
|
740
|
+
abortController,
|
|
741
|
+
runtimeContext,
|
|
742
|
+
writableStream,
|
|
743
|
+
tracingContext
|
|
364
744
|
}) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
745
|
+
let { date, fn } = entry;
|
|
746
|
+
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
747
|
+
type: AISpanType.WORKFLOW_SLEEP,
|
|
748
|
+
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
749
|
+
attributes: {
|
|
750
|
+
untilDate: date,
|
|
751
|
+
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
752
|
+
sleepType: fn ? "dynamic" : "fixed"
|
|
753
|
+
}
|
|
754
|
+
});
|
|
755
|
+
if (fn) {
|
|
756
|
+
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
757
|
+
const stepCallId = randomUUID();
|
|
758
|
+
return await fn({
|
|
759
|
+
runId,
|
|
760
|
+
workflowId,
|
|
761
|
+
mastra: this.mastra,
|
|
762
|
+
runtimeContext,
|
|
763
|
+
inputData: prevOutput,
|
|
764
|
+
runCount: -1,
|
|
765
|
+
tracingContext: {
|
|
766
|
+
currentSpan: sleepUntilSpan
|
|
767
|
+
},
|
|
768
|
+
getInitData: () => stepResults?.input,
|
|
769
|
+
getStepResult: (step) => {
|
|
770
|
+
if (!step?.id) {
|
|
771
|
+
return null;
|
|
772
|
+
}
|
|
773
|
+
const result = stepResults[step.id];
|
|
774
|
+
if (result?.status === "success") {
|
|
775
|
+
return result.output;
|
|
776
|
+
}
|
|
777
|
+
return null;
|
|
778
|
+
},
|
|
779
|
+
// TODO: this function shouldn't have suspend probably?
|
|
780
|
+
suspend: async (_suspendPayload) => {
|
|
781
|
+
},
|
|
782
|
+
bail: () => {
|
|
783
|
+
},
|
|
784
|
+
abort: () => {
|
|
785
|
+
abortController?.abort();
|
|
786
|
+
},
|
|
787
|
+
[EMITTER_SYMBOL]: emitter,
|
|
788
|
+
engine: { step: this.inngestStep },
|
|
789
|
+
abortSignal: abortController?.signal,
|
|
790
|
+
writer: new ToolStream(
|
|
791
|
+
{
|
|
792
|
+
prefix: "step",
|
|
793
|
+
callId: stepCallId,
|
|
794
|
+
name: "sleep",
|
|
795
|
+
runId
|
|
796
|
+
},
|
|
797
|
+
writableStream
|
|
798
|
+
)
|
|
799
|
+
});
|
|
800
|
+
});
|
|
801
|
+
const time = !date ? 0 : date.getTime() - Date.now();
|
|
802
|
+
sleepUntilSpan?.update({
|
|
803
|
+
attributes: {
|
|
804
|
+
durationMs: Math.max(0, time)
|
|
805
|
+
}
|
|
806
|
+
});
|
|
807
|
+
}
|
|
808
|
+
if (!(date instanceof Date)) {
|
|
809
|
+
sleepUntilSpan?.end();
|
|
810
|
+
return;
|
|
811
|
+
}
|
|
812
|
+
try {
|
|
813
|
+
await this.inngestStep.sleepUntil(entry.id, date);
|
|
814
|
+
sleepUntilSpan?.end();
|
|
815
|
+
} catch (e) {
|
|
816
|
+
sleepUntilSpan?.error({ error: e });
|
|
817
|
+
throw e;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
async executeWaitForEvent({ event, timeout }) {
|
|
821
|
+
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
822
|
+
event: `user-event-${event}`,
|
|
823
|
+
timeout: timeout ?? 5e3
|
|
375
824
|
});
|
|
825
|
+
if (eventData === null) {
|
|
826
|
+
throw "Timeout waiting for event";
|
|
827
|
+
}
|
|
828
|
+
return eventData?.data;
|
|
376
829
|
}
|
|
377
830
|
async executeStep({
|
|
378
831
|
step,
|
|
@@ -381,11 +834,24 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
381
834
|
resume,
|
|
382
835
|
prevOutput,
|
|
383
836
|
emitter,
|
|
384
|
-
|
|
837
|
+
abortController,
|
|
838
|
+
runtimeContext,
|
|
839
|
+
writableStream,
|
|
840
|
+
disableScorers,
|
|
841
|
+
tracingContext
|
|
385
842
|
}) {
|
|
386
|
-
|
|
843
|
+
const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
|
|
844
|
+
name: `workflow step: '${step.id}'`,
|
|
845
|
+
type: AISpanType.WORKFLOW_STEP,
|
|
846
|
+
input: prevOutput,
|
|
847
|
+
attributes: {
|
|
848
|
+
stepId: step.id
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
const startedAt = await this.inngestStep.run(
|
|
387
852
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
388
853
|
async () => {
|
|
854
|
+
const startedAt2 = Date.now();
|
|
389
855
|
await emitter.emit("watch", {
|
|
390
856
|
type: "watch",
|
|
391
857
|
payload: {
|
|
@@ -407,6 +873,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
407
873
|
},
|
|
408
874
|
eventTimestamp: Date.now()
|
|
409
875
|
});
|
|
876
|
+
await emitter.emit("watch-v2", {
|
|
877
|
+
type: "step-start",
|
|
878
|
+
payload: {
|
|
879
|
+
id: step.id,
|
|
880
|
+
status: "running",
|
|
881
|
+
payload: prevOutput,
|
|
882
|
+
startedAt: startedAt2
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
return startedAt2;
|
|
410
886
|
}
|
|
411
887
|
);
|
|
412
888
|
if (step instanceof InngestWorkflow) {
|
|
@@ -467,6 +943,15 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
467
943
|
},
|
|
468
944
|
eventTimestamp: Date.now()
|
|
469
945
|
});
|
|
946
|
+
await emitter.emit("watch-v2", {
|
|
947
|
+
type: "step-result",
|
|
948
|
+
payload: {
|
|
949
|
+
id: step.id,
|
|
950
|
+
status: "failed",
|
|
951
|
+
error: result?.error,
|
|
952
|
+
payload: prevOutput
|
|
953
|
+
}
|
|
954
|
+
});
|
|
470
955
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
471
956
|
} else if (result.status === "suspended") {
|
|
472
957
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
@@ -493,6 +978,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
493
978
|
},
|
|
494
979
|
eventTimestamp: Date.now()
|
|
495
980
|
});
|
|
981
|
+
await emitter.emit("watch-v2", {
|
|
982
|
+
type: "step-suspended",
|
|
983
|
+
payload: {
|
|
984
|
+
id: step.id,
|
|
985
|
+
status: "suspended"
|
|
986
|
+
}
|
|
987
|
+
});
|
|
496
988
|
return {
|
|
497
989
|
executionContext,
|
|
498
990
|
result: {
|
|
@@ -543,6 +1035,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
543
1035
|
},
|
|
544
1036
|
eventTimestamp: Date.now()
|
|
545
1037
|
});
|
|
1038
|
+
await emitter.emit("watch-v2", {
|
|
1039
|
+
type: "step-result",
|
|
1040
|
+
payload: {
|
|
1041
|
+
id: step.id,
|
|
1042
|
+
status: "success",
|
|
1043
|
+
output: result?.result
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
await emitter.emit("watch-v2", {
|
|
1047
|
+
type: "step-finish",
|
|
1048
|
+
payload: {
|
|
1049
|
+
id: step.id,
|
|
1050
|
+
metadata: {}
|
|
1051
|
+
}
|
|
1052
|
+
});
|
|
546
1053
|
return { executionContext, result: { status: "success", output: result?.result } };
|
|
547
1054
|
}
|
|
548
1055
|
);
|
|
@@ -552,12 +1059,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
552
1059
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
553
1060
|
let execResults;
|
|
554
1061
|
let suspended;
|
|
1062
|
+
let bailed;
|
|
555
1063
|
try {
|
|
556
1064
|
const result = await step.execute({
|
|
1065
|
+
runId: executionContext.runId,
|
|
557
1066
|
mastra: this.mastra,
|
|
558
1067
|
runtimeContext,
|
|
1068
|
+
writableStream,
|
|
559
1069
|
inputData: prevOutput,
|
|
560
1070
|
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1071
|
+
tracingContext: {
|
|
1072
|
+
currentSpan: stepAISpan
|
|
1073
|
+
},
|
|
561
1074
|
getInitData: () => stepResults?.input,
|
|
562
1075
|
getStepResult: (step2) => {
|
|
563
1076
|
const result2 = stepResults[step2.id];
|
|
@@ -570,24 +1083,60 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
570
1083
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
571
1084
|
suspended = { payload: suspendPayload };
|
|
572
1085
|
},
|
|
1086
|
+
bail: (result2) => {
|
|
1087
|
+
bailed = { payload: result2 };
|
|
1088
|
+
},
|
|
573
1089
|
resume: {
|
|
574
1090
|
steps: resume?.steps?.slice(1) || [],
|
|
575
1091
|
resumePayload: resume?.resumePayload,
|
|
576
1092
|
// @ts-ignore
|
|
577
1093
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
578
1094
|
},
|
|
579
|
-
emitter
|
|
1095
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1096
|
+
engine: {
|
|
1097
|
+
step: this.inngestStep
|
|
1098
|
+
},
|
|
1099
|
+
abortSignal: abortController.signal
|
|
580
1100
|
});
|
|
581
|
-
|
|
1101
|
+
const endedAt = Date.now();
|
|
1102
|
+
execResults = {
|
|
1103
|
+
status: "success",
|
|
1104
|
+
output: result,
|
|
1105
|
+
startedAt,
|
|
1106
|
+
endedAt,
|
|
1107
|
+
payload: prevOutput,
|
|
1108
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1109
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1110
|
+
};
|
|
582
1111
|
} catch (e) {
|
|
583
|
-
execResults = {
|
|
1112
|
+
execResults = {
|
|
1113
|
+
status: "failed",
|
|
1114
|
+
payload: prevOutput,
|
|
1115
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1116
|
+
endedAt: Date.now(),
|
|
1117
|
+
startedAt,
|
|
1118
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1119
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1120
|
+
};
|
|
584
1121
|
}
|
|
585
1122
|
if (suspended) {
|
|
586
|
-
execResults = {
|
|
1123
|
+
execResults = {
|
|
1124
|
+
status: "suspended",
|
|
1125
|
+
suspendedPayload: suspended.payload,
|
|
1126
|
+
payload: prevOutput,
|
|
1127
|
+
suspendedAt: Date.now(),
|
|
1128
|
+
startedAt,
|
|
1129
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1130
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1131
|
+
};
|
|
1132
|
+
} else if (bailed) {
|
|
1133
|
+
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
587
1134
|
}
|
|
588
1135
|
if (execResults.status === "failed") {
|
|
589
1136
|
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
590
|
-
|
|
1137
|
+
const error = new Error(execResults.error);
|
|
1138
|
+
stepAISpan?.error({ error });
|
|
1139
|
+
throw error;
|
|
591
1140
|
}
|
|
592
1141
|
}
|
|
593
1142
|
await emitter.emit("watch", {
|
|
@@ -595,20 +1144,60 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
595
1144
|
payload: {
|
|
596
1145
|
currentStep: {
|
|
597
1146
|
id: step.id,
|
|
598
|
-
|
|
599
|
-
output: execResults.output
|
|
1147
|
+
...execResults
|
|
600
1148
|
},
|
|
601
1149
|
workflowState: {
|
|
602
1150
|
status: "running",
|
|
603
|
-
steps: stepResults,
|
|
1151
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
604
1152
|
result: null,
|
|
605
1153
|
error: null
|
|
606
1154
|
}
|
|
607
1155
|
},
|
|
608
1156
|
eventTimestamp: Date.now()
|
|
609
1157
|
});
|
|
1158
|
+
if (execResults.status === "suspended") {
|
|
1159
|
+
await emitter.emit("watch-v2", {
|
|
1160
|
+
type: "step-suspended",
|
|
1161
|
+
payload: {
|
|
1162
|
+
id: step.id,
|
|
1163
|
+
...execResults
|
|
1164
|
+
}
|
|
1165
|
+
});
|
|
1166
|
+
} else {
|
|
1167
|
+
await emitter.emit("watch-v2", {
|
|
1168
|
+
type: "step-result",
|
|
1169
|
+
payload: {
|
|
1170
|
+
id: step.id,
|
|
1171
|
+
...execResults
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
await emitter.emit("watch-v2", {
|
|
1175
|
+
type: "step-finish",
|
|
1176
|
+
payload: {
|
|
1177
|
+
id: step.id,
|
|
1178
|
+
metadata: {}
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
stepAISpan?.end({ output: execResults });
|
|
610
1183
|
return { result: execResults, executionContext, stepResults };
|
|
611
1184
|
});
|
|
1185
|
+
if (disableScorers !== false) {
|
|
1186
|
+
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1187
|
+
if (step.scorers) {
|
|
1188
|
+
await this.runScorers({
|
|
1189
|
+
scorers: step.scorers,
|
|
1190
|
+
runId: executionContext.runId,
|
|
1191
|
+
input: prevOutput,
|
|
1192
|
+
output: stepRes.result,
|
|
1193
|
+
workflowId: executionContext.workflowId,
|
|
1194
|
+
stepId: step.id,
|
|
1195
|
+
runtimeContext,
|
|
1196
|
+
disableScorers
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
612
1201
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
613
1202
|
Object.assign(stepResults, stepRes.stepResults);
|
|
614
1203
|
return stepRes.result;
|
|
@@ -617,7 +1206,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
617
1206
|
workflowId,
|
|
618
1207
|
runId,
|
|
619
1208
|
stepResults,
|
|
620
|
-
executionContext
|
|
1209
|
+
executionContext,
|
|
1210
|
+
serializedStepGraph,
|
|
1211
|
+
workflowStatus,
|
|
1212
|
+
result,
|
|
1213
|
+
error
|
|
621
1214
|
}) {
|
|
622
1215
|
await this.inngestStep.run(
|
|
623
1216
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -631,6 +1224,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
631
1224
|
context: stepResults,
|
|
632
1225
|
activePaths: [],
|
|
633
1226
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1227
|
+
waitingPaths: {},
|
|
1228
|
+
serializedStepGraph,
|
|
1229
|
+
status: workflowStatus,
|
|
1230
|
+
result,
|
|
1231
|
+
error,
|
|
634
1232
|
// @ts-ignore
|
|
635
1233
|
timestamp: Date.now()
|
|
636
1234
|
}
|
|
@@ -645,20 +1243,47 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
645
1243
|
prevOutput,
|
|
646
1244
|
prevStep,
|
|
647
1245
|
stepResults,
|
|
1246
|
+
serializedStepGraph,
|
|
648
1247
|
resume,
|
|
649
1248
|
executionContext,
|
|
650
1249
|
emitter,
|
|
651
|
-
|
|
1250
|
+
abortController,
|
|
1251
|
+
runtimeContext,
|
|
1252
|
+
writableStream,
|
|
1253
|
+
disableScorers,
|
|
1254
|
+
tracingContext
|
|
652
1255
|
}) {
|
|
1256
|
+
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1257
|
+
type: AISpanType.WORKFLOW_CONDITIONAL,
|
|
1258
|
+
name: `conditional: ${entry.conditions.length} conditions`,
|
|
1259
|
+
input: prevOutput,
|
|
1260
|
+
attributes: {
|
|
1261
|
+
conditionCount: entry.conditions.length
|
|
1262
|
+
}
|
|
1263
|
+
});
|
|
653
1264
|
let execResults;
|
|
654
1265
|
const truthyIndexes = (await Promise.all(
|
|
655
1266
|
entry.conditions.map(
|
|
656
1267
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1268
|
+
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1269
|
+
type: AISpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1270
|
+
name: `condition ${index}`,
|
|
1271
|
+
input: prevOutput,
|
|
1272
|
+
attributes: {
|
|
1273
|
+
conditionIndex: index
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
657
1276
|
try {
|
|
658
1277
|
const result = await cond({
|
|
1278
|
+
runId,
|
|
1279
|
+
workflowId,
|
|
659
1280
|
mastra: this.mastra,
|
|
660
1281
|
runtimeContext,
|
|
1282
|
+
runCount: -1,
|
|
661
1283
|
inputData: prevOutput,
|
|
1284
|
+
tracingContext: {
|
|
1285
|
+
currentSpan: evalSpan
|
|
1286
|
+
},
|
|
662
1287
|
getInitData: () => stepResults?.input,
|
|
663
1288
|
getStepResult: (step) => {
|
|
664
1289
|
if (!step?.id) {
|
|
@@ -673,22 +1298,59 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
673
1298
|
// TODO: this function shouldn't have suspend probably?
|
|
674
1299
|
suspend: async (_suspendPayload) => {
|
|
675
1300
|
},
|
|
676
|
-
|
|
1301
|
+
bail: () => {
|
|
1302
|
+
},
|
|
1303
|
+
abort: () => {
|
|
1304
|
+
abortController.abort();
|
|
1305
|
+
},
|
|
1306
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1307
|
+
engine: {
|
|
1308
|
+
step: this.inngestStep
|
|
1309
|
+
},
|
|
1310
|
+
abortSignal: abortController.signal,
|
|
1311
|
+
writer: new ToolStream(
|
|
1312
|
+
{
|
|
1313
|
+
prefix: "step",
|
|
1314
|
+
callId: randomUUID(),
|
|
1315
|
+
name: "conditional",
|
|
1316
|
+
runId
|
|
1317
|
+
},
|
|
1318
|
+
writableStream
|
|
1319
|
+
)
|
|
1320
|
+
});
|
|
1321
|
+
evalSpan?.end({
|
|
1322
|
+
output: result,
|
|
1323
|
+
attributes: {
|
|
1324
|
+
result: !!result
|
|
1325
|
+
}
|
|
677
1326
|
});
|
|
678
1327
|
return result ? index : null;
|
|
679
1328
|
} catch (e) {
|
|
1329
|
+
evalSpan?.error({
|
|
1330
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1331
|
+
attributes: {
|
|
1332
|
+
result: false
|
|
1333
|
+
}
|
|
1334
|
+
});
|
|
680
1335
|
return null;
|
|
681
1336
|
}
|
|
682
1337
|
})
|
|
683
1338
|
)
|
|
684
1339
|
)).filter((index) => index !== null);
|
|
685
1340
|
const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
|
|
1341
|
+
conditionalSpan?.update({
|
|
1342
|
+
attributes: {
|
|
1343
|
+
truthyIndexes,
|
|
1344
|
+
selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
|
|
1345
|
+
}
|
|
1346
|
+
});
|
|
686
1347
|
const results = await Promise.all(
|
|
687
1348
|
stepsToRun.map(
|
|
688
1349
|
(step, index) => this.executeEntry({
|
|
689
1350
|
workflowId,
|
|
690
1351
|
runId,
|
|
691
1352
|
entry: step,
|
|
1353
|
+
serializedStepGraph,
|
|
692
1354
|
prevStep,
|
|
693
1355
|
stepResults,
|
|
694
1356
|
resume,
|
|
@@ -701,29 +1363,46 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
701
1363
|
executionSpan: executionContext.executionSpan
|
|
702
1364
|
},
|
|
703
1365
|
emitter,
|
|
704
|
-
|
|
1366
|
+
abortController,
|
|
1367
|
+
runtimeContext,
|
|
1368
|
+
writableStream,
|
|
1369
|
+
disableScorers,
|
|
1370
|
+
tracingContext: {
|
|
1371
|
+
currentSpan: conditionalSpan
|
|
1372
|
+
}
|
|
705
1373
|
})
|
|
706
1374
|
)
|
|
707
1375
|
);
|
|
708
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
709
|
-
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1376
|
+
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1377
|
+
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
710
1378
|
if (hasFailed) {
|
|
711
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1379
|
+
execResults = { status: "failed", error: hasFailed.result.error };
|
|
712
1380
|
} else if (hasSuspended) {
|
|
713
|
-
execResults = { status: "suspended", payload: hasSuspended.
|
|
1381
|
+
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
714
1382
|
} else {
|
|
715
1383
|
execResults = {
|
|
716
1384
|
status: "success",
|
|
717
1385
|
output: results.reduce((acc, result, index) => {
|
|
718
|
-
if (result.status === "success") {
|
|
1386
|
+
if (result.result.status === "success") {
|
|
719
1387
|
acc[stepsToRun[index].step.id] = result.output;
|
|
720
1388
|
}
|
|
721
1389
|
return acc;
|
|
722
1390
|
}, {})
|
|
723
1391
|
};
|
|
724
1392
|
}
|
|
1393
|
+
if (execResults.status === "failed") {
|
|
1394
|
+
conditionalSpan?.error({
|
|
1395
|
+
error: new Error(execResults.error)
|
|
1396
|
+
});
|
|
1397
|
+
} else {
|
|
1398
|
+
conditionalSpan?.end({
|
|
1399
|
+
output: execResults.output || execResults
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
725
1402
|
return execResults;
|
|
726
1403
|
}
|
|
727
1404
|
};
|
|
728
1405
|
|
|
729
|
-
export { InngestExecutionEngine, InngestRun, InngestWorkflow, init, serve };
|
|
1406
|
+
export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
|
|
1407
|
+
//# sourceMappingURL=index.js.map
|
|
1408
|
+
//# sourceMappingURL=index.js.map
|