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