@mastra/inngest 0.0.0-redis-cloud-transporter-20250508203756 → 0.0.0-remove-unused-import-20250909212718
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 +1016 -2
- package/LICENSE.md +11 -42
- package/dist/index.cjs +765 -78
- 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 +762 -76
- 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, STREAM_FORMAT_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,192 @@ 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,
|
|
656
|
+
emitter,
|
|
657
|
+
abortController,
|
|
658
|
+
runtimeContext,
|
|
359
659
|
executionContext,
|
|
360
|
-
|
|
660
|
+
writableStream,
|
|
661
|
+
tracingContext
|
|
662
|
+
}) {
|
|
663
|
+
let { duration, fn } = entry;
|
|
664
|
+
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
665
|
+
type: AISpanType.WORKFLOW_SLEEP,
|
|
666
|
+
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
667
|
+
attributes: {
|
|
668
|
+
durationMs: duration,
|
|
669
|
+
sleepType: fn ? "dynamic" : "fixed"
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
if (fn) {
|
|
673
|
+
const stepCallId = randomUUID();
|
|
674
|
+
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
675
|
+
return await fn({
|
|
676
|
+
runId,
|
|
677
|
+
workflowId,
|
|
678
|
+
mastra: this.mastra,
|
|
679
|
+
runtimeContext,
|
|
680
|
+
inputData: prevOutput,
|
|
681
|
+
runCount: -1,
|
|
682
|
+
tracingContext: {
|
|
683
|
+
currentSpan: sleepSpan
|
|
684
|
+
},
|
|
685
|
+
getInitData: () => stepResults?.input,
|
|
686
|
+
getStepResult: (step) => {
|
|
687
|
+
if (!step?.id) {
|
|
688
|
+
return null;
|
|
689
|
+
}
|
|
690
|
+
const result = stepResults[step.id];
|
|
691
|
+
if (result?.status === "success") {
|
|
692
|
+
return result.output;
|
|
693
|
+
}
|
|
694
|
+
return null;
|
|
695
|
+
},
|
|
696
|
+
// TODO: this function shouldn't have suspend probably?
|
|
697
|
+
suspend: async (_suspendPayload) => {
|
|
698
|
+
},
|
|
699
|
+
bail: () => {
|
|
700
|
+
},
|
|
701
|
+
abort: () => {
|
|
702
|
+
abortController?.abort();
|
|
703
|
+
},
|
|
704
|
+
[EMITTER_SYMBOL]: emitter,
|
|
705
|
+
// TODO: add streamVNext support
|
|
706
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
707
|
+
engine: { step: this.inngestStep },
|
|
708
|
+
abortSignal: abortController?.signal,
|
|
709
|
+
writer: new ToolStream(
|
|
710
|
+
{
|
|
711
|
+
prefix: "workflow-step",
|
|
712
|
+
callId: stepCallId,
|
|
713
|
+
name: "sleep",
|
|
714
|
+
runId
|
|
715
|
+
},
|
|
716
|
+
writableStream
|
|
717
|
+
)
|
|
718
|
+
});
|
|
719
|
+
});
|
|
720
|
+
sleepSpan?.update({
|
|
721
|
+
attributes: {
|
|
722
|
+
durationMs: duration
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
try {
|
|
727
|
+
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
728
|
+
sleepSpan?.end();
|
|
729
|
+
} catch (e) {
|
|
730
|
+
sleepSpan?.error({ error: e });
|
|
731
|
+
throw e;
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
async executeSleepUntil({
|
|
735
|
+
workflowId,
|
|
736
|
+
runId,
|
|
737
|
+
entry,
|
|
361
738
|
prevOutput,
|
|
739
|
+
stepResults,
|
|
362
740
|
emitter,
|
|
363
|
-
|
|
741
|
+
abortController,
|
|
742
|
+
runtimeContext,
|
|
743
|
+
executionContext,
|
|
744
|
+
writableStream,
|
|
745
|
+
tracingContext
|
|
364
746
|
}) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
runtimeContext
|
|
747
|
+
let { date, fn } = entry;
|
|
748
|
+
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
749
|
+
type: AISpanType.WORKFLOW_SLEEP,
|
|
750
|
+
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
751
|
+
attributes: {
|
|
752
|
+
untilDate: date,
|
|
753
|
+
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
754
|
+
sleepType: fn ? "dynamic" : "fixed"
|
|
755
|
+
}
|
|
375
756
|
});
|
|
757
|
+
if (fn) {
|
|
758
|
+
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
759
|
+
const stepCallId = randomUUID();
|
|
760
|
+
return await fn({
|
|
761
|
+
runId,
|
|
762
|
+
workflowId,
|
|
763
|
+
mastra: this.mastra,
|
|
764
|
+
runtimeContext,
|
|
765
|
+
inputData: prevOutput,
|
|
766
|
+
runCount: -1,
|
|
767
|
+
tracingContext: {
|
|
768
|
+
currentSpan: sleepUntilSpan
|
|
769
|
+
},
|
|
770
|
+
getInitData: () => stepResults?.input,
|
|
771
|
+
getStepResult: (step) => {
|
|
772
|
+
if (!step?.id) {
|
|
773
|
+
return null;
|
|
774
|
+
}
|
|
775
|
+
const result = stepResults[step.id];
|
|
776
|
+
if (result?.status === "success") {
|
|
777
|
+
return result.output;
|
|
778
|
+
}
|
|
779
|
+
return null;
|
|
780
|
+
},
|
|
781
|
+
// TODO: this function shouldn't have suspend probably?
|
|
782
|
+
suspend: async (_suspendPayload) => {
|
|
783
|
+
},
|
|
784
|
+
bail: () => {
|
|
785
|
+
},
|
|
786
|
+
abort: () => {
|
|
787
|
+
abortController?.abort();
|
|
788
|
+
},
|
|
789
|
+
[EMITTER_SYMBOL]: emitter,
|
|
790
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
791
|
+
// TODO: add streamVNext support
|
|
792
|
+
engine: { step: this.inngestStep },
|
|
793
|
+
abortSignal: abortController?.signal,
|
|
794
|
+
writer: new ToolStream(
|
|
795
|
+
{
|
|
796
|
+
prefix: "workflow-step",
|
|
797
|
+
callId: stepCallId,
|
|
798
|
+
name: "sleep",
|
|
799
|
+
runId
|
|
800
|
+
},
|
|
801
|
+
writableStream
|
|
802
|
+
)
|
|
803
|
+
});
|
|
804
|
+
});
|
|
805
|
+
const time = !date ? 0 : date.getTime() - Date.now();
|
|
806
|
+
sleepUntilSpan?.update({
|
|
807
|
+
attributes: {
|
|
808
|
+
durationMs: Math.max(0, time)
|
|
809
|
+
}
|
|
810
|
+
});
|
|
811
|
+
}
|
|
812
|
+
if (!(date instanceof Date)) {
|
|
813
|
+
sleepUntilSpan?.end();
|
|
814
|
+
return;
|
|
815
|
+
}
|
|
816
|
+
try {
|
|
817
|
+
await this.inngestStep.sleepUntil(entry.id, date);
|
|
818
|
+
sleepUntilSpan?.end();
|
|
819
|
+
} catch (e) {
|
|
820
|
+
sleepUntilSpan?.error({ error: e });
|
|
821
|
+
throw e;
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
async executeWaitForEvent({ event, timeout }) {
|
|
825
|
+
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
826
|
+
event: `user-event-${event}`,
|
|
827
|
+
timeout: timeout ?? 5e3
|
|
828
|
+
});
|
|
829
|
+
if (eventData === null) {
|
|
830
|
+
throw "Timeout waiting for event";
|
|
831
|
+
}
|
|
832
|
+
return eventData?.data;
|
|
376
833
|
}
|
|
377
834
|
async executeStep({
|
|
378
835
|
step,
|
|
@@ -381,11 +838,24 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
381
838
|
resume,
|
|
382
839
|
prevOutput,
|
|
383
840
|
emitter,
|
|
384
|
-
|
|
841
|
+
abortController,
|
|
842
|
+
runtimeContext,
|
|
843
|
+
tracingContext,
|
|
844
|
+
writableStream,
|
|
845
|
+
disableScorers
|
|
385
846
|
}) {
|
|
386
|
-
|
|
847
|
+
const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
|
|
848
|
+
name: `workflow step: '${step.id}'`,
|
|
849
|
+
type: AISpanType.WORKFLOW_STEP,
|
|
850
|
+
input: prevOutput,
|
|
851
|
+
attributes: {
|
|
852
|
+
stepId: step.id
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
const startedAt = await this.inngestStep.run(
|
|
387
856
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
388
857
|
async () => {
|
|
858
|
+
const startedAt2 = Date.now();
|
|
389
859
|
await emitter.emit("watch", {
|
|
390
860
|
type: "watch",
|
|
391
861
|
payload: {
|
|
@@ -407,6 +877,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
407
877
|
},
|
|
408
878
|
eventTimestamp: Date.now()
|
|
409
879
|
});
|
|
880
|
+
await emitter.emit("watch-v2", {
|
|
881
|
+
type: "workflow-step-start",
|
|
882
|
+
payload: {
|
|
883
|
+
id: step.id,
|
|
884
|
+
status: "running",
|
|
885
|
+
payload: prevOutput,
|
|
886
|
+
startedAt: startedAt2
|
|
887
|
+
}
|
|
888
|
+
});
|
|
889
|
+
return startedAt2;
|
|
410
890
|
}
|
|
411
891
|
);
|
|
412
892
|
if (step instanceof InngestWorkflow) {
|
|
@@ -467,6 +947,15 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
467
947
|
},
|
|
468
948
|
eventTimestamp: Date.now()
|
|
469
949
|
});
|
|
950
|
+
await emitter.emit("watch-v2", {
|
|
951
|
+
type: "workflow-step-result",
|
|
952
|
+
payload: {
|
|
953
|
+
id: step.id,
|
|
954
|
+
status: "failed",
|
|
955
|
+
error: result?.error,
|
|
956
|
+
payload: prevOutput
|
|
957
|
+
}
|
|
958
|
+
});
|
|
470
959
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
471
960
|
} else if (result.status === "suspended") {
|
|
472
961
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
@@ -493,6 +982,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
493
982
|
},
|
|
494
983
|
eventTimestamp: Date.now()
|
|
495
984
|
});
|
|
985
|
+
await emitter.emit("watch-v2", {
|
|
986
|
+
type: "workflow-step-suspended",
|
|
987
|
+
payload: {
|
|
988
|
+
id: step.id,
|
|
989
|
+
status: "suspended"
|
|
990
|
+
}
|
|
991
|
+
});
|
|
496
992
|
return {
|
|
497
993
|
executionContext,
|
|
498
994
|
result: {
|
|
@@ -543,6 +1039,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
543
1039
|
},
|
|
544
1040
|
eventTimestamp: Date.now()
|
|
545
1041
|
});
|
|
1042
|
+
await emitter.emit("watch-v2", {
|
|
1043
|
+
type: "workflow-step-result",
|
|
1044
|
+
payload: {
|
|
1045
|
+
id: step.id,
|
|
1046
|
+
status: "success",
|
|
1047
|
+
output: result?.result
|
|
1048
|
+
}
|
|
1049
|
+
});
|
|
1050
|
+
await emitter.emit("watch-v2", {
|
|
1051
|
+
type: "workflow-step-finish",
|
|
1052
|
+
payload: {
|
|
1053
|
+
id: step.id,
|
|
1054
|
+
metadata: {}
|
|
1055
|
+
}
|
|
1056
|
+
});
|
|
546
1057
|
return { executionContext, result: { status: "success", output: result?.result } };
|
|
547
1058
|
}
|
|
548
1059
|
);
|
|
@@ -552,12 +1063,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
552
1063
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
553
1064
|
let execResults;
|
|
554
1065
|
let suspended;
|
|
1066
|
+
let bailed;
|
|
555
1067
|
try {
|
|
556
1068
|
const result = await step.execute({
|
|
1069
|
+
runId: executionContext.runId,
|
|
557
1070
|
mastra: this.mastra,
|
|
558
1071
|
runtimeContext,
|
|
1072
|
+
writableStream,
|
|
559
1073
|
inputData: prevOutput,
|
|
560
1074
|
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1075
|
+
tracingContext: {
|
|
1076
|
+
currentSpan: stepAISpan
|
|
1077
|
+
},
|
|
561
1078
|
getInitData: () => stepResults?.input,
|
|
562
1079
|
getStepResult: (step2) => {
|
|
563
1080
|
const result2 = stepResults[step2.id];
|
|
@@ -570,24 +1087,60 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
570
1087
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
571
1088
|
suspended = { payload: suspendPayload };
|
|
572
1089
|
},
|
|
1090
|
+
bail: (result2) => {
|
|
1091
|
+
bailed = { payload: result2 };
|
|
1092
|
+
},
|
|
573
1093
|
resume: {
|
|
574
1094
|
steps: resume?.steps?.slice(1) || [],
|
|
575
1095
|
resumePayload: resume?.resumePayload,
|
|
576
1096
|
// @ts-ignore
|
|
577
1097
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
578
1098
|
},
|
|
579
|
-
emitter
|
|
1099
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1100
|
+
engine: {
|
|
1101
|
+
step: this.inngestStep
|
|
1102
|
+
},
|
|
1103
|
+
abortSignal: abortController.signal
|
|
580
1104
|
});
|
|
581
|
-
|
|
1105
|
+
const endedAt = Date.now();
|
|
1106
|
+
execResults = {
|
|
1107
|
+
status: "success",
|
|
1108
|
+
output: result,
|
|
1109
|
+
startedAt,
|
|
1110
|
+
endedAt,
|
|
1111
|
+
payload: prevOutput,
|
|
1112
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1113
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1114
|
+
};
|
|
582
1115
|
} catch (e) {
|
|
583
|
-
execResults = {
|
|
1116
|
+
execResults = {
|
|
1117
|
+
status: "failed",
|
|
1118
|
+
payload: prevOutput,
|
|
1119
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1120
|
+
endedAt: Date.now(),
|
|
1121
|
+
startedAt,
|
|
1122
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1123
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1124
|
+
};
|
|
584
1125
|
}
|
|
585
1126
|
if (suspended) {
|
|
586
|
-
execResults = {
|
|
1127
|
+
execResults = {
|
|
1128
|
+
status: "suspended",
|
|
1129
|
+
suspendedPayload: suspended.payload,
|
|
1130
|
+
payload: prevOutput,
|
|
1131
|
+
suspendedAt: Date.now(),
|
|
1132
|
+
startedAt,
|
|
1133
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1134
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1135
|
+
};
|
|
1136
|
+
} else if (bailed) {
|
|
1137
|
+
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
587
1138
|
}
|
|
588
1139
|
if (execResults.status === "failed") {
|
|
589
1140
|
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
590
|
-
|
|
1141
|
+
const error = new Error(execResults.error);
|
|
1142
|
+
stepAISpan?.error({ error });
|
|
1143
|
+
throw error;
|
|
591
1144
|
}
|
|
592
1145
|
}
|
|
593
1146
|
await emitter.emit("watch", {
|
|
@@ -595,20 +1148,61 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
595
1148
|
payload: {
|
|
596
1149
|
currentStep: {
|
|
597
1150
|
id: step.id,
|
|
598
|
-
|
|
599
|
-
output: execResults.output
|
|
1151
|
+
...execResults
|
|
600
1152
|
},
|
|
601
1153
|
workflowState: {
|
|
602
1154
|
status: "running",
|
|
603
|
-
steps: stepResults,
|
|
1155
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
604
1156
|
result: null,
|
|
605
1157
|
error: null
|
|
606
1158
|
}
|
|
607
1159
|
},
|
|
608
1160
|
eventTimestamp: Date.now()
|
|
609
1161
|
});
|
|
1162
|
+
if (execResults.status === "suspended") {
|
|
1163
|
+
await emitter.emit("watch-v2", {
|
|
1164
|
+
type: "workflow-step-suspended",
|
|
1165
|
+
payload: {
|
|
1166
|
+
id: step.id,
|
|
1167
|
+
...execResults
|
|
1168
|
+
}
|
|
1169
|
+
});
|
|
1170
|
+
} else {
|
|
1171
|
+
await emitter.emit("watch-v2", {
|
|
1172
|
+
type: "workflow-step-result",
|
|
1173
|
+
payload: {
|
|
1174
|
+
id: step.id,
|
|
1175
|
+
...execResults
|
|
1176
|
+
}
|
|
1177
|
+
});
|
|
1178
|
+
await emitter.emit("watch-v2", {
|
|
1179
|
+
type: "workflow-step-finish",
|
|
1180
|
+
payload: {
|
|
1181
|
+
id: step.id,
|
|
1182
|
+
metadata: {}
|
|
1183
|
+
}
|
|
1184
|
+
});
|
|
1185
|
+
}
|
|
1186
|
+
stepAISpan?.end({ output: execResults });
|
|
610
1187
|
return { result: execResults, executionContext, stepResults };
|
|
611
1188
|
});
|
|
1189
|
+
if (disableScorers !== false) {
|
|
1190
|
+
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1191
|
+
if (step.scorers) {
|
|
1192
|
+
await this.runScorers({
|
|
1193
|
+
scorers: step.scorers,
|
|
1194
|
+
runId: executionContext.runId,
|
|
1195
|
+
input: prevOutput,
|
|
1196
|
+
output: stepRes.result,
|
|
1197
|
+
workflowId: executionContext.workflowId,
|
|
1198
|
+
stepId: step.id,
|
|
1199
|
+
runtimeContext,
|
|
1200
|
+
disableScorers,
|
|
1201
|
+
tracingContext: { currentSpan: stepAISpan }
|
|
1202
|
+
});
|
|
1203
|
+
}
|
|
1204
|
+
});
|
|
1205
|
+
}
|
|
612
1206
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
613
1207
|
Object.assign(stepResults, stepRes.stepResults);
|
|
614
1208
|
return stepRes.result;
|
|
@@ -617,7 +1211,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
617
1211
|
workflowId,
|
|
618
1212
|
runId,
|
|
619
1213
|
stepResults,
|
|
620
|
-
executionContext
|
|
1214
|
+
executionContext,
|
|
1215
|
+
serializedStepGraph,
|
|
1216
|
+
workflowStatus,
|
|
1217
|
+
result,
|
|
1218
|
+
error
|
|
621
1219
|
}) {
|
|
622
1220
|
await this.inngestStep.run(
|
|
623
1221
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -631,6 +1229,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
631
1229
|
context: stepResults,
|
|
632
1230
|
activePaths: [],
|
|
633
1231
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1232
|
+
waitingPaths: {},
|
|
1233
|
+
serializedStepGraph,
|
|
1234
|
+
status: workflowStatus,
|
|
1235
|
+
result,
|
|
1236
|
+
error,
|
|
634
1237
|
// @ts-ignore
|
|
635
1238
|
timestamp: Date.now()
|
|
636
1239
|
}
|
|
@@ -645,20 +1248,47 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
645
1248
|
prevOutput,
|
|
646
1249
|
prevStep,
|
|
647
1250
|
stepResults,
|
|
1251
|
+
serializedStepGraph,
|
|
648
1252
|
resume,
|
|
649
1253
|
executionContext,
|
|
650
1254
|
emitter,
|
|
651
|
-
|
|
1255
|
+
abortController,
|
|
1256
|
+
runtimeContext,
|
|
1257
|
+
writableStream,
|
|
1258
|
+
disableScorers,
|
|
1259
|
+
tracingContext
|
|
652
1260
|
}) {
|
|
1261
|
+
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1262
|
+
type: AISpanType.WORKFLOW_CONDITIONAL,
|
|
1263
|
+
name: `conditional: ${entry.conditions.length} conditions`,
|
|
1264
|
+
input: prevOutput,
|
|
1265
|
+
attributes: {
|
|
1266
|
+
conditionCount: entry.conditions.length
|
|
1267
|
+
}
|
|
1268
|
+
});
|
|
653
1269
|
let execResults;
|
|
654
1270
|
const truthyIndexes = (await Promise.all(
|
|
655
1271
|
entry.conditions.map(
|
|
656
1272
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1273
|
+
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1274
|
+
type: AISpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1275
|
+
name: `condition ${index}`,
|
|
1276
|
+
input: prevOutput,
|
|
1277
|
+
attributes: {
|
|
1278
|
+
conditionIndex: index
|
|
1279
|
+
}
|
|
1280
|
+
});
|
|
657
1281
|
try {
|
|
658
1282
|
const result = await cond({
|
|
1283
|
+
runId,
|
|
1284
|
+
workflowId,
|
|
659
1285
|
mastra: this.mastra,
|
|
660
1286
|
runtimeContext,
|
|
1287
|
+
runCount: -1,
|
|
661
1288
|
inputData: prevOutput,
|
|
1289
|
+
tracingContext: {
|
|
1290
|
+
currentSpan: evalSpan
|
|
1291
|
+
},
|
|
662
1292
|
getInitData: () => stepResults?.input,
|
|
663
1293
|
getStepResult: (step) => {
|
|
664
1294
|
if (!step?.id) {
|
|
@@ -673,22 +1303,61 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
673
1303
|
// TODO: this function shouldn't have suspend probably?
|
|
674
1304
|
suspend: async (_suspendPayload) => {
|
|
675
1305
|
},
|
|
676
|
-
|
|
1306
|
+
bail: () => {
|
|
1307
|
+
},
|
|
1308
|
+
abort: () => {
|
|
1309
|
+
abortController.abort();
|
|
1310
|
+
},
|
|
1311
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1312
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1313
|
+
// TODO: add streamVNext support
|
|
1314
|
+
engine: {
|
|
1315
|
+
step: this.inngestStep
|
|
1316
|
+
},
|
|
1317
|
+
abortSignal: abortController.signal,
|
|
1318
|
+
writer: new ToolStream(
|
|
1319
|
+
{
|
|
1320
|
+
prefix: "workflow-step",
|
|
1321
|
+
callId: randomUUID(),
|
|
1322
|
+
name: "conditional",
|
|
1323
|
+
runId
|
|
1324
|
+
},
|
|
1325
|
+
writableStream
|
|
1326
|
+
)
|
|
1327
|
+
});
|
|
1328
|
+
evalSpan?.end({
|
|
1329
|
+
output: result,
|
|
1330
|
+
attributes: {
|
|
1331
|
+
result: !!result
|
|
1332
|
+
}
|
|
677
1333
|
});
|
|
678
1334
|
return result ? index : null;
|
|
679
1335
|
} catch (e) {
|
|
1336
|
+
evalSpan?.error({
|
|
1337
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1338
|
+
attributes: {
|
|
1339
|
+
result: false
|
|
1340
|
+
}
|
|
1341
|
+
});
|
|
680
1342
|
return null;
|
|
681
1343
|
}
|
|
682
1344
|
})
|
|
683
1345
|
)
|
|
684
1346
|
)).filter((index) => index !== null);
|
|
685
1347
|
const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
|
|
1348
|
+
conditionalSpan?.update({
|
|
1349
|
+
attributes: {
|
|
1350
|
+
truthyIndexes,
|
|
1351
|
+
selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
|
|
1352
|
+
}
|
|
1353
|
+
});
|
|
686
1354
|
const results = await Promise.all(
|
|
687
1355
|
stepsToRun.map(
|
|
688
1356
|
(step, index) => this.executeEntry({
|
|
689
1357
|
workflowId,
|
|
690
1358
|
runId,
|
|
691
1359
|
entry: step,
|
|
1360
|
+
serializedStepGraph,
|
|
692
1361
|
prevStep,
|
|
693
1362
|
stepResults,
|
|
694
1363
|
resume,
|
|
@@ -701,29 +1370,46 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
701
1370
|
executionSpan: executionContext.executionSpan
|
|
702
1371
|
},
|
|
703
1372
|
emitter,
|
|
704
|
-
|
|
1373
|
+
abortController,
|
|
1374
|
+
runtimeContext,
|
|
1375
|
+
writableStream,
|
|
1376
|
+
disableScorers,
|
|
1377
|
+
tracingContext: {
|
|
1378
|
+
currentSpan: conditionalSpan
|
|
1379
|
+
}
|
|
705
1380
|
})
|
|
706
1381
|
)
|
|
707
1382
|
);
|
|
708
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
709
|
-
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1383
|
+
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1384
|
+
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
710
1385
|
if (hasFailed) {
|
|
711
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1386
|
+
execResults = { status: "failed", error: hasFailed.result.error };
|
|
712
1387
|
} else if (hasSuspended) {
|
|
713
|
-
execResults = { status: "suspended", payload: hasSuspended.
|
|
1388
|
+
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
714
1389
|
} else {
|
|
715
1390
|
execResults = {
|
|
716
1391
|
status: "success",
|
|
717
1392
|
output: results.reduce((acc, result, index) => {
|
|
718
|
-
if (result.status === "success") {
|
|
1393
|
+
if (result.result.status === "success") {
|
|
719
1394
|
acc[stepsToRun[index].step.id] = result.output;
|
|
720
1395
|
}
|
|
721
1396
|
return acc;
|
|
722
1397
|
}, {})
|
|
723
1398
|
};
|
|
724
1399
|
}
|
|
1400
|
+
if (execResults.status === "failed") {
|
|
1401
|
+
conditionalSpan?.error({
|
|
1402
|
+
error: new Error(execResults.error)
|
|
1403
|
+
});
|
|
1404
|
+
} else {
|
|
1405
|
+
conditionalSpan?.end({
|
|
1406
|
+
output: execResults.output || execResults
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
725
1409
|
return execResults;
|
|
726
1410
|
}
|
|
727
1411
|
};
|
|
728
1412
|
|
|
729
|
-
export { InngestExecutionEngine, InngestRun, InngestWorkflow, init, serve };
|
|
1413
|
+
export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
|
|
1414
|
+
//# sourceMappingURL=index.js.map
|
|
1415
|
+
//# sourceMappingURL=index.js.map
|