@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.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,32 +177,101 @@ 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
|
+
let currentToolData = void 0;
|
|
206
|
+
const writer = writable.getWriter();
|
|
207
|
+
const unwatch = this.watch(async (event) => {
|
|
208
|
+
if (event.type === "workflow-agent-call-start") {
|
|
209
|
+
currentToolData = {
|
|
210
|
+
name: event.payload.name,
|
|
211
|
+
args: event.payload.args
|
|
212
|
+
};
|
|
213
|
+
await writer.write({
|
|
214
|
+
...event.payload,
|
|
215
|
+
type: "tool-call-streaming-start"
|
|
216
|
+
});
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
if (event.type === "workflow-agent-call-finish") {
|
|
221
|
+
return;
|
|
222
|
+
} else if (!event.type.startsWith("workflow-")) {
|
|
223
|
+
if (event.type === "text-delta") {
|
|
224
|
+
await writer.write({
|
|
225
|
+
type: "tool-call-delta",
|
|
226
|
+
...currentToolData ?? {},
|
|
227
|
+
argsTextDelta: event.textDelta
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
const e = {
|
|
233
|
+
...event,
|
|
234
|
+
type: event.type.replace("workflow-", "")
|
|
235
|
+
};
|
|
236
|
+
await writer.write(e);
|
|
237
|
+
} catch {
|
|
238
|
+
}
|
|
239
|
+
}, "watch-v2");
|
|
240
|
+
this.closeStreamAction = async () => {
|
|
241
|
+
unwatch();
|
|
242
|
+
try {
|
|
243
|
+
await writer.close();
|
|
244
|
+
} catch (err) {
|
|
245
|
+
console.error("Error closing stream:", err);
|
|
246
|
+
} finally {
|
|
247
|
+
writer.releaseLock();
|
|
248
|
+
}
|
|
249
|
+
};
|
|
250
|
+
this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
|
|
251
|
+
if (result.status !== "suspended") {
|
|
252
|
+
this.closeStreamAction?.().catch(() => {
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
return result;
|
|
256
|
+
});
|
|
257
|
+
return {
|
|
258
|
+
stream: readable,
|
|
259
|
+
getWorkflowState: () => this.executionResults
|
|
260
|
+
};
|
|
261
|
+
}
|
|
137
262
|
};
|
|
138
|
-
var InngestWorkflow = class _InngestWorkflow extends
|
|
263
|
+
var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
139
264
|
#mastra;
|
|
140
265
|
inngest;
|
|
141
266
|
function;
|
|
267
|
+
flowControlConfig;
|
|
142
268
|
constructor(params, inngest) {
|
|
143
|
-
|
|
269
|
+
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
270
|
+
super(workflowParams);
|
|
271
|
+
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
272
|
+
([_, value]) => value !== void 0
|
|
273
|
+
);
|
|
274
|
+
this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
|
|
144
275
|
this.#mastra = params.mastra;
|
|
145
276
|
this.inngest = inngest;
|
|
146
277
|
}
|
|
@@ -156,7 +287,7 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
156
287
|
const storage = this.#mastra?.getStorage();
|
|
157
288
|
if (!storage) {
|
|
158
289
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
159
|
-
return null;
|
|
290
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
160
291
|
}
|
|
161
292
|
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
162
293
|
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
@@ -187,6 +318,25 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
187
318
|
runId: runIdToUse,
|
|
188
319
|
executionEngine: this.executionEngine,
|
|
189
320
|
executionGraph: this.executionGraph,
|
|
321
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
322
|
+
mastra: this.#mastra,
|
|
323
|
+
retryConfig: this.retryConfig,
|
|
324
|
+
cleanup: () => this.runs.delete(runIdToUse)
|
|
325
|
+
},
|
|
326
|
+
this.inngest
|
|
327
|
+
);
|
|
328
|
+
this.runs.set(runIdToUse, run);
|
|
329
|
+
return run;
|
|
330
|
+
}
|
|
331
|
+
async createRunAsync(options) {
|
|
332
|
+
const runIdToUse = options?.runId || randomUUID();
|
|
333
|
+
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
334
|
+
{
|
|
335
|
+
workflowId: this.id,
|
|
336
|
+
runId: runIdToUse,
|
|
337
|
+
executionEngine: this.executionEngine,
|
|
338
|
+
executionGraph: this.executionGraph,
|
|
339
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
190
340
|
mastra: this.#mastra,
|
|
191
341
|
retryConfig: this.retryConfig,
|
|
192
342
|
cleanup: () => this.runs.delete(runIdToUse)
|
|
@@ -194,6 +344,27 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
194
344
|
this.inngest
|
|
195
345
|
);
|
|
196
346
|
this.runs.set(runIdToUse, run);
|
|
347
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
348
|
+
if (!workflowSnapshotInStorage) {
|
|
349
|
+
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
350
|
+
workflowName: this.id,
|
|
351
|
+
runId: runIdToUse,
|
|
352
|
+
snapshot: {
|
|
353
|
+
runId: runIdToUse,
|
|
354
|
+
status: "pending",
|
|
355
|
+
value: {},
|
|
356
|
+
context: {},
|
|
357
|
+
activePaths: [],
|
|
358
|
+
waitingPaths: {},
|
|
359
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
360
|
+
suspendedPaths: {},
|
|
361
|
+
result: void 0,
|
|
362
|
+
error: void 0,
|
|
363
|
+
// @ts-ignore
|
|
364
|
+
timestamp: Date.now()
|
|
365
|
+
}
|
|
366
|
+
});
|
|
367
|
+
}
|
|
197
368
|
return run;
|
|
198
369
|
}
|
|
199
370
|
getFunction() {
|
|
@@ -201,8 +372,14 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
201
372
|
return this.function;
|
|
202
373
|
}
|
|
203
374
|
this.function = this.inngest.createFunction(
|
|
204
|
-
|
|
205
|
-
|
|
375
|
+
{
|
|
376
|
+
id: `workflow.${this.id}`,
|
|
377
|
+
// @ts-ignore
|
|
378
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
379
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
380
|
+
// Spread flow control configuration
|
|
381
|
+
...this.flowControlConfig
|
|
382
|
+
},
|
|
206
383
|
{ event: `workflow.${this.id}` },
|
|
207
384
|
async ({ event, step, attempt, publish }) => {
|
|
208
385
|
let { inputData, runId, resume } = event.data;
|
|
@@ -219,12 +396,18 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
219
396
|
try {
|
|
220
397
|
await publish({
|
|
221
398
|
channel: `workflow:${this.id}:${runId}`,
|
|
222
|
-
topic:
|
|
399
|
+
topic: event2,
|
|
223
400
|
data
|
|
224
401
|
});
|
|
225
402
|
} catch (err) {
|
|
226
403
|
this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
|
|
227
404
|
}
|
|
405
|
+
},
|
|
406
|
+
on: (_event, _callback) => {
|
|
407
|
+
},
|
|
408
|
+
off: (_event, _callback) => {
|
|
409
|
+
},
|
|
410
|
+
once: (_event, _callback) => {
|
|
228
411
|
}
|
|
229
412
|
};
|
|
230
413
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
@@ -232,12 +415,16 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
232
415
|
workflowId: this.id,
|
|
233
416
|
runId,
|
|
234
417
|
graph: this.executionGraph,
|
|
418
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
235
419
|
input: inputData,
|
|
236
420
|
emitter,
|
|
237
421
|
retryConfig: this.retryConfig,
|
|
238
422
|
runtimeContext: new RuntimeContext(),
|
|
239
423
|
// TODO
|
|
240
|
-
resume
|
|
424
|
+
resume,
|
|
425
|
+
abortController: new AbortController(),
|
|
426
|
+
currentSpan: void 0
|
|
427
|
+
// TODO: Pass actual parent AI span from workflow execution context
|
|
241
428
|
});
|
|
242
429
|
return { result, runId };
|
|
243
430
|
}
|
|
@@ -261,20 +448,95 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
261
448
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
262
449
|
}
|
|
263
450
|
};
|
|
264
|
-
function
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
451
|
+
function isAgent(params) {
|
|
452
|
+
return params?.component === "AGENT";
|
|
453
|
+
}
|
|
454
|
+
function isTool(params) {
|
|
455
|
+
return params instanceof Tool;
|
|
456
|
+
}
|
|
457
|
+
function createStep(params) {
|
|
458
|
+
if (isAgent(params)) {
|
|
459
|
+
return {
|
|
460
|
+
id: params.name,
|
|
461
|
+
// @ts-ignore
|
|
462
|
+
inputSchema: z.object({
|
|
463
|
+
prompt: z.string()
|
|
464
|
+
// resourceId: z.string().optional(),
|
|
465
|
+
// threadId: z.string().optional(),
|
|
466
|
+
}),
|
|
467
|
+
// @ts-ignore
|
|
468
|
+
outputSchema: z.object({
|
|
469
|
+
text: z.string()
|
|
470
|
+
}),
|
|
471
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
|
|
472
|
+
let streamPromise = {};
|
|
473
|
+
streamPromise.promise = new Promise((resolve, reject) => {
|
|
474
|
+
streamPromise.resolve = resolve;
|
|
475
|
+
streamPromise.reject = reject;
|
|
476
|
+
});
|
|
477
|
+
const toolData = {
|
|
478
|
+
name: params.name,
|
|
479
|
+
args: inputData
|
|
480
|
+
};
|
|
481
|
+
await emitter.emit("watch-v2", {
|
|
482
|
+
type: "workflow-agent-call-start",
|
|
483
|
+
payload: toolData
|
|
484
|
+
});
|
|
485
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
486
|
+
// resourceId: inputData.resourceId,
|
|
487
|
+
// threadId: inputData.threadId,
|
|
488
|
+
runtimeContext,
|
|
489
|
+
tracingContext,
|
|
490
|
+
onFinish: (result) => {
|
|
491
|
+
streamPromise.resolve(result.text);
|
|
492
|
+
},
|
|
493
|
+
abortSignal
|
|
494
|
+
});
|
|
495
|
+
if (abortSignal.aborted) {
|
|
496
|
+
return abort();
|
|
497
|
+
}
|
|
498
|
+
for await (const chunk of fullStream) {
|
|
499
|
+
await emitter.emit("watch-v2", chunk);
|
|
500
|
+
}
|
|
501
|
+
await emitter.emit("watch-v2", {
|
|
502
|
+
type: "workflow-agent-call-finish",
|
|
503
|
+
payload: toolData
|
|
504
|
+
});
|
|
505
|
+
return {
|
|
506
|
+
text: await streamPromise.promise
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
if (isTool(params)) {
|
|
512
|
+
if (!params.inputSchema || !params.outputSchema) {
|
|
513
|
+
throw new Error("Tool must have input and output schemas defined");
|
|
514
|
+
}
|
|
515
|
+
return {
|
|
516
|
+
// TODO: tool probably should have strong id type
|
|
517
|
+
// @ts-ignore
|
|
518
|
+
id: params.id,
|
|
519
|
+
inputSchema: params.inputSchema,
|
|
520
|
+
outputSchema: params.outputSchema,
|
|
521
|
+
execute: async ({ inputData, mastra, runtimeContext, tracingContext }) => {
|
|
522
|
+
return params.execute({
|
|
523
|
+
context: inputData,
|
|
524
|
+
mastra: wrapMastra(mastra, tracingContext),
|
|
525
|
+
runtimeContext,
|
|
526
|
+
tracingContext
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
};
|
|
530
|
+
}
|
|
531
|
+
return {
|
|
532
|
+
id: params.id,
|
|
533
|
+
description: params.description,
|
|
534
|
+
inputSchema: params.inputSchema,
|
|
535
|
+
outputSchema: params.outputSchema,
|
|
536
|
+
resumeSchema: params.resumeSchema,
|
|
537
|
+
suspendSchema: params.suspendSchema,
|
|
538
|
+
execute: params.execute
|
|
539
|
+
};
|
|
278
540
|
}
|
|
279
541
|
function init(inngest) {
|
|
280
542
|
return {
|
|
@@ -282,8 +544,27 @@ function init(inngest) {
|
|
|
282
544
|
return new InngestWorkflow(params, inngest);
|
|
283
545
|
},
|
|
284
546
|
createStep,
|
|
285
|
-
cloneStep,
|
|
286
|
-
|
|
547
|
+
cloneStep(step, opts) {
|
|
548
|
+
return {
|
|
549
|
+
id: opts.id,
|
|
550
|
+
description: step.description,
|
|
551
|
+
inputSchema: step.inputSchema,
|
|
552
|
+
outputSchema: step.outputSchema,
|
|
553
|
+
execute: step.execute
|
|
554
|
+
};
|
|
555
|
+
},
|
|
556
|
+
cloneWorkflow(workflow, opts) {
|
|
557
|
+
const wf = new Workflow({
|
|
558
|
+
id: opts.id,
|
|
559
|
+
inputSchema: workflow.inputSchema,
|
|
560
|
+
outputSchema: workflow.outputSchema,
|
|
561
|
+
steps: workflow.stepDefs,
|
|
562
|
+
mastra: workflow.mastra
|
|
563
|
+
});
|
|
564
|
+
wf.setStepFlow(workflow.stepGraph);
|
|
565
|
+
wf.commit();
|
|
566
|
+
return wf;
|
|
567
|
+
}
|
|
287
568
|
};
|
|
288
569
|
}
|
|
289
570
|
var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
@@ -294,6 +575,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
294
575
|
this.inngestStep = inngestStep;
|
|
295
576
|
this.inngestAttempts = inngestAttempts;
|
|
296
577
|
}
|
|
578
|
+
async execute(params) {
|
|
579
|
+
await params.emitter.emit("watch-v2", {
|
|
580
|
+
type: "workflow-start",
|
|
581
|
+
payload: { runId: params.runId }
|
|
582
|
+
});
|
|
583
|
+
const result = await super.execute(params);
|
|
584
|
+
await params.emitter.emit("watch-v2", {
|
|
585
|
+
type: "workflow-finish",
|
|
586
|
+
payload: { runId: params.runId }
|
|
587
|
+
});
|
|
588
|
+
return result;
|
|
589
|
+
}
|
|
297
590
|
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
298
591
|
const base = {
|
|
299
592
|
status: lastOutput.status,
|
|
@@ -351,28 +644,186 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
351
644
|
executionSpan?.end();
|
|
352
645
|
return base;
|
|
353
646
|
}
|
|
354
|
-
async
|
|
647
|
+
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
648
|
+
// await this.inngestStep.sleep(id, duration);
|
|
649
|
+
// }
|
|
650
|
+
async executeSleep({
|
|
355
651
|
workflowId,
|
|
356
652
|
runId,
|
|
357
|
-
|
|
653
|
+
entry,
|
|
654
|
+
prevOutput,
|
|
358
655
|
stepResults,
|
|
359
|
-
|
|
360
|
-
|
|
656
|
+
emitter,
|
|
657
|
+
abortController,
|
|
658
|
+
runtimeContext,
|
|
659
|
+
writableStream,
|
|
660
|
+
tracingContext
|
|
661
|
+
}) {
|
|
662
|
+
let { duration, fn } = entry;
|
|
663
|
+
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
664
|
+
type: AISpanType.WORKFLOW_SLEEP,
|
|
665
|
+
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
666
|
+
attributes: {
|
|
667
|
+
durationMs: duration,
|
|
668
|
+
sleepType: fn ? "dynamic" : "fixed"
|
|
669
|
+
}
|
|
670
|
+
});
|
|
671
|
+
if (fn) {
|
|
672
|
+
const stepCallId = randomUUID();
|
|
673
|
+
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
674
|
+
return await fn({
|
|
675
|
+
runId,
|
|
676
|
+
workflowId,
|
|
677
|
+
mastra: this.mastra,
|
|
678
|
+
runtimeContext,
|
|
679
|
+
inputData: prevOutput,
|
|
680
|
+
runCount: -1,
|
|
681
|
+
tracingContext: {
|
|
682
|
+
currentSpan: sleepSpan
|
|
683
|
+
},
|
|
684
|
+
getInitData: () => stepResults?.input,
|
|
685
|
+
getStepResult: (step) => {
|
|
686
|
+
if (!step?.id) {
|
|
687
|
+
return null;
|
|
688
|
+
}
|
|
689
|
+
const result = stepResults[step.id];
|
|
690
|
+
if (result?.status === "success") {
|
|
691
|
+
return result.output;
|
|
692
|
+
}
|
|
693
|
+
return null;
|
|
694
|
+
},
|
|
695
|
+
// TODO: this function shouldn't have suspend probably?
|
|
696
|
+
suspend: async (_suspendPayload) => {
|
|
697
|
+
},
|
|
698
|
+
bail: () => {
|
|
699
|
+
},
|
|
700
|
+
abort: () => {
|
|
701
|
+
abortController?.abort();
|
|
702
|
+
},
|
|
703
|
+
[EMITTER_SYMBOL]: emitter,
|
|
704
|
+
engine: { step: this.inngestStep },
|
|
705
|
+
abortSignal: abortController?.signal,
|
|
706
|
+
writer: new ToolStream(
|
|
707
|
+
{
|
|
708
|
+
prefix: "workflow-step",
|
|
709
|
+
callId: stepCallId,
|
|
710
|
+
name: "sleep",
|
|
711
|
+
runId
|
|
712
|
+
},
|
|
713
|
+
writableStream
|
|
714
|
+
)
|
|
715
|
+
});
|
|
716
|
+
});
|
|
717
|
+
sleepSpan?.update({
|
|
718
|
+
attributes: {
|
|
719
|
+
durationMs: duration
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
try {
|
|
724
|
+
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
725
|
+
sleepSpan?.end();
|
|
726
|
+
} catch (e) {
|
|
727
|
+
sleepSpan?.error({ error: e });
|
|
728
|
+
throw e;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
async executeSleepUntil({
|
|
732
|
+
workflowId,
|
|
733
|
+
runId,
|
|
734
|
+
entry,
|
|
361
735
|
prevOutput,
|
|
736
|
+
stepResults,
|
|
362
737
|
emitter,
|
|
363
|
-
|
|
738
|
+
abortController,
|
|
739
|
+
runtimeContext,
|
|
740
|
+
writableStream,
|
|
741
|
+
tracingContext
|
|
364
742
|
}) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
runtimeContext
|
|
743
|
+
let { date, fn } = entry;
|
|
744
|
+
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
745
|
+
type: AISpanType.WORKFLOW_SLEEP,
|
|
746
|
+
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
747
|
+
attributes: {
|
|
748
|
+
untilDate: date,
|
|
749
|
+
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
750
|
+
sleepType: fn ? "dynamic" : "fixed"
|
|
751
|
+
}
|
|
375
752
|
});
|
|
753
|
+
if (fn) {
|
|
754
|
+
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
755
|
+
const stepCallId = randomUUID();
|
|
756
|
+
return await fn({
|
|
757
|
+
runId,
|
|
758
|
+
workflowId,
|
|
759
|
+
mastra: this.mastra,
|
|
760
|
+
runtimeContext,
|
|
761
|
+
inputData: prevOutput,
|
|
762
|
+
runCount: -1,
|
|
763
|
+
tracingContext: {
|
|
764
|
+
currentSpan: sleepUntilSpan
|
|
765
|
+
},
|
|
766
|
+
getInitData: () => stepResults?.input,
|
|
767
|
+
getStepResult: (step) => {
|
|
768
|
+
if (!step?.id) {
|
|
769
|
+
return null;
|
|
770
|
+
}
|
|
771
|
+
const result = stepResults[step.id];
|
|
772
|
+
if (result?.status === "success") {
|
|
773
|
+
return result.output;
|
|
774
|
+
}
|
|
775
|
+
return null;
|
|
776
|
+
},
|
|
777
|
+
// TODO: this function shouldn't have suspend probably?
|
|
778
|
+
suspend: async (_suspendPayload) => {
|
|
779
|
+
},
|
|
780
|
+
bail: () => {
|
|
781
|
+
},
|
|
782
|
+
abort: () => {
|
|
783
|
+
abortController?.abort();
|
|
784
|
+
},
|
|
785
|
+
[EMITTER_SYMBOL]: emitter,
|
|
786
|
+
engine: { step: this.inngestStep },
|
|
787
|
+
abortSignal: abortController?.signal,
|
|
788
|
+
writer: new ToolStream(
|
|
789
|
+
{
|
|
790
|
+
prefix: "workflow-step",
|
|
791
|
+
callId: stepCallId,
|
|
792
|
+
name: "sleep",
|
|
793
|
+
runId
|
|
794
|
+
},
|
|
795
|
+
writableStream
|
|
796
|
+
)
|
|
797
|
+
});
|
|
798
|
+
});
|
|
799
|
+
const time = !date ? 0 : date.getTime() - Date.now();
|
|
800
|
+
sleepUntilSpan?.update({
|
|
801
|
+
attributes: {
|
|
802
|
+
durationMs: Math.max(0, time)
|
|
803
|
+
}
|
|
804
|
+
});
|
|
805
|
+
}
|
|
806
|
+
if (!(date instanceof Date)) {
|
|
807
|
+
sleepUntilSpan?.end();
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
try {
|
|
811
|
+
await this.inngestStep.sleepUntil(entry.id, date);
|
|
812
|
+
sleepUntilSpan?.end();
|
|
813
|
+
} catch (e) {
|
|
814
|
+
sleepUntilSpan?.error({ error: e });
|
|
815
|
+
throw e;
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
async executeWaitForEvent({ event, timeout }) {
|
|
819
|
+
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
820
|
+
event: `user-event-${event}`,
|
|
821
|
+
timeout: timeout ?? 5e3
|
|
822
|
+
});
|
|
823
|
+
if (eventData === null) {
|
|
824
|
+
throw "Timeout waiting for event";
|
|
825
|
+
}
|
|
826
|
+
return eventData?.data;
|
|
376
827
|
}
|
|
377
828
|
async executeStep({
|
|
378
829
|
step,
|
|
@@ -381,11 +832,24 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
381
832
|
resume,
|
|
382
833
|
prevOutput,
|
|
383
834
|
emitter,
|
|
384
|
-
|
|
835
|
+
abortController,
|
|
836
|
+
runtimeContext,
|
|
837
|
+
tracingContext,
|
|
838
|
+
writableStream,
|
|
839
|
+
disableScorers
|
|
385
840
|
}) {
|
|
386
|
-
|
|
841
|
+
const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
|
|
842
|
+
name: `workflow step: '${step.id}'`,
|
|
843
|
+
type: AISpanType.WORKFLOW_STEP,
|
|
844
|
+
input: prevOutput,
|
|
845
|
+
attributes: {
|
|
846
|
+
stepId: step.id
|
|
847
|
+
}
|
|
848
|
+
});
|
|
849
|
+
const startedAt = await this.inngestStep.run(
|
|
387
850
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
388
851
|
async () => {
|
|
852
|
+
const startedAt2 = Date.now();
|
|
389
853
|
await emitter.emit("watch", {
|
|
390
854
|
type: "watch",
|
|
391
855
|
payload: {
|
|
@@ -407,6 +871,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
407
871
|
},
|
|
408
872
|
eventTimestamp: Date.now()
|
|
409
873
|
});
|
|
874
|
+
await emitter.emit("watch-v2", {
|
|
875
|
+
type: "workflow-step-start",
|
|
876
|
+
payload: {
|
|
877
|
+
id: step.id,
|
|
878
|
+
status: "running",
|
|
879
|
+
payload: prevOutput,
|
|
880
|
+
startedAt: startedAt2
|
|
881
|
+
}
|
|
882
|
+
});
|
|
883
|
+
return startedAt2;
|
|
410
884
|
}
|
|
411
885
|
);
|
|
412
886
|
if (step instanceof InngestWorkflow) {
|
|
@@ -467,6 +941,15 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
467
941
|
},
|
|
468
942
|
eventTimestamp: Date.now()
|
|
469
943
|
});
|
|
944
|
+
await emitter.emit("watch-v2", {
|
|
945
|
+
type: "workflow-step-result",
|
|
946
|
+
payload: {
|
|
947
|
+
id: step.id,
|
|
948
|
+
status: "failed",
|
|
949
|
+
error: result?.error,
|
|
950
|
+
payload: prevOutput
|
|
951
|
+
}
|
|
952
|
+
});
|
|
470
953
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
471
954
|
} else if (result.status === "suspended") {
|
|
472
955
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
@@ -493,6 +976,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
493
976
|
},
|
|
494
977
|
eventTimestamp: Date.now()
|
|
495
978
|
});
|
|
979
|
+
await emitter.emit("watch-v2", {
|
|
980
|
+
type: "workflow-step-suspended",
|
|
981
|
+
payload: {
|
|
982
|
+
id: step.id,
|
|
983
|
+
status: "suspended"
|
|
984
|
+
}
|
|
985
|
+
});
|
|
496
986
|
return {
|
|
497
987
|
executionContext,
|
|
498
988
|
result: {
|
|
@@ -543,6 +1033,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
543
1033
|
},
|
|
544
1034
|
eventTimestamp: Date.now()
|
|
545
1035
|
});
|
|
1036
|
+
await emitter.emit("watch-v2", {
|
|
1037
|
+
type: "workflow-step-result",
|
|
1038
|
+
payload: {
|
|
1039
|
+
id: step.id,
|
|
1040
|
+
status: "success",
|
|
1041
|
+
output: result?.result
|
|
1042
|
+
}
|
|
1043
|
+
});
|
|
1044
|
+
await emitter.emit("watch-v2", {
|
|
1045
|
+
type: "workflow-step-finish",
|
|
1046
|
+
payload: {
|
|
1047
|
+
id: step.id,
|
|
1048
|
+
metadata: {}
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
546
1051
|
return { executionContext, result: { status: "success", output: result?.result } };
|
|
547
1052
|
}
|
|
548
1053
|
);
|
|
@@ -552,12 +1057,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
552
1057
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
553
1058
|
let execResults;
|
|
554
1059
|
let suspended;
|
|
1060
|
+
let bailed;
|
|
555
1061
|
try {
|
|
556
1062
|
const result = await step.execute({
|
|
1063
|
+
runId: executionContext.runId,
|
|
557
1064
|
mastra: this.mastra,
|
|
558
1065
|
runtimeContext,
|
|
1066
|
+
writableStream,
|
|
559
1067
|
inputData: prevOutput,
|
|
560
1068
|
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1069
|
+
tracingContext: {
|
|
1070
|
+
currentSpan: stepAISpan
|
|
1071
|
+
},
|
|
561
1072
|
getInitData: () => stepResults?.input,
|
|
562
1073
|
getStepResult: (step2) => {
|
|
563
1074
|
const result2 = stepResults[step2.id];
|
|
@@ -570,24 +1081,60 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
570
1081
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
571
1082
|
suspended = { payload: suspendPayload };
|
|
572
1083
|
},
|
|
1084
|
+
bail: (result2) => {
|
|
1085
|
+
bailed = { payload: result2 };
|
|
1086
|
+
},
|
|
573
1087
|
resume: {
|
|
574
1088
|
steps: resume?.steps?.slice(1) || [],
|
|
575
1089
|
resumePayload: resume?.resumePayload,
|
|
576
1090
|
// @ts-ignore
|
|
577
1091
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
578
1092
|
},
|
|
579
|
-
emitter
|
|
1093
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1094
|
+
engine: {
|
|
1095
|
+
step: this.inngestStep
|
|
1096
|
+
},
|
|
1097
|
+
abortSignal: abortController.signal
|
|
580
1098
|
});
|
|
581
|
-
|
|
1099
|
+
const endedAt = Date.now();
|
|
1100
|
+
execResults = {
|
|
1101
|
+
status: "success",
|
|
1102
|
+
output: result,
|
|
1103
|
+
startedAt,
|
|
1104
|
+
endedAt,
|
|
1105
|
+
payload: prevOutput,
|
|
1106
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1107
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1108
|
+
};
|
|
582
1109
|
} catch (e) {
|
|
583
|
-
execResults = {
|
|
1110
|
+
execResults = {
|
|
1111
|
+
status: "failed",
|
|
1112
|
+
payload: prevOutput,
|
|
1113
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1114
|
+
endedAt: Date.now(),
|
|
1115
|
+
startedAt,
|
|
1116
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1117
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1118
|
+
};
|
|
584
1119
|
}
|
|
585
1120
|
if (suspended) {
|
|
586
|
-
execResults = {
|
|
1121
|
+
execResults = {
|
|
1122
|
+
status: "suspended",
|
|
1123
|
+
suspendedPayload: suspended.payload,
|
|
1124
|
+
payload: prevOutput,
|
|
1125
|
+
suspendedAt: Date.now(),
|
|
1126
|
+
startedAt,
|
|
1127
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1128
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1129
|
+
};
|
|
1130
|
+
} else if (bailed) {
|
|
1131
|
+
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
587
1132
|
}
|
|
588
1133
|
if (execResults.status === "failed") {
|
|
589
1134
|
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
590
|
-
|
|
1135
|
+
const error = new Error(execResults.error);
|
|
1136
|
+
stepAISpan?.error({ error });
|
|
1137
|
+
throw error;
|
|
591
1138
|
}
|
|
592
1139
|
}
|
|
593
1140
|
await emitter.emit("watch", {
|
|
@@ -595,20 +1142,60 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
595
1142
|
payload: {
|
|
596
1143
|
currentStep: {
|
|
597
1144
|
id: step.id,
|
|
598
|
-
|
|
599
|
-
output: execResults.output
|
|
1145
|
+
...execResults
|
|
600
1146
|
},
|
|
601
1147
|
workflowState: {
|
|
602
1148
|
status: "running",
|
|
603
|
-
steps: stepResults,
|
|
1149
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
604
1150
|
result: null,
|
|
605
1151
|
error: null
|
|
606
1152
|
}
|
|
607
1153
|
},
|
|
608
1154
|
eventTimestamp: Date.now()
|
|
609
1155
|
});
|
|
1156
|
+
if (execResults.status === "suspended") {
|
|
1157
|
+
await emitter.emit("watch-v2", {
|
|
1158
|
+
type: "workflow-step-suspended",
|
|
1159
|
+
payload: {
|
|
1160
|
+
id: step.id,
|
|
1161
|
+
...execResults
|
|
1162
|
+
}
|
|
1163
|
+
});
|
|
1164
|
+
} else {
|
|
1165
|
+
await emitter.emit("watch-v2", {
|
|
1166
|
+
type: "workflow-step-result",
|
|
1167
|
+
payload: {
|
|
1168
|
+
id: step.id,
|
|
1169
|
+
...execResults
|
|
1170
|
+
}
|
|
1171
|
+
});
|
|
1172
|
+
await emitter.emit("watch-v2", {
|
|
1173
|
+
type: "workflow-step-finish",
|
|
1174
|
+
payload: {
|
|
1175
|
+
id: step.id,
|
|
1176
|
+
metadata: {}
|
|
1177
|
+
}
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
stepAISpan?.end({ output: execResults });
|
|
610
1181
|
return { result: execResults, executionContext, stepResults };
|
|
611
1182
|
});
|
|
1183
|
+
if (disableScorers !== false) {
|
|
1184
|
+
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1185
|
+
if (step.scorers) {
|
|
1186
|
+
await this.runScorers({
|
|
1187
|
+
scorers: step.scorers,
|
|
1188
|
+
runId: executionContext.runId,
|
|
1189
|
+
input: prevOutput,
|
|
1190
|
+
output: stepRes.result,
|
|
1191
|
+
workflowId: executionContext.workflowId,
|
|
1192
|
+
stepId: step.id,
|
|
1193
|
+
runtimeContext,
|
|
1194
|
+
disableScorers
|
|
1195
|
+
});
|
|
1196
|
+
}
|
|
1197
|
+
});
|
|
1198
|
+
}
|
|
612
1199
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
613
1200
|
Object.assign(stepResults, stepRes.stepResults);
|
|
614
1201
|
return stepRes.result;
|
|
@@ -617,7 +1204,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
617
1204
|
workflowId,
|
|
618
1205
|
runId,
|
|
619
1206
|
stepResults,
|
|
620
|
-
executionContext
|
|
1207
|
+
executionContext,
|
|
1208
|
+
serializedStepGraph,
|
|
1209
|
+
workflowStatus,
|
|
1210
|
+
result,
|
|
1211
|
+
error
|
|
621
1212
|
}) {
|
|
622
1213
|
await this.inngestStep.run(
|
|
623
1214
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -631,6 +1222,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
631
1222
|
context: stepResults,
|
|
632
1223
|
activePaths: [],
|
|
633
1224
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1225
|
+
waitingPaths: {},
|
|
1226
|
+
serializedStepGraph,
|
|
1227
|
+
status: workflowStatus,
|
|
1228
|
+
result,
|
|
1229
|
+
error,
|
|
634
1230
|
// @ts-ignore
|
|
635
1231
|
timestamp: Date.now()
|
|
636
1232
|
}
|
|
@@ -645,20 +1241,47 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
645
1241
|
prevOutput,
|
|
646
1242
|
prevStep,
|
|
647
1243
|
stepResults,
|
|
1244
|
+
serializedStepGraph,
|
|
648
1245
|
resume,
|
|
649
1246
|
executionContext,
|
|
650
1247
|
emitter,
|
|
651
|
-
|
|
1248
|
+
abortController,
|
|
1249
|
+
runtimeContext,
|
|
1250
|
+
writableStream,
|
|
1251
|
+
disableScorers,
|
|
1252
|
+
tracingContext
|
|
652
1253
|
}) {
|
|
1254
|
+
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1255
|
+
type: AISpanType.WORKFLOW_CONDITIONAL,
|
|
1256
|
+
name: `conditional: ${entry.conditions.length} conditions`,
|
|
1257
|
+
input: prevOutput,
|
|
1258
|
+
attributes: {
|
|
1259
|
+
conditionCount: entry.conditions.length
|
|
1260
|
+
}
|
|
1261
|
+
});
|
|
653
1262
|
let execResults;
|
|
654
1263
|
const truthyIndexes = (await Promise.all(
|
|
655
1264
|
entry.conditions.map(
|
|
656
1265
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1266
|
+
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1267
|
+
type: AISpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1268
|
+
name: `condition ${index}`,
|
|
1269
|
+
input: prevOutput,
|
|
1270
|
+
attributes: {
|
|
1271
|
+
conditionIndex: index
|
|
1272
|
+
}
|
|
1273
|
+
});
|
|
657
1274
|
try {
|
|
658
1275
|
const result = await cond({
|
|
1276
|
+
runId,
|
|
1277
|
+
workflowId,
|
|
659
1278
|
mastra: this.mastra,
|
|
660
1279
|
runtimeContext,
|
|
1280
|
+
runCount: -1,
|
|
661
1281
|
inputData: prevOutput,
|
|
1282
|
+
tracingContext: {
|
|
1283
|
+
currentSpan: evalSpan
|
|
1284
|
+
},
|
|
662
1285
|
getInitData: () => stepResults?.input,
|
|
663
1286
|
getStepResult: (step) => {
|
|
664
1287
|
if (!step?.id) {
|
|
@@ -673,22 +1296,59 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
673
1296
|
// TODO: this function shouldn't have suspend probably?
|
|
674
1297
|
suspend: async (_suspendPayload) => {
|
|
675
1298
|
},
|
|
676
|
-
|
|
1299
|
+
bail: () => {
|
|
1300
|
+
},
|
|
1301
|
+
abort: () => {
|
|
1302
|
+
abortController.abort();
|
|
1303
|
+
},
|
|
1304
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1305
|
+
engine: {
|
|
1306
|
+
step: this.inngestStep
|
|
1307
|
+
},
|
|
1308
|
+
abortSignal: abortController.signal,
|
|
1309
|
+
writer: new ToolStream(
|
|
1310
|
+
{
|
|
1311
|
+
prefix: "workflow-step",
|
|
1312
|
+
callId: randomUUID(),
|
|
1313
|
+
name: "conditional",
|
|
1314
|
+
runId
|
|
1315
|
+
},
|
|
1316
|
+
writableStream
|
|
1317
|
+
)
|
|
1318
|
+
});
|
|
1319
|
+
evalSpan?.end({
|
|
1320
|
+
output: result,
|
|
1321
|
+
attributes: {
|
|
1322
|
+
result: !!result
|
|
1323
|
+
}
|
|
677
1324
|
});
|
|
678
1325
|
return result ? index : null;
|
|
679
1326
|
} catch (e) {
|
|
1327
|
+
evalSpan?.error({
|
|
1328
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1329
|
+
attributes: {
|
|
1330
|
+
result: false
|
|
1331
|
+
}
|
|
1332
|
+
});
|
|
680
1333
|
return null;
|
|
681
1334
|
}
|
|
682
1335
|
})
|
|
683
1336
|
)
|
|
684
1337
|
)).filter((index) => index !== null);
|
|
685
1338
|
const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
|
|
1339
|
+
conditionalSpan?.update({
|
|
1340
|
+
attributes: {
|
|
1341
|
+
truthyIndexes,
|
|
1342
|
+
selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
|
|
1343
|
+
}
|
|
1344
|
+
});
|
|
686
1345
|
const results = await Promise.all(
|
|
687
1346
|
stepsToRun.map(
|
|
688
1347
|
(step, index) => this.executeEntry({
|
|
689
1348
|
workflowId,
|
|
690
1349
|
runId,
|
|
691
1350
|
entry: step,
|
|
1351
|
+
serializedStepGraph,
|
|
692
1352
|
prevStep,
|
|
693
1353
|
stepResults,
|
|
694
1354
|
resume,
|
|
@@ -701,29 +1361,46 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
701
1361
|
executionSpan: executionContext.executionSpan
|
|
702
1362
|
},
|
|
703
1363
|
emitter,
|
|
704
|
-
|
|
1364
|
+
abortController,
|
|
1365
|
+
runtimeContext,
|
|
1366
|
+
writableStream,
|
|
1367
|
+
disableScorers,
|
|
1368
|
+
tracingContext: {
|
|
1369
|
+
currentSpan: conditionalSpan
|
|
1370
|
+
}
|
|
705
1371
|
})
|
|
706
1372
|
)
|
|
707
1373
|
);
|
|
708
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
709
|
-
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1374
|
+
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1375
|
+
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
710
1376
|
if (hasFailed) {
|
|
711
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1377
|
+
execResults = { status: "failed", error: hasFailed.result.error };
|
|
712
1378
|
} else if (hasSuspended) {
|
|
713
|
-
execResults = { status: "suspended", payload: hasSuspended.
|
|
1379
|
+
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
714
1380
|
} else {
|
|
715
1381
|
execResults = {
|
|
716
1382
|
status: "success",
|
|
717
1383
|
output: results.reduce((acc, result, index) => {
|
|
718
|
-
if (result.status === "success") {
|
|
1384
|
+
if (result.result.status === "success") {
|
|
719
1385
|
acc[stepsToRun[index].step.id] = result.output;
|
|
720
1386
|
}
|
|
721
1387
|
return acc;
|
|
722
1388
|
}, {})
|
|
723
1389
|
};
|
|
724
1390
|
}
|
|
1391
|
+
if (execResults.status === "failed") {
|
|
1392
|
+
conditionalSpan?.error({
|
|
1393
|
+
error: new Error(execResults.error)
|
|
1394
|
+
});
|
|
1395
|
+
} else {
|
|
1396
|
+
conditionalSpan?.end({
|
|
1397
|
+
output: execResults.output || execResults
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
725
1400
|
return execResults;
|
|
726
1401
|
}
|
|
727
1402
|
};
|
|
728
1403
|
|
|
729
|
-
export { InngestExecutionEngine, InngestRun, InngestWorkflow, init, serve };
|
|
1404
|
+
export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
|
|
1405
|
+
//# sourceMappingURL=index.js.map
|
|
1406
|
+
//# sourceMappingURL=index.js.map
|