@mastra/inngest 0.0.0-iterate-traces-ui-again-20250912091900 → 0.0.0-main-test-20251105183450
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 +447 -3
- package/dist/index.cjs +687 -567
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +119 -83
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +688 -568
- package/dist/index.js.map +1 -1
- package/package.json +17 -14
package/dist/index.cjs
CHANGED
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var crypto = require('crypto');
|
|
4
|
+
var web = require('stream/web');
|
|
4
5
|
var realtime = require('@inngest/realtime');
|
|
5
|
-
var aiTracing = require('@mastra/core/ai-tracing');
|
|
6
6
|
var di = require('@mastra/core/di');
|
|
7
|
+
var observability = require('@mastra/core/observability');
|
|
8
|
+
var stream = require('@mastra/core/stream');
|
|
7
9
|
var tools = require('@mastra/core/tools');
|
|
8
10
|
var workflows = require('@mastra/core/workflows');
|
|
9
11
|
var _constants = require('@mastra/core/workflows/_constants');
|
|
12
|
+
var inngest = require('inngest');
|
|
10
13
|
var hono = require('inngest/hono');
|
|
11
14
|
var zod = require('zod');
|
|
12
15
|
|
|
13
16
|
// src/index.ts
|
|
14
|
-
function serve({
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
function serve({
|
|
18
|
+
mastra,
|
|
19
|
+
inngest,
|
|
20
|
+
functions: userFunctions = [],
|
|
21
|
+
registerOptions
|
|
22
|
+
}) {
|
|
23
|
+
const wfs = mastra.listWorkflows();
|
|
24
|
+
const workflowFunctions = Array.from(
|
|
17
25
|
new Set(
|
|
18
26
|
Object.values(wfs).flatMap((wf) => {
|
|
19
27
|
if (wf instanceof InngestWorkflow) {
|
|
@@ -25,8 +33,9 @@ function serve({ mastra, inngest }) {
|
|
|
25
33
|
)
|
|
26
34
|
);
|
|
27
35
|
return hono.serve({
|
|
36
|
+
...registerOptions,
|
|
28
37
|
client: inngest,
|
|
29
|
-
functions
|
|
38
|
+
functions: [...workflowFunctions, ...userFunctions]
|
|
30
39
|
});
|
|
31
40
|
}
|
|
32
41
|
var InngestRun = class extends workflows.Run {
|
|
@@ -50,14 +59,21 @@ var InngestRun = class extends workflows.Run {
|
|
|
50
59
|
}
|
|
51
60
|
async getRunOutput(eventId) {
|
|
52
61
|
let runs = await this.getRuns(eventId);
|
|
62
|
+
const storage = this.#mastra?.getStorage();
|
|
53
63
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
54
64
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
55
65
|
runs = await this.getRuns(eventId);
|
|
56
66
|
if (runs?.[0]?.status === "Failed") {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
67
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
68
|
+
workflowName: this.workflowId,
|
|
69
|
+
runId: this.runId
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
if (runs?.[0]?.status === "Cancelled") {
|
|
76
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
61
77
|
workflowName: this.workflowId,
|
|
62
78
|
runId: this.runId
|
|
63
79
|
});
|
|
@@ -73,20 +89,22 @@ var InngestRun = class extends workflows.Run {
|
|
|
73
89
|
});
|
|
74
90
|
}
|
|
75
91
|
async cancel() {
|
|
92
|
+
const storage = this.#mastra?.getStorage();
|
|
76
93
|
await this.inngest.send({
|
|
77
94
|
name: `cancel.workflow.${this.workflowId}`,
|
|
78
95
|
data: {
|
|
79
96
|
runId: this.runId
|
|
80
97
|
}
|
|
81
98
|
});
|
|
82
|
-
const snapshot = await
|
|
99
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
83
100
|
workflowName: this.workflowId,
|
|
84
101
|
runId: this.runId
|
|
85
102
|
});
|
|
86
103
|
if (snapshot) {
|
|
87
|
-
await
|
|
104
|
+
await storage?.persistWorkflowSnapshot({
|
|
88
105
|
workflowName: this.workflowId,
|
|
89
106
|
runId: this.runId,
|
|
107
|
+
resourceId: this.resourceId,
|
|
90
108
|
snapshot: {
|
|
91
109
|
...snapshot,
|
|
92
110
|
status: "canceled"
|
|
@@ -94,12 +112,20 @@ var InngestRun = class extends workflows.Run {
|
|
|
94
112
|
});
|
|
95
113
|
}
|
|
96
114
|
}
|
|
97
|
-
async start({
|
|
98
|
-
|
|
115
|
+
async start(params) {
|
|
116
|
+
return this._start(params);
|
|
117
|
+
}
|
|
118
|
+
async _start({
|
|
119
|
+
inputData,
|
|
120
|
+
initialState,
|
|
121
|
+
outputOptions,
|
|
122
|
+
tracingOptions,
|
|
123
|
+
format
|
|
99
124
|
}) {
|
|
100
125
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
101
126
|
workflowName: this.workflowId,
|
|
102
127
|
runId: this.runId,
|
|
128
|
+
resourceId: this.resourceId,
|
|
103
129
|
snapshot: {
|
|
104
130
|
runId: this.runId,
|
|
105
131
|
serializedStepGraph: this.serializedStepGraph,
|
|
@@ -107,16 +133,24 @@ var InngestRun = class extends workflows.Run {
|
|
|
107
133
|
context: {},
|
|
108
134
|
activePaths: [],
|
|
109
135
|
suspendedPaths: {},
|
|
136
|
+
resumeLabels: {},
|
|
110
137
|
waitingPaths: {},
|
|
111
138
|
timestamp: Date.now(),
|
|
112
139
|
status: "running"
|
|
113
140
|
}
|
|
114
141
|
});
|
|
142
|
+
const inputDataToUse = await this._validateInput(inputData);
|
|
143
|
+
const initialStateToUse = await this._validateInitialState(initialState ?? {});
|
|
115
144
|
const eventOutput = await this.inngest.send({
|
|
116
145
|
name: `workflow.${this.workflowId}`,
|
|
117
146
|
data: {
|
|
118
|
-
inputData,
|
|
119
|
-
|
|
147
|
+
inputData: inputDataToUse,
|
|
148
|
+
initialState: initialStateToUse,
|
|
149
|
+
runId: this.runId,
|
|
150
|
+
resourceId: this.resourceId,
|
|
151
|
+
outputOptions,
|
|
152
|
+
tracingOptions,
|
|
153
|
+
format
|
|
120
154
|
}
|
|
121
155
|
});
|
|
122
156
|
const eventId = eventOutput.ids[0];
|
|
@@ -145,24 +179,28 @@ var InngestRun = class extends workflows.Run {
|
|
|
145
179
|
return p;
|
|
146
180
|
}
|
|
147
181
|
async _resume(params) {
|
|
182
|
+
const storage = this.#mastra?.getStorage();
|
|
148
183
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
149
184
|
(step) => typeof step === "string" ? step : step?.id
|
|
150
185
|
);
|
|
151
|
-
const snapshot = await
|
|
186
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
152
187
|
workflowName: this.workflowId,
|
|
153
188
|
runId: this.runId
|
|
154
189
|
});
|
|
190
|
+
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
191
|
+
const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
|
|
155
192
|
const eventOutput = await this.inngest.send({
|
|
156
193
|
name: `workflow.${this.workflowId}`,
|
|
157
194
|
data: {
|
|
158
|
-
inputData:
|
|
195
|
+
inputData: resumeDataToUse,
|
|
196
|
+
initialState: snapshot?.value ?? {},
|
|
159
197
|
runId: this.runId,
|
|
160
198
|
workflowId: this.workflowId,
|
|
161
199
|
stepResults: snapshot?.context,
|
|
162
200
|
resume: {
|
|
163
201
|
steps,
|
|
164
202
|
stepResults: snapshot?.context,
|
|
165
|
-
resumePayload:
|
|
203
|
+
resumePayload: resumeDataToUse,
|
|
166
204
|
// @ts-ignore
|
|
167
205
|
resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
|
|
168
206
|
}
|
|
@@ -179,12 +217,12 @@ var InngestRun = class extends workflows.Run {
|
|
|
179
217
|
}
|
|
180
218
|
return result;
|
|
181
219
|
}
|
|
182
|
-
watch(cb
|
|
220
|
+
watch(cb) {
|
|
183
221
|
let active = true;
|
|
184
222
|
const streamPromise = realtime.subscribe(
|
|
185
223
|
{
|
|
186
224
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
187
|
-
topics: [
|
|
225
|
+
topics: ["watch"],
|
|
188
226
|
app: this.inngest
|
|
189
227
|
},
|
|
190
228
|
(message) => {
|
|
@@ -202,44 +240,35 @@ var InngestRun = class extends workflows.Run {
|
|
|
202
240
|
});
|
|
203
241
|
};
|
|
204
242
|
}
|
|
205
|
-
|
|
243
|
+
streamLegacy({ inputData, requestContext } = {}) {
|
|
206
244
|
const { readable, writable } = new TransformStream();
|
|
207
|
-
let currentToolData = void 0;
|
|
208
245
|
const writer = writable.getWriter();
|
|
209
246
|
const unwatch = this.watch(async (event) => {
|
|
210
|
-
|
|
211
|
-
currentToolData = {
|
|
212
|
-
name: event.payload.name,
|
|
213
|
-
args: event.payload.args
|
|
214
|
-
};
|
|
247
|
+
try {
|
|
215
248
|
await writer.write({
|
|
216
|
-
|
|
217
|
-
type: "
|
|
249
|
+
// @ts-ignore
|
|
250
|
+
type: "start",
|
|
251
|
+
// @ts-ignore
|
|
252
|
+
payload: { runId: this.runId }
|
|
218
253
|
});
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
try {
|
|
222
|
-
if (event.type === "workflow-agent-call-finish") {
|
|
223
|
-
return;
|
|
224
|
-
} else if (!event.type.startsWith("workflow-")) {
|
|
225
|
-
if (event.type === "text-delta") {
|
|
226
|
-
await writer.write({
|
|
227
|
-
type: "tool-call-delta",
|
|
228
|
-
...currentToolData ?? {},
|
|
229
|
-
argsTextDelta: event.textDelta
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
254
|
const e = {
|
|
235
255
|
...event,
|
|
236
256
|
type: event.type.replace("workflow-", "")
|
|
237
257
|
};
|
|
258
|
+
if (e.type === "step-output") {
|
|
259
|
+
e.type = e.payload.output.type;
|
|
260
|
+
e.payload = e.payload.output.payload;
|
|
261
|
+
}
|
|
238
262
|
await writer.write(e);
|
|
239
263
|
} catch {
|
|
240
264
|
}
|
|
241
|
-
}
|
|
265
|
+
});
|
|
242
266
|
this.closeStreamAction = async () => {
|
|
267
|
+
await writer.write({
|
|
268
|
+
type: "finish",
|
|
269
|
+
// @ts-ignore
|
|
270
|
+
payload: { runId: this.runId }
|
|
271
|
+
});
|
|
243
272
|
unwatch();
|
|
244
273
|
try {
|
|
245
274
|
await writer.close();
|
|
@@ -249,7 +278,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
249
278
|
writer.releaseLock();
|
|
250
279
|
}
|
|
251
280
|
};
|
|
252
|
-
this.executionResults = this.
|
|
281
|
+
this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
|
|
253
282
|
if (result.status !== "suspended") {
|
|
254
283
|
this.closeStreamAction?.().catch(() => {
|
|
255
284
|
});
|
|
@@ -261,6 +290,82 @@ var InngestRun = class extends workflows.Run {
|
|
|
261
290
|
getWorkflowState: () => this.executionResults
|
|
262
291
|
};
|
|
263
292
|
}
|
|
293
|
+
stream({
|
|
294
|
+
inputData,
|
|
295
|
+
requestContext,
|
|
296
|
+
tracingOptions,
|
|
297
|
+
closeOnSuspend = true,
|
|
298
|
+
initialState,
|
|
299
|
+
outputOptions
|
|
300
|
+
} = {}) {
|
|
301
|
+
if (this.closeStreamAction && this.streamOutput) {
|
|
302
|
+
return this.streamOutput;
|
|
303
|
+
}
|
|
304
|
+
this.closeStreamAction = async () => {
|
|
305
|
+
};
|
|
306
|
+
const self = this;
|
|
307
|
+
const stream$1 = new web.ReadableStream({
|
|
308
|
+
async start(controller) {
|
|
309
|
+
const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
|
|
310
|
+
controller.enqueue({
|
|
311
|
+
type,
|
|
312
|
+
runId: self.runId,
|
|
313
|
+
from,
|
|
314
|
+
payload: {
|
|
315
|
+
stepName: payload?.id,
|
|
316
|
+
...payload
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
self.closeStreamAction = async () => {
|
|
321
|
+
unwatch();
|
|
322
|
+
try {
|
|
323
|
+
await controller.close();
|
|
324
|
+
} catch (err) {
|
|
325
|
+
console.error("Error closing stream:", err);
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
const executionResultsPromise = self._start({
|
|
329
|
+
inputData,
|
|
330
|
+
requestContext,
|
|
331
|
+
// tracingContext, // We are not able to pass a reference to a span here, what to do?
|
|
332
|
+
initialState,
|
|
333
|
+
tracingOptions,
|
|
334
|
+
outputOptions,
|
|
335
|
+
format: "vnext"
|
|
336
|
+
});
|
|
337
|
+
let executionResults;
|
|
338
|
+
try {
|
|
339
|
+
executionResults = await executionResultsPromise;
|
|
340
|
+
if (closeOnSuspend) {
|
|
341
|
+
self.closeStreamAction?.().catch(() => {
|
|
342
|
+
});
|
|
343
|
+
} else if (executionResults.status !== "suspended") {
|
|
344
|
+
self.closeStreamAction?.().catch(() => {
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
if (self.streamOutput) {
|
|
348
|
+
self.streamOutput.updateResults(
|
|
349
|
+
executionResults
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
} catch (err) {
|
|
353
|
+
self.streamOutput?.rejectResults(err);
|
|
354
|
+
self.closeStreamAction?.().catch(() => {
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
this.streamOutput = new stream.WorkflowRunOutput({
|
|
360
|
+
runId: this.runId,
|
|
361
|
+
workflowId: this.workflowId,
|
|
362
|
+
stream: stream$1
|
|
363
|
+
});
|
|
364
|
+
return this.streamOutput;
|
|
365
|
+
}
|
|
366
|
+
streamVNext(args = {}) {
|
|
367
|
+
return this.stream(args);
|
|
368
|
+
}
|
|
264
369
|
};
|
|
265
370
|
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
266
371
|
#mastra;
|
|
@@ -277,13 +382,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
277
382
|
this.#mastra = params.mastra;
|
|
278
383
|
this.inngest = inngest;
|
|
279
384
|
}
|
|
280
|
-
async
|
|
385
|
+
async listWorkflowRuns(args) {
|
|
281
386
|
const storage = this.#mastra?.getStorage();
|
|
282
387
|
if (!storage) {
|
|
283
388
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
284
389
|
return { runs: [], total: 0 };
|
|
285
390
|
}
|
|
286
|
-
return storage.
|
|
391
|
+
return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
287
392
|
}
|
|
288
393
|
async getWorkflowRunById(runId) {
|
|
289
394
|
const storage = this.#mastra?.getStorage();
|
|
@@ -312,45 +417,34 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
312
417
|
}
|
|
313
418
|
}
|
|
314
419
|
}
|
|
315
|
-
createRun(options) {
|
|
316
|
-
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
317
|
-
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
318
|
-
{
|
|
319
|
-
workflowId: this.id,
|
|
320
|
-
runId: runIdToUse,
|
|
321
|
-
executionEngine: this.executionEngine,
|
|
322
|
-
executionGraph: this.executionGraph,
|
|
323
|
-
serializedStepGraph: this.serializedStepGraph,
|
|
324
|
-
mastra: this.#mastra,
|
|
325
|
-
retryConfig: this.retryConfig,
|
|
326
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
327
|
-
},
|
|
328
|
-
this.inngest
|
|
329
|
-
);
|
|
330
|
-
this.runs.set(runIdToUse, run);
|
|
331
|
-
return run;
|
|
332
|
-
}
|
|
333
|
-
async createRunAsync(options) {
|
|
420
|
+
async createRun(options) {
|
|
334
421
|
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
335
422
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
336
423
|
{
|
|
337
424
|
workflowId: this.id,
|
|
338
425
|
runId: runIdToUse,
|
|
426
|
+
resourceId: options?.resourceId,
|
|
339
427
|
executionEngine: this.executionEngine,
|
|
340
428
|
executionGraph: this.executionGraph,
|
|
341
429
|
serializedStepGraph: this.serializedStepGraph,
|
|
342
430
|
mastra: this.#mastra,
|
|
343
431
|
retryConfig: this.retryConfig,
|
|
344
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
432
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
433
|
+
workflowSteps: this.steps
|
|
345
434
|
},
|
|
346
435
|
this.inngest
|
|
347
436
|
);
|
|
348
437
|
this.runs.set(runIdToUse, run);
|
|
438
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
439
|
+
workflowStatus: run.workflowRunStatus,
|
|
440
|
+
stepResults: {}
|
|
441
|
+
});
|
|
349
442
|
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
350
|
-
if (!workflowSnapshotInStorage) {
|
|
443
|
+
if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
|
|
351
444
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
352
445
|
workflowName: this.id,
|
|
353
446
|
runId: runIdToUse,
|
|
447
|
+
resourceId: options?.resourceId,
|
|
354
448
|
snapshot: {
|
|
355
449
|
runId: runIdToUse,
|
|
356
450
|
status: "pending",
|
|
@@ -360,6 +454,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
360
454
|
waitingPaths: {},
|
|
361
455
|
serializedStepGraph: this.serializedStepGraph,
|
|
362
456
|
suspendedPaths: {},
|
|
457
|
+
resumeLabels: {},
|
|
363
458
|
result: void 0,
|
|
364
459
|
error: void 0,
|
|
365
460
|
// @ts-ignore
|
|
@@ -384,7 +479,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
384
479
|
},
|
|
385
480
|
{ event: `workflow.${this.id}` },
|
|
386
481
|
async ({ event, step, attempt, publish }) => {
|
|
387
|
-
let { inputData, runId, resume } = event.data;
|
|
482
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
|
|
388
483
|
if (!runId) {
|
|
389
484
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
390
485
|
return crypto.randomUUID();
|
|
@@ -412,21 +507,38 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
412
507
|
once: (_event, _callback) => {
|
|
413
508
|
}
|
|
414
509
|
};
|
|
415
|
-
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
510
|
+
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
416
511
|
const result = await engine.execute({
|
|
417
512
|
workflowId: this.id,
|
|
418
513
|
runId,
|
|
514
|
+
resourceId,
|
|
419
515
|
graph: this.executionGraph,
|
|
420
516
|
serializedStepGraph: this.serializedStepGraph,
|
|
421
517
|
input: inputData,
|
|
518
|
+
initialState,
|
|
422
519
|
emitter,
|
|
423
520
|
retryConfig: this.retryConfig,
|
|
424
|
-
|
|
521
|
+
requestContext: new di.RequestContext(),
|
|
425
522
|
// TODO
|
|
426
523
|
resume,
|
|
524
|
+
format,
|
|
427
525
|
abortController: new AbortController(),
|
|
428
|
-
currentSpan:
|
|
429
|
-
|
|
526
|
+
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
527
|
+
outputOptions,
|
|
528
|
+
writableStream: new WritableStream({
|
|
529
|
+
write(chunk) {
|
|
530
|
+
void emitter.emit("watch", chunk).catch(() => {
|
|
531
|
+
});
|
|
532
|
+
}
|
|
533
|
+
})
|
|
534
|
+
});
|
|
535
|
+
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
536
|
+
if (result.status === "failed") {
|
|
537
|
+
throw new inngest.NonRetriableError(`Workflow failed`, {
|
|
538
|
+
cause: result
|
|
539
|
+
});
|
|
540
|
+
}
|
|
541
|
+
return result;
|
|
430
542
|
});
|
|
431
543
|
return { result, runId };
|
|
432
544
|
}
|
|
@@ -456,10 +568,11 @@ function isAgent(params) {
|
|
|
456
568
|
function isTool(params) {
|
|
457
569
|
return params instanceof tools.Tool;
|
|
458
570
|
}
|
|
459
|
-
function createStep(params) {
|
|
571
|
+
function createStep(params, agentOptions) {
|
|
460
572
|
if (isAgent(params)) {
|
|
461
573
|
return {
|
|
462
574
|
id: params.name,
|
|
575
|
+
description: params.getDescription(),
|
|
463
576
|
// @ts-ignore
|
|
464
577
|
inputSchema: zod.z.object({
|
|
465
578
|
prompt: zod.z.string()
|
|
@@ -470,7 +583,16 @@ function createStep(params) {
|
|
|
470
583
|
outputSchema: zod.z.object({
|
|
471
584
|
text: zod.z.string()
|
|
472
585
|
}),
|
|
473
|
-
execute: async ({
|
|
586
|
+
execute: async ({
|
|
587
|
+
inputData,
|
|
588
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
589
|
+
[_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
|
|
590
|
+
requestContext,
|
|
591
|
+
tracingContext,
|
|
592
|
+
abortSignal,
|
|
593
|
+
abort,
|
|
594
|
+
writer
|
|
595
|
+
}) => {
|
|
474
596
|
let streamPromise = {};
|
|
475
597
|
streamPromise.promise = new Promise((resolve, reject) => {
|
|
476
598
|
streamPromise.resolve = resolve;
|
|
@@ -480,34 +602,65 @@ function createStep(params) {
|
|
|
480
602
|
name: params.name,
|
|
481
603
|
args: inputData
|
|
482
604
|
};
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
605
|
+
let stream;
|
|
606
|
+
if ((await params.getModel()).specificationVersion === "v1") {
|
|
607
|
+
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
608
|
+
...agentOptions ?? {},
|
|
609
|
+
// resourceId: inputData.resourceId,
|
|
610
|
+
// threadId: inputData.threadId,
|
|
611
|
+
requestContext,
|
|
612
|
+
tracingContext,
|
|
613
|
+
onFinish: (result) => {
|
|
614
|
+
streamPromise.resolve(result.text);
|
|
615
|
+
void agentOptions?.onFinish?.(result);
|
|
616
|
+
},
|
|
617
|
+
abortSignal
|
|
618
|
+
});
|
|
619
|
+
stream = fullStream;
|
|
620
|
+
} else {
|
|
621
|
+
const modelOutput = await params.stream(inputData.prompt, {
|
|
622
|
+
...agentOptions ?? {},
|
|
623
|
+
requestContext,
|
|
624
|
+
tracingContext,
|
|
625
|
+
onFinish: (result) => {
|
|
626
|
+
streamPromise.resolve(result.text);
|
|
627
|
+
void agentOptions?.onFinish?.(result);
|
|
628
|
+
},
|
|
629
|
+
abortSignal
|
|
630
|
+
});
|
|
631
|
+
stream = modelOutput.fullStream;
|
|
632
|
+
}
|
|
633
|
+
if (streamFormat === "legacy") {
|
|
634
|
+
await emitter.emit("watch", {
|
|
635
|
+
type: "tool-call-streaming-start",
|
|
636
|
+
...toolData ?? {}
|
|
637
|
+
});
|
|
638
|
+
for await (const chunk of stream) {
|
|
639
|
+
if (chunk.type === "text-delta") {
|
|
640
|
+
await emitter.emit("watch", {
|
|
641
|
+
type: "tool-call-delta",
|
|
642
|
+
...toolData ?? {},
|
|
643
|
+
argsTextDelta: chunk.textDelta
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
await emitter.emit("watch", {
|
|
648
|
+
type: "tool-call-streaming-finish",
|
|
649
|
+
...toolData ?? {}
|
|
650
|
+
});
|
|
651
|
+
} else {
|
|
652
|
+
for await (const chunk of stream) {
|
|
653
|
+
await writer.write(chunk);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
497
656
|
if (abortSignal.aborted) {
|
|
498
657
|
return abort();
|
|
499
658
|
}
|
|
500
|
-
for await (const chunk of fullStream) {
|
|
501
|
-
await emitter.emit("watch-v2", chunk);
|
|
502
|
-
}
|
|
503
|
-
await emitter.emit("watch-v2", {
|
|
504
|
-
type: "workflow-agent-call-finish",
|
|
505
|
-
payload: toolData
|
|
506
|
-
});
|
|
507
659
|
return {
|
|
508
660
|
text: await streamPromise.promise
|
|
509
661
|
};
|
|
510
|
-
}
|
|
662
|
+
},
|
|
663
|
+
component: params.component
|
|
511
664
|
};
|
|
512
665
|
}
|
|
513
666
|
if (isTool(params)) {
|
|
@@ -518,16 +671,20 @@ function createStep(params) {
|
|
|
518
671
|
// TODO: tool probably should have strong id type
|
|
519
672
|
// @ts-ignore
|
|
520
673
|
id: params.id,
|
|
674
|
+
description: params.description,
|
|
521
675
|
inputSchema: params.inputSchema,
|
|
522
676
|
outputSchema: params.outputSchema,
|
|
523
|
-
execute: async ({ inputData, mastra,
|
|
677
|
+
execute: async ({ inputData, mastra, requestContext, tracingContext, suspend, resumeData }) => {
|
|
524
678
|
return params.execute({
|
|
525
679
|
context: inputData,
|
|
526
|
-
mastra:
|
|
527
|
-
|
|
528
|
-
tracingContext
|
|
680
|
+
mastra: observability.wrapMastra(mastra, tracingContext),
|
|
681
|
+
requestContext,
|
|
682
|
+
tracingContext,
|
|
683
|
+
suspend,
|
|
684
|
+
resumeData
|
|
529
685
|
});
|
|
530
|
-
}
|
|
686
|
+
},
|
|
687
|
+
component: "TOOL"
|
|
531
688
|
};
|
|
532
689
|
}
|
|
533
690
|
return {
|
|
@@ -543,7 +700,10 @@ function createStep(params) {
|
|
|
543
700
|
function init(inngest) {
|
|
544
701
|
return {
|
|
545
702
|
createWorkflow(params) {
|
|
546
|
-
return new InngestWorkflow(
|
|
703
|
+
return new InngestWorkflow(
|
|
704
|
+
params,
|
|
705
|
+
inngest
|
|
706
|
+
);
|
|
547
707
|
},
|
|
548
708
|
createStep,
|
|
549
709
|
cloneStep(step, opts) {
|
|
@@ -552,7 +712,11 @@ function init(inngest) {
|
|
|
552
712
|
description: step.description,
|
|
553
713
|
inputSchema: step.inputSchema,
|
|
554
714
|
outputSchema: step.outputSchema,
|
|
555
|
-
|
|
715
|
+
resumeSchema: step.resumeSchema,
|
|
716
|
+
suspendSchema: step.suspendSchema,
|
|
717
|
+
stateSchema: step.stateSchema,
|
|
718
|
+
execute: step.execute,
|
|
719
|
+
component: step.component
|
|
556
720
|
};
|
|
557
721
|
},
|
|
558
722
|
cloneWorkflow(workflow, opts) {
|
|
@@ -572,78 +736,30 @@ function init(inngest) {
|
|
|
572
736
|
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
573
737
|
inngestStep;
|
|
574
738
|
inngestAttempts;
|
|
575
|
-
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
576
|
-
super({ mastra });
|
|
739
|
+
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
740
|
+
super({ mastra, options });
|
|
577
741
|
this.inngestStep = inngestStep;
|
|
578
742
|
this.inngestAttempts = inngestAttempts;
|
|
579
743
|
}
|
|
580
|
-
async
|
|
581
|
-
await params.emitter.emit("watch-v2", {
|
|
582
|
-
type: "workflow-start",
|
|
583
|
-
payload: { runId: params.runId }
|
|
584
|
-
});
|
|
585
|
-
const result = await super.execute(params);
|
|
586
|
-
await params.emitter.emit("watch-v2", {
|
|
587
|
-
type: "workflow-finish",
|
|
588
|
-
payload: { runId: params.runId }
|
|
589
|
-
});
|
|
590
|
-
return result;
|
|
591
|
-
}
|
|
592
|
-
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
744
|
+
async fmtReturnValue(emitter, stepResults, lastOutput, error) {
|
|
593
745
|
const base = {
|
|
594
746
|
status: lastOutput.status,
|
|
595
747
|
steps: stepResults
|
|
596
748
|
};
|
|
597
749
|
if (lastOutput.status === "success") {
|
|
598
|
-
await emitter.emit("watch", {
|
|
599
|
-
type: "watch",
|
|
600
|
-
payload: {
|
|
601
|
-
workflowState: {
|
|
602
|
-
status: lastOutput.status,
|
|
603
|
-
steps: stepResults,
|
|
604
|
-
result: lastOutput.output
|
|
605
|
-
}
|
|
606
|
-
},
|
|
607
|
-
eventTimestamp: Date.now()
|
|
608
|
-
});
|
|
609
750
|
base.result = lastOutput.output;
|
|
610
751
|
} else if (lastOutput.status === "failed") {
|
|
611
752
|
base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
|
|
612
|
-
await emitter.emit("watch", {
|
|
613
|
-
type: "watch",
|
|
614
|
-
payload: {
|
|
615
|
-
workflowState: {
|
|
616
|
-
status: lastOutput.status,
|
|
617
|
-
steps: stepResults,
|
|
618
|
-
result: null,
|
|
619
|
-
error: base.error
|
|
620
|
-
}
|
|
621
|
-
},
|
|
622
|
-
eventTimestamp: Date.now()
|
|
623
|
-
});
|
|
624
753
|
} else if (lastOutput.status === "suspended") {
|
|
625
|
-
await emitter.emit("watch", {
|
|
626
|
-
type: "watch",
|
|
627
|
-
payload: {
|
|
628
|
-
workflowState: {
|
|
629
|
-
status: lastOutput.status,
|
|
630
|
-
steps: stepResults,
|
|
631
|
-
result: null,
|
|
632
|
-
error: null
|
|
633
|
-
}
|
|
634
|
-
},
|
|
635
|
-
eventTimestamp: Date.now()
|
|
636
|
-
});
|
|
637
754
|
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
638
755
|
if (stepResult?.status === "suspended") {
|
|
639
|
-
const nestedPath = stepResult?.
|
|
756
|
+
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
640
757
|
return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
|
|
641
758
|
}
|
|
642
759
|
return [];
|
|
643
760
|
});
|
|
644
761
|
base.suspended = suspendedStepIds;
|
|
645
762
|
}
|
|
646
|
-
executionSpan?.end();
|
|
647
763
|
return base;
|
|
648
764
|
}
|
|
649
765
|
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
@@ -657,67 +773,71 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
657
773
|
stepResults,
|
|
658
774
|
emitter,
|
|
659
775
|
abortController,
|
|
660
|
-
|
|
776
|
+
requestContext,
|
|
661
777
|
executionContext,
|
|
662
778
|
writableStream,
|
|
663
779
|
tracingContext
|
|
664
780
|
}) {
|
|
665
781
|
let { duration, fn } = entry;
|
|
666
782
|
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
667
|
-
type:
|
|
783
|
+
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
668
784
|
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
669
785
|
attributes: {
|
|
670
786
|
durationMs: duration,
|
|
671
787
|
sleepType: fn ? "dynamic" : "fixed"
|
|
672
|
-
}
|
|
788
|
+
},
|
|
789
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
673
790
|
});
|
|
674
791
|
if (fn) {
|
|
675
792
|
const stepCallId = crypto.randomUUID();
|
|
676
793
|
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
677
|
-
return await fn(
|
|
678
|
-
|
|
679
|
-
workflowId,
|
|
680
|
-
mastra: this.mastra,
|
|
681
|
-
runtimeContext,
|
|
682
|
-
inputData: prevOutput,
|
|
683
|
-
runCount: -1,
|
|
684
|
-
tracingContext: {
|
|
685
|
-
currentSpan: sleepSpan
|
|
686
|
-
},
|
|
687
|
-
getInitData: () => stepResults?.input,
|
|
688
|
-
getStepResult: (step) => {
|
|
689
|
-
if (!step?.id) {
|
|
690
|
-
return null;
|
|
691
|
-
}
|
|
692
|
-
const result = stepResults[step.id];
|
|
693
|
-
if (result?.status === "success") {
|
|
694
|
-
return result.output;
|
|
695
|
-
}
|
|
696
|
-
return null;
|
|
697
|
-
},
|
|
698
|
-
// TODO: this function shouldn't have suspend probably?
|
|
699
|
-
suspend: async (_suspendPayload) => {
|
|
700
|
-
},
|
|
701
|
-
bail: () => {
|
|
702
|
-
},
|
|
703
|
-
abort: () => {
|
|
704
|
-
abortController?.abort();
|
|
705
|
-
},
|
|
706
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
707
|
-
// TODO: add streamVNext support
|
|
708
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
709
|
-
engine: { step: this.inngestStep },
|
|
710
|
-
abortSignal: abortController?.signal,
|
|
711
|
-
writer: new tools.ToolStream(
|
|
794
|
+
return await fn(
|
|
795
|
+
workflows.createDeprecationProxy(
|
|
712
796
|
{
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
797
|
+
runId,
|
|
798
|
+
workflowId,
|
|
799
|
+
mastra: this.mastra,
|
|
800
|
+
requestContext,
|
|
801
|
+
inputData: prevOutput,
|
|
802
|
+
state: executionContext.state,
|
|
803
|
+
setState: (state) => {
|
|
804
|
+
executionContext.state = state;
|
|
805
|
+
},
|
|
806
|
+
retryCount: -1,
|
|
807
|
+
tracingContext: {
|
|
808
|
+
currentSpan: sleepSpan
|
|
809
|
+
},
|
|
810
|
+
getInitData: () => stepResults?.input,
|
|
811
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
812
|
+
// TODO: this function shouldn't have suspend probably?
|
|
813
|
+
suspend: async (_suspendPayload) => {
|
|
814
|
+
},
|
|
815
|
+
bail: () => {
|
|
816
|
+
},
|
|
817
|
+
abort: () => {
|
|
818
|
+
abortController?.abort();
|
|
819
|
+
},
|
|
820
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
821
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
822
|
+
engine: { step: this.inngestStep },
|
|
823
|
+
abortSignal: abortController?.signal,
|
|
824
|
+
writer: new tools.ToolStream(
|
|
825
|
+
{
|
|
826
|
+
prefix: "workflow-step",
|
|
827
|
+
callId: stepCallId,
|
|
828
|
+
name: "sleep",
|
|
829
|
+
runId
|
|
830
|
+
},
|
|
831
|
+
writableStream
|
|
832
|
+
)
|
|
717
833
|
},
|
|
718
|
-
|
|
834
|
+
{
|
|
835
|
+
paramName: "runCount",
|
|
836
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
837
|
+
logger: this.logger
|
|
838
|
+
}
|
|
719
839
|
)
|
|
720
|
-
|
|
840
|
+
);
|
|
721
841
|
});
|
|
722
842
|
sleepSpan?.update({
|
|
723
843
|
attributes: {
|
|
@@ -741,69 +861,76 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
741
861
|
stepResults,
|
|
742
862
|
emitter,
|
|
743
863
|
abortController,
|
|
744
|
-
|
|
864
|
+
requestContext,
|
|
745
865
|
executionContext,
|
|
746
866
|
writableStream,
|
|
747
867
|
tracingContext
|
|
748
868
|
}) {
|
|
749
869
|
let { date, fn } = entry;
|
|
750
870
|
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
751
|
-
type:
|
|
871
|
+
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
752
872
|
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
753
873
|
attributes: {
|
|
754
874
|
untilDate: date,
|
|
755
875
|
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
756
876
|
sleepType: fn ? "dynamic" : "fixed"
|
|
757
|
-
}
|
|
877
|
+
},
|
|
878
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
758
879
|
});
|
|
759
880
|
if (fn) {
|
|
760
881
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
761
882
|
const stepCallId = crypto.randomUUID();
|
|
762
|
-
return await fn(
|
|
763
|
-
|
|
764
|
-
workflowId,
|
|
765
|
-
mastra: this.mastra,
|
|
766
|
-
runtimeContext,
|
|
767
|
-
inputData: prevOutput,
|
|
768
|
-
runCount: -1,
|
|
769
|
-
tracingContext: {
|
|
770
|
-
currentSpan: sleepUntilSpan
|
|
771
|
-
},
|
|
772
|
-
getInitData: () => stepResults?.input,
|
|
773
|
-
getStepResult: (step) => {
|
|
774
|
-
if (!step?.id) {
|
|
775
|
-
return null;
|
|
776
|
-
}
|
|
777
|
-
const result = stepResults[step.id];
|
|
778
|
-
if (result?.status === "success") {
|
|
779
|
-
return result.output;
|
|
780
|
-
}
|
|
781
|
-
return null;
|
|
782
|
-
},
|
|
783
|
-
// TODO: this function shouldn't have suspend probably?
|
|
784
|
-
suspend: async (_suspendPayload) => {
|
|
785
|
-
},
|
|
786
|
-
bail: () => {
|
|
787
|
-
},
|
|
788
|
-
abort: () => {
|
|
789
|
-
abortController?.abort();
|
|
790
|
-
},
|
|
791
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
792
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
793
|
-
// TODO: add streamVNext support
|
|
794
|
-
engine: { step: this.inngestStep },
|
|
795
|
-
abortSignal: abortController?.signal,
|
|
796
|
-
writer: new tools.ToolStream(
|
|
883
|
+
return await fn(
|
|
884
|
+
workflows.createDeprecationProxy(
|
|
797
885
|
{
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
886
|
+
runId,
|
|
887
|
+
workflowId,
|
|
888
|
+
mastra: this.mastra,
|
|
889
|
+
requestContext,
|
|
890
|
+
inputData: prevOutput,
|
|
891
|
+
state: executionContext.state,
|
|
892
|
+
setState: (state) => {
|
|
893
|
+
executionContext.state = state;
|
|
894
|
+
},
|
|
895
|
+
retryCount: -1,
|
|
896
|
+
tracingContext: {
|
|
897
|
+
currentSpan: sleepUntilSpan
|
|
898
|
+
},
|
|
899
|
+
getInitData: () => stepResults?.input,
|
|
900
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
901
|
+
// TODO: this function shouldn't have suspend probably?
|
|
902
|
+
suspend: async (_suspendPayload) => {
|
|
903
|
+
},
|
|
904
|
+
bail: () => {
|
|
905
|
+
},
|
|
906
|
+
abort: () => {
|
|
907
|
+
abortController?.abort();
|
|
908
|
+
},
|
|
909
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
910
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
911
|
+
engine: { step: this.inngestStep },
|
|
912
|
+
abortSignal: abortController?.signal,
|
|
913
|
+
writer: new tools.ToolStream(
|
|
914
|
+
{
|
|
915
|
+
prefix: "workflow-step",
|
|
916
|
+
callId: stepCallId,
|
|
917
|
+
name: "sleep",
|
|
918
|
+
runId
|
|
919
|
+
},
|
|
920
|
+
writableStream
|
|
921
|
+
)
|
|
802
922
|
},
|
|
803
|
-
|
|
923
|
+
{
|
|
924
|
+
paramName: "runCount",
|
|
925
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
926
|
+
logger: this.logger
|
|
927
|
+
}
|
|
804
928
|
)
|
|
805
|
-
|
|
929
|
+
);
|
|
806
930
|
});
|
|
931
|
+
if (date && !(date instanceof Date)) {
|
|
932
|
+
date = new Date(date);
|
|
933
|
+
}
|
|
807
934
|
const time = !date ? 0 : date.getTime() - Date.now();
|
|
808
935
|
sleepUntilSpan?.update({
|
|
809
936
|
attributes: {
|
|
@@ -841,50 +968,35 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
841
968
|
prevOutput,
|
|
842
969
|
emitter,
|
|
843
970
|
abortController,
|
|
844
|
-
|
|
971
|
+
requestContext,
|
|
845
972
|
tracingContext,
|
|
846
973
|
writableStream,
|
|
847
974
|
disableScorers
|
|
848
975
|
}) {
|
|
849
|
-
const
|
|
976
|
+
const stepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
850
977
|
name: `workflow step: '${step.id}'`,
|
|
851
|
-
type:
|
|
978
|
+
type: observability.SpanType.WORKFLOW_STEP,
|
|
852
979
|
input: prevOutput,
|
|
853
980
|
attributes: {
|
|
854
981
|
stepId: step.id
|
|
855
|
-
}
|
|
982
|
+
},
|
|
983
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
984
|
+
});
|
|
985
|
+
const { inputData, validationError } = await workflows.validateStepInput({
|
|
986
|
+
prevOutput,
|
|
987
|
+
step,
|
|
988
|
+
validateInputs: this.options?.validateInputs ?? false
|
|
856
989
|
});
|
|
857
990
|
const startedAt = await this.inngestStep.run(
|
|
858
991
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
859
992
|
async () => {
|
|
860
993
|
const startedAt2 = Date.now();
|
|
861
994
|
await emitter.emit("watch", {
|
|
862
|
-
type: "watch",
|
|
863
|
-
payload: {
|
|
864
|
-
currentStep: {
|
|
865
|
-
id: step.id,
|
|
866
|
-
status: "running"
|
|
867
|
-
},
|
|
868
|
-
workflowState: {
|
|
869
|
-
status: "running",
|
|
870
|
-
steps: {
|
|
871
|
-
...stepResults,
|
|
872
|
-
[step.id]: {
|
|
873
|
-
status: "running"
|
|
874
|
-
}
|
|
875
|
-
},
|
|
876
|
-
result: null,
|
|
877
|
-
error: null
|
|
878
|
-
}
|
|
879
|
-
},
|
|
880
|
-
eventTimestamp: Date.now()
|
|
881
|
-
});
|
|
882
|
-
await emitter.emit("watch-v2", {
|
|
883
995
|
type: "workflow-step-start",
|
|
884
996
|
payload: {
|
|
885
997
|
id: step.id,
|
|
886
998
|
status: "running",
|
|
887
|
-
payload:
|
|
999
|
+
payload: inputData,
|
|
888
1000
|
startedAt: startedAt2
|
|
889
1001
|
}
|
|
890
1002
|
});
|
|
@@ -895,61 +1007,66 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
895
1007
|
const isResume = !!resume?.steps?.length;
|
|
896
1008
|
let result;
|
|
897
1009
|
let runId;
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1010
|
+
try {
|
|
1011
|
+
if (isResume) {
|
|
1012
|
+
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1013
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1014
|
+
workflowName: step.id,
|
|
1015
|
+
runId
|
|
1016
|
+
});
|
|
1017
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1018
|
+
function: step.getFunction(),
|
|
1019
|
+
data: {
|
|
1020
|
+
inputData,
|
|
1021
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
910
1022
|
runId,
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
1023
|
+
resume: {
|
|
1024
|
+
runId,
|
|
1025
|
+
steps: resume.steps.slice(1),
|
|
1026
|
+
stepResults: snapshot?.context,
|
|
1027
|
+
resumePayload: resume.resumePayload,
|
|
1028
|
+
// @ts-ignore
|
|
1029
|
+
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1030
|
+
},
|
|
1031
|
+
outputOptions: { includeState: true }
|
|
916
1032
|
}
|
|
917
|
-
}
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
1033
|
+
});
|
|
1034
|
+
result = invokeResp.result;
|
|
1035
|
+
runId = invokeResp.runId;
|
|
1036
|
+
executionContext.state = invokeResp.result.state;
|
|
1037
|
+
} else {
|
|
1038
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1039
|
+
function: step.getFunction(),
|
|
1040
|
+
data: {
|
|
1041
|
+
inputData,
|
|
1042
|
+
initialState: executionContext.state ?? {},
|
|
1043
|
+
outputOptions: { includeState: true }
|
|
1044
|
+
}
|
|
1045
|
+
});
|
|
1046
|
+
result = invokeResp.result;
|
|
1047
|
+
runId = invokeResp.runId;
|
|
1048
|
+
executionContext.state = invokeResp.result.state;
|
|
1049
|
+
}
|
|
1050
|
+
} catch (e) {
|
|
1051
|
+
const errorCause = e?.cause;
|
|
1052
|
+
if (errorCause && typeof errorCause === "object") {
|
|
1053
|
+
result = errorCause;
|
|
1054
|
+
runId = errorCause.runId || crypto.randomUUID();
|
|
1055
|
+
} else {
|
|
1056
|
+
runId = crypto.randomUUID();
|
|
1057
|
+
result = {
|
|
1058
|
+
status: "failed",
|
|
1059
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1060
|
+
steps: {},
|
|
1061
|
+
input: inputData
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
930
1064
|
}
|
|
931
1065
|
const res = await this.inngestStep.run(
|
|
932
1066
|
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
933
1067
|
async () => {
|
|
934
1068
|
if (result.status === "failed") {
|
|
935
1069
|
await emitter.emit("watch", {
|
|
936
|
-
type: "watch",
|
|
937
|
-
payload: {
|
|
938
|
-
currentStep: {
|
|
939
|
-
id: step.id,
|
|
940
|
-
status: "failed",
|
|
941
|
-
error: result?.error
|
|
942
|
-
},
|
|
943
|
-
workflowState: {
|
|
944
|
-
status: "running",
|
|
945
|
-
steps: stepResults,
|
|
946
|
-
result: null,
|
|
947
|
-
error: null
|
|
948
|
-
}
|
|
949
|
-
},
|
|
950
|
-
eventTimestamp: Date.now()
|
|
951
|
-
});
|
|
952
|
-
await emitter.emit("watch-v2", {
|
|
953
1070
|
type: "workflow-step-result",
|
|
954
1071
|
payload: {
|
|
955
1072
|
id: step.id,
|
|
@@ -965,26 +1082,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
965
1082
|
return stepRes2?.status === "suspended";
|
|
966
1083
|
});
|
|
967
1084
|
for (const [stepName, stepResult] of suspendedSteps) {
|
|
968
|
-
const suspendPath = [stepName, ...stepResult?.
|
|
1085
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
969
1086
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
970
1087
|
await emitter.emit("watch", {
|
|
971
|
-
type: "watch",
|
|
972
|
-
payload: {
|
|
973
|
-
currentStep: {
|
|
974
|
-
id: step.id,
|
|
975
|
-
status: "suspended",
|
|
976
|
-
payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
|
|
977
|
-
},
|
|
978
|
-
workflowState: {
|
|
979
|
-
status: "running",
|
|
980
|
-
steps: stepResults,
|
|
981
|
-
result: null,
|
|
982
|
-
error: null
|
|
983
|
-
}
|
|
984
|
-
},
|
|
985
|
-
eventTimestamp: Date.now()
|
|
986
|
-
});
|
|
987
|
-
await emitter.emit("watch-v2", {
|
|
988
1088
|
type: "workflow-step-suspended",
|
|
989
1089
|
payload: {
|
|
990
1090
|
id: step.id,
|
|
@@ -995,27 +1095,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
995
1095
|
executionContext,
|
|
996
1096
|
result: {
|
|
997
1097
|
status: "suspended",
|
|
998
|
-
payload:
|
|
1098
|
+
payload: stepResult.payload,
|
|
1099
|
+
suspendPayload: {
|
|
1100
|
+
...stepResult?.suspendPayload,
|
|
1101
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1102
|
+
}
|
|
999
1103
|
}
|
|
1000
1104
|
};
|
|
1001
1105
|
}
|
|
1002
|
-
await emitter.emit("watch", {
|
|
1003
|
-
type: "watch",
|
|
1004
|
-
payload: {
|
|
1005
|
-
currentStep: {
|
|
1006
|
-
id: step.id,
|
|
1007
|
-
status: "suspended",
|
|
1008
|
-
payload: {}
|
|
1009
|
-
},
|
|
1010
|
-
workflowState: {
|
|
1011
|
-
status: "running",
|
|
1012
|
-
steps: stepResults,
|
|
1013
|
-
result: null,
|
|
1014
|
-
error: null
|
|
1015
|
-
}
|
|
1016
|
-
},
|
|
1017
|
-
eventTimestamp: Date.now()
|
|
1018
|
-
});
|
|
1019
1106
|
return {
|
|
1020
1107
|
executionContext,
|
|
1021
1108
|
result: {
|
|
@@ -1025,23 +1112,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1025
1112
|
};
|
|
1026
1113
|
}
|
|
1027
1114
|
await emitter.emit("watch", {
|
|
1028
|
-
type: "watch",
|
|
1029
|
-
payload: {
|
|
1030
|
-
currentStep: {
|
|
1031
|
-
id: step.id,
|
|
1032
|
-
status: "success",
|
|
1033
|
-
output: result?.result
|
|
1034
|
-
},
|
|
1035
|
-
workflowState: {
|
|
1036
|
-
status: "running",
|
|
1037
|
-
steps: stepResults,
|
|
1038
|
-
result: null,
|
|
1039
|
-
error: null
|
|
1040
|
-
}
|
|
1041
|
-
},
|
|
1042
|
-
eventTimestamp: Date.now()
|
|
1043
|
-
});
|
|
1044
|
-
await emitter.emit("watch-v2", {
|
|
1045
1115
|
type: "workflow-step-result",
|
|
1046
1116
|
payload: {
|
|
1047
1117
|
id: step.id,
|
|
@@ -1049,7 +1119,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1049
1119
|
output: result?.result
|
|
1050
1120
|
}
|
|
1051
1121
|
});
|
|
1052
|
-
await emitter.emit("watch
|
|
1122
|
+
await emitter.emit("watch", {
|
|
1053
1123
|
type: "workflow-step-finish",
|
|
1054
1124
|
payload: {
|
|
1055
1125
|
id: step.id,
|
|
@@ -1060,159 +1130,196 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1060
1130
|
}
|
|
1061
1131
|
);
|
|
1062
1132
|
Object.assign(executionContext, res.executionContext);
|
|
1063
|
-
return
|
|
1133
|
+
return {
|
|
1134
|
+
...res.result,
|
|
1135
|
+
startedAt,
|
|
1136
|
+
endedAt: Date.now(),
|
|
1137
|
+
payload: inputData,
|
|
1138
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1139
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1140
|
+
};
|
|
1064
1141
|
}
|
|
1065
|
-
const
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1142
|
+
const stepCallId = crypto.randomUUID();
|
|
1143
|
+
let stepRes;
|
|
1144
|
+
try {
|
|
1145
|
+
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1146
|
+
let execResults;
|
|
1147
|
+
let suspended;
|
|
1148
|
+
let bailed;
|
|
1149
|
+
try {
|
|
1150
|
+
if (validationError) {
|
|
1151
|
+
throw validationError;
|
|
1152
|
+
}
|
|
1153
|
+
const result = await step.execute({
|
|
1154
|
+
runId: executionContext.runId,
|
|
1155
|
+
mastra: this.mastra,
|
|
1156
|
+
requestContext,
|
|
1157
|
+
writer: new tools.ToolStream(
|
|
1158
|
+
{
|
|
1159
|
+
prefix: "workflow-step",
|
|
1160
|
+
callId: stepCallId,
|
|
1161
|
+
name: step.id,
|
|
1162
|
+
runId: executionContext.runId
|
|
1163
|
+
},
|
|
1164
|
+
writableStream
|
|
1165
|
+
),
|
|
1166
|
+
state: executionContext?.state ?? {},
|
|
1167
|
+
setState: (state) => {
|
|
1168
|
+
executionContext.state = state;
|
|
1169
|
+
},
|
|
1170
|
+
inputData,
|
|
1171
|
+
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1172
|
+
tracingContext: {
|
|
1173
|
+
currentSpan: stepSpan
|
|
1174
|
+
},
|
|
1175
|
+
getInitData: () => stepResults?.input,
|
|
1176
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1177
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1178
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1179
|
+
if (suspendOptions?.resumeLabel) {
|
|
1180
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1181
|
+
for (const label of resumeLabel) {
|
|
1182
|
+
executionContext.resumeLabels[label] = {
|
|
1183
|
+
stepId: step.id,
|
|
1184
|
+
foreachIndex: executionContext.foreachIndex
|
|
1185
|
+
};
|
|
1186
|
+
}
|
|
1187
|
+
}
|
|
1188
|
+
suspended = { payload: suspendPayload };
|
|
1189
|
+
},
|
|
1190
|
+
bail: (result2) => {
|
|
1191
|
+
bailed = { payload: result2 };
|
|
1192
|
+
},
|
|
1193
|
+
resume: {
|
|
1194
|
+
steps: resume?.steps?.slice(1) || [],
|
|
1195
|
+
resumePayload: resume?.resumePayload,
|
|
1196
|
+
// @ts-ignore
|
|
1197
|
+
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1198
|
+
},
|
|
1199
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1200
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1201
|
+
engine: {
|
|
1202
|
+
step: this.inngestStep
|
|
1203
|
+
},
|
|
1204
|
+
abortSignal: abortController.signal
|
|
1205
|
+
});
|
|
1206
|
+
const endedAt = Date.now();
|
|
1207
|
+
execResults = {
|
|
1208
|
+
status: "success",
|
|
1209
|
+
output: result,
|
|
1210
|
+
startedAt,
|
|
1211
|
+
endedAt,
|
|
1212
|
+
payload: inputData,
|
|
1213
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1214
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1215
|
+
};
|
|
1216
|
+
} catch (e) {
|
|
1217
|
+
const stepFailure = {
|
|
1218
|
+
status: "failed",
|
|
1219
|
+
payload: inputData,
|
|
1220
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1221
|
+
endedAt: Date.now(),
|
|
1222
|
+
startedAt,
|
|
1223
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1224
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1225
|
+
};
|
|
1226
|
+
execResults = stepFailure;
|
|
1227
|
+
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1228
|
+
stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1229
|
+
throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1230
|
+
cause: execResults
|
|
1231
|
+
});
|
|
1232
|
+
}
|
|
1233
|
+
if (suspended) {
|
|
1234
|
+
execResults = {
|
|
1235
|
+
status: "suspended",
|
|
1236
|
+
suspendPayload: suspended.payload,
|
|
1237
|
+
payload: inputData,
|
|
1238
|
+
suspendedAt: Date.now(),
|
|
1239
|
+
startedAt,
|
|
1240
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1241
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1242
|
+
};
|
|
1243
|
+
} else if (bailed) {
|
|
1244
|
+
execResults = {
|
|
1245
|
+
status: "bailed",
|
|
1246
|
+
output: bailed.payload,
|
|
1247
|
+
payload: inputData,
|
|
1248
|
+
endedAt: Date.now(),
|
|
1249
|
+
startedAt
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
if (execResults.status === "suspended") {
|
|
1253
|
+
await emitter.emit("watch", {
|
|
1254
|
+
type: "workflow-step-suspended",
|
|
1255
|
+
payload: {
|
|
1256
|
+
id: step.id,
|
|
1257
|
+
...execResults
|
|
1085
1258
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
}
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
engine: {
|
|
1103
|
-
step: this.inngestStep
|
|
1104
|
-
},
|
|
1105
|
-
abortSignal: abortController.signal
|
|
1106
|
-
});
|
|
1107
|
-
const endedAt = Date.now();
|
|
1108
|
-
execResults = {
|
|
1109
|
-
status: "success",
|
|
1110
|
-
output: result,
|
|
1111
|
-
startedAt,
|
|
1112
|
-
endedAt,
|
|
1113
|
-
payload: prevOutput,
|
|
1114
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1115
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1116
|
-
};
|
|
1117
|
-
} catch (e) {
|
|
1118
|
-
execResults = {
|
|
1119
|
-
status: "failed",
|
|
1120
|
-
payload: prevOutput,
|
|
1121
|
-
error: e instanceof Error ? e.message : String(e),
|
|
1122
|
-
endedAt: Date.now(),
|
|
1123
|
-
startedAt,
|
|
1124
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1125
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1126
|
-
};
|
|
1127
|
-
}
|
|
1128
|
-
if (suspended) {
|
|
1129
|
-
execResults = {
|
|
1130
|
-
status: "suspended",
|
|
1131
|
-
suspendedPayload: suspended.payload,
|
|
1132
|
-
payload: prevOutput,
|
|
1133
|
-
suspendedAt: Date.now(),
|
|
1134
|
-
startedAt,
|
|
1135
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1136
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1137
|
-
};
|
|
1138
|
-
} else if (bailed) {
|
|
1139
|
-
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
1140
|
-
}
|
|
1141
|
-
if (execResults.status === "failed") {
|
|
1142
|
-
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
1143
|
-
const error = new Error(execResults.error);
|
|
1144
|
-
stepAISpan?.error({ error });
|
|
1145
|
-
throw error;
|
|
1259
|
+
});
|
|
1260
|
+
} else {
|
|
1261
|
+
await emitter.emit("watch", {
|
|
1262
|
+
type: "workflow-step-result",
|
|
1263
|
+
payload: {
|
|
1264
|
+
id: step.id,
|
|
1265
|
+
...execResults
|
|
1266
|
+
}
|
|
1267
|
+
});
|
|
1268
|
+
await emitter.emit("watch", {
|
|
1269
|
+
type: "workflow-step-finish",
|
|
1270
|
+
payload: {
|
|
1271
|
+
id: step.id,
|
|
1272
|
+
metadata: {}
|
|
1273
|
+
}
|
|
1274
|
+
});
|
|
1146
1275
|
}
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
type: "watch",
|
|
1150
|
-
payload: {
|
|
1151
|
-
currentStep: {
|
|
1152
|
-
id: step.id,
|
|
1153
|
-
...execResults
|
|
1154
|
-
},
|
|
1155
|
-
workflowState: {
|
|
1156
|
-
status: "running",
|
|
1157
|
-
steps: { ...stepResults, [step.id]: execResults },
|
|
1158
|
-
result: null,
|
|
1159
|
-
error: null
|
|
1160
|
-
}
|
|
1161
|
-
},
|
|
1162
|
-
eventTimestamp: Date.now()
|
|
1276
|
+
stepSpan?.end({ output: execResults });
|
|
1277
|
+
return { result: execResults, executionContext, stepResults };
|
|
1163
1278
|
});
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
payload: {
|
|
1183
|
-
id: step.id,
|
|
1184
|
-
metadata: {}
|
|
1185
|
-
}
|
|
1186
|
-
});
|
|
1187
|
-
}
|
|
1188
|
-
stepAISpan?.end({ output: execResults });
|
|
1189
|
-
return { result: execResults, executionContext, stepResults };
|
|
1190
|
-
});
|
|
1191
|
-
if (disableScorers !== false) {
|
|
1279
|
+
} catch (e) {
|
|
1280
|
+
const stepFailure = e instanceof Error ? e?.cause : {
|
|
1281
|
+
status: "failed",
|
|
1282
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1283
|
+
payload: inputData,
|
|
1284
|
+
startedAt,
|
|
1285
|
+
endedAt: Date.now()
|
|
1286
|
+
};
|
|
1287
|
+
stepRes = {
|
|
1288
|
+
result: stepFailure,
|
|
1289
|
+
executionContext,
|
|
1290
|
+
stepResults: {
|
|
1291
|
+
...stepResults,
|
|
1292
|
+
[step.id]: stepFailure
|
|
1293
|
+
}
|
|
1294
|
+
};
|
|
1295
|
+
}
|
|
1296
|
+
if (disableScorers !== false && stepRes.result.status === "success") {
|
|
1192
1297
|
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1193
1298
|
if (step.scorers) {
|
|
1194
1299
|
await this.runScorers({
|
|
1195
1300
|
scorers: step.scorers,
|
|
1196
1301
|
runId: executionContext.runId,
|
|
1197
|
-
input:
|
|
1302
|
+
input: inputData,
|
|
1198
1303
|
output: stepRes.result,
|
|
1199
1304
|
workflowId: executionContext.workflowId,
|
|
1200
1305
|
stepId: step.id,
|
|
1201
|
-
|
|
1306
|
+
requestContext,
|
|
1202
1307
|
disableScorers,
|
|
1203
|
-
tracingContext: { currentSpan:
|
|
1308
|
+
tracingContext: { currentSpan: stepSpan }
|
|
1204
1309
|
});
|
|
1205
1310
|
}
|
|
1206
1311
|
});
|
|
1207
1312
|
}
|
|
1208
1313
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1209
1314
|
Object.assign(stepResults, stepRes.stepResults);
|
|
1315
|
+
executionContext.state = stepRes.executionContext.state;
|
|
1210
1316
|
return stepRes.result;
|
|
1211
1317
|
}
|
|
1212
1318
|
async persistStepUpdate({
|
|
1213
1319
|
workflowId,
|
|
1214
1320
|
runId,
|
|
1215
1321
|
stepResults,
|
|
1322
|
+
resourceId,
|
|
1216
1323
|
executionContext,
|
|
1217
1324
|
serializedStepGraph,
|
|
1218
1325
|
workflowStatus,
|
|
@@ -1222,15 +1329,21 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1222
1329
|
await this.inngestStep.run(
|
|
1223
1330
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1224
1331
|
async () => {
|
|
1332
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
|
|
1333
|
+
if (!shouldPersistSnapshot) {
|
|
1334
|
+
return;
|
|
1335
|
+
}
|
|
1225
1336
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1226
1337
|
workflowName: workflowId,
|
|
1227
1338
|
runId,
|
|
1339
|
+
resourceId,
|
|
1228
1340
|
snapshot: {
|
|
1229
1341
|
runId,
|
|
1230
|
-
value:
|
|
1342
|
+
value: executionContext.state,
|
|
1231
1343
|
context: stepResults,
|
|
1232
1344
|
activePaths: [],
|
|
1233
1345
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1346
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1234
1347
|
waitingPaths: {},
|
|
1235
1348
|
serializedStepGraph,
|
|
1236
1349
|
status: workflowStatus,
|
|
@@ -1248,85 +1361,88 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1248
1361
|
runId,
|
|
1249
1362
|
entry,
|
|
1250
1363
|
prevOutput,
|
|
1251
|
-
prevStep,
|
|
1252
1364
|
stepResults,
|
|
1253
|
-
serializedStepGraph,
|
|
1254
1365
|
resume,
|
|
1255
1366
|
executionContext,
|
|
1256
1367
|
emitter,
|
|
1257
1368
|
abortController,
|
|
1258
|
-
|
|
1369
|
+
requestContext,
|
|
1259
1370
|
writableStream,
|
|
1260
1371
|
disableScorers,
|
|
1261
1372
|
tracingContext
|
|
1262
1373
|
}) {
|
|
1263
1374
|
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1264
|
-
type:
|
|
1375
|
+
type: observability.SpanType.WORKFLOW_CONDITIONAL,
|
|
1265
1376
|
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1266
1377
|
input: prevOutput,
|
|
1267
1378
|
attributes: {
|
|
1268
1379
|
conditionCount: entry.conditions.length
|
|
1269
|
-
}
|
|
1380
|
+
},
|
|
1381
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1270
1382
|
});
|
|
1271
1383
|
let execResults;
|
|
1272
1384
|
const truthyIndexes = (await Promise.all(
|
|
1273
1385
|
entry.conditions.map(
|
|
1274
1386
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1275
1387
|
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1276
|
-
type:
|
|
1388
|
+
type: observability.SpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1277
1389
|
name: `condition: '${index}'`,
|
|
1278
1390
|
input: prevOutput,
|
|
1279
1391
|
attributes: {
|
|
1280
1392
|
conditionIndex: index
|
|
1281
|
-
}
|
|
1393
|
+
},
|
|
1394
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1282
1395
|
});
|
|
1283
1396
|
try {
|
|
1284
|
-
const result = await cond(
|
|
1285
|
-
|
|
1286
|
-
workflowId,
|
|
1287
|
-
mastra: this.mastra,
|
|
1288
|
-
runtimeContext,
|
|
1289
|
-
runCount: -1,
|
|
1290
|
-
inputData: prevOutput,
|
|
1291
|
-
tracingContext: {
|
|
1292
|
-
currentSpan: evalSpan
|
|
1293
|
-
},
|
|
1294
|
-
getInitData: () => stepResults?.input,
|
|
1295
|
-
getStepResult: (step) => {
|
|
1296
|
-
if (!step?.id) {
|
|
1297
|
-
return null;
|
|
1298
|
-
}
|
|
1299
|
-
const result2 = stepResults[step.id];
|
|
1300
|
-
if (result2?.status === "success") {
|
|
1301
|
-
return result2.output;
|
|
1302
|
-
}
|
|
1303
|
-
return null;
|
|
1304
|
-
},
|
|
1305
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1306
|
-
suspend: async (_suspendPayload) => {
|
|
1307
|
-
},
|
|
1308
|
-
bail: () => {
|
|
1309
|
-
},
|
|
1310
|
-
abort: () => {
|
|
1311
|
-
abortController.abort();
|
|
1312
|
-
},
|
|
1313
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1314
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1315
|
-
// TODO: add streamVNext support
|
|
1316
|
-
engine: {
|
|
1317
|
-
step: this.inngestStep
|
|
1318
|
-
},
|
|
1319
|
-
abortSignal: abortController.signal,
|
|
1320
|
-
writer: new tools.ToolStream(
|
|
1397
|
+
const result = await cond(
|
|
1398
|
+
workflows.createDeprecationProxy(
|
|
1321
1399
|
{
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1400
|
+
runId,
|
|
1401
|
+
workflowId,
|
|
1402
|
+
mastra: this.mastra,
|
|
1403
|
+
requestContext,
|
|
1404
|
+
retryCount: -1,
|
|
1405
|
+
inputData: prevOutput,
|
|
1406
|
+
state: executionContext.state,
|
|
1407
|
+
setState: (state) => {
|
|
1408
|
+
executionContext.state = state;
|
|
1409
|
+
},
|
|
1410
|
+
tracingContext: {
|
|
1411
|
+
currentSpan: evalSpan
|
|
1412
|
+
},
|
|
1413
|
+
getInitData: () => stepResults?.input,
|
|
1414
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1415
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1416
|
+
suspend: async (_suspendPayload) => {
|
|
1417
|
+
},
|
|
1418
|
+
bail: () => {
|
|
1419
|
+
},
|
|
1420
|
+
abort: () => {
|
|
1421
|
+
abortController.abort();
|
|
1422
|
+
},
|
|
1423
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1424
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1425
|
+
engine: {
|
|
1426
|
+
step: this.inngestStep
|
|
1427
|
+
},
|
|
1428
|
+
abortSignal: abortController.signal,
|
|
1429
|
+
writer: new tools.ToolStream(
|
|
1430
|
+
{
|
|
1431
|
+
prefix: "workflow-step",
|
|
1432
|
+
callId: crypto.randomUUID(),
|
|
1433
|
+
name: "conditional",
|
|
1434
|
+
runId
|
|
1435
|
+
},
|
|
1436
|
+
writableStream
|
|
1437
|
+
)
|
|
1326
1438
|
},
|
|
1327
|
-
|
|
1439
|
+
{
|
|
1440
|
+
paramName: "runCount",
|
|
1441
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1442
|
+
logger: this.logger
|
|
1443
|
+
}
|
|
1328
1444
|
)
|
|
1329
|
-
|
|
1445
|
+
);
|
|
1330
1446
|
evalSpan?.end({
|
|
1331
1447
|
output: result,
|
|
1332
1448
|
attributes: {
|
|
@@ -1354,13 +1470,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1354
1470
|
}
|
|
1355
1471
|
});
|
|
1356
1472
|
const results = await Promise.all(
|
|
1357
|
-
stepsToRun.map(
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1473
|
+
stepsToRun.map(async (step, index) => {
|
|
1474
|
+
const currStepResult = stepResults[step.step.id];
|
|
1475
|
+
if (currStepResult && currStepResult.status === "success") {
|
|
1476
|
+
return currStepResult;
|
|
1477
|
+
}
|
|
1478
|
+
const result = await this.executeStep({
|
|
1479
|
+
step: step.step,
|
|
1480
|
+
prevOutput,
|
|
1364
1481
|
stepResults,
|
|
1365
1482
|
resume,
|
|
1366
1483
|
executionContext: {
|
|
@@ -1368,31 +1485,34 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1368
1485
|
runId,
|
|
1369
1486
|
executionPath: [...executionContext.executionPath, index],
|
|
1370
1487
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1488
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1371
1489
|
retryConfig: executionContext.retryConfig,
|
|
1372
|
-
|
|
1490
|
+
state: executionContext.state
|
|
1373
1491
|
},
|
|
1374
1492
|
emitter,
|
|
1375
1493
|
abortController,
|
|
1376
|
-
|
|
1494
|
+
requestContext,
|
|
1377
1495
|
writableStream,
|
|
1378
1496
|
disableScorers,
|
|
1379
1497
|
tracingContext: {
|
|
1380
1498
|
currentSpan: conditionalSpan
|
|
1381
1499
|
}
|
|
1382
|
-
})
|
|
1383
|
-
|
|
1500
|
+
});
|
|
1501
|
+
stepResults[step.step.id] = result;
|
|
1502
|
+
return result;
|
|
1503
|
+
})
|
|
1384
1504
|
);
|
|
1385
|
-
const hasFailed = results.find((result) => result.
|
|
1386
|
-
const hasSuspended = results.find((result) => result.
|
|
1505
|
+
const hasFailed = results.find((result) => result.status === "failed");
|
|
1506
|
+
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1387
1507
|
if (hasFailed) {
|
|
1388
|
-
execResults = { status: "failed", error: hasFailed.
|
|
1508
|
+
execResults = { status: "failed", error: hasFailed.error };
|
|
1389
1509
|
} else if (hasSuspended) {
|
|
1390
|
-
execResults = { status: "suspended",
|
|
1510
|
+
execResults = { status: "suspended", suspendPayload: hasSuspended.suspendPayload };
|
|
1391
1511
|
} else {
|
|
1392
1512
|
execResults = {
|
|
1393
1513
|
status: "success",
|
|
1394
1514
|
output: results.reduce((acc, result, index) => {
|
|
1395
|
-
if (result.
|
|
1515
|
+
if (result.status === "success") {
|
|
1396
1516
|
acc[stepsToRun[index].step.id] = result.output;
|
|
1397
1517
|
}
|
|
1398
1518
|
return acc;
|