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