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