@mastra/inngest 0.0.0-monorepo-binary-20251013210052 → 0.0.0-netlify-no-bundle-20251127120354
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 +475 -3
- package/dist/index.cjs +681 -435
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +122 -83
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +683 -437
- package/dist/index.js.map +1 -1
- package/package.json +20 -15
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
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');
|
|
@@ -18,7 +20,7 @@ function serve({
|
|
|
18
20
|
functions: userFunctions = [],
|
|
19
21
|
registerOptions
|
|
20
22
|
}) {
|
|
21
|
-
const wfs = mastra.
|
|
23
|
+
const wfs = mastra.listWorkflows();
|
|
22
24
|
const workflowFunctions = Array.from(
|
|
23
25
|
new Set(
|
|
24
26
|
Object.values(wfs).flatMap((wf) => {
|
|
@@ -57,11 +59,12 @@ var InngestRun = class extends workflows.Run {
|
|
|
57
59
|
}
|
|
58
60
|
async getRunOutput(eventId) {
|
|
59
61
|
let runs = await this.getRuns(eventId);
|
|
62
|
+
const storage = this.#mastra?.getStorage();
|
|
60
63
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
61
64
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
62
65
|
runs = await this.getRuns(eventId);
|
|
63
66
|
if (runs?.[0]?.status === "Failed") {
|
|
64
|
-
const snapshot = await
|
|
67
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
65
68
|
workflowName: this.workflowId,
|
|
66
69
|
runId: this.runId
|
|
67
70
|
});
|
|
@@ -70,7 +73,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
70
73
|
};
|
|
71
74
|
}
|
|
72
75
|
if (runs?.[0]?.status === "Cancelled") {
|
|
73
|
-
const snapshot = await
|
|
76
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
74
77
|
workflowName: this.workflowId,
|
|
75
78
|
runId: this.runId
|
|
76
79
|
});
|
|
@@ -79,38 +82,40 @@ var InngestRun = class extends workflows.Run {
|
|
|
79
82
|
}
|
|
80
83
|
return runs?.[0];
|
|
81
84
|
}
|
|
82
|
-
async sendEvent(event, data) {
|
|
83
|
-
await this.inngest.send({
|
|
84
|
-
name: `user-event-${event}`,
|
|
85
|
-
data
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
85
|
async cancel() {
|
|
86
|
+
const storage = this.#mastra?.getStorage();
|
|
89
87
|
await this.inngest.send({
|
|
90
88
|
name: `cancel.workflow.${this.workflowId}`,
|
|
91
89
|
data: {
|
|
92
90
|
runId: this.runId
|
|
93
91
|
}
|
|
94
92
|
});
|
|
95
|
-
const snapshot = await
|
|
93
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
96
94
|
workflowName: this.workflowId,
|
|
97
95
|
runId: this.runId
|
|
98
96
|
});
|
|
99
97
|
if (snapshot) {
|
|
100
|
-
await
|
|
98
|
+
await storage?.persistWorkflowSnapshot({
|
|
101
99
|
workflowName: this.workflowId,
|
|
102
100
|
runId: this.runId,
|
|
103
101
|
resourceId: this.resourceId,
|
|
104
102
|
snapshot: {
|
|
105
103
|
...snapshot,
|
|
106
|
-
status: "canceled"
|
|
104
|
+
status: "canceled",
|
|
105
|
+
value: snapshot.value
|
|
107
106
|
}
|
|
108
107
|
});
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
|
-
async start({
|
|
110
|
+
async start(params) {
|
|
111
|
+
return this._start(params);
|
|
112
|
+
}
|
|
113
|
+
async _start({
|
|
112
114
|
inputData,
|
|
113
|
-
initialState
|
|
115
|
+
initialState,
|
|
116
|
+
outputOptions,
|
|
117
|
+
tracingOptions,
|
|
118
|
+
format
|
|
114
119
|
}) {
|
|
115
120
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
116
121
|
workflowName: this.workflowId,
|
|
@@ -119,13 +124,15 @@ var InngestRun = class extends workflows.Run {
|
|
|
119
124
|
snapshot: {
|
|
120
125
|
runId: this.runId,
|
|
121
126
|
serializedStepGraph: this.serializedStepGraph,
|
|
127
|
+
status: "running",
|
|
122
128
|
value: {},
|
|
123
129
|
context: {},
|
|
124
130
|
activePaths: [],
|
|
125
131
|
suspendedPaths: {},
|
|
132
|
+
activeStepsPath: {},
|
|
133
|
+
resumeLabels: {},
|
|
126
134
|
waitingPaths: {},
|
|
127
|
-
timestamp: Date.now()
|
|
128
|
-
status: "running"
|
|
135
|
+
timestamp: Date.now()
|
|
129
136
|
}
|
|
130
137
|
});
|
|
131
138
|
const inputDataToUse = await this._validateInput(inputData);
|
|
@@ -136,7 +143,10 @@ var InngestRun = class extends workflows.Run {
|
|
|
136
143
|
inputData: inputDataToUse,
|
|
137
144
|
initialState: initialStateToUse,
|
|
138
145
|
runId: this.runId,
|
|
139
|
-
resourceId: this.resourceId
|
|
146
|
+
resourceId: this.resourceId,
|
|
147
|
+
outputOptions,
|
|
148
|
+
tracingOptions,
|
|
149
|
+
format
|
|
140
150
|
}
|
|
141
151
|
});
|
|
142
152
|
const eventId = eventOutput.ids[0];
|
|
@@ -165,10 +175,16 @@ var InngestRun = class extends workflows.Run {
|
|
|
165
175
|
return p;
|
|
166
176
|
}
|
|
167
177
|
async _resume(params) {
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
)
|
|
171
|
-
|
|
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({
|
|
172
188
|
workflowName: this.workflowId,
|
|
173
189
|
runId: this.runId
|
|
174
190
|
});
|
|
@@ -186,8 +202,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
186
202
|
steps,
|
|
187
203
|
stepResults: snapshot?.context,
|
|
188
204
|
resumePayload: resumeDataToUse,
|
|
189
|
-
|
|
190
|
-
resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
|
|
205
|
+
resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
|
|
191
206
|
}
|
|
192
207
|
}
|
|
193
208
|
});
|
|
@@ -202,12 +217,103 @@ var InngestRun = class extends workflows.Run {
|
|
|
202
217
|
}
|
|
203
218
|
return result;
|
|
204
219
|
}
|
|
205
|
-
|
|
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()
|
|
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
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
const eventId = eventOutput.ids[0];
|
|
301
|
+
if (!eventId) {
|
|
302
|
+
throw new Error("Event ID is not set");
|
|
303
|
+
}
|
|
304
|
+
const runOutput = await this.getRunOutput(eventId);
|
|
305
|
+
const result = runOutput?.output?.result;
|
|
306
|
+
if (result.status === "failed") {
|
|
307
|
+
result.error = new Error(result.error);
|
|
308
|
+
}
|
|
309
|
+
return result;
|
|
310
|
+
}
|
|
311
|
+
watch(cb) {
|
|
206
312
|
let active = true;
|
|
207
313
|
const streamPromise = realtime.subscribe(
|
|
208
314
|
{
|
|
209
315
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
210
|
-
topics: [
|
|
316
|
+
topics: ["watch"],
|
|
211
317
|
app: this.inngest
|
|
212
318
|
},
|
|
213
319
|
(message) => {
|
|
@@ -225,20 +331,35 @@ var InngestRun = class extends workflows.Run {
|
|
|
225
331
|
});
|
|
226
332
|
};
|
|
227
333
|
}
|
|
228
|
-
|
|
334
|
+
streamLegacy({ inputData, requestContext } = {}) {
|
|
229
335
|
const { readable, writable } = new TransformStream();
|
|
230
336
|
const writer = writable.getWriter();
|
|
337
|
+
void writer.write({
|
|
338
|
+
// @ts-ignore
|
|
339
|
+
type: "start",
|
|
340
|
+
// @ts-ignore
|
|
341
|
+
payload: { runId: this.runId }
|
|
342
|
+
});
|
|
231
343
|
const unwatch = this.watch(async (event) => {
|
|
232
344
|
try {
|
|
233
345
|
const e = {
|
|
234
346
|
...event,
|
|
235
347
|
type: event.type.replace("workflow-", "")
|
|
236
348
|
};
|
|
349
|
+
if (e.type === "step-output") {
|
|
350
|
+
e.type = e.payload.output.type;
|
|
351
|
+
e.payload = e.payload.output.payload;
|
|
352
|
+
}
|
|
237
353
|
await writer.write(e);
|
|
238
354
|
} catch {
|
|
239
355
|
}
|
|
240
|
-
}
|
|
356
|
+
});
|
|
241
357
|
this.closeStreamAction = async () => {
|
|
358
|
+
await writer.write({
|
|
359
|
+
type: "finish",
|
|
360
|
+
// @ts-ignore
|
|
361
|
+
payload: { runId: this.runId }
|
|
362
|
+
});
|
|
242
363
|
unwatch();
|
|
243
364
|
try {
|
|
244
365
|
await writer.close();
|
|
@@ -248,7 +369,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
248
369
|
writer.releaseLock();
|
|
249
370
|
}
|
|
250
371
|
};
|
|
251
|
-
this.executionResults = this.
|
|
372
|
+
this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
|
|
252
373
|
if (result.status !== "suspended") {
|
|
253
374
|
this.closeStreamAction?.().catch(() => {
|
|
254
375
|
});
|
|
@@ -260,6 +381,151 @@ var InngestRun = class extends workflows.Run {
|
|
|
260
381
|
getWorkflowState: () => this.executionResults
|
|
261
382
|
};
|
|
262
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
|
+
}
|
|
263
529
|
};
|
|
264
530
|
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
265
531
|
#mastra;
|
|
@@ -269,6 +535,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
269
535
|
constructor(params, inngest) {
|
|
270
536
|
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
271
537
|
super(workflowParams);
|
|
538
|
+
this.engineType = "inngest";
|
|
272
539
|
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
273
540
|
([_, value]) => value !== void 0
|
|
274
541
|
);
|
|
@@ -276,13 +543,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
276
543
|
this.#mastra = params.mastra;
|
|
277
544
|
this.inngest = inngest;
|
|
278
545
|
}
|
|
279
|
-
async
|
|
546
|
+
async listWorkflowRuns(args) {
|
|
280
547
|
const storage = this.#mastra?.getStorage();
|
|
281
548
|
if (!storage) {
|
|
282
549
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
283
550
|
return { runs: [], total: 0 };
|
|
284
551
|
}
|
|
285
|
-
return storage.
|
|
552
|
+
return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
286
553
|
}
|
|
287
554
|
async getWorkflowRunById(runId) {
|
|
288
555
|
const storage = this.#mastra?.getStorage();
|
|
@@ -311,16 +578,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
311
578
|
}
|
|
312
579
|
}
|
|
313
580
|
}
|
|
314
|
-
|
|
315
|
-
* @deprecated Use createRunAsync() instead.
|
|
316
|
-
* @throws {Error} Always throws an error directing users to use createRunAsync()
|
|
317
|
-
*/
|
|
318
|
-
createRun(_options) {
|
|
319
|
-
throw new Error(
|
|
320
|
-
"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."
|
|
321
|
-
);
|
|
322
|
-
}
|
|
323
|
-
async createRunAsync(options) {
|
|
581
|
+
async createRun(options) {
|
|
324
582
|
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
325
583
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
326
584
|
{
|
|
@@ -333,7 +591,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
333
591
|
mastra: this.#mastra,
|
|
334
592
|
retryConfig: this.retryConfig,
|
|
335
593
|
cleanup: () => this.runs.delete(runIdToUse),
|
|
336
|
-
workflowSteps: this.steps
|
|
594
|
+
workflowSteps: this.steps,
|
|
595
|
+
workflowEngineType: this.engineType,
|
|
596
|
+
validateInputs: this.options.validateInputs
|
|
337
597
|
},
|
|
338
598
|
this.inngest
|
|
339
599
|
);
|
|
@@ -354,12 +614,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
354
614
|
value: {},
|
|
355
615
|
context: {},
|
|
356
616
|
activePaths: [],
|
|
617
|
+
activeStepsPath: {},
|
|
357
618
|
waitingPaths: {},
|
|
358
619
|
serializedStepGraph: this.serializedStepGraph,
|
|
359
620
|
suspendedPaths: {},
|
|
621
|
+
resumeLabels: {},
|
|
360
622
|
result: void 0,
|
|
361
623
|
error: void 0,
|
|
362
|
-
// @ts-ignore
|
|
363
624
|
timestamp: Date.now()
|
|
364
625
|
}
|
|
365
626
|
});
|
|
@@ -373,15 +634,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
373
634
|
this.function = this.inngest.createFunction(
|
|
374
635
|
{
|
|
375
636
|
id: `workflow.${this.id}`,
|
|
376
|
-
|
|
377
|
-
retries: this.retryConfig?.attempts ?? 0,
|
|
637
|
+
retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
|
|
378
638
|
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
379
639
|
// Spread flow control configuration
|
|
380
640
|
...this.flowControlConfig
|
|
381
641
|
},
|
|
382
642
|
{ event: `workflow.${this.id}` },
|
|
383
643
|
async ({ event, step, attempt, publish }) => {
|
|
384
|
-
let { inputData, initialState, runId, resourceId, resume, outputOptions } = event.data;
|
|
644
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
|
|
385
645
|
if (!runId) {
|
|
386
646
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
387
647
|
return crypto.randomUUID();
|
|
@@ -420,13 +680,20 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
420
680
|
initialState,
|
|
421
681
|
emitter,
|
|
422
682
|
retryConfig: this.retryConfig,
|
|
423
|
-
|
|
683
|
+
requestContext: new di.RequestContext(),
|
|
424
684
|
// TODO
|
|
425
685
|
resume,
|
|
686
|
+
timeTravel,
|
|
687
|
+
format,
|
|
426
688
|
abortController: new AbortController(),
|
|
427
|
-
currentSpan:
|
|
428
|
-
|
|
429
|
-
|
|
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
|
+
})
|
|
430
697
|
});
|
|
431
698
|
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
432
699
|
if (result.status === "failed") {
|
|
@@ -464,20 +731,29 @@ function isAgent(params) {
|
|
|
464
731
|
function isTool(params) {
|
|
465
732
|
return params instanceof tools.Tool;
|
|
466
733
|
}
|
|
467
|
-
function createStep(params) {
|
|
734
|
+
function createStep(params, agentOptions) {
|
|
468
735
|
if (isAgent(params)) {
|
|
469
736
|
return {
|
|
470
737
|
id: params.name,
|
|
471
738
|
description: params.getDescription(),
|
|
472
|
-
// @ts-ignore
|
|
473
739
|
inputSchema: zod.z.object({
|
|
474
740
|
prompt: zod.z.string()
|
|
741
|
+
// resourceId: z.string().optional(),
|
|
742
|
+
// threadId: z.string().optional(),
|
|
475
743
|
}),
|
|
476
|
-
// @ts-ignore
|
|
477
744
|
outputSchema: zod.z.object({
|
|
478
745
|
text: zod.z.string()
|
|
479
746
|
}),
|
|
480
|
-
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
|
+
}) => {
|
|
481
757
|
let streamPromise = {};
|
|
482
758
|
streamPromise.promise = new Promise((resolve, reject) => {
|
|
483
759
|
streamPromise.resolve = resolve;
|
|
@@ -487,61 +763,60 @@ function createStep(params) {
|
|
|
487
763
|
name: params.name,
|
|
488
764
|
args: inputData
|
|
489
765
|
};
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
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,
|
|
493
773
|
tracingContext,
|
|
494
774
|
onFinish: (result) => {
|
|
495
775
|
streamPromise.resolve(result.text);
|
|
776
|
+
void agentOptions?.onFinish?.(result);
|
|
496
777
|
},
|
|
497
778
|
abortSignal
|
|
498
779
|
});
|
|
499
|
-
|
|
500
|
-
return abort();
|
|
501
|
-
}
|
|
502
|
-
await emitter.emit("watch-v2", {
|
|
503
|
-
type: "tool-call-streaming-start",
|
|
504
|
-
...toolData ?? {}
|
|
505
|
-
});
|
|
506
|
-
for await (const chunk of fullStream) {
|
|
507
|
-
if (chunk.type === "text-delta") {
|
|
508
|
-
await emitter.emit("watch-v2", {
|
|
509
|
-
type: "tool-call-delta",
|
|
510
|
-
...toolData ?? {},
|
|
511
|
-
argsTextDelta: chunk.payload.text
|
|
512
|
-
});
|
|
513
|
-
}
|
|
514
|
-
}
|
|
780
|
+
stream = fullStream;
|
|
515
781
|
} else {
|
|
516
|
-
const
|
|
517
|
-
|
|
782
|
+
const modelOutput = await params.stream(inputData.prompt, {
|
|
783
|
+
...agentOptions ?? {},
|
|
784
|
+
requestContext,
|
|
518
785
|
tracingContext,
|
|
519
786
|
onFinish: (result) => {
|
|
520
787
|
streamPromise.resolve(result.text);
|
|
788
|
+
void agentOptions?.onFinish?.(result);
|
|
521
789
|
},
|
|
522
790
|
abortSignal
|
|
523
791
|
});
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
await emitter.emit("watch
|
|
792
|
+
stream = modelOutput.fullStream;
|
|
793
|
+
}
|
|
794
|
+
if (streamFormat === "legacy") {
|
|
795
|
+
await emitter.emit("watch", {
|
|
528
796
|
type: "tool-call-streaming-start",
|
|
529
797
|
...toolData ?? {}
|
|
530
798
|
});
|
|
531
|
-
for await (const chunk of
|
|
799
|
+
for await (const chunk of stream) {
|
|
532
800
|
if (chunk.type === "text-delta") {
|
|
533
|
-
await emitter.emit("watch
|
|
801
|
+
await emitter.emit("watch", {
|
|
534
802
|
type: "tool-call-delta",
|
|
535
803
|
...toolData ?? {},
|
|
536
804
|
argsTextDelta: chunk.textDelta
|
|
537
805
|
});
|
|
538
806
|
}
|
|
539
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);
|
|
815
|
+
}
|
|
816
|
+
}
|
|
817
|
+
if (abortSignal.aborted) {
|
|
818
|
+
return abort();
|
|
540
819
|
}
|
|
541
|
-
await emitter.emit("watch-v2", {
|
|
542
|
-
type: "tool-call-streaming-finish",
|
|
543
|
-
...toolData ?? {}
|
|
544
|
-
});
|
|
545
820
|
return {
|
|
546
821
|
text: await streamPromise.promise
|
|
547
822
|
};
|
|
@@ -555,20 +830,38 @@ function createStep(params) {
|
|
|
555
830
|
}
|
|
556
831
|
return {
|
|
557
832
|
// TODO: tool probably should have strong id type
|
|
558
|
-
// @ts-ignore
|
|
559
833
|
id: params.id,
|
|
560
834
|
description: params.description,
|
|
561
835
|
inputSchema: params.inputSchema,
|
|
562
836
|
outputSchema: params.outputSchema,
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
837
|
+
suspendSchema: params.suspendSchema,
|
|
838
|
+
resumeSchema: params.resumeSchema,
|
|
839
|
+
execute: async ({
|
|
840
|
+
inputData,
|
|
841
|
+
mastra,
|
|
842
|
+
requestContext,
|
|
843
|
+
tracingContext,
|
|
844
|
+
suspend,
|
|
845
|
+
resumeData,
|
|
846
|
+
runId,
|
|
847
|
+
workflowId,
|
|
848
|
+
state,
|
|
849
|
+
setState
|
|
850
|
+
}) => {
|
|
851
|
+
const toolContext = {
|
|
852
|
+
mastra,
|
|
853
|
+
requestContext,
|
|
568
854
|
tracingContext,
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
855
|
+
workflow: {
|
|
856
|
+
runId,
|
|
857
|
+
resumeData,
|
|
858
|
+
suspend,
|
|
859
|
+
workflowId,
|
|
860
|
+
state,
|
|
861
|
+
setState
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
return params.execute(inputData, toolContext);
|
|
572
865
|
},
|
|
573
866
|
component: "TOOL"
|
|
574
867
|
};
|
|
@@ -602,6 +895,8 @@ function init(inngest) {
|
|
|
602
895
|
suspendSchema: step.suspendSchema,
|
|
603
896
|
stateSchema: step.stateSchema,
|
|
604
897
|
execute: step.execute,
|
|
898
|
+
retries: step.retries,
|
|
899
|
+
scorers: step.scorers,
|
|
605
900
|
component: step.component
|
|
606
901
|
};
|
|
607
902
|
},
|
|
@@ -611,7 +906,8 @@ function init(inngest) {
|
|
|
611
906
|
inputSchema: workflow.inputSchema,
|
|
612
907
|
outputSchema: workflow.outputSchema,
|
|
613
908
|
steps: workflow.stepDefs,
|
|
614
|
-
mastra: workflow.mastra
|
|
909
|
+
mastra: workflow.mastra,
|
|
910
|
+
options: workflow.options
|
|
615
911
|
});
|
|
616
912
|
wf.setStepFlow(workflow.stepGraph);
|
|
617
913
|
wf.commit();
|
|
@@ -627,63 +923,16 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
627
923
|
this.inngestStep = inngestStep;
|
|
628
924
|
this.inngestAttempts = inngestAttempts;
|
|
629
925
|
}
|
|
630
|
-
async
|
|
631
|
-
await params.emitter.emit("watch-v2", {
|
|
632
|
-
type: "workflow-start",
|
|
633
|
-
payload: { runId: params.runId }
|
|
634
|
-
});
|
|
635
|
-
const result = await super.execute(params);
|
|
636
|
-
await params.emitter.emit("watch-v2", {
|
|
637
|
-
type: "workflow-finish",
|
|
638
|
-
payload: { runId: params.runId }
|
|
639
|
-
});
|
|
640
|
-
return result;
|
|
641
|
-
}
|
|
642
|
-
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
926
|
+
async fmtReturnValue(emitter, stepResults, lastOutput, error) {
|
|
643
927
|
const base = {
|
|
644
928
|
status: lastOutput.status,
|
|
645
929
|
steps: stepResults
|
|
646
930
|
};
|
|
647
931
|
if (lastOutput.status === "success") {
|
|
648
|
-
await emitter.emit("watch", {
|
|
649
|
-
type: "watch",
|
|
650
|
-
payload: {
|
|
651
|
-
workflowState: {
|
|
652
|
-
status: lastOutput.status,
|
|
653
|
-
steps: stepResults,
|
|
654
|
-
result: lastOutput.output
|
|
655
|
-
}
|
|
656
|
-
},
|
|
657
|
-
eventTimestamp: Date.now()
|
|
658
|
-
});
|
|
659
932
|
base.result = lastOutput.output;
|
|
660
933
|
} else if (lastOutput.status === "failed") {
|
|
661
934
|
base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
|
|
662
|
-
await emitter.emit("watch", {
|
|
663
|
-
type: "watch",
|
|
664
|
-
payload: {
|
|
665
|
-
workflowState: {
|
|
666
|
-
status: lastOutput.status,
|
|
667
|
-
steps: stepResults,
|
|
668
|
-
result: null,
|
|
669
|
-
error: base.error
|
|
670
|
-
}
|
|
671
|
-
},
|
|
672
|
-
eventTimestamp: Date.now()
|
|
673
|
-
});
|
|
674
935
|
} else if (lastOutput.status === "suspended") {
|
|
675
|
-
await emitter.emit("watch", {
|
|
676
|
-
type: "watch",
|
|
677
|
-
payload: {
|
|
678
|
-
workflowState: {
|
|
679
|
-
status: lastOutput.status,
|
|
680
|
-
steps: stepResults,
|
|
681
|
-
result: null,
|
|
682
|
-
error: null
|
|
683
|
-
}
|
|
684
|
-
},
|
|
685
|
-
eventTimestamp: Date.now()
|
|
686
|
-
});
|
|
687
936
|
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
688
937
|
if (stepResult?.status === "suspended") {
|
|
689
938
|
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
@@ -693,7 +942,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
693
942
|
});
|
|
694
943
|
base.suspended = suspendedStepIds;
|
|
695
944
|
}
|
|
696
|
-
executionSpan?.end();
|
|
697
945
|
return base;
|
|
698
946
|
}
|
|
699
947
|
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
@@ -707,14 +955,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
707
955
|
stepResults,
|
|
708
956
|
emitter,
|
|
709
957
|
abortController,
|
|
710
|
-
|
|
958
|
+
requestContext,
|
|
711
959
|
executionContext,
|
|
712
960
|
writableStream,
|
|
713
961
|
tracingContext
|
|
714
962
|
}) {
|
|
715
963
|
let { duration, fn } = entry;
|
|
716
964
|
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
717
|
-
type:
|
|
965
|
+
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
718
966
|
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
719
967
|
attributes: {
|
|
720
968
|
durationMs: duration,
|
|
@@ -725,45 +973,53 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
725
973
|
if (fn) {
|
|
726
974
|
const stepCallId = crypto.randomUUID();
|
|
727
975
|
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
728
|
-
return await fn(
|
|
729
|
-
|
|
730
|
-
workflowId,
|
|
731
|
-
mastra: this.mastra,
|
|
732
|
-
runtimeContext,
|
|
733
|
-
inputData: prevOutput,
|
|
734
|
-
state: executionContext.state,
|
|
735
|
-
setState: (state) => {
|
|
736
|
-
executionContext.state = state;
|
|
737
|
-
},
|
|
738
|
-
runCount: -1,
|
|
739
|
-
tracingContext: {
|
|
740
|
-
currentSpan: sleepSpan
|
|
741
|
-
},
|
|
742
|
-
getInitData: () => stepResults?.input,
|
|
743
|
-
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
744
|
-
// TODO: this function shouldn't have suspend probably?
|
|
745
|
-
suspend: async (_suspendPayload) => {
|
|
746
|
-
},
|
|
747
|
-
bail: () => {
|
|
748
|
-
},
|
|
749
|
-
abort: () => {
|
|
750
|
-
abortController?.abort();
|
|
751
|
-
},
|
|
752
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
753
|
-
// TODO: add streamVNext support
|
|
754
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
755
|
-
engine: { step: this.inngestStep },
|
|
756
|
-
abortSignal: abortController?.signal,
|
|
757
|
-
writer: new tools.ToolStream(
|
|
976
|
+
return await fn(
|
|
977
|
+
workflows.createDeprecationProxy(
|
|
758
978
|
{
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
979
|
+
runId,
|
|
980
|
+
workflowId,
|
|
981
|
+
mastra: this.mastra,
|
|
982
|
+
requestContext,
|
|
983
|
+
inputData: prevOutput,
|
|
984
|
+
state: executionContext.state,
|
|
985
|
+
setState: (state) => {
|
|
986
|
+
executionContext.state = state;
|
|
987
|
+
},
|
|
988
|
+
retryCount: -1,
|
|
989
|
+
tracingContext: {
|
|
990
|
+
currentSpan: sleepSpan
|
|
991
|
+
},
|
|
992
|
+
getInitData: () => stepResults?.input,
|
|
993
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
994
|
+
// TODO: this function shouldn't have suspend probably?
|
|
995
|
+
suspend: async (_suspendPayload) => {
|
|
996
|
+
},
|
|
997
|
+
bail: () => {
|
|
998
|
+
},
|
|
999
|
+
abort: () => {
|
|
1000
|
+
abortController?.abort();
|
|
1001
|
+
},
|
|
1002
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1003
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1004
|
+
engine: { step: this.inngestStep },
|
|
1005
|
+
abortSignal: abortController?.signal,
|
|
1006
|
+
writer: new tools.ToolStream(
|
|
1007
|
+
{
|
|
1008
|
+
prefix: "workflow-step",
|
|
1009
|
+
callId: stepCallId,
|
|
1010
|
+
name: "sleep",
|
|
1011
|
+
runId
|
|
1012
|
+
},
|
|
1013
|
+
writableStream
|
|
1014
|
+
)
|
|
763
1015
|
},
|
|
764
|
-
|
|
1016
|
+
{
|
|
1017
|
+
paramName: "runCount",
|
|
1018
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1019
|
+
logger: this.logger
|
|
1020
|
+
}
|
|
765
1021
|
)
|
|
766
|
-
|
|
1022
|
+
);
|
|
767
1023
|
});
|
|
768
1024
|
sleepSpan?.update({
|
|
769
1025
|
attributes: {
|
|
@@ -787,14 +1043,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
787
1043
|
stepResults,
|
|
788
1044
|
emitter,
|
|
789
1045
|
abortController,
|
|
790
|
-
|
|
1046
|
+
requestContext,
|
|
791
1047
|
executionContext,
|
|
792
1048
|
writableStream,
|
|
793
1049
|
tracingContext
|
|
794
1050
|
}) {
|
|
795
1051
|
let { date, fn } = entry;
|
|
796
1052
|
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
797
|
-
type:
|
|
1053
|
+
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
798
1054
|
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
799
1055
|
attributes: {
|
|
800
1056
|
untilDate: date,
|
|
@@ -806,45 +1062,53 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
806
1062
|
if (fn) {
|
|
807
1063
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
808
1064
|
const stepCallId = crypto.randomUUID();
|
|
809
|
-
return await fn(
|
|
810
|
-
|
|
811
|
-
workflowId,
|
|
812
|
-
mastra: this.mastra,
|
|
813
|
-
runtimeContext,
|
|
814
|
-
inputData: prevOutput,
|
|
815
|
-
state: executionContext.state,
|
|
816
|
-
setState: (state) => {
|
|
817
|
-
executionContext.state = state;
|
|
818
|
-
},
|
|
819
|
-
runCount: -1,
|
|
820
|
-
tracingContext: {
|
|
821
|
-
currentSpan: sleepUntilSpan
|
|
822
|
-
},
|
|
823
|
-
getInitData: () => stepResults?.input,
|
|
824
|
-
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
825
|
-
// TODO: this function shouldn't have suspend probably?
|
|
826
|
-
suspend: async (_suspendPayload) => {
|
|
827
|
-
},
|
|
828
|
-
bail: () => {
|
|
829
|
-
},
|
|
830
|
-
abort: () => {
|
|
831
|
-
abortController?.abort();
|
|
832
|
-
},
|
|
833
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
834
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
835
|
-
// TODO: add streamVNext support
|
|
836
|
-
engine: { step: this.inngestStep },
|
|
837
|
-
abortSignal: abortController?.signal,
|
|
838
|
-
writer: new tools.ToolStream(
|
|
1065
|
+
return await fn(
|
|
1066
|
+
workflows.createDeprecationProxy(
|
|
839
1067
|
{
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1068
|
+
runId,
|
|
1069
|
+
workflowId,
|
|
1070
|
+
mastra: this.mastra,
|
|
1071
|
+
requestContext,
|
|
1072
|
+
inputData: prevOutput,
|
|
1073
|
+
state: executionContext.state,
|
|
1074
|
+
setState: (state) => {
|
|
1075
|
+
executionContext.state = state;
|
|
1076
|
+
},
|
|
1077
|
+
retryCount: -1,
|
|
1078
|
+
tracingContext: {
|
|
1079
|
+
currentSpan: sleepUntilSpan
|
|
1080
|
+
},
|
|
1081
|
+
getInitData: () => stepResults?.input,
|
|
1082
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1083
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1084
|
+
suspend: async (_suspendPayload) => {
|
|
1085
|
+
},
|
|
1086
|
+
bail: () => {
|
|
1087
|
+
},
|
|
1088
|
+
abort: () => {
|
|
1089
|
+
abortController?.abort();
|
|
1090
|
+
},
|
|
1091
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1092
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1093
|
+
engine: { step: this.inngestStep },
|
|
1094
|
+
abortSignal: abortController?.signal,
|
|
1095
|
+
writer: new tools.ToolStream(
|
|
1096
|
+
{
|
|
1097
|
+
prefix: "workflow-step",
|
|
1098
|
+
callId: stepCallId,
|
|
1099
|
+
name: "sleep",
|
|
1100
|
+
runId
|
|
1101
|
+
},
|
|
1102
|
+
writableStream
|
|
1103
|
+
)
|
|
844
1104
|
},
|
|
845
|
-
|
|
1105
|
+
{
|
|
1106
|
+
paramName: "runCount",
|
|
1107
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1108
|
+
logger: this.logger
|
|
1109
|
+
}
|
|
846
1110
|
)
|
|
847
|
-
|
|
1111
|
+
);
|
|
848
1112
|
});
|
|
849
1113
|
if (date && !(date instanceof Date)) {
|
|
850
1114
|
date = new Date(date);
|
|
@@ -868,32 +1132,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
868
1132
|
throw e;
|
|
869
1133
|
}
|
|
870
1134
|
}
|
|
871
|
-
async executeWaitForEvent({ event, timeout }) {
|
|
872
|
-
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
873
|
-
event: `user-event-${event}`,
|
|
874
|
-
timeout: timeout ?? 5e3
|
|
875
|
-
});
|
|
876
|
-
if (eventData === null) {
|
|
877
|
-
throw "Timeout waiting for event";
|
|
878
|
-
}
|
|
879
|
-
return eventData?.data;
|
|
880
|
-
}
|
|
881
1135
|
async executeStep({
|
|
882
1136
|
step,
|
|
883
1137
|
stepResults,
|
|
884
1138
|
executionContext,
|
|
885
1139
|
resume,
|
|
1140
|
+
timeTravel,
|
|
886
1141
|
prevOutput,
|
|
887
1142
|
emitter,
|
|
888
1143
|
abortController,
|
|
889
|
-
|
|
1144
|
+
requestContext,
|
|
890
1145
|
tracingContext,
|
|
891
1146
|
writableStream,
|
|
892
1147
|
disableScorers
|
|
893
1148
|
}) {
|
|
894
|
-
const
|
|
1149
|
+
const stepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
895
1150
|
name: `workflow step: '${step.id}'`,
|
|
896
|
-
type:
|
|
1151
|
+
type: observability.SpanType.WORKFLOW_STEP,
|
|
897
1152
|
input: prevOutput,
|
|
898
1153
|
attributes: {
|
|
899
1154
|
stepId: step.id
|
|
@@ -903,34 +1158,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
903
1158
|
const { inputData, validationError } = await workflows.validateStepInput({
|
|
904
1159
|
prevOutput,
|
|
905
1160
|
step,
|
|
906
|
-
validateInputs: this.options?.validateInputs ??
|
|
1161
|
+
validateInputs: this.options?.validateInputs ?? true
|
|
907
1162
|
});
|
|
908
1163
|
const startedAt = await this.inngestStep.run(
|
|
909
1164
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
910
1165
|
async () => {
|
|
911
1166
|
const startedAt2 = Date.now();
|
|
912
1167
|
await emitter.emit("watch", {
|
|
913
|
-
type: "watch",
|
|
914
|
-
payload: {
|
|
915
|
-
currentStep: {
|
|
916
|
-
id: step.id,
|
|
917
|
-
status: "running"
|
|
918
|
-
},
|
|
919
|
-
workflowState: {
|
|
920
|
-
status: "running",
|
|
921
|
-
steps: {
|
|
922
|
-
...stepResults,
|
|
923
|
-
[step.id]: {
|
|
924
|
-
status: "running"
|
|
925
|
-
}
|
|
926
|
-
},
|
|
927
|
-
result: null,
|
|
928
|
-
error: null
|
|
929
|
-
}
|
|
930
|
-
},
|
|
931
|
-
eventTimestamp: Date.now()
|
|
932
|
-
});
|
|
933
|
-
await emitter.emit("watch-v2", {
|
|
934
1168
|
type: "workflow-step-start",
|
|
935
1169
|
payload: {
|
|
936
1170
|
id: step.id,
|
|
@@ -946,9 +1180,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
946
1180
|
const isResume = !!resume?.steps?.length;
|
|
947
1181
|
let result;
|
|
948
1182
|
let runId;
|
|
1183
|
+
const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
|
|
949
1184
|
try {
|
|
950
1185
|
if (isResume) {
|
|
951
|
-
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1186
|
+
runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
952
1187
|
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
953
1188
|
workflowName: step.id,
|
|
954
1189
|
runId
|
|
@@ -964,8 +1199,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
964
1199
|
steps: resume.steps.slice(1),
|
|
965
1200
|
stepResults: snapshot?.context,
|
|
966
1201
|
resumePayload: resume.resumePayload,
|
|
967
|
-
|
|
968
|
-
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1202
|
+
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
969
1203
|
},
|
|
970
1204
|
outputOptions: { includeState: true }
|
|
971
1205
|
}
|
|
@@ -973,6 +1207,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
973
1207
|
result = invokeResp.result;
|
|
974
1208
|
runId = invokeResp.runId;
|
|
975
1209
|
executionContext.state = invokeResp.result.state;
|
|
1210
|
+
} else if (isTimeTravel) {
|
|
1211
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1212
|
+
workflowName: step.id,
|
|
1213
|
+
runId: executionContext.runId
|
|
1214
|
+
}) ?? { context: {} };
|
|
1215
|
+
const timeTravelParams = workflows.createTimeTravelExecutionParams({
|
|
1216
|
+
steps: timeTravel.steps.slice(1),
|
|
1217
|
+
inputData: timeTravel.inputData,
|
|
1218
|
+
resumeData: timeTravel.resumeData,
|
|
1219
|
+
context: timeTravel.nestedStepResults?.[step.id] ?? {},
|
|
1220
|
+
nestedStepsContext: timeTravel.nestedStepResults ?? {},
|
|
1221
|
+
snapshot,
|
|
1222
|
+
graph: step.buildExecutionGraph()
|
|
1223
|
+
});
|
|
1224
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1225
|
+
function: step.getFunction(),
|
|
1226
|
+
data: {
|
|
1227
|
+
timeTravel: timeTravelParams,
|
|
1228
|
+
initialState: executionContext.state ?? {},
|
|
1229
|
+
runId: executionContext.runId,
|
|
1230
|
+
outputOptions: { includeState: true }
|
|
1231
|
+
}
|
|
1232
|
+
});
|
|
1233
|
+
result = invokeResp.result;
|
|
1234
|
+
runId = invokeResp.runId;
|
|
1235
|
+
executionContext.state = invokeResp.result.state;
|
|
976
1236
|
} else {
|
|
977
1237
|
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
978
1238
|
function: step.getFunction(),
|
|
@@ -1006,23 +1266,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1006
1266
|
async () => {
|
|
1007
1267
|
if (result.status === "failed") {
|
|
1008
1268
|
await emitter.emit("watch", {
|
|
1009
|
-
type: "watch",
|
|
1010
|
-
payload: {
|
|
1011
|
-
currentStep: {
|
|
1012
|
-
id: step.id,
|
|
1013
|
-
status: "failed",
|
|
1014
|
-
error: result?.error
|
|
1015
|
-
},
|
|
1016
|
-
workflowState: {
|
|
1017
|
-
status: "running",
|
|
1018
|
-
steps: stepResults,
|
|
1019
|
-
result: null,
|
|
1020
|
-
error: null
|
|
1021
|
-
}
|
|
1022
|
-
},
|
|
1023
|
-
eventTimestamp: Date.now()
|
|
1024
|
-
});
|
|
1025
|
-
await emitter.emit("watch-v2", {
|
|
1026
1269
|
type: "workflow-step-result",
|
|
1027
1270
|
payload: {
|
|
1028
1271
|
id: step.id,
|
|
@@ -1041,27 +1284,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1041
1284
|
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
1042
1285
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1043
1286
|
await emitter.emit("watch", {
|
|
1044
|
-
type: "watch",
|
|
1045
|
-
payload: {
|
|
1046
|
-
currentStep: {
|
|
1047
|
-
id: step.id,
|
|
1048
|
-
status: "suspended",
|
|
1049
|
-
payload: stepResult.payload,
|
|
1050
|
-
suspendPayload: {
|
|
1051
|
-
...stepResult?.suspendPayload,
|
|
1052
|
-
__workflow_meta: { runId, path: suspendPath }
|
|
1053
|
-
}
|
|
1054
|
-
},
|
|
1055
|
-
workflowState: {
|
|
1056
|
-
status: "running",
|
|
1057
|
-
steps: stepResults,
|
|
1058
|
-
result: null,
|
|
1059
|
-
error: null
|
|
1060
|
-
}
|
|
1061
|
-
},
|
|
1062
|
-
eventTimestamp: Date.now()
|
|
1063
|
-
});
|
|
1064
|
-
await emitter.emit("watch-v2", {
|
|
1065
1287
|
type: "workflow-step-suspended",
|
|
1066
1288
|
payload: {
|
|
1067
1289
|
id: step.id,
|
|
@@ -1080,23 +1302,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1080
1302
|
}
|
|
1081
1303
|
};
|
|
1082
1304
|
}
|
|
1083
|
-
await emitter.emit("watch", {
|
|
1084
|
-
type: "watch",
|
|
1085
|
-
payload: {
|
|
1086
|
-
currentStep: {
|
|
1087
|
-
id: step.id,
|
|
1088
|
-
status: "suspended",
|
|
1089
|
-
payload: {}
|
|
1090
|
-
},
|
|
1091
|
-
workflowState: {
|
|
1092
|
-
status: "running",
|
|
1093
|
-
steps: stepResults,
|
|
1094
|
-
result: null,
|
|
1095
|
-
error: null
|
|
1096
|
-
}
|
|
1097
|
-
},
|
|
1098
|
-
eventTimestamp: Date.now()
|
|
1099
|
-
});
|
|
1100
1305
|
return {
|
|
1101
1306
|
executionContext,
|
|
1102
1307
|
result: {
|
|
@@ -1106,23 +1311,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1106
1311
|
};
|
|
1107
1312
|
}
|
|
1108
1313
|
await emitter.emit("watch", {
|
|
1109
|
-
type: "watch",
|
|
1110
|
-
payload: {
|
|
1111
|
-
currentStep: {
|
|
1112
|
-
id: step.id,
|
|
1113
|
-
status: "success",
|
|
1114
|
-
output: result?.result
|
|
1115
|
-
},
|
|
1116
|
-
workflowState: {
|
|
1117
|
-
status: "running",
|
|
1118
|
-
steps: stepResults,
|
|
1119
|
-
result: null,
|
|
1120
|
-
error: null
|
|
1121
|
-
}
|
|
1122
|
-
},
|
|
1123
|
-
eventTimestamp: Date.now()
|
|
1124
|
-
});
|
|
1125
|
-
await emitter.emit("watch-v2", {
|
|
1126
1314
|
type: "workflow-step-result",
|
|
1127
1315
|
payload: {
|
|
1128
1316
|
id: step.id,
|
|
@@ -1130,7 +1318,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1130
1318
|
output: result?.result
|
|
1131
1319
|
}
|
|
1132
1320
|
});
|
|
1133
|
-
await emitter.emit("watch
|
|
1321
|
+
await emitter.emit("watch", {
|
|
1134
1322
|
type: "workflow-step-finish",
|
|
1135
1323
|
payload: {
|
|
1136
1324
|
id: step.id,
|
|
@@ -1150,46 +1338,87 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1150
1338
|
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1151
1339
|
};
|
|
1152
1340
|
}
|
|
1341
|
+
const stepCallId = crypto.randomUUID();
|
|
1153
1342
|
let stepRes;
|
|
1154
1343
|
try {
|
|
1155
1344
|
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1156
1345
|
let execResults;
|
|
1157
1346
|
let suspended;
|
|
1158
1347
|
let bailed;
|
|
1348
|
+
const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
|
|
1349
|
+
resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
|
|
1350
|
+
step
|
|
1351
|
+
});
|
|
1352
|
+
let resumeDataToUse;
|
|
1353
|
+
if (timeTravelResumeData && !timeTravelResumeValidationError) {
|
|
1354
|
+
resumeDataToUse = timeTravelResumeData;
|
|
1355
|
+
} else if (timeTravelResumeData && timeTravelResumeValidationError) {
|
|
1356
|
+
this.logger.warn("Time travel resume data validation failed", {
|
|
1357
|
+
stepId: step.id,
|
|
1358
|
+
error: timeTravelResumeValidationError.message
|
|
1359
|
+
});
|
|
1360
|
+
} else if (resume?.steps[0] === step.id) {
|
|
1361
|
+
resumeDataToUse = resume?.resumePayload;
|
|
1362
|
+
}
|
|
1159
1363
|
try {
|
|
1160
1364
|
if (validationError) {
|
|
1161
1365
|
throw validationError;
|
|
1162
1366
|
}
|
|
1367
|
+
const retryCount = this.getOrGenerateRetryCount(step.id);
|
|
1163
1368
|
const result = await step.execute({
|
|
1164
1369
|
runId: executionContext.runId,
|
|
1370
|
+
workflowId: executionContext.workflowId,
|
|
1165
1371
|
mastra: this.mastra,
|
|
1166
|
-
|
|
1167
|
-
|
|
1372
|
+
requestContext,
|
|
1373
|
+
retryCount,
|
|
1374
|
+
writer: new tools.ToolStream(
|
|
1375
|
+
{
|
|
1376
|
+
prefix: "workflow-step",
|
|
1377
|
+
callId: stepCallId,
|
|
1378
|
+
name: step.id,
|
|
1379
|
+
runId: executionContext.runId
|
|
1380
|
+
},
|
|
1381
|
+
writableStream
|
|
1382
|
+
),
|
|
1168
1383
|
state: executionContext?.state ?? {},
|
|
1169
1384
|
setState: (state) => {
|
|
1170
1385
|
executionContext.state = state;
|
|
1171
1386
|
},
|
|
1172
1387
|
inputData,
|
|
1173
|
-
resumeData:
|
|
1388
|
+
resumeData: resumeDataToUse,
|
|
1174
1389
|
tracingContext: {
|
|
1175
|
-
currentSpan:
|
|
1390
|
+
currentSpan: stepSpan
|
|
1176
1391
|
},
|
|
1177
1392
|
getInitData: () => stepResults?.input,
|
|
1178
1393
|
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1179
|
-
suspend: async (suspendPayload) => {
|
|
1394
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1395
|
+
const { suspendData, validationError: validationError2 } = await workflows.validateStepSuspendData({
|
|
1396
|
+
suspendData: suspendPayload,
|
|
1397
|
+
step
|
|
1398
|
+
});
|
|
1399
|
+
if (validationError2) {
|
|
1400
|
+
throw validationError2;
|
|
1401
|
+
}
|
|
1180
1402
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1181
|
-
|
|
1403
|
+
if (suspendOptions?.resumeLabel) {
|
|
1404
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1405
|
+
for (const label of resumeLabel) {
|
|
1406
|
+
executionContext.resumeLabels[label] = {
|
|
1407
|
+
stepId: step.id,
|
|
1408
|
+
foreachIndex: executionContext.foreachIndex
|
|
1409
|
+
};
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
suspended = { payload: suspendData };
|
|
1182
1413
|
},
|
|
1183
1414
|
bail: (result2) => {
|
|
1184
1415
|
bailed = { payload: result2 };
|
|
1185
1416
|
},
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
resumePayload: resume?.resumePayload,
|
|
1189
|
-
// @ts-ignore
|
|
1190
|
-
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1417
|
+
abort: () => {
|
|
1418
|
+
abortController?.abort();
|
|
1191
1419
|
},
|
|
1192
1420
|
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1421
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1193
1422
|
engine: {
|
|
1194
1423
|
step: this.inngestStep
|
|
1195
1424
|
},
|
|
@@ -1202,8 +1431,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1202
1431
|
startedAt,
|
|
1203
1432
|
endedAt,
|
|
1204
1433
|
payload: inputData,
|
|
1205
|
-
resumedAt:
|
|
1206
|
-
resumePayload:
|
|
1434
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1435
|
+
resumePayload: resumeDataToUse
|
|
1207
1436
|
};
|
|
1208
1437
|
} catch (e) {
|
|
1209
1438
|
const stepFailure = {
|
|
@@ -1212,12 +1441,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1212
1441
|
error: e instanceof Error ? e.message : String(e),
|
|
1213
1442
|
endedAt: Date.now(),
|
|
1214
1443
|
startedAt,
|
|
1215
|
-
resumedAt:
|
|
1216
|
-
resumePayload:
|
|
1444
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1445
|
+
resumePayload: resumeDataToUse
|
|
1217
1446
|
};
|
|
1218
1447
|
execResults = stepFailure;
|
|
1219
1448
|
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1220
|
-
|
|
1449
|
+
stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1221
1450
|
throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1222
1451
|
cause: execResults
|
|
1223
1452
|
});
|
|
@@ -1226,11 +1455,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1226
1455
|
execResults = {
|
|
1227
1456
|
status: "suspended",
|
|
1228
1457
|
suspendPayload: suspended.payload,
|
|
1458
|
+
...execResults.output ? { suspendOutput: execResults.output } : {},
|
|
1229
1459
|
payload: inputData,
|
|
1230
1460
|
suspendedAt: Date.now(),
|
|
1231
1461
|
startedAt,
|
|
1232
|
-
resumedAt:
|
|
1233
|
-
resumePayload:
|
|
1462
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1463
|
+
resumePayload: resumeDataToUse
|
|
1234
1464
|
};
|
|
1235
1465
|
} else if (bailed) {
|
|
1236
1466
|
execResults = {
|
|
@@ -1241,24 +1471,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1241
1471
|
startedAt
|
|
1242
1472
|
};
|
|
1243
1473
|
}
|
|
1244
|
-
await emitter.emit("watch", {
|
|
1245
|
-
type: "watch",
|
|
1246
|
-
payload: {
|
|
1247
|
-
currentStep: {
|
|
1248
|
-
id: step.id,
|
|
1249
|
-
...execResults
|
|
1250
|
-
},
|
|
1251
|
-
workflowState: {
|
|
1252
|
-
status: "running",
|
|
1253
|
-
steps: { ...stepResults, [step.id]: execResults },
|
|
1254
|
-
result: null,
|
|
1255
|
-
error: null
|
|
1256
|
-
}
|
|
1257
|
-
},
|
|
1258
|
-
eventTimestamp: Date.now()
|
|
1259
|
-
});
|
|
1260
1474
|
if (execResults.status === "suspended") {
|
|
1261
|
-
await emitter.emit("watch
|
|
1475
|
+
await emitter.emit("watch", {
|
|
1262
1476
|
type: "workflow-step-suspended",
|
|
1263
1477
|
payload: {
|
|
1264
1478
|
id: step.id,
|
|
@@ -1266,14 +1480,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1266
1480
|
}
|
|
1267
1481
|
});
|
|
1268
1482
|
} else {
|
|
1269
|
-
await emitter.emit("watch
|
|
1483
|
+
await emitter.emit("watch", {
|
|
1270
1484
|
type: "workflow-step-result",
|
|
1271
1485
|
payload: {
|
|
1272
1486
|
id: step.id,
|
|
1273
1487
|
...execResults
|
|
1274
1488
|
}
|
|
1275
1489
|
});
|
|
1276
|
-
await emitter.emit("watch
|
|
1490
|
+
await emitter.emit("watch", {
|
|
1277
1491
|
type: "workflow-step-finish",
|
|
1278
1492
|
payload: {
|
|
1279
1493
|
id: step.id,
|
|
@@ -1281,7 +1495,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1281
1495
|
}
|
|
1282
1496
|
});
|
|
1283
1497
|
}
|
|
1284
|
-
|
|
1498
|
+
stepSpan?.end({ output: execResults });
|
|
1285
1499
|
return { result: execResults, executionContext, stepResults };
|
|
1286
1500
|
});
|
|
1287
1501
|
} catch (e) {
|
|
@@ -1292,6 +1506,20 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1292
1506
|
startedAt,
|
|
1293
1507
|
endedAt: Date.now()
|
|
1294
1508
|
};
|
|
1509
|
+
await emitter.emit("watch", {
|
|
1510
|
+
type: "workflow-step-result",
|
|
1511
|
+
payload: {
|
|
1512
|
+
id: step.id,
|
|
1513
|
+
...stepFailure
|
|
1514
|
+
}
|
|
1515
|
+
});
|
|
1516
|
+
await emitter.emit("watch", {
|
|
1517
|
+
type: "workflow-step-finish",
|
|
1518
|
+
payload: {
|
|
1519
|
+
id: step.id,
|
|
1520
|
+
metadata: {}
|
|
1521
|
+
}
|
|
1522
|
+
});
|
|
1295
1523
|
stepRes = {
|
|
1296
1524
|
result: stepFailure,
|
|
1297
1525
|
executionContext,
|
|
@@ -1311,15 +1539,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1311
1539
|
output: stepRes.result,
|
|
1312
1540
|
workflowId: executionContext.workflowId,
|
|
1313
1541
|
stepId: step.id,
|
|
1314
|
-
|
|
1542
|
+
requestContext,
|
|
1315
1543
|
disableScorers,
|
|
1316
|
-
tracingContext: { currentSpan:
|
|
1544
|
+
tracingContext: { currentSpan: stepSpan }
|
|
1317
1545
|
});
|
|
1318
1546
|
}
|
|
1319
1547
|
});
|
|
1320
1548
|
}
|
|
1321
1549
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1322
|
-
Object.assign(stepResults, stepRes.stepResults);
|
|
1323
1550
|
executionContext.state = stepRes.executionContext.state;
|
|
1324
1551
|
return stepRes.result;
|
|
1325
1552
|
}
|
|
@@ -1347,16 +1574,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1347
1574
|
resourceId,
|
|
1348
1575
|
snapshot: {
|
|
1349
1576
|
runId,
|
|
1577
|
+
status: workflowStatus,
|
|
1350
1578
|
value: executionContext.state,
|
|
1351
1579
|
context: stepResults,
|
|
1352
|
-
activePaths:
|
|
1580
|
+
activePaths: executionContext.executionPath,
|
|
1581
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1353
1582
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1583
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1354
1584
|
waitingPaths: {},
|
|
1355
1585
|
serializedStepGraph,
|
|
1356
|
-
status: workflowStatus,
|
|
1357
1586
|
result,
|
|
1358
1587
|
error,
|
|
1359
|
-
// @ts-ignore
|
|
1360
1588
|
timestamp: Date.now()
|
|
1361
1589
|
}
|
|
1362
1590
|
});
|
|
@@ -1368,20 +1596,19 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1368
1596
|
runId,
|
|
1369
1597
|
entry,
|
|
1370
1598
|
prevOutput,
|
|
1371
|
-
prevStep,
|
|
1372
1599
|
stepResults,
|
|
1373
|
-
|
|
1600
|
+
timeTravel,
|
|
1374
1601
|
resume,
|
|
1375
1602
|
executionContext,
|
|
1376
1603
|
emitter,
|
|
1377
1604
|
abortController,
|
|
1378
|
-
|
|
1605
|
+
requestContext,
|
|
1379
1606
|
writableStream,
|
|
1380
1607
|
disableScorers,
|
|
1381
1608
|
tracingContext
|
|
1382
1609
|
}) {
|
|
1383
1610
|
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1384
|
-
type:
|
|
1611
|
+
type: observability.SpanType.WORKFLOW_CONDITIONAL,
|
|
1385
1612
|
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1386
1613
|
input: prevOutput,
|
|
1387
1614
|
attributes: {
|
|
@@ -1394,7 +1621,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1394
1621
|
entry.conditions.map(
|
|
1395
1622
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1396
1623
|
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1397
|
-
type:
|
|
1624
|
+
type: observability.SpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1398
1625
|
name: `condition: '${index}'`,
|
|
1399
1626
|
input: prevOutput,
|
|
1400
1627
|
attributes: {
|
|
@@ -1403,47 +1630,55 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1403
1630
|
tracingPolicy: this.options?.tracingPolicy
|
|
1404
1631
|
});
|
|
1405
1632
|
try {
|
|
1406
|
-
const result = await cond(
|
|
1407
|
-
|
|
1408
|
-
workflowId,
|
|
1409
|
-
mastra: this.mastra,
|
|
1410
|
-
runtimeContext,
|
|
1411
|
-
runCount: -1,
|
|
1412
|
-
inputData: prevOutput,
|
|
1413
|
-
state: executionContext.state,
|
|
1414
|
-
setState: (state) => {
|
|
1415
|
-
executionContext.state = state;
|
|
1416
|
-
},
|
|
1417
|
-
tracingContext: {
|
|
1418
|
-
currentSpan: evalSpan
|
|
1419
|
-
},
|
|
1420
|
-
getInitData: () => stepResults?.input,
|
|
1421
|
-
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1422
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1423
|
-
suspend: async (_suspendPayload) => {
|
|
1424
|
-
},
|
|
1425
|
-
bail: () => {
|
|
1426
|
-
},
|
|
1427
|
-
abort: () => {
|
|
1428
|
-
abortController.abort();
|
|
1429
|
-
},
|
|
1430
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1431
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1432
|
-
// TODO: add streamVNext support
|
|
1433
|
-
engine: {
|
|
1434
|
-
step: this.inngestStep
|
|
1435
|
-
},
|
|
1436
|
-
abortSignal: abortController.signal,
|
|
1437
|
-
writer: new tools.ToolStream(
|
|
1633
|
+
const result = await cond(
|
|
1634
|
+
workflows.createDeprecationProxy(
|
|
1438
1635
|
{
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1636
|
+
runId,
|
|
1637
|
+
workflowId,
|
|
1638
|
+
mastra: this.mastra,
|
|
1639
|
+
requestContext,
|
|
1640
|
+
retryCount: -1,
|
|
1641
|
+
inputData: prevOutput,
|
|
1642
|
+
state: executionContext.state,
|
|
1643
|
+
setState: (state) => {
|
|
1644
|
+
executionContext.state = state;
|
|
1645
|
+
},
|
|
1646
|
+
tracingContext: {
|
|
1647
|
+
currentSpan: evalSpan
|
|
1648
|
+
},
|
|
1649
|
+
getInitData: () => stepResults?.input,
|
|
1650
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1651
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1652
|
+
suspend: async (_suspendPayload) => {
|
|
1653
|
+
},
|
|
1654
|
+
bail: () => {
|
|
1655
|
+
},
|
|
1656
|
+
abort: () => {
|
|
1657
|
+
abortController.abort();
|
|
1658
|
+
},
|
|
1659
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1660
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1661
|
+
engine: {
|
|
1662
|
+
step: this.inngestStep
|
|
1663
|
+
},
|
|
1664
|
+
abortSignal: abortController.signal,
|
|
1665
|
+
writer: new tools.ToolStream(
|
|
1666
|
+
{
|
|
1667
|
+
prefix: "workflow-step",
|
|
1668
|
+
callId: crypto.randomUUID(),
|
|
1669
|
+
name: "conditional",
|
|
1670
|
+
runId
|
|
1671
|
+
},
|
|
1672
|
+
writableStream
|
|
1673
|
+
)
|
|
1443
1674
|
},
|
|
1444
|
-
|
|
1675
|
+
{
|
|
1676
|
+
paramName: "runCount",
|
|
1677
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1678
|
+
logger: this.logger
|
|
1679
|
+
}
|
|
1445
1680
|
)
|
|
1446
|
-
|
|
1681
|
+
);
|
|
1447
1682
|
evalSpan?.end({
|
|
1448
1683
|
output: result,
|
|
1449
1684
|
attributes: {
|
|
@@ -1471,47 +1706,58 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1471
1706
|
}
|
|
1472
1707
|
});
|
|
1473
1708
|
const results = await Promise.all(
|
|
1474
|
-
stepsToRun.map(
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1709
|
+
stepsToRun.map(async (step, index) => {
|
|
1710
|
+
const currStepResult = stepResults[step.step.id];
|
|
1711
|
+
if (currStepResult && currStepResult.status === "success") {
|
|
1712
|
+
return currStepResult;
|
|
1713
|
+
}
|
|
1714
|
+
const result = await this.executeStep({
|
|
1715
|
+
step: step.step,
|
|
1716
|
+
prevOutput,
|
|
1481
1717
|
stepResults,
|
|
1482
1718
|
resume,
|
|
1719
|
+
timeTravel,
|
|
1483
1720
|
executionContext: {
|
|
1484
1721
|
workflowId,
|
|
1485
1722
|
runId,
|
|
1486
1723
|
executionPath: [...executionContext.executionPath, index],
|
|
1724
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1487
1725
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1726
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1488
1727
|
retryConfig: executionContext.retryConfig,
|
|
1489
|
-
executionSpan: executionContext.executionSpan,
|
|
1490
1728
|
state: executionContext.state
|
|
1491
1729
|
},
|
|
1492
1730
|
emitter,
|
|
1493
1731
|
abortController,
|
|
1494
|
-
|
|
1732
|
+
requestContext,
|
|
1495
1733
|
writableStream,
|
|
1496
1734
|
disableScorers,
|
|
1497
1735
|
tracingContext: {
|
|
1498
1736
|
currentSpan: conditionalSpan
|
|
1499
1737
|
}
|
|
1500
|
-
})
|
|
1501
|
-
|
|
1738
|
+
});
|
|
1739
|
+
stepResults[step.step.id] = result;
|
|
1740
|
+
return result;
|
|
1741
|
+
})
|
|
1502
1742
|
);
|
|
1503
|
-
const hasFailed = results.find((result) => result.
|
|
1504
|
-
const hasSuspended = results.find((result) => result.
|
|
1743
|
+
const hasFailed = results.find((result) => result.status === "failed");
|
|
1744
|
+
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1505
1745
|
if (hasFailed) {
|
|
1506
|
-
execResults = { status: "failed", error: hasFailed.
|
|
1746
|
+
execResults = { status: "failed", error: hasFailed.error };
|
|
1507
1747
|
} else if (hasSuspended) {
|
|
1508
|
-
execResults = {
|
|
1748
|
+
execResults = {
|
|
1749
|
+
status: "suspended",
|
|
1750
|
+
suspendPayload: hasSuspended.suspendPayload,
|
|
1751
|
+
...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
|
|
1752
|
+
};
|
|
1509
1753
|
} else {
|
|
1510
1754
|
execResults = {
|
|
1511
1755
|
status: "success",
|
|
1512
1756
|
output: results.reduce((acc, result, index) => {
|
|
1513
|
-
if (result.
|
|
1514
|
-
|
|
1757
|
+
if (result.status === "success") {
|
|
1758
|
+
if ("step" in stepsToRun[index]) {
|
|
1759
|
+
acc[stepsToRun[index].step.id] = result.output;
|
|
1760
|
+
}
|
|
1515
1761
|
}
|
|
1516
1762
|
return acc;
|
|
1517
1763
|
}, {})
|