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