@mastra/inngest 0.0.0-vector-sources-20250516175436 → 0.0.0-vector-extension-schema-20250922130418
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 +1022 -2
- package/LICENSE.md +11 -42
- package/dist/index.cjs +744 -102
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +293 -5
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +741 -100
- 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 -958
- package/tsconfig.json +0 -5
- package/vitest.config.ts +0 -8
package/dist/index.js
CHANGED
|
@@ -1,34 +1,48 @@
|
|
|
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, getStepResult } 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
|
-
function serve({
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
function serve({
|
|
13
|
+
mastra,
|
|
14
|
+
inngest,
|
|
15
|
+
functions: userFunctions = []
|
|
16
|
+
}) {
|
|
17
|
+
const wfs = mastra.getWorkflows();
|
|
18
|
+
const workflowFunctions = Array.from(
|
|
19
|
+
new Set(
|
|
20
|
+
Object.values(wfs).flatMap((wf) => {
|
|
21
|
+
if (wf instanceof InngestWorkflow) {
|
|
22
|
+
wf.__registerMastra(mastra);
|
|
23
|
+
return wf.getFunctions();
|
|
24
|
+
}
|
|
25
|
+
return [];
|
|
26
|
+
})
|
|
27
|
+
)
|
|
28
|
+
);
|
|
17
29
|
return serve$1({
|
|
18
30
|
client: inngest,
|
|
19
|
-
functions
|
|
31
|
+
functions: [...workflowFunctions, ...userFunctions]
|
|
20
32
|
});
|
|
21
33
|
}
|
|
22
34
|
var InngestRun = class extends Run {
|
|
23
35
|
inngest;
|
|
36
|
+
serializedStepGraph;
|
|
24
37
|
#mastra;
|
|
25
38
|
constructor(params, inngest) {
|
|
26
39
|
super(params);
|
|
27
40
|
this.inngest = inngest;
|
|
41
|
+
this.serializedStepGraph = params.serializedStepGraph;
|
|
28
42
|
this.#mastra = params.mastra;
|
|
29
43
|
}
|
|
30
44
|
async getRuns(eventId) {
|
|
31
|
-
const response = await fetch(`${this.inngest.apiBaseUrl}/v1/events/${eventId}/runs`, {
|
|
45
|
+
const response = await fetch(`${this.inngest.apiBaseUrl ?? "https://api.inngest.com"}/v1/events/${eventId}/runs`, {
|
|
32
46
|
headers: {
|
|
33
47
|
Authorization: `Bearer ${process.env.INNGEST_SIGNING_KEY}`
|
|
34
48
|
}
|
|
@@ -38,35 +52,75 @@ var InngestRun = class extends Run {
|
|
|
38
52
|
}
|
|
39
53
|
async getRunOutput(eventId) {
|
|
40
54
|
let runs = await this.getRuns(eventId);
|
|
41
|
-
while (runs?.[0]?.status !== "Completed") {
|
|
55
|
+
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
42
56
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
43
57
|
runs = await this.getRuns(eventId);
|
|
44
|
-
if (runs?.[0]?.status === "Failed"
|
|
58
|
+
if (runs?.[0]?.status === "Failed") {
|
|
45
59
|
throw new Error(`Function run ${runs?.[0]?.status}`);
|
|
60
|
+
} else if (runs?.[0]?.status === "Cancelled") {
|
|
61
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
62
|
+
workflowName: this.workflowId,
|
|
63
|
+
runId: this.runId
|
|
64
|
+
});
|
|
65
|
+
return { output: { result: { steps: snapshot?.context, status: "canceled" } } };
|
|
46
66
|
}
|
|
47
67
|
}
|
|
48
68
|
return runs?.[0];
|
|
49
69
|
}
|
|
70
|
+
async sendEvent(event, data) {
|
|
71
|
+
await this.inngest.send({
|
|
72
|
+
name: `user-event-${event}`,
|
|
73
|
+
data
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
async cancel() {
|
|
77
|
+
await this.inngest.send({
|
|
78
|
+
name: `cancel.workflow.${this.workflowId}`,
|
|
79
|
+
data: {
|
|
80
|
+
runId: this.runId
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
84
|
+
workflowName: this.workflowId,
|
|
85
|
+
runId: this.runId
|
|
86
|
+
});
|
|
87
|
+
if (snapshot) {
|
|
88
|
+
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
89
|
+
workflowName: this.workflowId,
|
|
90
|
+
runId: this.runId,
|
|
91
|
+
resourceId: this.resourceId,
|
|
92
|
+
snapshot: {
|
|
93
|
+
...snapshot,
|
|
94
|
+
status: "canceled"
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
50
99
|
async start({
|
|
51
100
|
inputData
|
|
52
101
|
}) {
|
|
53
102
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
54
103
|
workflowName: this.workflowId,
|
|
55
104
|
runId: this.runId,
|
|
105
|
+
resourceId: this.resourceId,
|
|
56
106
|
snapshot: {
|
|
57
107
|
runId: this.runId,
|
|
108
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
58
109
|
value: {},
|
|
59
110
|
context: {},
|
|
60
111
|
activePaths: [],
|
|
61
112
|
suspendedPaths: {},
|
|
62
|
-
|
|
113
|
+
waitingPaths: {},
|
|
114
|
+
timestamp: Date.now(),
|
|
115
|
+
status: "running"
|
|
63
116
|
}
|
|
64
117
|
});
|
|
65
118
|
const eventOutput = await this.inngest.send({
|
|
66
119
|
name: `workflow.${this.workflowId}`,
|
|
67
120
|
data: {
|
|
68
121
|
inputData,
|
|
69
|
-
runId: this.runId
|
|
122
|
+
runId: this.runId,
|
|
123
|
+
resourceId: this.resourceId
|
|
70
124
|
}
|
|
71
125
|
});
|
|
72
126
|
const eventId = eventOutput.ids[0];
|
|
@@ -78,10 +132,23 @@ var InngestRun = class extends Run {
|
|
|
78
132
|
if (result.status === "failed") {
|
|
79
133
|
result.error = new Error(result.error);
|
|
80
134
|
}
|
|
81
|
-
|
|
135
|
+
if (result.status !== "suspended") {
|
|
136
|
+
this.cleanup?.();
|
|
137
|
+
}
|
|
82
138
|
return result;
|
|
83
139
|
}
|
|
84
140
|
async resume(params) {
|
|
141
|
+
const p = this._resume(params).then((result) => {
|
|
142
|
+
if (result.status !== "suspended") {
|
|
143
|
+
this.closeStreamAction?.().catch(() => {
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
return result;
|
|
147
|
+
});
|
|
148
|
+
this.executionResults = p;
|
|
149
|
+
return p;
|
|
150
|
+
}
|
|
151
|
+
async _resume(params) {
|
|
85
152
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
86
153
|
(step) => typeof step === "string" ? step : step?.id
|
|
87
154
|
);
|
|
@@ -94,6 +161,7 @@ var InngestRun = class extends Run {
|
|
|
94
161
|
data: {
|
|
95
162
|
inputData: params.resumeData,
|
|
96
163
|
runId: this.runId,
|
|
164
|
+
workflowId: this.workflowId,
|
|
97
165
|
stepResults: snapshot?.context,
|
|
98
166
|
resume: {
|
|
99
167
|
steps,
|
|
@@ -115,32 +183,77 @@ var InngestRun = class extends Run {
|
|
|
115
183
|
}
|
|
116
184
|
return result;
|
|
117
185
|
}
|
|
118
|
-
watch(cb) {
|
|
186
|
+
watch(cb, type = "watch") {
|
|
187
|
+
let active = true;
|
|
119
188
|
const streamPromise = subscribe(
|
|
120
189
|
{
|
|
121
190
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
122
|
-
topics: [
|
|
191
|
+
topics: [type],
|
|
123
192
|
app: this.inngest
|
|
124
193
|
},
|
|
125
194
|
(message) => {
|
|
126
|
-
|
|
195
|
+
if (active) {
|
|
196
|
+
cb(message.data);
|
|
197
|
+
}
|
|
127
198
|
}
|
|
128
199
|
);
|
|
129
200
|
return () => {
|
|
130
|
-
|
|
131
|
-
|
|
201
|
+
active = false;
|
|
202
|
+
streamPromise.then(async (stream) => {
|
|
203
|
+
return stream.cancel();
|
|
132
204
|
}).catch((err) => {
|
|
133
205
|
console.error(err);
|
|
134
206
|
});
|
|
135
207
|
};
|
|
136
208
|
}
|
|
209
|
+
stream({ inputData, runtimeContext } = {}) {
|
|
210
|
+
const { readable, writable } = new TransformStream();
|
|
211
|
+
const writer = writable.getWriter();
|
|
212
|
+
const unwatch = this.watch(async (event) => {
|
|
213
|
+
try {
|
|
214
|
+
const e = {
|
|
215
|
+
...event,
|
|
216
|
+
type: event.type.replace("workflow-", "")
|
|
217
|
+
};
|
|
218
|
+
await writer.write(e);
|
|
219
|
+
} catch {
|
|
220
|
+
}
|
|
221
|
+
}, "watch-v2");
|
|
222
|
+
this.closeStreamAction = async () => {
|
|
223
|
+
unwatch();
|
|
224
|
+
try {
|
|
225
|
+
await writer.close();
|
|
226
|
+
} catch (err) {
|
|
227
|
+
console.error("Error closing stream:", err);
|
|
228
|
+
} finally {
|
|
229
|
+
writer.releaseLock();
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
this.executionResults = this.start({ inputData, runtimeContext }).then((result) => {
|
|
233
|
+
if (result.status !== "suspended") {
|
|
234
|
+
this.closeStreamAction?.().catch(() => {
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
return result;
|
|
238
|
+
});
|
|
239
|
+
return {
|
|
240
|
+
stream: readable,
|
|
241
|
+
getWorkflowState: () => this.executionResults
|
|
242
|
+
};
|
|
243
|
+
}
|
|
137
244
|
};
|
|
138
|
-
var InngestWorkflow = class _InngestWorkflow extends
|
|
245
|
+
var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
139
246
|
#mastra;
|
|
140
247
|
inngest;
|
|
141
248
|
function;
|
|
249
|
+
flowControlConfig;
|
|
142
250
|
constructor(params, inngest) {
|
|
143
|
-
|
|
251
|
+
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
252
|
+
super(workflowParams);
|
|
253
|
+
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
254
|
+
([_, value]) => value !== void 0
|
|
255
|
+
);
|
|
256
|
+
this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
|
|
144
257
|
this.#mastra = params.mastra;
|
|
145
258
|
this.inngest = inngest;
|
|
146
259
|
}
|
|
@@ -156,7 +269,7 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
156
269
|
const storage = this.#mastra?.getStorage();
|
|
157
270
|
if (!storage) {
|
|
158
271
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
159
|
-
return null;
|
|
272
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
160
273
|
}
|
|
161
274
|
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
162
275
|
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
@@ -179,14 +292,25 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
179
292
|
}
|
|
180
293
|
}
|
|
181
294
|
}
|
|
182
|
-
|
|
295
|
+
/**
|
|
296
|
+
* @deprecated Use createRunAsync() instead.
|
|
297
|
+
* @throws {Error} Always throws an error directing users to use createRunAsync()
|
|
298
|
+
*/
|
|
299
|
+
createRun(_options) {
|
|
300
|
+
throw new Error(
|
|
301
|
+
"createRun() has been deprecated. Please use createRunAsync() instead.\n\nMigration guide:\n Before: const run = workflow.createRun();\n After: const run = await workflow.createRunAsync();\n\nNote: createRunAsync() is an async method, so make sure your calling function is async."
|
|
302
|
+
);
|
|
303
|
+
}
|
|
304
|
+
async createRunAsync(options) {
|
|
183
305
|
const runIdToUse = options?.runId || randomUUID();
|
|
184
306
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
185
307
|
{
|
|
186
308
|
workflowId: this.id,
|
|
187
309
|
runId: runIdToUse,
|
|
310
|
+
resourceId: options?.resourceId,
|
|
188
311
|
executionEngine: this.executionEngine,
|
|
189
312
|
executionGraph: this.executionGraph,
|
|
313
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
190
314
|
mastra: this.#mastra,
|
|
191
315
|
retryConfig: this.retryConfig,
|
|
192
316
|
cleanup: () => this.runs.delete(runIdToUse)
|
|
@@ -194,6 +318,28 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
194
318
|
this.inngest
|
|
195
319
|
);
|
|
196
320
|
this.runs.set(runIdToUse, run);
|
|
321
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
322
|
+
if (!workflowSnapshotInStorage) {
|
|
323
|
+
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
324
|
+
workflowName: this.id,
|
|
325
|
+
runId: runIdToUse,
|
|
326
|
+
resourceId: options?.resourceId,
|
|
327
|
+
snapshot: {
|
|
328
|
+
runId: runIdToUse,
|
|
329
|
+
status: "pending",
|
|
330
|
+
value: {},
|
|
331
|
+
context: {},
|
|
332
|
+
activePaths: [],
|
|
333
|
+
waitingPaths: {},
|
|
334
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
335
|
+
suspendedPaths: {},
|
|
336
|
+
result: void 0,
|
|
337
|
+
error: void 0,
|
|
338
|
+
// @ts-ignore
|
|
339
|
+
timestamp: Date.now()
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
}
|
|
197
343
|
return run;
|
|
198
344
|
}
|
|
199
345
|
getFunction() {
|
|
@@ -201,11 +347,17 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
201
347
|
return this.function;
|
|
202
348
|
}
|
|
203
349
|
this.function = this.inngest.createFunction(
|
|
204
|
-
|
|
205
|
-
|
|
350
|
+
{
|
|
351
|
+
id: `workflow.${this.id}`,
|
|
352
|
+
// @ts-ignore
|
|
353
|
+
retries: this.retryConfig?.attempts ?? 0,
|
|
354
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
355
|
+
// Spread flow control configuration
|
|
356
|
+
...this.flowControlConfig
|
|
357
|
+
},
|
|
206
358
|
{ event: `workflow.${this.id}` },
|
|
207
359
|
async ({ event, step, attempt, publish }) => {
|
|
208
|
-
let { inputData, runId, resume } = event.data;
|
|
360
|
+
let { inputData, runId, resourceId, resume } = event.data;
|
|
209
361
|
if (!runId) {
|
|
210
362
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
211
363
|
return randomUUID();
|
|
@@ -219,25 +371,36 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
219
371
|
try {
|
|
220
372
|
await publish({
|
|
221
373
|
channel: `workflow:${this.id}:${runId}`,
|
|
222
|
-
topic:
|
|
374
|
+
topic: event2,
|
|
223
375
|
data
|
|
224
376
|
});
|
|
225
377
|
} catch (err) {
|
|
226
378
|
this.logger.error("Error emitting event: " + (err?.stack ?? err?.message ?? err));
|
|
227
379
|
}
|
|
380
|
+
},
|
|
381
|
+
on: (_event, _callback) => {
|
|
382
|
+
},
|
|
383
|
+
off: (_event, _callback) => {
|
|
384
|
+
},
|
|
385
|
+
once: (_event, _callback) => {
|
|
228
386
|
}
|
|
229
387
|
};
|
|
230
388
|
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
231
389
|
const result = await engine.execute({
|
|
232
390
|
workflowId: this.id,
|
|
233
391
|
runId,
|
|
392
|
+
resourceId,
|
|
234
393
|
graph: this.executionGraph,
|
|
394
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
235
395
|
input: inputData,
|
|
236
396
|
emitter,
|
|
237
397
|
retryConfig: this.retryConfig,
|
|
238
398
|
runtimeContext: new RuntimeContext(),
|
|
239
399
|
// TODO
|
|
240
|
-
resume
|
|
400
|
+
resume,
|
|
401
|
+
abortController: new AbortController(),
|
|
402
|
+
currentSpan: void 0
|
|
403
|
+
// TODO: Pass actual parent AI span from workflow execution context
|
|
241
404
|
});
|
|
242
405
|
return { result, runId };
|
|
243
406
|
}
|
|
@@ -261,20 +424,97 @@ var InngestWorkflow = class _InngestWorkflow extends NewWorkflow {
|
|
|
261
424
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
262
425
|
}
|
|
263
426
|
};
|
|
264
|
-
function
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
427
|
+
function isAgent(params) {
|
|
428
|
+
return params?.component === "AGENT";
|
|
429
|
+
}
|
|
430
|
+
function isTool(params) {
|
|
431
|
+
return params instanceof Tool;
|
|
432
|
+
}
|
|
433
|
+
function createStep(params) {
|
|
434
|
+
if (isAgent(params)) {
|
|
435
|
+
return {
|
|
436
|
+
id: params.name,
|
|
437
|
+
// @ts-ignore
|
|
438
|
+
inputSchema: z.object({
|
|
439
|
+
prompt: z.string()
|
|
440
|
+
}),
|
|
441
|
+
// @ts-ignore
|
|
442
|
+
outputSchema: z.object({
|
|
443
|
+
text: z.string()
|
|
444
|
+
}),
|
|
445
|
+
execute: async ({ inputData, [EMITTER_SYMBOL]: emitter, runtimeContext, abortSignal, abort, tracingContext }) => {
|
|
446
|
+
let streamPromise = {};
|
|
447
|
+
streamPromise.promise = new Promise((resolve, reject) => {
|
|
448
|
+
streamPromise.resolve = resolve;
|
|
449
|
+
streamPromise.reject = reject;
|
|
450
|
+
});
|
|
451
|
+
const toolData = {
|
|
452
|
+
name: params.name,
|
|
453
|
+
args: inputData
|
|
454
|
+
};
|
|
455
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
456
|
+
runtimeContext,
|
|
457
|
+
tracingContext,
|
|
458
|
+
onFinish: (result) => {
|
|
459
|
+
streamPromise.resolve(result.text);
|
|
460
|
+
},
|
|
461
|
+
abortSignal
|
|
462
|
+
});
|
|
463
|
+
if (abortSignal.aborted) {
|
|
464
|
+
return abort();
|
|
465
|
+
}
|
|
466
|
+
await emitter.emit("watch-v2", {
|
|
467
|
+
type: "tool-call-streaming-start",
|
|
468
|
+
...toolData ?? {}
|
|
469
|
+
});
|
|
470
|
+
for await (const chunk of fullStream) {
|
|
471
|
+
if (chunk.type === "text-delta") {
|
|
472
|
+
await emitter.emit("watch-v2", {
|
|
473
|
+
type: "tool-call-delta",
|
|
474
|
+
...toolData ?? {},
|
|
475
|
+
argsTextDelta: chunk.textDelta
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
await emitter.emit("watch-v2", {
|
|
480
|
+
type: "tool-call-streaming-finish",
|
|
481
|
+
...toolData ?? {}
|
|
482
|
+
});
|
|
483
|
+
return {
|
|
484
|
+
text: await streamPromise.promise
|
|
485
|
+
};
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
if (isTool(params)) {
|
|
490
|
+
if (!params.inputSchema || !params.outputSchema) {
|
|
491
|
+
throw new Error("Tool must have input and output schemas defined");
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
// TODO: tool probably should have strong id type
|
|
495
|
+
// @ts-ignore
|
|
496
|
+
id: params.id,
|
|
497
|
+
inputSchema: params.inputSchema,
|
|
498
|
+
outputSchema: params.outputSchema,
|
|
499
|
+
execute: async ({ inputData, mastra, runtimeContext, tracingContext }) => {
|
|
500
|
+
return params.execute({
|
|
501
|
+
context: inputData,
|
|
502
|
+
mastra: wrapMastra(mastra, tracingContext),
|
|
503
|
+
runtimeContext,
|
|
504
|
+
tracingContext
|
|
505
|
+
});
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
return {
|
|
510
|
+
id: params.id,
|
|
511
|
+
description: params.description,
|
|
512
|
+
inputSchema: params.inputSchema,
|
|
513
|
+
outputSchema: params.outputSchema,
|
|
514
|
+
resumeSchema: params.resumeSchema,
|
|
515
|
+
suspendSchema: params.suspendSchema,
|
|
516
|
+
execute: params.execute
|
|
517
|
+
};
|
|
278
518
|
}
|
|
279
519
|
function init(inngest) {
|
|
280
520
|
return {
|
|
@@ -282,18 +522,49 @@ function init(inngest) {
|
|
|
282
522
|
return new InngestWorkflow(params, inngest);
|
|
283
523
|
},
|
|
284
524
|
createStep,
|
|
285
|
-
cloneStep,
|
|
286
|
-
|
|
525
|
+
cloneStep(step, opts) {
|
|
526
|
+
return {
|
|
527
|
+
id: opts.id,
|
|
528
|
+
description: step.description,
|
|
529
|
+
inputSchema: step.inputSchema,
|
|
530
|
+
outputSchema: step.outputSchema,
|
|
531
|
+
execute: step.execute
|
|
532
|
+
};
|
|
533
|
+
},
|
|
534
|
+
cloneWorkflow(workflow, opts) {
|
|
535
|
+
const wf = new Workflow({
|
|
536
|
+
id: opts.id,
|
|
537
|
+
inputSchema: workflow.inputSchema,
|
|
538
|
+
outputSchema: workflow.outputSchema,
|
|
539
|
+
steps: workflow.stepDefs,
|
|
540
|
+
mastra: workflow.mastra
|
|
541
|
+
});
|
|
542
|
+
wf.setStepFlow(workflow.stepGraph);
|
|
543
|
+
wf.commit();
|
|
544
|
+
return wf;
|
|
545
|
+
}
|
|
287
546
|
};
|
|
288
547
|
}
|
|
289
548
|
var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
290
549
|
inngestStep;
|
|
291
550
|
inngestAttempts;
|
|
292
|
-
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
293
|
-
super({ mastra });
|
|
551
|
+
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
552
|
+
super({ mastra, options });
|
|
294
553
|
this.inngestStep = inngestStep;
|
|
295
554
|
this.inngestAttempts = inngestAttempts;
|
|
296
555
|
}
|
|
556
|
+
async execute(params) {
|
|
557
|
+
await params.emitter.emit("watch-v2", {
|
|
558
|
+
type: "workflow-start",
|
|
559
|
+
payload: { runId: params.runId }
|
|
560
|
+
});
|
|
561
|
+
const result = await super.execute(params);
|
|
562
|
+
await params.emitter.emit("watch-v2", {
|
|
563
|
+
type: "workflow-finish",
|
|
564
|
+
payload: { runId: params.runId }
|
|
565
|
+
});
|
|
566
|
+
return result;
|
|
567
|
+
}
|
|
297
568
|
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
298
569
|
const base = {
|
|
299
570
|
status: lastOutput.status,
|
|
@@ -351,28 +622,179 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
351
622
|
executionSpan?.end();
|
|
352
623
|
return base;
|
|
353
624
|
}
|
|
354
|
-
async
|
|
625
|
+
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
626
|
+
// await this.inngestStep.sleep(id, duration);
|
|
627
|
+
// }
|
|
628
|
+
async executeSleep({
|
|
355
629
|
workflowId,
|
|
356
630
|
runId,
|
|
357
|
-
|
|
631
|
+
entry,
|
|
632
|
+
prevOutput,
|
|
358
633
|
stepResults,
|
|
634
|
+
emitter,
|
|
635
|
+
abortController,
|
|
636
|
+
runtimeContext,
|
|
359
637
|
executionContext,
|
|
360
|
-
|
|
638
|
+
writableStream,
|
|
639
|
+
tracingContext
|
|
640
|
+
}) {
|
|
641
|
+
let { duration, fn } = entry;
|
|
642
|
+
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
643
|
+
type: AISpanType.WORKFLOW_SLEEP,
|
|
644
|
+
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
645
|
+
attributes: {
|
|
646
|
+
durationMs: duration,
|
|
647
|
+
sleepType: fn ? "dynamic" : "fixed"
|
|
648
|
+
},
|
|
649
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
650
|
+
});
|
|
651
|
+
if (fn) {
|
|
652
|
+
const stepCallId = randomUUID();
|
|
653
|
+
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
654
|
+
return await fn({
|
|
655
|
+
runId,
|
|
656
|
+
workflowId,
|
|
657
|
+
mastra: this.mastra,
|
|
658
|
+
runtimeContext,
|
|
659
|
+
inputData: prevOutput,
|
|
660
|
+
runCount: -1,
|
|
661
|
+
tracingContext: {
|
|
662
|
+
currentSpan: sleepSpan
|
|
663
|
+
},
|
|
664
|
+
getInitData: () => stepResults?.input,
|
|
665
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
666
|
+
// TODO: this function shouldn't have suspend probably?
|
|
667
|
+
suspend: async (_suspendPayload) => {
|
|
668
|
+
},
|
|
669
|
+
bail: () => {
|
|
670
|
+
},
|
|
671
|
+
abort: () => {
|
|
672
|
+
abortController?.abort();
|
|
673
|
+
},
|
|
674
|
+
[EMITTER_SYMBOL]: emitter,
|
|
675
|
+
// TODO: add streamVNext support
|
|
676
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
677
|
+
engine: { step: this.inngestStep },
|
|
678
|
+
abortSignal: abortController?.signal,
|
|
679
|
+
writer: new ToolStream(
|
|
680
|
+
{
|
|
681
|
+
prefix: "workflow-step",
|
|
682
|
+
callId: stepCallId,
|
|
683
|
+
name: "sleep",
|
|
684
|
+
runId
|
|
685
|
+
},
|
|
686
|
+
writableStream
|
|
687
|
+
)
|
|
688
|
+
});
|
|
689
|
+
});
|
|
690
|
+
sleepSpan?.update({
|
|
691
|
+
attributes: {
|
|
692
|
+
durationMs: duration
|
|
693
|
+
}
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
try {
|
|
697
|
+
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
698
|
+
sleepSpan?.end();
|
|
699
|
+
} catch (e) {
|
|
700
|
+
sleepSpan?.error({ error: e });
|
|
701
|
+
throw e;
|
|
702
|
+
}
|
|
703
|
+
}
|
|
704
|
+
async executeSleepUntil({
|
|
705
|
+
workflowId,
|
|
706
|
+
runId,
|
|
707
|
+
entry,
|
|
361
708
|
prevOutput,
|
|
709
|
+
stepResults,
|
|
362
710
|
emitter,
|
|
363
|
-
|
|
711
|
+
abortController,
|
|
712
|
+
runtimeContext,
|
|
713
|
+
executionContext,
|
|
714
|
+
writableStream,
|
|
715
|
+
tracingContext
|
|
364
716
|
}) {
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
717
|
+
let { date, fn } = entry;
|
|
718
|
+
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
719
|
+
type: AISpanType.WORKFLOW_SLEEP,
|
|
720
|
+
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
721
|
+
attributes: {
|
|
722
|
+
untilDate: date,
|
|
723
|
+
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
724
|
+
sleepType: fn ? "dynamic" : "fixed"
|
|
725
|
+
},
|
|
726
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
375
727
|
});
|
|
728
|
+
if (fn) {
|
|
729
|
+
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
730
|
+
const stepCallId = randomUUID();
|
|
731
|
+
return await fn({
|
|
732
|
+
runId,
|
|
733
|
+
workflowId,
|
|
734
|
+
mastra: this.mastra,
|
|
735
|
+
runtimeContext,
|
|
736
|
+
inputData: prevOutput,
|
|
737
|
+
runCount: -1,
|
|
738
|
+
tracingContext: {
|
|
739
|
+
currentSpan: sleepUntilSpan
|
|
740
|
+
},
|
|
741
|
+
getInitData: () => stepResults?.input,
|
|
742
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
743
|
+
// TODO: this function shouldn't have suspend probably?
|
|
744
|
+
suspend: async (_suspendPayload) => {
|
|
745
|
+
},
|
|
746
|
+
bail: () => {
|
|
747
|
+
},
|
|
748
|
+
abort: () => {
|
|
749
|
+
abortController?.abort();
|
|
750
|
+
},
|
|
751
|
+
[EMITTER_SYMBOL]: emitter,
|
|
752
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
753
|
+
// TODO: add streamVNext support
|
|
754
|
+
engine: { step: this.inngestStep },
|
|
755
|
+
abortSignal: abortController?.signal,
|
|
756
|
+
writer: new ToolStream(
|
|
757
|
+
{
|
|
758
|
+
prefix: "workflow-step",
|
|
759
|
+
callId: stepCallId,
|
|
760
|
+
name: "sleep",
|
|
761
|
+
runId
|
|
762
|
+
},
|
|
763
|
+
writableStream
|
|
764
|
+
)
|
|
765
|
+
});
|
|
766
|
+
});
|
|
767
|
+
if (date && !(date instanceof Date)) {
|
|
768
|
+
date = new Date(date);
|
|
769
|
+
}
|
|
770
|
+
const time = !date ? 0 : date.getTime() - Date.now();
|
|
771
|
+
sleepUntilSpan?.update({
|
|
772
|
+
attributes: {
|
|
773
|
+
durationMs: Math.max(0, time)
|
|
774
|
+
}
|
|
775
|
+
});
|
|
776
|
+
}
|
|
777
|
+
if (!(date instanceof Date)) {
|
|
778
|
+
sleepUntilSpan?.end();
|
|
779
|
+
return;
|
|
780
|
+
}
|
|
781
|
+
try {
|
|
782
|
+
await this.inngestStep.sleepUntil(entry.id, date);
|
|
783
|
+
sleepUntilSpan?.end();
|
|
784
|
+
} catch (e) {
|
|
785
|
+
sleepUntilSpan?.error({ error: e });
|
|
786
|
+
throw e;
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
async executeWaitForEvent({ event, timeout }) {
|
|
790
|
+
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
791
|
+
event: `user-event-${event}`,
|
|
792
|
+
timeout: timeout ?? 5e3
|
|
793
|
+
});
|
|
794
|
+
if (eventData === null) {
|
|
795
|
+
throw "Timeout waiting for event";
|
|
796
|
+
}
|
|
797
|
+
return eventData?.data;
|
|
376
798
|
}
|
|
377
799
|
async executeStep({
|
|
378
800
|
step,
|
|
@@ -381,11 +803,25 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
381
803
|
resume,
|
|
382
804
|
prevOutput,
|
|
383
805
|
emitter,
|
|
384
|
-
|
|
806
|
+
abortController,
|
|
807
|
+
runtimeContext,
|
|
808
|
+
tracingContext,
|
|
809
|
+
writableStream,
|
|
810
|
+
disableScorers
|
|
385
811
|
}) {
|
|
386
|
-
|
|
812
|
+
const stepAISpan = tracingContext?.currentSpan?.createChildSpan({
|
|
813
|
+
name: `workflow step: '${step.id}'`,
|
|
814
|
+
type: AISpanType.WORKFLOW_STEP,
|
|
815
|
+
input: prevOutput,
|
|
816
|
+
attributes: {
|
|
817
|
+
stepId: step.id
|
|
818
|
+
},
|
|
819
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
820
|
+
});
|
|
821
|
+
const startedAt = await this.inngestStep.run(
|
|
387
822
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
388
823
|
async () => {
|
|
824
|
+
const startedAt2 = Date.now();
|
|
389
825
|
await emitter.emit("watch", {
|
|
390
826
|
type: "watch",
|
|
391
827
|
payload: {
|
|
@@ -407,6 +843,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
407
843
|
},
|
|
408
844
|
eventTimestamp: Date.now()
|
|
409
845
|
});
|
|
846
|
+
await emitter.emit("watch-v2", {
|
|
847
|
+
type: "workflow-step-start",
|
|
848
|
+
payload: {
|
|
849
|
+
id: step.id,
|
|
850
|
+
status: "running",
|
|
851
|
+
payload: prevOutput,
|
|
852
|
+
startedAt: startedAt2
|
|
853
|
+
}
|
|
854
|
+
});
|
|
855
|
+
return startedAt2;
|
|
410
856
|
}
|
|
411
857
|
);
|
|
412
858
|
if (step instanceof InngestWorkflow) {
|
|
@@ -467,6 +913,15 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
467
913
|
},
|
|
468
914
|
eventTimestamp: Date.now()
|
|
469
915
|
});
|
|
916
|
+
await emitter.emit("watch-v2", {
|
|
917
|
+
type: "workflow-step-result",
|
|
918
|
+
payload: {
|
|
919
|
+
id: step.id,
|
|
920
|
+
status: "failed",
|
|
921
|
+
error: result?.error,
|
|
922
|
+
payload: prevOutput
|
|
923
|
+
}
|
|
924
|
+
});
|
|
470
925
|
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
471
926
|
} else if (result.status === "suspended") {
|
|
472
927
|
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
@@ -493,6 +948,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
493
948
|
},
|
|
494
949
|
eventTimestamp: Date.now()
|
|
495
950
|
});
|
|
951
|
+
await emitter.emit("watch-v2", {
|
|
952
|
+
type: "workflow-step-suspended",
|
|
953
|
+
payload: {
|
|
954
|
+
id: step.id,
|
|
955
|
+
status: "suspended"
|
|
956
|
+
}
|
|
957
|
+
});
|
|
496
958
|
return {
|
|
497
959
|
executionContext,
|
|
498
960
|
result: {
|
|
@@ -543,6 +1005,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
543
1005
|
},
|
|
544
1006
|
eventTimestamp: Date.now()
|
|
545
1007
|
});
|
|
1008
|
+
await emitter.emit("watch-v2", {
|
|
1009
|
+
type: "workflow-step-result",
|
|
1010
|
+
payload: {
|
|
1011
|
+
id: step.id,
|
|
1012
|
+
status: "success",
|
|
1013
|
+
output: result?.result
|
|
1014
|
+
}
|
|
1015
|
+
});
|
|
1016
|
+
await emitter.emit("watch-v2", {
|
|
1017
|
+
type: "workflow-step-finish",
|
|
1018
|
+
payload: {
|
|
1019
|
+
id: step.id,
|
|
1020
|
+
metadata: {}
|
|
1021
|
+
}
|
|
1022
|
+
});
|
|
546
1023
|
return { executionContext, result: { status: "success", output: result?.result } };
|
|
547
1024
|
}
|
|
548
1025
|
);
|
|
@@ -552,42 +1029,78 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
552
1029
|
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
553
1030
|
let execResults;
|
|
554
1031
|
let suspended;
|
|
1032
|
+
let bailed;
|
|
555
1033
|
try {
|
|
556
1034
|
const result = await step.execute({
|
|
1035
|
+
runId: executionContext.runId,
|
|
557
1036
|
mastra: this.mastra,
|
|
558
1037
|
runtimeContext,
|
|
1038
|
+
writableStream,
|
|
559
1039
|
inputData: prevOutput,
|
|
560
1040
|
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
const result2 = stepResults[step2.id];
|
|
564
|
-
if (result2?.status === "success") {
|
|
565
|
-
return result2.output;
|
|
566
|
-
}
|
|
567
|
-
return null;
|
|
1041
|
+
tracingContext: {
|
|
1042
|
+
currentSpan: stepAISpan
|
|
568
1043
|
},
|
|
1044
|
+
getInitData: () => stepResults?.input,
|
|
1045
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
569
1046
|
suspend: async (suspendPayload) => {
|
|
570
1047
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
571
1048
|
suspended = { payload: suspendPayload };
|
|
572
1049
|
},
|
|
1050
|
+
bail: (result2) => {
|
|
1051
|
+
bailed = { payload: result2 };
|
|
1052
|
+
},
|
|
573
1053
|
resume: {
|
|
574
1054
|
steps: resume?.steps?.slice(1) || [],
|
|
575
1055
|
resumePayload: resume?.resumePayload,
|
|
576
1056
|
// @ts-ignore
|
|
577
1057
|
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
578
1058
|
},
|
|
579
|
-
emitter
|
|
1059
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1060
|
+
engine: {
|
|
1061
|
+
step: this.inngestStep
|
|
1062
|
+
},
|
|
1063
|
+
abortSignal: abortController.signal
|
|
580
1064
|
});
|
|
581
|
-
|
|
1065
|
+
const endedAt = Date.now();
|
|
1066
|
+
execResults = {
|
|
1067
|
+
status: "success",
|
|
1068
|
+
output: result,
|
|
1069
|
+
startedAt,
|
|
1070
|
+
endedAt,
|
|
1071
|
+
payload: prevOutput,
|
|
1072
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1073
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1074
|
+
};
|
|
582
1075
|
} catch (e) {
|
|
583
|
-
execResults = {
|
|
1076
|
+
execResults = {
|
|
1077
|
+
status: "failed",
|
|
1078
|
+
payload: prevOutput,
|
|
1079
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1080
|
+
endedAt: Date.now(),
|
|
1081
|
+
startedAt,
|
|
1082
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1083
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1084
|
+
};
|
|
584
1085
|
}
|
|
585
1086
|
if (suspended) {
|
|
586
|
-
execResults = {
|
|
1087
|
+
execResults = {
|
|
1088
|
+
status: "suspended",
|
|
1089
|
+
suspendedPayload: suspended.payload,
|
|
1090
|
+
payload: prevOutput,
|
|
1091
|
+
suspendedAt: Date.now(),
|
|
1092
|
+
startedAt,
|
|
1093
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1094
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1095
|
+
};
|
|
1096
|
+
} else if (bailed) {
|
|
1097
|
+
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
587
1098
|
}
|
|
588
1099
|
if (execResults.status === "failed") {
|
|
589
1100
|
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
590
|
-
|
|
1101
|
+
const error = new Error(execResults.error);
|
|
1102
|
+
stepAISpan?.error({ error });
|
|
1103
|
+
throw error;
|
|
591
1104
|
}
|
|
592
1105
|
}
|
|
593
1106
|
await emitter.emit("watch", {
|
|
@@ -595,20 +1108,61 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
595
1108
|
payload: {
|
|
596
1109
|
currentStep: {
|
|
597
1110
|
id: step.id,
|
|
598
|
-
|
|
599
|
-
output: execResults.output
|
|
1111
|
+
...execResults
|
|
600
1112
|
},
|
|
601
1113
|
workflowState: {
|
|
602
1114
|
status: "running",
|
|
603
|
-
steps: stepResults,
|
|
1115
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
604
1116
|
result: null,
|
|
605
1117
|
error: null
|
|
606
1118
|
}
|
|
607
1119
|
},
|
|
608
1120
|
eventTimestamp: Date.now()
|
|
609
1121
|
});
|
|
1122
|
+
if (execResults.status === "suspended") {
|
|
1123
|
+
await emitter.emit("watch-v2", {
|
|
1124
|
+
type: "workflow-step-suspended",
|
|
1125
|
+
payload: {
|
|
1126
|
+
id: step.id,
|
|
1127
|
+
...execResults
|
|
1128
|
+
}
|
|
1129
|
+
});
|
|
1130
|
+
} else {
|
|
1131
|
+
await emitter.emit("watch-v2", {
|
|
1132
|
+
type: "workflow-step-result",
|
|
1133
|
+
payload: {
|
|
1134
|
+
id: step.id,
|
|
1135
|
+
...execResults
|
|
1136
|
+
}
|
|
1137
|
+
});
|
|
1138
|
+
await emitter.emit("watch-v2", {
|
|
1139
|
+
type: "workflow-step-finish",
|
|
1140
|
+
payload: {
|
|
1141
|
+
id: step.id,
|
|
1142
|
+
metadata: {}
|
|
1143
|
+
}
|
|
1144
|
+
});
|
|
1145
|
+
}
|
|
1146
|
+
stepAISpan?.end({ output: execResults });
|
|
610
1147
|
return { result: execResults, executionContext, stepResults };
|
|
611
1148
|
});
|
|
1149
|
+
if (disableScorers !== false) {
|
|
1150
|
+
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1151
|
+
if (step.scorers) {
|
|
1152
|
+
await this.runScorers({
|
|
1153
|
+
scorers: step.scorers,
|
|
1154
|
+
runId: executionContext.runId,
|
|
1155
|
+
input: prevOutput,
|
|
1156
|
+
output: stepRes.result,
|
|
1157
|
+
workflowId: executionContext.workflowId,
|
|
1158
|
+
stepId: step.id,
|
|
1159
|
+
runtimeContext,
|
|
1160
|
+
disableScorers,
|
|
1161
|
+
tracingContext: { currentSpan: stepAISpan }
|
|
1162
|
+
});
|
|
1163
|
+
}
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
612
1166
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
613
1167
|
Object.assign(stepResults, stepRes.stepResults);
|
|
614
1168
|
return stepRes.result;
|
|
@@ -617,7 +1171,12 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
617
1171
|
workflowId,
|
|
618
1172
|
runId,
|
|
619
1173
|
stepResults,
|
|
620
|
-
|
|
1174
|
+
resourceId,
|
|
1175
|
+
executionContext,
|
|
1176
|
+
serializedStepGraph,
|
|
1177
|
+
workflowStatus,
|
|
1178
|
+
result,
|
|
1179
|
+
error
|
|
621
1180
|
}) {
|
|
622
1181
|
await this.inngestStep.run(
|
|
623
1182
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
@@ -625,12 +1184,18 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
625
1184
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
626
1185
|
workflowName: workflowId,
|
|
627
1186
|
runId,
|
|
1187
|
+
resourceId,
|
|
628
1188
|
snapshot: {
|
|
629
1189
|
runId,
|
|
630
1190
|
value: {},
|
|
631
1191
|
context: stepResults,
|
|
632
1192
|
activePaths: [],
|
|
633
1193
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1194
|
+
waitingPaths: {},
|
|
1195
|
+
serializedStepGraph,
|
|
1196
|
+
status: workflowStatus,
|
|
1197
|
+
result,
|
|
1198
|
+
error,
|
|
634
1199
|
// @ts-ignore
|
|
635
1200
|
timestamp: Date.now()
|
|
636
1201
|
}
|
|
@@ -645,50 +1210,109 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
645
1210
|
prevOutput,
|
|
646
1211
|
prevStep,
|
|
647
1212
|
stepResults,
|
|
1213
|
+
serializedStepGraph,
|
|
648
1214
|
resume,
|
|
649
1215
|
executionContext,
|
|
650
1216
|
emitter,
|
|
651
|
-
|
|
1217
|
+
abortController,
|
|
1218
|
+
runtimeContext,
|
|
1219
|
+
writableStream,
|
|
1220
|
+
disableScorers,
|
|
1221
|
+
tracingContext
|
|
652
1222
|
}) {
|
|
1223
|
+
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1224
|
+
type: AISpanType.WORKFLOW_CONDITIONAL,
|
|
1225
|
+
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1226
|
+
input: prevOutput,
|
|
1227
|
+
attributes: {
|
|
1228
|
+
conditionCount: entry.conditions.length
|
|
1229
|
+
},
|
|
1230
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1231
|
+
});
|
|
653
1232
|
let execResults;
|
|
654
1233
|
const truthyIndexes = (await Promise.all(
|
|
655
1234
|
entry.conditions.map(
|
|
656
1235
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1236
|
+
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1237
|
+
type: AISpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1238
|
+
name: `condition: '${index}'`,
|
|
1239
|
+
input: prevOutput,
|
|
1240
|
+
attributes: {
|
|
1241
|
+
conditionIndex: index
|
|
1242
|
+
},
|
|
1243
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1244
|
+
});
|
|
657
1245
|
try {
|
|
658
1246
|
const result = await cond({
|
|
1247
|
+
runId,
|
|
1248
|
+
workflowId,
|
|
659
1249
|
mastra: this.mastra,
|
|
660
1250
|
runtimeContext,
|
|
1251
|
+
runCount: -1,
|
|
661
1252
|
inputData: prevOutput,
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
if (!step?.id) {
|
|
665
|
-
return null;
|
|
666
|
-
}
|
|
667
|
-
const result2 = stepResults[step.id];
|
|
668
|
-
if (result2?.status === "success") {
|
|
669
|
-
return result2.output;
|
|
670
|
-
}
|
|
671
|
-
return null;
|
|
1253
|
+
tracingContext: {
|
|
1254
|
+
currentSpan: evalSpan
|
|
672
1255
|
},
|
|
1256
|
+
getInitData: () => stepResults?.input,
|
|
1257
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
673
1258
|
// TODO: this function shouldn't have suspend probably?
|
|
674
1259
|
suspend: async (_suspendPayload) => {
|
|
675
1260
|
},
|
|
676
|
-
|
|
1261
|
+
bail: () => {
|
|
1262
|
+
},
|
|
1263
|
+
abort: () => {
|
|
1264
|
+
abortController.abort();
|
|
1265
|
+
},
|
|
1266
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1267
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1268
|
+
// TODO: add streamVNext support
|
|
1269
|
+
engine: {
|
|
1270
|
+
step: this.inngestStep
|
|
1271
|
+
},
|
|
1272
|
+
abortSignal: abortController.signal,
|
|
1273
|
+
writer: new ToolStream(
|
|
1274
|
+
{
|
|
1275
|
+
prefix: "workflow-step",
|
|
1276
|
+
callId: randomUUID(),
|
|
1277
|
+
name: "conditional",
|
|
1278
|
+
runId
|
|
1279
|
+
},
|
|
1280
|
+
writableStream
|
|
1281
|
+
)
|
|
1282
|
+
});
|
|
1283
|
+
evalSpan?.end({
|
|
1284
|
+
output: result,
|
|
1285
|
+
attributes: {
|
|
1286
|
+
result: !!result
|
|
1287
|
+
}
|
|
677
1288
|
});
|
|
678
1289
|
return result ? index : null;
|
|
679
1290
|
} catch (e) {
|
|
1291
|
+
evalSpan?.error({
|
|
1292
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1293
|
+
attributes: {
|
|
1294
|
+
result: false
|
|
1295
|
+
}
|
|
1296
|
+
});
|
|
680
1297
|
return null;
|
|
681
1298
|
}
|
|
682
1299
|
})
|
|
683
1300
|
)
|
|
684
1301
|
)).filter((index) => index !== null);
|
|
685
1302
|
const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
|
|
1303
|
+
conditionalSpan?.update({
|
|
1304
|
+
attributes: {
|
|
1305
|
+
truthyIndexes,
|
|
1306
|
+
selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
|
|
1307
|
+
}
|
|
1308
|
+
});
|
|
686
1309
|
const results = await Promise.all(
|
|
687
1310
|
stepsToRun.map(
|
|
688
1311
|
(step, index) => this.executeEntry({
|
|
689
1312
|
workflowId,
|
|
690
1313
|
runId,
|
|
691
1314
|
entry: step,
|
|
1315
|
+
serializedStepGraph,
|
|
692
1316
|
prevStep,
|
|
693
1317
|
stepResults,
|
|
694
1318
|
resume,
|
|
@@ -701,29 +1325,46 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
701
1325
|
executionSpan: executionContext.executionSpan
|
|
702
1326
|
},
|
|
703
1327
|
emitter,
|
|
704
|
-
|
|
1328
|
+
abortController,
|
|
1329
|
+
runtimeContext,
|
|
1330
|
+
writableStream,
|
|
1331
|
+
disableScorers,
|
|
1332
|
+
tracingContext: {
|
|
1333
|
+
currentSpan: conditionalSpan
|
|
1334
|
+
}
|
|
705
1335
|
})
|
|
706
1336
|
)
|
|
707
1337
|
);
|
|
708
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
709
|
-
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1338
|
+
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1339
|
+
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
710
1340
|
if (hasFailed) {
|
|
711
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1341
|
+
execResults = { status: "failed", error: hasFailed.result.error };
|
|
712
1342
|
} else if (hasSuspended) {
|
|
713
|
-
execResults = { status: "suspended", payload: hasSuspended.
|
|
1343
|
+
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
714
1344
|
} else {
|
|
715
1345
|
execResults = {
|
|
716
1346
|
status: "success",
|
|
717
1347
|
output: results.reduce((acc, result, index) => {
|
|
718
|
-
if (result.status === "success") {
|
|
1348
|
+
if (result.result.status === "success") {
|
|
719
1349
|
acc[stepsToRun[index].step.id] = result.output;
|
|
720
1350
|
}
|
|
721
1351
|
return acc;
|
|
722
1352
|
}, {})
|
|
723
1353
|
};
|
|
724
1354
|
}
|
|
1355
|
+
if (execResults.status === "failed") {
|
|
1356
|
+
conditionalSpan?.error({
|
|
1357
|
+
error: new Error(execResults.error)
|
|
1358
|
+
});
|
|
1359
|
+
} else {
|
|
1360
|
+
conditionalSpan?.end({
|
|
1361
|
+
output: execResults.output || execResults
|
|
1362
|
+
});
|
|
1363
|
+
}
|
|
725
1364
|
return execResults;
|
|
726
1365
|
}
|
|
727
1366
|
};
|
|
728
1367
|
|
|
729
|
-
export { InngestExecutionEngine, InngestRun, InngestWorkflow, init, serve };
|
|
1368
|
+
export { InngestExecutionEngine, InngestRun, InngestWorkflow, createStep, init, serve };
|
|
1369
|
+
//# sourceMappingURL=index.js.map
|
|
1370
|
+
//# sourceMappingURL=index.js.map
|