@mastra/inngest 0.0.0-cloud-transporter-20250513033346 → 0.0.0-consolidate-changesets-20250904042643
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 +899 -2
- package/LICENSE.md +11 -42
- package/dist/index.cjs +757 -79
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +281 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +754 -77
- package/dist/index.js.map +1 -0
- package/package.json +39 -20
- 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/docker-compose.yaml +0 -10
- package/eslint.config.js +0 -6
- package/src/index.test.ts +0 -5437
- package/src/index.ts +0 -956
- package/tsconfig.json +0 -5
- package/vitest.config.ts +0 -8
package/dist/index.cjs
CHANGED
|
@@ -2,35 +2,45 @@
|
|
|
2
2
|
|
|
3
3
|
var crypto = require('crypto');
|
|
4
4
|
var realtime = require('@inngest/realtime');
|
|
5
|
+
var aiTracing = require('@mastra/core/ai-tracing');
|
|
5
6
|
var di = require('@mastra/core/di');
|
|
6
|
-
var
|
|
7
|
+
var tools = require('@mastra/core/tools');
|
|
8
|
+
var workflows = require('@mastra/core/workflows');
|
|
9
|
+
var _constants = require('@mastra/core/workflows/_constants');
|
|
7
10
|
var hono = require('inngest/hono');
|
|
11
|
+
var zod = require('zod');
|
|
8
12
|
|
|
9
13
|
// src/index.ts
|
|
10
14
|
function serve({ mastra, inngest }) {
|
|
11
|
-
const wfs = mastra.
|
|
12
|
-
const functions =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
const wfs = mastra.getWorkflows();
|
|
16
|
+
const functions = Array.from(
|
|
17
|
+
new Set(
|
|
18
|
+
Object.values(wfs).flatMap((wf) => {
|
|
19
|
+
if (wf instanceof InngestWorkflow) {
|
|
20
|
+
wf.__registerMastra(mastra);
|
|
21
|
+
return wf.getFunctions();
|
|
22
|
+
}
|
|
23
|
+
return [];
|
|
24
|
+
})
|
|
25
|
+
)
|
|
26
|
+
);
|
|
19
27
|
return hono.serve({
|
|
20
28
|
client: inngest,
|
|
21
29
|
functions
|
|
22
30
|
});
|
|
23
31
|
}
|
|
24
|
-
var InngestRun = class extends
|
|
32
|
+
var InngestRun = class extends workflows.Run {
|
|
25
33
|
inngest;
|
|
34
|
+
serializedStepGraph;
|
|
26
35
|
#mastra;
|
|
27
36
|
constructor(params, inngest) {
|
|
28
37
|
super(params);
|
|
29
38
|
this.inngest = inngest;
|
|
39
|
+
this.serializedStepGraph = params.serializedStepGraph;
|
|
30
40
|
this.#mastra = params.mastra;
|
|
31
41
|
}
|
|
32
42
|
async getRuns(eventId) {
|
|
33
|
-
const response = await fetch(`${this.inngest.apiBaseUrl}/v1/events/${eventId}/runs`, {
|
|
43
|
+
const response = await fetch(`${this.inngest.apiBaseUrl ?? "https://api.inngest.com"}/v1/events/${eventId}/runs`, {
|
|
34
44
|
headers: {
|
|
35
45
|
Authorization: `Bearer ${process.env.INNGEST_SIGNING_KEY}`
|
|
36
46
|
}
|
|
@@ -40,15 +50,50 @@ var InngestRun = class extends vNext.Run {
|
|
|
40
50
|
}
|
|
41
51
|
async getRunOutput(eventId) {
|
|
42
52
|
let runs = await this.getRuns(eventId);
|
|
43
|
-
while (runs?.[0]?.status !== "Completed") {
|
|
53
|
+
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
44
54
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
45
55
|
runs = await this.getRuns(eventId);
|
|
46
|
-
if (runs?.[0]?.status === "Failed"
|
|
56
|
+
if (runs?.[0]?.status === "Failed") {
|
|
57
|
+
console.log("run", runs?.[0]);
|
|
47
58
|
throw new Error(`Function run ${runs?.[0]?.status}`);
|
|
59
|
+
} else if (runs?.[0]?.status === "Cancelled") {
|
|
60
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
61
|
+
workflowName: this.workflowId,
|
|
62
|
+
runId: this.runId
|
|
63
|
+
});
|
|
64
|
+
return { output: { result: { steps: snapshot?.context, status: "canceled" } } };
|
|
48
65
|
}
|
|
49
66
|
}
|
|
50
67
|
return runs?.[0];
|
|
51
68
|
}
|
|
69
|
+
async sendEvent(event, data) {
|
|
70
|
+
await this.inngest.send({
|
|
71
|
+
name: `user-event-${event}`,
|
|
72
|
+
data
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
async cancel() {
|
|
76
|
+
await this.inngest.send({
|
|
77
|
+
name: `cancel.workflow.${this.workflowId}`,
|
|
78
|
+
data: {
|
|
79
|
+
runId: this.runId
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
83
|
+
workflowName: this.workflowId,
|
|
84
|
+
runId: this.runId
|
|
85
|
+
});
|
|
86
|
+
if (snapshot) {
|
|
87
|
+
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
88
|
+
workflowName: this.workflowId,
|
|
89
|
+
runId: this.runId,
|
|
90
|
+
snapshot: {
|
|
91
|
+
...snapshot,
|
|
92
|
+
status: "canceled"
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
52
97
|
async start({
|
|
53
98
|
inputData
|
|
54
99
|
}) {
|
|
@@ -57,11 +102,14 @@ var InngestRun = class extends vNext.Run {
|
|
|
57
102
|
runId: this.runId,
|
|
58
103
|
snapshot: {
|
|
59
104
|
runId: this.runId,
|
|
105
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
60
106
|
value: {},
|
|
61
107
|
context: {},
|
|
62
108
|
activePaths: [],
|
|
63
109
|
suspendedPaths: {},
|
|
64
|
-
|
|
110
|
+
waitingPaths: {},
|
|
111
|
+
timestamp: Date.now(),
|
|
112
|
+
status: "running"
|
|
65
113
|
}
|
|
66
114
|
});
|
|
67
115
|
const eventOutput = await this.inngest.send({
|
|
@@ -80,10 +128,23 @@ var InngestRun = class extends vNext.Run {
|
|
|
80
128
|
if (result.status === "failed") {
|
|
81
129
|
result.error = new Error(result.error);
|
|
82
130
|
}
|
|
83
|
-
|
|
131
|
+
if (result.status !== "suspended") {
|
|
132
|
+
this.cleanup?.();
|
|
133
|
+
}
|
|
84
134
|
return result;
|
|
85
135
|
}
|
|
86
136
|
async resume(params) {
|
|
137
|
+
const p = this._resume(params).then((result) => {
|
|
138
|
+
if (result.status !== "suspended") {
|
|
139
|
+
this.closeStreamAction?.().catch(() => {
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
});
|
|
144
|
+
this.executionResults = p;
|
|
145
|
+
return p;
|
|
146
|
+
}
|
|
147
|
+
async _resume(params) {
|
|
87
148
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
88
149
|
(step) => typeof step === "string" ? step : step?.id
|
|
89
150
|
);
|
|
@@ -96,6 +157,7 @@ var InngestRun = class extends vNext.Run {
|
|
|
96
157
|
data: {
|
|
97
158
|
inputData: params.resumeData,
|
|
98
159
|
runId: this.runId,
|
|
160
|
+
workflowId: this.workflowId,
|
|
99
161
|
stepResults: snapshot?.context,
|
|
100
162
|
resume: {
|
|
101
163
|
steps,
|
|
@@ -117,32 +179,101 @@ var InngestRun = class extends vNext.Run {
|
|
|
117
179
|
}
|
|
118
180
|
return result;
|
|
119
181
|
}
|
|
120
|
-
watch(cb) {
|
|
182
|
+
watch(cb, type = "watch") {
|
|
183
|
+
let active = true;
|
|
121
184
|
const streamPromise = realtime.subscribe(
|
|
122
185
|
{
|
|
123
186
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
124
|
-
topics: [
|
|
187
|
+
topics: [type],
|
|
125
188
|
app: this.inngest
|
|
126
189
|
},
|
|
127
190
|
(message) => {
|
|
128
|
-
|
|
191
|
+
if (active) {
|
|
192
|
+
cb(message.data);
|
|
193
|
+
}
|
|
129
194
|
}
|
|
130
195
|
);
|
|
131
196
|
return () => {
|
|
132
|
-
|
|
133
|
-
|
|
197
|
+
active = false;
|
|
198
|
+
streamPromise.then(async (stream) => {
|
|
199
|
+
return stream.cancel();
|
|
134
200
|
}).catch((err) => {
|
|
135
201
|
console.error(err);
|
|
136
202
|
});
|
|
137
203
|
};
|
|
138
204
|
}
|
|
205
|
+
stream({ inputData, runtimeContext } = {}) {
|
|
206
|
+
const { readable, writable } = new TransformStream();
|
|
207
|
+
let currentToolData = void 0;
|
|
208
|
+
const writer = writable.getWriter();
|
|
209
|
+
const unwatch = this.watch(async (event) => {
|
|
210
|
+
if (event.type === "workflow-agent-call-start") {
|
|
211
|
+
currentToolData = {
|
|
212
|
+
name: event.payload.name,
|
|
213
|
+
args: event.payload.args
|
|
214
|
+
};
|
|
215
|
+
await writer.write({
|
|
216
|
+
...event.payload,
|
|
217
|
+
type: "tool-call-streaming-start"
|
|
218
|
+
});
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
try {
|
|
222
|
+
if (event.type === "workflow-agent-call-finish") {
|
|
223
|
+
return;
|
|
224
|
+
} else if (!event.type.startsWith("workflow-")) {
|
|
225
|
+
if (event.type === "text-delta") {
|
|
226
|
+
await writer.write({
|
|
227
|
+
type: "tool-call-delta",
|
|
228
|
+
...currentToolData ?? {},
|
|
229
|
+
argsTextDelta: event.textDelta
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
const e = {
|
|
235
|
+
...event,
|
|
236
|
+
type: event.type.replace("workflow-", "")
|
|
237
|
+
};
|
|
238
|
+
await writer.write(e);
|
|
239
|
+
} catch {
|
|
240
|
+
}
|
|
241
|
+
}, "watch-v2");
|
|
242
|
+
this.closeStreamAction = async () => {
|
|
243
|
+
unwatch();
|
|
244
|
+
try {
|
|
245
|
+
await writer.close();
|
|
246
|
+
} catch (err) {
|
|
247
|
+
console.error("Error closing stream:", err);
|
|
248
|
+
} finally {
|
|
249
|
+
writer.releaseLock();
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
|
|
253
|
+
if (result.status !== "suspended") {
|
|
254
|
+
this.closeStreamAction?.().catch(() => {
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return result;
|
|
258
|
+
});
|
|
259
|
+
return {
|
|
260
|
+
stream: readable,
|
|
261
|
+
getWorkflowState: () => this.executionResults
|
|
262
|
+
};
|
|
263
|
+
}
|
|
139
264
|
};
|
|
140
|
-
var InngestWorkflow = class _InngestWorkflow extends
|
|
265
|
+
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
141
266
|
#mastra;
|
|
142
267
|
inngest;
|
|
143
268
|
function;
|
|
269
|
+
flowControlConfig;
|
|
144
270
|
constructor(params, inngest) {
|
|
145
|
-
|
|
271
|
+
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
272
|
+
super(workflowParams);
|
|
273
|
+
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
274
|
+
([_, value]) => value !== void 0
|
|
275
|
+
);
|
|
276
|
+
this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
|
|
146
277
|
this.#mastra = params.mastra;
|
|
147
278
|
this.inngest = inngest;
|
|
148
279
|
}
|
|
@@ -158,7 +289,7 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
158
289
|
const storage = this.#mastra?.getStorage();
|
|
159
290
|
if (!storage) {
|
|
160
291
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
161
|
-
return null;
|
|
292
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
162
293
|
}
|
|
163
294
|
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
164
295
|
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
@@ -189,6 +320,25 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
189
320
|
runId: runIdToUse,
|
|
190
321
|
executionEngine: this.executionEngine,
|
|
191
322
|
executionGraph: this.executionGraph,
|
|
323
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
324
|
+
mastra: this.#mastra,
|
|
325
|
+
retryConfig: this.retryConfig,
|
|
326
|
+
cleanup: () => this.runs.delete(runIdToUse)
|
|
327
|
+
},
|
|
328
|
+
this.inngest
|
|
329
|
+
);
|
|
330
|
+
this.runs.set(runIdToUse, run);
|
|
331
|
+
return run;
|
|
332
|
+
}
|
|
333
|
+
async createRunAsync(options) {
|
|
334
|
+
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
335
|
+
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
336
|
+
{
|
|
337
|
+
workflowId: this.id,
|
|
338
|
+
runId: runIdToUse,
|
|
339
|
+
executionEngine: this.executionEngine,
|
|
340
|
+
executionGraph: this.executionGraph,
|
|
341
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
192
342
|
mastra: this.#mastra,
|
|
193
343
|
retryConfig: this.retryConfig,
|
|
194
344
|
cleanup: () => this.runs.delete(runIdToUse)
|
|
@@ -196,6 +346,27 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
196
346
|
this.inngest
|
|
197
347
|
);
|
|
198
348
|
this.runs.set(runIdToUse, run);
|
|
349
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
350
|
+
if (!workflowSnapshotInStorage) {
|
|
351
|
+
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
352
|
+
workflowName: this.id,
|
|
353
|
+
runId: runIdToUse,
|
|
354
|
+
snapshot: {
|
|
355
|
+
runId: runIdToUse,
|
|
356
|
+
status: "pending",
|
|
357
|
+
value: {},
|
|
358
|
+
context: {},
|
|
359
|
+
activePaths: [],
|
|
360
|
+
waitingPaths: {},
|
|
361
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
362
|
+
suspendedPaths: {},
|
|
363
|
+
result: void 0,
|
|
364
|
+
error: void 0,
|
|
365
|
+
// @ts-ignore
|
|
366
|
+
timestamp: Date.now()
|
|
367
|
+
}
|
|
368
|
+
});
|
|
369
|
+
}
|
|
199
370
|
return run;
|
|
200
371
|
}
|
|
201
372
|
getFunction() {
|
|
@@ -203,8 +374,14 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
203
374
|
return this.function;
|
|
204
375
|
}
|
|
205
376
|
this.function = this.inngest.createFunction(
|
|
206
|
-
|
|
207
|
-
|
|
377
|
+
{
|
|
378
|
+
id: `workflow.${this.id}`,
|
|
379
|
+
// @ts-ignore
|
|
380
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
381
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
382
|
+
// Spread flow control configuration
|
|
383
|
+
...this.flowControlConfig
|
|
384
|
+
},
|
|
208
385
|
{ event: `workflow.${this.id}` },
|
|
209
386
|
async ({ event, step, attempt, publish }) => {
|
|
210
387
|
let { inputData, runId, resume } = event.data;
|
|
@@ -221,12 +398,18 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
221
398
|
try {
|
|
222
399
|
await publish({
|
|
223
400
|
channel: `workflow:${this.id}:${runId}`,
|
|
224
|
-
topic:
|
|
401
|
+
topic: event2,
|
|
225
402
|
data
|
|
226
403
|
});
|
|
227
404
|
} catch (err) {
|
|
228
405
|
this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
|
|
229
406
|
}
|
|
407
|
+
},
|
|
408
|
+
on: (_event, _callback) => {
|
|
409
|
+
},
|
|
410
|
+
off: (_event, _callback) => {
|
|
411
|
+
},
|
|
412
|
+
once: (_event, _callback) => {
|
|
230
413
|
}
|
|
231
414
|
};
|
|
232
415
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
@@ -234,12 +417,16 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
234
417
|
workflowId: this.id,
|
|
235
418
|
runId,
|
|
236
419
|
graph: this.executionGraph,
|
|
420
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
237
421
|
input: inputData,
|
|
238
422
|
emitter,
|
|
239
423
|
retryConfig: this.retryConfig,
|
|
240
424
|
runtimeContext: new di.RuntimeContext(),
|
|
241
425
|
// TODO
|
|
242
|
-
resume
|
|
426
|
+
resume,
|
|
427
|
+
abortController: new AbortController(),
|
|
428
|
+
currentSpan: void 0
|
|
429
|
+
// TODO: Pass actual parent AI span from workflow execution context
|
|
243
430
|
});
|
|
244
431
|
return { result, runId };
|
|
245
432
|
}
|
|
@@ -263,32 +450,126 @@ var InngestWorkflow = class _InngestWorkflow extends vNext.NewWorkflow {
|
|
|
263
450
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
264
451
|
}
|
|
265
452
|
};
|
|
266
|
-
function
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
453
|
+
function isAgent(params) {
|
|
454
|
+
return params?.component === "AGENT";
|
|
455
|
+
}
|
|
456
|
+
function isTool(params) {
|
|
457
|
+
return params instanceof tools.Tool;
|
|
458
|
+
}
|
|
459
|
+
function createStep(params) {
|
|
460
|
+
if (isAgent(params)) {
|
|
461
|
+
return {
|
|
462
|
+
id: params.name,
|
|
463
|
+
// @ts-ignore
|
|
464
|
+
inputSchema: zod.z.object({
|
|
465
|
+
prompt: zod.z.string()
|
|
466
|
+
// resourceId: z.string().optional(),
|
|
467
|
+
// threadId: z.string().optional(),
|
|
468
|
+
}),
|
|
469
|
+
// @ts-ignore
|
|
470
|
+
outputSchema: zod.z.object({
|
|
471
|
+
text: zod.z.string()
|
|
472
|
+
}),
|
|
473
|
+
execute: async ({ inputData, [_constants.EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
|
|
474
|
+
let streamPromise = {};
|
|
475
|
+
streamPromise.promise = new Promise((resolve, reject) => {
|
|
476
|
+
streamPromise.resolve = resolve;
|
|
477
|
+
streamPromise.reject = reject;
|
|
478
|
+
});
|
|
479
|
+
const toolData = {
|
|
480
|
+
name: params.name,
|
|
481
|
+
args: inputData
|
|
482
|
+
};
|
|
483
|
+
await emitter.emit("watch-v2", {
|
|
484
|
+
type: "workflow-agent-call-start",
|
|
485
|
+
payload: toolData
|
|
486
|
+
});
|
|
487
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
488
|
+
// resourceId: inputData.resourceId,
|
|
489
|
+
// threadId: inputData.threadId,
|
|
490
|
+
runtimeContext,
|
|
491
|
+
tracingContext,
|
|
492
|
+
onFinish: (result) => {
|
|
493
|
+
streamPromise.resolve(result.text);
|
|
494
|
+
},
|
|
495
|
+
abortSignal
|
|
496
|
+
});
|
|
497
|
+
if (abortSignal.aborted) {
|
|
498
|
+
return abort();
|
|
499
|
+
}
|
|
500
|
+
for await (const chunk of fullStream) {
|
|
501
|
+
await emitter.emit("watch-v2", chunk);
|
|
502
|
+
}
|
|
503
|
+
await emitter.emit("watch-v2", {
|
|
504
|
+
type: "workflow-agent-call-finish",
|
|
505
|
+
payload: toolData
|
|
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: aiTracing.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
|
+
};
|
|
280
542
|
}
|
|
281
543
|
function init(inngest) {
|
|
282
544
|
return {
|
|
283
545
|
createWorkflow(params) {
|
|
284
546
|
return new InngestWorkflow(params, inngest);
|
|
285
547
|
},
|
|
286
|
-
createStep
|
|
287
|
-
cloneStep
|
|
288
|
-
|
|
548
|
+
createStep,
|
|
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 workflows.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
|
+
}
|
|
289
570
|
};
|
|
290
571
|
}
|
|
291
|
-
var InngestExecutionEngine = class extends
|
|
572
|
+
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
292
573
|
inngestStep;
|
|
293
574
|
inngestAttempts;
|
|
294
575
|
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
@@ -296,6 +577,18 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
296
577
|
this.inngestStep = inngestStep;
|
|
297
578
|
this.inngestAttempts = inngestAttempts;
|
|
298
579
|
}
|
|
580
|
+
async execute(params) {
|
|
581
|
+
await params.emitter.emit("watch-v2", {
|
|
582
|
+
type: "workflow-start",
|
|
583
|
+
payload: { runId: params.runId }
|
|
584
|
+
});
|
|
585
|
+
const result = await super.execute(params);
|
|
586
|
+
await params.emitter.emit("watch-v2", {
|
|
587
|
+
type: "workflow-finish",
|
|
588
|
+
payload: { runId: params.runId }
|
|
589
|
+
});
|
|
590
|
+
return result;
|
|
591
|
+
}
|
|
299
592
|
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
300
593
|
const base = {
|
|
301
594
|
status: lastOutput.status,
|
|
@@ -353,28 +646,186 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
353
646
|
executionSpan?.end();
|
|
354
647
|
return base;
|
|
355
648
|
}
|
|
356
|
-
async
|
|
649
|
+
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
650
|
+
// await this.inngestStep.sleep(id, duration);
|
|
651
|
+
// }
|
|
652
|
+
async executeSleep({
|
|
357
653
|
workflowId,
|
|
358
654
|
runId,
|
|
359
|
-
|
|
655
|
+
entry,
|
|
656
|
+
prevOutput,
|
|
360
657
|
stepResults,
|
|
361
|
-
|
|
362
|
-
|
|
658
|
+
emitter,
|
|
659
|
+
abortController,
|
|
660
|
+
runtimeContext,
|
|
661
|
+
writableStream,
|
|
662
|
+
tracingContext
|
|
663
|
+
}) {
|
|
664
|
+
let { duration, fn } = entry;
|
|
665
|
+
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
666
|
+
type: aiTracing.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 = crypto.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
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
706
|
+
engine: { step: this.inngestStep },
|
|
707
|
+
abortSignal: abortController?.signal,
|
|
708
|
+
writer: new tools.ToolStream(
|
|
709
|
+
{
|
|
710
|
+
prefix: "workflow-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,
|
|
363
737
|
prevOutput,
|
|
738
|
+
stepResults,
|
|
364
739
|
emitter,
|
|
365
|
-
|
|
740
|
+
abortController,
|
|
741
|
+
runtimeContext,
|
|
742
|
+
writableStream,
|
|
743
|
+
tracingContext
|
|
366
744
|
}) {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
runtimeContext
|
|
745
|
+
let { date, fn } = entry;
|
|
746
|
+
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
747
|
+
type: aiTracing.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
|
+
}
|
|
377
754
|
});
|
|
755
|
+
if (fn) {
|
|
756
|
+
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
757
|
+
const stepCallId = crypto.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
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
788
|
+
engine: { step: this.inngestStep },
|
|
789
|
+
abortSignal: abortController?.signal,
|
|
790
|
+
writer: new tools.ToolStream(
|
|
791
|
+
{
|
|
792
|
+
prefix: "workflow-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
|
|
824
|
+
});
|
|
825
|
+
if (eventData === null) {
|
|
826
|
+
throw "Timeout waiting for event";
|
|
827
|
+
}
|
|
828
|
+
return eventData?.data;
|
|
378
829
|
}
|
|
379
830
|
async executeStep({
|
|
380
831
|
step,
|
|
@@ -383,11 +834,24 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
383
834
|
resume,
|
|
384
835
|
prevOutput,
|
|
385
836
|
emitter,
|
|
386
|
-
|
|
837
|
+
abortController,
|
|
838
|
+
runtimeContext,
|
|
839
|
+
tracingContext,
|
|
840
|
+
writableStream,
|
|
841
|
+
disableScorers
|
|
387
842
|
}) {
|
|
388
|
-
|
|
843
|
+
const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
|
|
844
|
+
name: `workflow step: '${step.id}'`,
|
|
845
|
+
type: aiTracing.AISpanType.WORKFLOW_STEP,
|
|
846
|
+
input: prevOutput,
|
|
847
|
+
attributes: {
|
|
848
|
+
stepId: step.id
|
|
849
|
+
}
|
|
850
|
+
});
|
|
851
|
+
const startedAt = await this.inngestStep.run(
|
|
389
852
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
390
853
|
async () => {
|
|
854
|
+
const startedAt2 = Date.now();
|
|
391
855
|
await emitter.emit("watch", {
|
|
392
856
|
type: "watch",
|
|
393
857
|
payload: {
|
|
@@ -409,6 +873,16 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
409
873
|
},
|
|
410
874
|
eventTimestamp: Date.now()
|
|
411
875
|
});
|
|
876
|
+
await emitter.emit("watch-v2", {
|
|
877
|
+
type: "workflow-step-start",
|
|
878
|
+
payload: {
|
|
879
|
+
id: step.id,
|
|
880
|
+
status: "running",
|
|
881
|
+
payload: prevOutput,
|
|
882
|
+
startedAt: startedAt2
|
|
883
|
+
}
|
|
884
|
+
});
|
|
885
|
+
return startedAt2;
|
|
412
886
|
}
|
|
413
887
|
);
|
|
414
888
|
if (step instanceof InngestWorkflow) {
|
|
@@ -469,6 +943,15 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
469
943
|
},
|
|
470
944
|
eventTimestamp: Date.now()
|
|
471
945
|
});
|
|
946
|
+
await emitter.emit("watch-v2", {
|
|
947
|
+
type: "workflow-step-result",
|
|
948
|
+
payload: {
|
|
949
|
+
id: step.id,
|
|
950
|
+
status: "failed",
|
|
951
|
+
error: result?.error,
|
|
952
|
+
payload: prevOutput
|
|
953
|
+
}
|
|
954
|
+
});
|
|
472
955
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
473
956
|
} else if (result.status === "suspended") {
|
|
474
957
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
@@ -495,6 +978,13 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
495
978
|
},
|
|
496
979
|
eventTimestamp: Date.now()
|
|
497
980
|
});
|
|
981
|
+
await emitter.emit("watch-v2", {
|
|
982
|
+
type: "workflow-step-suspended",
|
|
983
|
+
payload: {
|
|
984
|
+
id: step.id,
|
|
985
|
+
status: "suspended"
|
|
986
|
+
}
|
|
987
|
+
});
|
|
498
988
|
return {
|
|
499
989
|
executionContext,
|
|
500
990
|
result: {
|
|
@@ -545,6 +1035,21 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
545
1035
|
},
|
|
546
1036
|
eventTimestamp: Date.now()
|
|
547
1037
|
});
|
|
1038
|
+
await emitter.emit("watch-v2", {
|
|
1039
|
+
type: "workflow-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: "workflow-step-finish",
|
|
1048
|
+
payload: {
|
|
1049
|
+
id: step.id,
|
|
1050
|
+
metadata: {}
|
|
1051
|
+
}
|
|
1052
|
+
});
|
|
548
1053
|
return { executionContext, result: { status: "success", output: result?.result } };
|
|
549
1054
|
}
|
|
550
1055
|
);
|
|
@@ -554,12 +1059,18 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
554
1059
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
555
1060
|
let execResults;
|
|
556
1061
|
let suspended;
|
|
1062
|
+
let bailed;
|
|
557
1063
|
try {
|
|
558
1064
|
const result = await step.execute({
|
|
1065
|
+
runId: executionContext.runId,
|
|
559
1066
|
mastra: this.mastra,
|
|
560
1067
|
runtimeContext,
|
|
1068
|
+
writableStream,
|
|
561
1069
|
inputData: prevOutput,
|
|
562
1070
|
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1071
|
+
tracingContext: {
|
|
1072
|
+
currentSpan: stepAISpan
|
|
1073
|
+
},
|
|
563
1074
|
getInitData: () => stepResults?.input,
|
|
564
1075
|
getStepResult: (step2) => {
|
|
565
1076
|
const result2 = stepResults[step2.id];
|
|
@@ -572,24 +1083,60 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
572
1083
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
573
1084
|
suspended = { payload: suspendPayload };
|
|
574
1085
|
},
|
|
1086
|
+
bail: (result2) => {
|
|
1087
|
+
bailed = { payload: result2 };
|
|
1088
|
+
},
|
|
575
1089
|
resume: {
|
|
576
1090
|
steps: resume?.steps?.slice(1) || [],
|
|
577
1091
|
resumePayload: resume?.resumePayload,
|
|
578
1092
|
// @ts-ignore
|
|
579
1093
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
580
1094
|
},
|
|
581
|
-
emitter
|
|
1095
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1096
|
+
engine: {
|
|
1097
|
+
step: this.inngestStep
|
|
1098
|
+
},
|
|
1099
|
+
abortSignal: abortController.signal
|
|
582
1100
|
});
|
|
583
|
-
|
|
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
|
+
};
|
|
584
1111
|
} catch (e) {
|
|
585
|
-
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
|
+
};
|
|
586
1121
|
}
|
|
587
1122
|
if (suspended) {
|
|
588
|
-
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 };
|
|
589
1134
|
}
|
|
590
1135
|
if (execResults.status === "failed") {
|
|
591
1136
|
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
592
|
-
|
|
1137
|
+
const error = new Error(execResults.error);
|
|
1138
|
+
stepAISpan?.error({ error });
|
|
1139
|
+
throw error;
|
|
593
1140
|
}
|
|
594
1141
|
}
|
|
595
1142
|
await emitter.emit("watch", {
|
|
@@ -597,20 +1144,60 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
597
1144
|
payload: {
|
|
598
1145
|
currentStep: {
|
|
599
1146
|
id: step.id,
|
|
600
|
-
|
|
601
|
-
output: execResults.output
|
|
1147
|
+
...execResults
|
|
602
1148
|
},
|
|
603
1149
|
workflowState: {
|
|
604
1150
|
status: "running",
|
|
605
|
-
steps: stepResults,
|
|
1151
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
606
1152
|
result: null,
|
|
607
1153
|
error: null
|
|
608
1154
|
}
|
|
609
1155
|
},
|
|
610
1156
|
eventTimestamp: Date.now()
|
|
611
1157
|
});
|
|
1158
|
+
if (execResults.status === "suspended") {
|
|
1159
|
+
await emitter.emit("watch-v2", {
|
|
1160
|
+
type: "workflow-step-suspended",
|
|
1161
|
+
payload: {
|
|
1162
|
+
id: step.id,
|
|
1163
|
+
...execResults
|
|
1164
|
+
}
|
|
1165
|
+
});
|
|
1166
|
+
} else {
|
|
1167
|
+
await emitter.emit("watch-v2", {
|
|
1168
|
+
type: "workflow-step-result",
|
|
1169
|
+
payload: {
|
|
1170
|
+
id: step.id,
|
|
1171
|
+
...execResults
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
await emitter.emit("watch-v2", {
|
|
1175
|
+
type: "workflow-step-finish",
|
|
1176
|
+
payload: {
|
|
1177
|
+
id: step.id,
|
|
1178
|
+
metadata: {}
|
|
1179
|
+
}
|
|
1180
|
+
});
|
|
1181
|
+
}
|
|
1182
|
+
stepAISpan?.end({ output: execResults });
|
|
612
1183
|
return { result: execResults, executionContext, stepResults };
|
|
613
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
|
+
}
|
|
614
1201
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
615
1202
|
Object.assign(stepResults, stepRes.stepResults);
|
|
616
1203
|
return stepRes.result;
|
|
@@ -619,7 +1206,11 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
619
1206
|
workflowId,
|
|
620
1207
|
runId,
|
|
621
1208
|
stepResults,
|
|
622
|
-
executionContext
|
|
1209
|
+
executionContext,
|
|
1210
|
+
serializedStepGraph,
|
|
1211
|
+
workflowStatus,
|
|
1212
|
+
result,
|
|
1213
|
+
error
|
|
623
1214
|
}) {
|
|
624
1215
|
await this.inngestStep.run(
|
|
625
1216
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -633,6 +1224,11 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
633
1224
|
context: stepResults,
|
|
634
1225
|
activePaths: [],
|
|
635
1226
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1227
|
+
waitingPaths: {},
|
|
1228
|
+
serializedStepGraph,
|
|
1229
|
+
status: workflowStatus,
|
|
1230
|
+
result,
|
|
1231
|
+
error,
|
|
636
1232
|
// @ts-ignore
|
|
637
1233
|
timestamp: Date.now()
|
|
638
1234
|
}
|
|
@@ -647,20 +1243,47 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
647
1243
|
prevOutput,
|
|
648
1244
|
prevStep,
|
|
649
1245
|
stepResults,
|
|
1246
|
+
serializedStepGraph,
|
|
650
1247
|
resume,
|
|
651
1248
|
executionContext,
|
|
652
1249
|
emitter,
|
|
653
|
-
|
|
1250
|
+
abortController,
|
|
1251
|
+
runtimeContext,
|
|
1252
|
+
writableStream,
|
|
1253
|
+
disableScorers,
|
|
1254
|
+
tracingContext
|
|
654
1255
|
}) {
|
|
1256
|
+
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1257
|
+
type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL,
|
|
1258
|
+
name: `conditional: ${entry.conditions.length} conditions`,
|
|
1259
|
+
input: prevOutput,
|
|
1260
|
+
attributes: {
|
|
1261
|
+
conditionCount: entry.conditions.length
|
|
1262
|
+
}
|
|
1263
|
+
});
|
|
655
1264
|
let execResults;
|
|
656
1265
|
const truthyIndexes = (await Promise.all(
|
|
657
1266
|
entry.conditions.map(
|
|
658
1267
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1268
|
+
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1269
|
+
type: aiTracing.AISpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1270
|
+
name: `condition ${index}`,
|
|
1271
|
+
input: prevOutput,
|
|
1272
|
+
attributes: {
|
|
1273
|
+
conditionIndex: index
|
|
1274
|
+
}
|
|
1275
|
+
});
|
|
659
1276
|
try {
|
|
660
1277
|
const result = await cond({
|
|
1278
|
+
runId,
|
|
1279
|
+
workflowId,
|
|
661
1280
|
mastra: this.mastra,
|
|
662
1281
|
runtimeContext,
|
|
1282
|
+
runCount: -1,
|
|
663
1283
|
inputData: prevOutput,
|
|
1284
|
+
tracingContext: {
|
|
1285
|
+
currentSpan: evalSpan
|
|
1286
|
+
},
|
|
664
1287
|
getInitData: () => stepResults?.input,
|
|
665
1288
|
getStepResult: (step) => {
|
|
666
1289
|
if (!step?.id) {
|
|
@@ -675,22 +1298,59 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
675
1298
|
// TODO: this function shouldn't have suspend probably?
|
|
676
1299
|
suspend: async (_suspendPayload) => {
|
|
677
1300
|
},
|
|
678
|
-
|
|
1301
|
+
bail: () => {
|
|
1302
|
+
},
|
|
1303
|
+
abort: () => {
|
|
1304
|
+
abortController.abort();
|
|
1305
|
+
},
|
|
1306
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1307
|
+
engine: {
|
|
1308
|
+
step: this.inngestStep
|
|
1309
|
+
},
|
|
1310
|
+
abortSignal: abortController.signal,
|
|
1311
|
+
writer: new tools.ToolStream(
|
|
1312
|
+
{
|
|
1313
|
+
prefix: "workflow-step",
|
|
1314
|
+
callId: crypto.randomUUID(),
|
|
1315
|
+
name: "conditional",
|
|
1316
|
+
runId
|
|
1317
|
+
},
|
|
1318
|
+
writableStream
|
|
1319
|
+
)
|
|
1320
|
+
});
|
|
1321
|
+
evalSpan?.end({
|
|
1322
|
+
output: result,
|
|
1323
|
+
attributes: {
|
|
1324
|
+
result: !!result
|
|
1325
|
+
}
|
|
679
1326
|
});
|
|
680
1327
|
return result ? index : null;
|
|
681
1328
|
} catch (e) {
|
|
1329
|
+
evalSpan?.error({
|
|
1330
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1331
|
+
attributes: {
|
|
1332
|
+
result: false
|
|
1333
|
+
}
|
|
1334
|
+
});
|
|
682
1335
|
return null;
|
|
683
1336
|
}
|
|
684
1337
|
})
|
|
685
1338
|
)
|
|
686
1339
|
)).filter((index) => index !== null);
|
|
687
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
|
+
});
|
|
688
1347
|
const results = await Promise.all(
|
|
689
1348
|
stepsToRun.map(
|
|
690
1349
|
(step, index) => this.executeEntry({
|
|
691
1350
|
workflowId,
|
|
692
1351
|
runId,
|
|
693
1352
|
entry: step,
|
|
1353
|
+
serializedStepGraph,
|
|
694
1354
|
prevStep,
|
|
695
1355
|
stepResults,
|
|
696
1356
|
resume,
|
|
@@ -703,27 +1363,42 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
703
1363
|
executionSpan: executionContext.executionSpan
|
|
704
1364
|
},
|
|
705
1365
|
emitter,
|
|
706
|
-
|
|
1366
|
+
abortController,
|
|
1367
|
+
runtimeContext,
|
|
1368
|
+
writableStream,
|
|
1369
|
+
disableScorers,
|
|
1370
|
+
tracingContext: {
|
|
1371
|
+
currentSpan: conditionalSpan
|
|
1372
|
+
}
|
|
707
1373
|
})
|
|
708
1374
|
)
|
|
709
1375
|
);
|
|
710
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
711
|
-
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");
|
|
712
1378
|
if (hasFailed) {
|
|
713
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1379
|
+
execResults = { status: "failed", error: hasFailed.result.error };
|
|
714
1380
|
} else if (hasSuspended) {
|
|
715
|
-
execResults = { status: "suspended", payload: hasSuspended.
|
|
1381
|
+
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
716
1382
|
} else {
|
|
717
1383
|
execResults = {
|
|
718
1384
|
status: "success",
|
|
719
1385
|
output: results.reduce((acc, result, index) => {
|
|
720
|
-
if (result.status === "success") {
|
|
1386
|
+
if (result.result.status === "success") {
|
|
721
1387
|
acc[stepsToRun[index].step.id] = result.output;
|
|
722
1388
|
}
|
|
723
1389
|
return acc;
|
|
724
1390
|
}, {})
|
|
725
1391
|
};
|
|
726
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
|
+
}
|
|
727
1402
|
return execResults;
|
|
728
1403
|
}
|
|
729
1404
|
};
|
|
@@ -731,5 +1406,8 @@ var InngestExecutionEngine = class extends vNext.DefaultExecutionEngine {
|
|
|
731
1406
|
exports.InngestExecutionEngine = InngestExecutionEngine;
|
|
732
1407
|
exports.InngestRun = InngestRun;
|
|
733
1408
|
exports.InngestWorkflow = InngestWorkflow;
|
|
1409
|
+
exports.createStep = createStep;
|
|
734
1410
|
exports.init = init;
|
|
735
1411
|
exports.serve = serve;
|
|
1412
|
+
//# sourceMappingURL=index.cjs.map
|
|
1413
|
+
//# sourceMappingURL=index.cjs.map
|