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