@mastra/inngest 0.0.0-chore-core-swap-aiv5-ai-package-naming-20251009203931 → 0.0.0-client-js-listmessages-agentid-fix-20251119175531
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 +476 -5
- package/dist/index.cjs +655 -433
- 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 +657 -435
- 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();
|
|
231
337
|
const unwatch = this.watch(async (event) => {
|
|
232
338
|
try {
|
|
339
|
+
await writer.write({
|
|
340
|
+
// @ts-ignore
|
|
341
|
+
type: "start",
|
|
342
|
+
// @ts-ignore
|
|
343
|
+
payload: { runId: this.runId }
|
|
344
|
+
});
|
|
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,36 @@ 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
|
-
execute: async ({
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
837
|
+
execute: async ({
|
|
838
|
+
inputData,
|
|
839
|
+
mastra,
|
|
840
|
+
requestContext,
|
|
841
|
+
tracingContext,
|
|
842
|
+
suspend,
|
|
843
|
+
resumeData,
|
|
844
|
+
runId,
|
|
845
|
+
workflowId,
|
|
846
|
+
state,
|
|
847
|
+
setState
|
|
848
|
+
}) => {
|
|
849
|
+
const toolContext = {
|
|
850
|
+
mastra,
|
|
851
|
+
requestContext,
|
|
568
852
|
tracingContext,
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
853
|
+
resumeData,
|
|
854
|
+
workflow: {
|
|
855
|
+
runId,
|
|
856
|
+
suspend,
|
|
857
|
+
workflowId,
|
|
858
|
+
state,
|
|
859
|
+
setState
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
return params.execute(inputData, toolContext);
|
|
572
863
|
},
|
|
573
864
|
component: "TOOL"
|
|
574
865
|
};
|
|
@@ -602,6 +893,8 @@ function init(inngest) {
|
|
|
602
893
|
suspendSchema: step.suspendSchema,
|
|
603
894
|
stateSchema: step.stateSchema,
|
|
604
895
|
execute: step.execute,
|
|
896
|
+
retries: step.retries,
|
|
897
|
+
scorers: step.scorers,
|
|
605
898
|
component: step.component
|
|
606
899
|
};
|
|
607
900
|
},
|
|
@@ -627,63 +920,16 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
627
920
|
this.inngestStep = inngestStep;
|
|
628
921
|
this.inngestAttempts = inngestAttempts;
|
|
629
922
|
}
|
|
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) {
|
|
923
|
+
async fmtReturnValue(emitter, stepResults, lastOutput, error) {
|
|
643
924
|
const base = {
|
|
644
925
|
status: lastOutput.status,
|
|
645
926
|
steps: stepResults
|
|
646
927
|
};
|
|
647
928
|
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
929
|
base.result = lastOutput.output;
|
|
660
930
|
} else if (lastOutput.status === "failed") {
|
|
661
931
|
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
932
|
} 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
933
|
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
688
934
|
if (stepResult?.status === "suspended") {
|
|
689
935
|
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
@@ -693,7 +939,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
693
939
|
});
|
|
694
940
|
base.suspended = suspendedStepIds;
|
|
695
941
|
}
|
|
696
|
-
executionSpan?.end();
|
|
697
942
|
return base;
|
|
698
943
|
}
|
|
699
944
|
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
@@ -707,14 +952,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
707
952
|
stepResults,
|
|
708
953
|
emitter,
|
|
709
954
|
abortController,
|
|
710
|
-
|
|
955
|
+
requestContext,
|
|
711
956
|
executionContext,
|
|
712
957
|
writableStream,
|
|
713
958
|
tracingContext
|
|
714
959
|
}) {
|
|
715
960
|
let { duration, fn } = entry;
|
|
716
961
|
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
717
|
-
type:
|
|
962
|
+
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
718
963
|
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
719
964
|
attributes: {
|
|
720
965
|
durationMs: duration,
|
|
@@ -725,45 +970,53 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
725
970
|
if (fn) {
|
|
726
971
|
const stepCallId = crypto.randomUUID();
|
|
727
972
|
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(
|
|
973
|
+
return await fn(
|
|
974
|
+
workflows.createDeprecationProxy(
|
|
758
975
|
{
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
976
|
+
runId,
|
|
977
|
+
workflowId,
|
|
978
|
+
mastra: this.mastra,
|
|
979
|
+
requestContext,
|
|
980
|
+
inputData: prevOutput,
|
|
981
|
+
state: executionContext.state,
|
|
982
|
+
setState: (state) => {
|
|
983
|
+
executionContext.state = state;
|
|
984
|
+
},
|
|
985
|
+
retryCount: -1,
|
|
986
|
+
tracingContext: {
|
|
987
|
+
currentSpan: sleepSpan
|
|
988
|
+
},
|
|
989
|
+
getInitData: () => stepResults?.input,
|
|
990
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
991
|
+
// TODO: this function shouldn't have suspend probably?
|
|
992
|
+
suspend: async (_suspendPayload) => {
|
|
993
|
+
},
|
|
994
|
+
bail: () => {
|
|
995
|
+
},
|
|
996
|
+
abort: () => {
|
|
997
|
+
abortController?.abort();
|
|
998
|
+
},
|
|
999
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1000
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1001
|
+
engine: { step: this.inngestStep },
|
|
1002
|
+
abortSignal: abortController?.signal,
|
|
1003
|
+
writer: new tools.ToolStream(
|
|
1004
|
+
{
|
|
1005
|
+
prefix: "workflow-step",
|
|
1006
|
+
callId: stepCallId,
|
|
1007
|
+
name: "sleep",
|
|
1008
|
+
runId
|
|
1009
|
+
},
|
|
1010
|
+
writableStream
|
|
1011
|
+
)
|
|
763
1012
|
},
|
|
764
|
-
|
|
1013
|
+
{
|
|
1014
|
+
paramName: "runCount",
|
|
1015
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1016
|
+
logger: this.logger
|
|
1017
|
+
}
|
|
765
1018
|
)
|
|
766
|
-
|
|
1019
|
+
);
|
|
767
1020
|
});
|
|
768
1021
|
sleepSpan?.update({
|
|
769
1022
|
attributes: {
|
|
@@ -787,14 +1040,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
787
1040
|
stepResults,
|
|
788
1041
|
emitter,
|
|
789
1042
|
abortController,
|
|
790
|
-
|
|
1043
|
+
requestContext,
|
|
791
1044
|
executionContext,
|
|
792
1045
|
writableStream,
|
|
793
1046
|
tracingContext
|
|
794
1047
|
}) {
|
|
795
1048
|
let { date, fn } = entry;
|
|
796
1049
|
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
797
|
-
type:
|
|
1050
|
+
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
798
1051
|
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
799
1052
|
attributes: {
|
|
800
1053
|
untilDate: date,
|
|
@@ -806,45 +1059,53 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
806
1059
|
if (fn) {
|
|
807
1060
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
808
1061
|
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(
|
|
1062
|
+
return await fn(
|
|
1063
|
+
workflows.createDeprecationProxy(
|
|
839
1064
|
{
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
1065
|
+
runId,
|
|
1066
|
+
workflowId,
|
|
1067
|
+
mastra: this.mastra,
|
|
1068
|
+
requestContext,
|
|
1069
|
+
inputData: prevOutput,
|
|
1070
|
+
state: executionContext.state,
|
|
1071
|
+
setState: (state) => {
|
|
1072
|
+
executionContext.state = state;
|
|
1073
|
+
},
|
|
1074
|
+
retryCount: -1,
|
|
1075
|
+
tracingContext: {
|
|
1076
|
+
currentSpan: sleepUntilSpan
|
|
1077
|
+
},
|
|
1078
|
+
getInitData: () => stepResults?.input,
|
|
1079
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1080
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1081
|
+
suspend: async (_suspendPayload) => {
|
|
1082
|
+
},
|
|
1083
|
+
bail: () => {
|
|
1084
|
+
},
|
|
1085
|
+
abort: () => {
|
|
1086
|
+
abortController?.abort();
|
|
1087
|
+
},
|
|
1088
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1089
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1090
|
+
engine: { step: this.inngestStep },
|
|
1091
|
+
abortSignal: abortController?.signal,
|
|
1092
|
+
writer: new tools.ToolStream(
|
|
1093
|
+
{
|
|
1094
|
+
prefix: "workflow-step",
|
|
1095
|
+
callId: stepCallId,
|
|
1096
|
+
name: "sleep",
|
|
1097
|
+
runId
|
|
1098
|
+
},
|
|
1099
|
+
writableStream
|
|
1100
|
+
)
|
|
844
1101
|
},
|
|
845
|
-
|
|
1102
|
+
{
|
|
1103
|
+
paramName: "runCount",
|
|
1104
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1105
|
+
logger: this.logger
|
|
1106
|
+
}
|
|
846
1107
|
)
|
|
847
|
-
|
|
1108
|
+
);
|
|
848
1109
|
});
|
|
849
1110
|
if (date && !(date instanceof Date)) {
|
|
850
1111
|
date = new Date(date);
|
|
@@ -868,32 +1129,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
868
1129
|
throw e;
|
|
869
1130
|
}
|
|
870
1131
|
}
|
|
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
1132
|
async executeStep({
|
|
882
1133
|
step,
|
|
883
1134
|
stepResults,
|
|
884
1135
|
executionContext,
|
|
885
1136
|
resume,
|
|
1137
|
+
timeTravel,
|
|
886
1138
|
prevOutput,
|
|
887
1139
|
emitter,
|
|
888
1140
|
abortController,
|
|
889
|
-
|
|
1141
|
+
requestContext,
|
|
890
1142
|
tracingContext,
|
|
891
1143
|
writableStream,
|
|
892
1144
|
disableScorers
|
|
893
1145
|
}) {
|
|
894
|
-
const
|
|
1146
|
+
const stepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
895
1147
|
name: `workflow step: '${step.id}'`,
|
|
896
|
-
type:
|
|
1148
|
+
type: observability.SpanType.WORKFLOW_STEP,
|
|
897
1149
|
input: prevOutput,
|
|
898
1150
|
attributes: {
|
|
899
1151
|
stepId: step.id
|
|
@@ -903,34 +1155,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
903
1155
|
const { inputData, validationError } = await workflows.validateStepInput({
|
|
904
1156
|
prevOutput,
|
|
905
1157
|
step,
|
|
906
|
-
validateInputs: this.options?.validateInputs ??
|
|
1158
|
+
validateInputs: this.options?.validateInputs ?? true
|
|
907
1159
|
});
|
|
908
1160
|
const startedAt = await this.inngestStep.run(
|
|
909
1161
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
910
1162
|
async () => {
|
|
911
1163
|
const startedAt2 = Date.now();
|
|
912
1164
|
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
1165
|
type: "workflow-step-start",
|
|
935
1166
|
payload: {
|
|
936
1167
|
id: step.id,
|
|
@@ -946,9 +1177,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
946
1177
|
const isResume = !!resume?.steps?.length;
|
|
947
1178
|
let result;
|
|
948
1179
|
let runId;
|
|
1180
|
+
const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
|
|
949
1181
|
try {
|
|
950
1182
|
if (isResume) {
|
|
951
|
-
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1183
|
+
runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
952
1184
|
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
953
1185
|
workflowName: step.id,
|
|
954
1186
|
runId
|
|
@@ -964,8 +1196,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
964
1196
|
steps: resume.steps.slice(1),
|
|
965
1197
|
stepResults: snapshot?.context,
|
|
966
1198
|
resumePayload: resume.resumePayload,
|
|
967
|
-
|
|
968
|
-
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1199
|
+
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
969
1200
|
},
|
|
970
1201
|
outputOptions: { includeState: true }
|
|
971
1202
|
}
|
|
@@ -973,6 +1204,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
973
1204
|
result = invokeResp.result;
|
|
974
1205
|
runId = invokeResp.runId;
|
|
975
1206
|
executionContext.state = invokeResp.result.state;
|
|
1207
|
+
} else if (isTimeTravel) {
|
|
1208
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1209
|
+
workflowName: step.id,
|
|
1210
|
+
runId: executionContext.runId
|
|
1211
|
+
}) ?? { context: {} };
|
|
1212
|
+
const timeTravelParams = workflows.createTimeTravelExecutionParams({
|
|
1213
|
+
steps: timeTravel.steps.slice(1),
|
|
1214
|
+
inputData: timeTravel.inputData,
|
|
1215
|
+
resumeData: timeTravel.resumeData,
|
|
1216
|
+
context: timeTravel.nestedStepResults?.[step.id] ?? {},
|
|
1217
|
+
nestedStepsContext: timeTravel.nestedStepResults ?? {},
|
|
1218
|
+
snapshot,
|
|
1219
|
+
graph: step.buildExecutionGraph()
|
|
1220
|
+
});
|
|
1221
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1222
|
+
function: step.getFunction(),
|
|
1223
|
+
data: {
|
|
1224
|
+
timeTravel: timeTravelParams,
|
|
1225
|
+
initialState: executionContext.state ?? {},
|
|
1226
|
+
runId: executionContext.runId,
|
|
1227
|
+
outputOptions: { includeState: true }
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
result = invokeResp.result;
|
|
1231
|
+
runId = invokeResp.runId;
|
|
1232
|
+
executionContext.state = invokeResp.result.state;
|
|
976
1233
|
} else {
|
|
977
1234
|
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
978
1235
|
function: step.getFunction(),
|
|
@@ -1006,23 +1263,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1006
1263
|
async () => {
|
|
1007
1264
|
if (result.status === "failed") {
|
|
1008
1265
|
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
1266
|
type: "workflow-step-result",
|
|
1027
1267
|
payload: {
|
|
1028
1268
|
id: step.id,
|
|
@@ -1041,27 +1281,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1041
1281
|
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
1042
1282
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1043
1283
|
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
1284
|
type: "workflow-step-suspended",
|
|
1066
1285
|
payload: {
|
|
1067
1286
|
id: step.id,
|
|
@@ -1080,23 +1299,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1080
1299
|
}
|
|
1081
1300
|
};
|
|
1082
1301
|
}
|
|
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
1302
|
return {
|
|
1101
1303
|
executionContext,
|
|
1102
1304
|
result: {
|
|
@@ -1106,23 +1308,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1106
1308
|
};
|
|
1107
1309
|
}
|
|
1108
1310
|
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
1311
|
type: "workflow-step-result",
|
|
1127
1312
|
payload: {
|
|
1128
1313
|
id: step.id,
|
|
@@ -1130,7 +1315,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1130
1315
|
output: result?.result
|
|
1131
1316
|
}
|
|
1132
1317
|
});
|
|
1133
|
-
await emitter.emit("watch
|
|
1318
|
+
await emitter.emit("watch", {
|
|
1134
1319
|
type: "workflow-step-finish",
|
|
1135
1320
|
payload: {
|
|
1136
1321
|
id: step.id,
|
|
@@ -1150,46 +1335,80 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1150
1335
|
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1151
1336
|
};
|
|
1152
1337
|
}
|
|
1338
|
+
const stepCallId = crypto.randomUUID();
|
|
1153
1339
|
let stepRes;
|
|
1154
1340
|
try {
|
|
1155
1341
|
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1156
1342
|
let execResults;
|
|
1157
1343
|
let suspended;
|
|
1158
1344
|
let bailed;
|
|
1345
|
+
const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
|
|
1346
|
+
resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
|
|
1347
|
+
step
|
|
1348
|
+
});
|
|
1349
|
+
let resumeDataToUse;
|
|
1350
|
+
if (timeTravelResumeData && !timeTravelResumeValidationError) {
|
|
1351
|
+
resumeDataToUse = timeTravelResumeData;
|
|
1352
|
+
} else if (timeTravelResumeData && timeTravelResumeValidationError) {
|
|
1353
|
+
this.logger.warn("Time travel resume data validation failed", {
|
|
1354
|
+
stepId: step.id,
|
|
1355
|
+
error: timeTravelResumeValidationError.message
|
|
1356
|
+
});
|
|
1357
|
+
} else if (resume?.steps[0] === step.id) {
|
|
1358
|
+
resumeDataToUse = resume?.resumePayload;
|
|
1359
|
+
}
|
|
1159
1360
|
try {
|
|
1160
1361
|
if (validationError) {
|
|
1161
1362
|
throw validationError;
|
|
1162
1363
|
}
|
|
1364
|
+
const retryCount = this.getOrGenerateRetryCount(step.id);
|
|
1163
1365
|
const result = await step.execute({
|
|
1164
1366
|
runId: executionContext.runId,
|
|
1367
|
+
workflowId: executionContext.workflowId,
|
|
1165
1368
|
mastra: this.mastra,
|
|
1166
|
-
|
|
1167
|
-
|
|
1369
|
+
requestContext,
|
|
1370
|
+
retryCount,
|
|
1371
|
+
writer: new tools.ToolStream(
|
|
1372
|
+
{
|
|
1373
|
+
prefix: "workflow-step",
|
|
1374
|
+
callId: stepCallId,
|
|
1375
|
+
name: step.id,
|
|
1376
|
+
runId: executionContext.runId
|
|
1377
|
+
},
|
|
1378
|
+
writableStream
|
|
1379
|
+
),
|
|
1168
1380
|
state: executionContext?.state ?? {},
|
|
1169
1381
|
setState: (state) => {
|
|
1170
1382
|
executionContext.state = state;
|
|
1171
1383
|
},
|
|
1172
1384
|
inputData,
|
|
1173
|
-
resumeData:
|
|
1385
|
+
resumeData: resumeDataToUse,
|
|
1174
1386
|
tracingContext: {
|
|
1175
|
-
currentSpan:
|
|
1387
|
+
currentSpan: stepSpan
|
|
1176
1388
|
},
|
|
1177
1389
|
getInitData: () => stepResults?.input,
|
|
1178
1390
|
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1179
|
-
suspend: async (suspendPayload) => {
|
|
1391
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1180
1392
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1393
|
+
if (suspendOptions?.resumeLabel) {
|
|
1394
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1395
|
+
for (const label of resumeLabel) {
|
|
1396
|
+
executionContext.resumeLabels[label] = {
|
|
1397
|
+
stepId: step.id,
|
|
1398
|
+
foreachIndex: executionContext.foreachIndex
|
|
1399
|
+
};
|
|
1400
|
+
}
|
|
1401
|
+
}
|
|
1181
1402
|
suspended = { payload: suspendPayload };
|
|
1182
1403
|
},
|
|
1183
1404
|
bail: (result2) => {
|
|
1184
1405
|
bailed = { payload: result2 };
|
|
1185
1406
|
},
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
resumePayload: resume?.resumePayload,
|
|
1189
|
-
// @ts-ignore
|
|
1190
|
-
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1407
|
+
abort: () => {
|
|
1408
|
+
abortController?.abort();
|
|
1191
1409
|
},
|
|
1192
1410
|
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1411
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1193
1412
|
engine: {
|
|
1194
1413
|
step: this.inngestStep
|
|
1195
1414
|
},
|
|
@@ -1202,8 +1421,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1202
1421
|
startedAt,
|
|
1203
1422
|
endedAt,
|
|
1204
1423
|
payload: inputData,
|
|
1205
|
-
resumedAt:
|
|
1206
|
-
resumePayload:
|
|
1424
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1425
|
+
resumePayload: resumeDataToUse
|
|
1207
1426
|
};
|
|
1208
1427
|
} catch (e) {
|
|
1209
1428
|
const stepFailure = {
|
|
@@ -1212,12 +1431,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1212
1431
|
error: e instanceof Error ? e.message : String(e),
|
|
1213
1432
|
endedAt: Date.now(),
|
|
1214
1433
|
startedAt,
|
|
1215
|
-
resumedAt:
|
|
1216
|
-
resumePayload:
|
|
1434
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1435
|
+
resumePayload: resumeDataToUse
|
|
1217
1436
|
};
|
|
1218
1437
|
execResults = stepFailure;
|
|
1219
1438
|
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1220
|
-
|
|
1439
|
+
stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1221
1440
|
throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1222
1441
|
cause: execResults
|
|
1223
1442
|
});
|
|
@@ -1226,11 +1445,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1226
1445
|
execResults = {
|
|
1227
1446
|
status: "suspended",
|
|
1228
1447
|
suspendPayload: suspended.payload,
|
|
1448
|
+
...execResults.output ? { suspendOutput: execResults.output } : {},
|
|
1229
1449
|
payload: inputData,
|
|
1230
1450
|
suspendedAt: Date.now(),
|
|
1231
1451
|
startedAt,
|
|
1232
|
-
resumedAt:
|
|
1233
|
-
resumePayload:
|
|
1452
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1453
|
+
resumePayload: resumeDataToUse
|
|
1234
1454
|
};
|
|
1235
1455
|
} else if (bailed) {
|
|
1236
1456
|
execResults = {
|
|
@@ -1241,24 +1461,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1241
1461
|
startedAt
|
|
1242
1462
|
};
|
|
1243
1463
|
}
|
|
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
1464
|
if (execResults.status === "suspended") {
|
|
1261
|
-
await emitter.emit("watch
|
|
1465
|
+
await emitter.emit("watch", {
|
|
1262
1466
|
type: "workflow-step-suspended",
|
|
1263
1467
|
payload: {
|
|
1264
1468
|
id: step.id,
|
|
@@ -1266,14 +1470,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1266
1470
|
}
|
|
1267
1471
|
});
|
|
1268
1472
|
} else {
|
|
1269
|
-
await emitter.emit("watch
|
|
1473
|
+
await emitter.emit("watch", {
|
|
1270
1474
|
type: "workflow-step-result",
|
|
1271
1475
|
payload: {
|
|
1272
1476
|
id: step.id,
|
|
1273
1477
|
...execResults
|
|
1274
1478
|
}
|
|
1275
1479
|
});
|
|
1276
|
-
await emitter.emit("watch
|
|
1480
|
+
await emitter.emit("watch", {
|
|
1277
1481
|
type: "workflow-step-finish",
|
|
1278
1482
|
payload: {
|
|
1279
1483
|
id: step.id,
|
|
@@ -1281,7 +1485,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1281
1485
|
}
|
|
1282
1486
|
});
|
|
1283
1487
|
}
|
|
1284
|
-
|
|
1488
|
+
stepSpan?.end({ output: execResults });
|
|
1285
1489
|
return { result: execResults, executionContext, stepResults };
|
|
1286
1490
|
});
|
|
1287
1491
|
} catch (e) {
|
|
@@ -1311,15 +1515,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1311
1515
|
output: stepRes.result,
|
|
1312
1516
|
workflowId: executionContext.workflowId,
|
|
1313
1517
|
stepId: step.id,
|
|
1314
|
-
|
|
1518
|
+
requestContext,
|
|
1315
1519
|
disableScorers,
|
|
1316
|
-
tracingContext: { currentSpan:
|
|
1520
|
+
tracingContext: { currentSpan: stepSpan }
|
|
1317
1521
|
});
|
|
1318
1522
|
}
|
|
1319
1523
|
});
|
|
1320
1524
|
}
|
|
1321
1525
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1322
|
-
Object.assign(stepResults, stepRes.stepResults);
|
|
1323
1526
|
executionContext.state = stepRes.executionContext.state;
|
|
1324
1527
|
return stepRes.result;
|
|
1325
1528
|
}
|
|
@@ -1347,16 +1550,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1347
1550
|
resourceId,
|
|
1348
1551
|
snapshot: {
|
|
1349
1552
|
runId,
|
|
1553
|
+
status: workflowStatus,
|
|
1350
1554
|
value: executionContext.state,
|
|
1351
1555
|
context: stepResults,
|
|
1352
|
-
activePaths:
|
|
1556
|
+
activePaths: executionContext.executionPath,
|
|
1557
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1353
1558
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1559
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1354
1560
|
waitingPaths: {},
|
|
1355
1561
|
serializedStepGraph,
|
|
1356
|
-
status: workflowStatus,
|
|
1357
1562
|
result,
|
|
1358
1563
|
error,
|
|
1359
|
-
// @ts-ignore
|
|
1360
1564
|
timestamp: Date.now()
|
|
1361
1565
|
}
|
|
1362
1566
|
});
|
|
@@ -1368,20 +1572,19 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1368
1572
|
runId,
|
|
1369
1573
|
entry,
|
|
1370
1574
|
prevOutput,
|
|
1371
|
-
prevStep,
|
|
1372
1575
|
stepResults,
|
|
1373
|
-
|
|
1576
|
+
timeTravel,
|
|
1374
1577
|
resume,
|
|
1375
1578
|
executionContext,
|
|
1376
1579
|
emitter,
|
|
1377
1580
|
abortController,
|
|
1378
|
-
|
|
1581
|
+
requestContext,
|
|
1379
1582
|
writableStream,
|
|
1380
1583
|
disableScorers,
|
|
1381
1584
|
tracingContext
|
|
1382
1585
|
}) {
|
|
1383
1586
|
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1384
|
-
type:
|
|
1587
|
+
type: observability.SpanType.WORKFLOW_CONDITIONAL,
|
|
1385
1588
|
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1386
1589
|
input: prevOutput,
|
|
1387
1590
|
attributes: {
|
|
@@ -1394,7 +1597,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1394
1597
|
entry.conditions.map(
|
|
1395
1598
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1396
1599
|
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1397
|
-
type:
|
|
1600
|
+
type: observability.SpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1398
1601
|
name: `condition: '${index}'`,
|
|
1399
1602
|
input: prevOutput,
|
|
1400
1603
|
attributes: {
|
|
@@ -1403,47 +1606,55 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1403
1606
|
tracingPolicy: this.options?.tracingPolicy
|
|
1404
1607
|
});
|
|
1405
1608
|
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(
|
|
1609
|
+
const result = await cond(
|
|
1610
|
+
workflows.createDeprecationProxy(
|
|
1438
1611
|
{
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1612
|
+
runId,
|
|
1613
|
+
workflowId,
|
|
1614
|
+
mastra: this.mastra,
|
|
1615
|
+
requestContext,
|
|
1616
|
+
retryCount: -1,
|
|
1617
|
+
inputData: prevOutput,
|
|
1618
|
+
state: executionContext.state,
|
|
1619
|
+
setState: (state) => {
|
|
1620
|
+
executionContext.state = state;
|
|
1621
|
+
},
|
|
1622
|
+
tracingContext: {
|
|
1623
|
+
currentSpan: evalSpan
|
|
1624
|
+
},
|
|
1625
|
+
getInitData: () => stepResults?.input,
|
|
1626
|
+
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1627
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1628
|
+
suspend: async (_suspendPayload) => {
|
|
1629
|
+
},
|
|
1630
|
+
bail: () => {
|
|
1631
|
+
},
|
|
1632
|
+
abort: () => {
|
|
1633
|
+
abortController.abort();
|
|
1634
|
+
},
|
|
1635
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1636
|
+
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1637
|
+
engine: {
|
|
1638
|
+
step: this.inngestStep
|
|
1639
|
+
},
|
|
1640
|
+
abortSignal: abortController.signal,
|
|
1641
|
+
writer: new tools.ToolStream(
|
|
1642
|
+
{
|
|
1643
|
+
prefix: "workflow-step",
|
|
1644
|
+
callId: crypto.randomUUID(),
|
|
1645
|
+
name: "conditional",
|
|
1646
|
+
runId
|
|
1647
|
+
},
|
|
1648
|
+
writableStream
|
|
1649
|
+
)
|
|
1443
1650
|
},
|
|
1444
|
-
|
|
1651
|
+
{
|
|
1652
|
+
paramName: "runCount",
|
|
1653
|
+
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1654
|
+
logger: this.logger
|
|
1655
|
+
}
|
|
1445
1656
|
)
|
|
1446
|
-
|
|
1657
|
+
);
|
|
1447
1658
|
evalSpan?.end({
|
|
1448
1659
|
output: result,
|
|
1449
1660
|
attributes: {
|
|
@@ -1471,47 +1682,58 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1471
1682
|
}
|
|
1472
1683
|
});
|
|
1473
1684
|
const results = await Promise.all(
|
|
1474
|
-
stepsToRun.map(
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1685
|
+
stepsToRun.map(async (step, index) => {
|
|
1686
|
+
const currStepResult = stepResults[step.step.id];
|
|
1687
|
+
if (currStepResult && currStepResult.status === "success") {
|
|
1688
|
+
return currStepResult;
|
|
1689
|
+
}
|
|
1690
|
+
const result = await this.executeStep({
|
|
1691
|
+
step: step.step,
|
|
1692
|
+
prevOutput,
|
|
1481
1693
|
stepResults,
|
|
1482
1694
|
resume,
|
|
1695
|
+
timeTravel,
|
|
1483
1696
|
executionContext: {
|
|
1484
1697
|
workflowId,
|
|
1485
1698
|
runId,
|
|
1486
1699
|
executionPath: [...executionContext.executionPath, index],
|
|
1700
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1487
1701
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1702
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1488
1703
|
retryConfig: executionContext.retryConfig,
|
|
1489
|
-
executionSpan: executionContext.executionSpan,
|
|
1490
1704
|
state: executionContext.state
|
|
1491
1705
|
},
|
|
1492
1706
|
emitter,
|
|
1493
1707
|
abortController,
|
|
1494
|
-
|
|
1708
|
+
requestContext,
|
|
1495
1709
|
writableStream,
|
|
1496
1710
|
disableScorers,
|
|
1497
1711
|
tracingContext: {
|
|
1498
1712
|
currentSpan: conditionalSpan
|
|
1499
1713
|
}
|
|
1500
|
-
})
|
|
1501
|
-
|
|
1714
|
+
});
|
|
1715
|
+
stepResults[step.step.id] = result;
|
|
1716
|
+
return result;
|
|
1717
|
+
})
|
|
1502
1718
|
);
|
|
1503
|
-
const hasFailed = results.find((result) => result.
|
|
1504
|
-
const hasSuspended = results.find((result) => result.
|
|
1719
|
+
const hasFailed = results.find((result) => result.status === "failed");
|
|
1720
|
+
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1505
1721
|
if (hasFailed) {
|
|
1506
|
-
execResults = { status: "failed", error: hasFailed.
|
|
1722
|
+
execResults = { status: "failed", error: hasFailed.error };
|
|
1507
1723
|
} else if (hasSuspended) {
|
|
1508
|
-
execResults = {
|
|
1724
|
+
execResults = {
|
|
1725
|
+
status: "suspended",
|
|
1726
|
+
suspendPayload: hasSuspended.suspendPayload,
|
|
1727
|
+
...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
|
|
1728
|
+
};
|
|
1509
1729
|
} else {
|
|
1510
1730
|
execResults = {
|
|
1511
1731
|
status: "success",
|
|
1512
1732
|
output: results.reduce((acc, result, index) => {
|
|
1513
|
-
if (result.
|
|
1514
|
-
|
|
1733
|
+
if (result.status === "success") {
|
|
1734
|
+
if ("step" in stepsToRun[index]) {
|
|
1735
|
+
acc[stepsToRun[index].step.id] = result.output;
|
|
1736
|
+
}
|
|
1515
1737
|
}
|
|
1516
1738
|
return acc;
|
|
1517
1739
|
}, {})
|