@mastra/inngest 0.0.0-bundle-recursion-20251030002519 → 0.0.0-client-js-listmessages-agentid-fix-20251119175531
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +350 -3
- package/dist/index.cjs +337 -270
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +80 -57
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +339 -272
- package/dist/index.js.map +1 -1
- package/package.json +18 -13
package/dist/index.cjs
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
var crypto = require('crypto');
|
|
4
4
|
var web = require('stream/web');
|
|
5
5
|
var realtime = require('@inngest/realtime');
|
|
6
|
-
var aiTracing = require('@mastra/core/ai-tracing');
|
|
7
6
|
var di = require('@mastra/core/di');
|
|
7
|
+
var observability = require('@mastra/core/observability');
|
|
8
8
|
var stream = require('@mastra/core/stream');
|
|
9
9
|
var tools = require('@mastra/core/tools');
|
|
10
10
|
var workflows = require('@mastra/core/workflows');
|
|
@@ -20,7 +20,7 @@ function serve({
|
|
|
20
20
|
functions: userFunctions = [],
|
|
21
21
|
registerOptions
|
|
22
22
|
}) {
|
|
23
|
-
const wfs = mastra.
|
|
23
|
+
const wfs = mastra.listWorkflows();
|
|
24
24
|
const workflowFunctions = Array.from(
|
|
25
25
|
new Set(
|
|
26
26
|
Object.values(wfs).flatMap((wf) => {
|
|
@@ -59,11 +59,12 @@ var InngestRun = class extends workflows.Run {
|
|
|
59
59
|
}
|
|
60
60
|
async getRunOutput(eventId) {
|
|
61
61
|
let runs = await this.getRuns(eventId);
|
|
62
|
+
const storage = this.#mastra?.getStorage();
|
|
62
63
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
63
64
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
64
65
|
runs = await this.getRuns(eventId);
|
|
65
66
|
if (runs?.[0]?.status === "Failed") {
|
|
66
|
-
const snapshot = await
|
|
67
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
67
68
|
workflowName: this.workflowId,
|
|
68
69
|
runId: this.runId
|
|
69
70
|
});
|
|
@@ -72,7 +73,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
72
73
|
};
|
|
73
74
|
}
|
|
74
75
|
if (runs?.[0]?.status === "Cancelled") {
|
|
75
|
-
const snapshot = await
|
|
76
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
76
77
|
workflowName: this.workflowId,
|
|
77
78
|
runId: this.runId
|
|
78
79
|
});
|
|
@@ -81,31 +82,27 @@ var InngestRun = class extends workflows.Run {
|
|
|
81
82
|
}
|
|
82
83
|
return runs?.[0];
|
|
83
84
|
}
|
|
84
|
-
async sendEvent(event, data) {
|
|
85
|
-
await this.inngest.send({
|
|
86
|
-
name: `user-event-${event}`,
|
|
87
|
-
data
|
|
88
|
-
});
|
|
89
|
-
}
|
|
90
85
|
async cancel() {
|
|
86
|
+
const storage = this.#mastra?.getStorage();
|
|
91
87
|
await this.inngest.send({
|
|
92
88
|
name: `cancel.workflow.${this.workflowId}`,
|
|
93
89
|
data: {
|
|
94
90
|
runId: this.runId
|
|
95
91
|
}
|
|
96
92
|
});
|
|
97
|
-
const snapshot = await
|
|
93
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
98
94
|
workflowName: this.workflowId,
|
|
99
95
|
runId: this.runId
|
|
100
96
|
});
|
|
101
97
|
if (snapshot) {
|
|
102
|
-
await
|
|
98
|
+
await storage?.persistWorkflowSnapshot({
|
|
103
99
|
workflowName: this.workflowId,
|
|
104
100
|
runId: this.runId,
|
|
105
101
|
resourceId: this.resourceId,
|
|
106
102
|
snapshot: {
|
|
107
103
|
...snapshot,
|
|
108
|
-
status: "canceled"
|
|
104
|
+
status: "canceled",
|
|
105
|
+
value: snapshot.value
|
|
109
106
|
}
|
|
110
107
|
});
|
|
111
108
|
}
|
|
@@ -127,14 +124,15 @@ var InngestRun = class extends workflows.Run {
|
|
|
127
124
|
snapshot: {
|
|
128
125
|
runId: this.runId,
|
|
129
126
|
serializedStepGraph: this.serializedStepGraph,
|
|
127
|
+
status: "running",
|
|
130
128
|
value: {},
|
|
131
129
|
context: {},
|
|
132
130
|
activePaths: [],
|
|
133
131
|
suspendedPaths: {},
|
|
132
|
+
activeStepsPath: {},
|
|
134
133
|
resumeLabels: {},
|
|
135
134
|
waitingPaths: {},
|
|
136
|
-
timestamp: Date.now()
|
|
137
|
-
status: "running"
|
|
135
|
+
timestamp: Date.now()
|
|
138
136
|
}
|
|
139
137
|
});
|
|
140
138
|
const inputDataToUse = await this._validateInput(inputData);
|
|
@@ -177,10 +175,16 @@ var InngestRun = class extends workflows.Run {
|
|
|
177
175
|
return p;
|
|
178
176
|
}
|
|
179
177
|
async _resume(params) {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
)
|
|
183
|
-
|
|
178
|
+
const storage = this.#mastra?.getStorage();
|
|
179
|
+
let steps = [];
|
|
180
|
+
if (typeof params.step === "string") {
|
|
181
|
+
steps = params.step.split(".");
|
|
182
|
+
} else {
|
|
183
|
+
steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
184
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
184
188
|
workflowName: this.workflowId,
|
|
185
189
|
runId: this.runId
|
|
186
190
|
});
|
|
@@ -198,9 +202,99 @@ var InngestRun = class extends workflows.Run {
|
|
|
198
202
|
steps,
|
|
199
203
|
stepResults: snapshot?.context,
|
|
200
204
|
resumePayload: resumeDataToUse,
|
|
201
|
-
|
|
202
|
-
|
|
205
|
+
resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
});
|
|
209
|
+
const eventId = eventOutput.ids[0];
|
|
210
|
+
if (!eventId) {
|
|
211
|
+
throw new Error("Event ID is not set");
|
|
212
|
+
}
|
|
213
|
+
const runOutput = await this.getRunOutput(eventId);
|
|
214
|
+
const result = runOutput?.output?.result;
|
|
215
|
+
if (result.status === "failed") {
|
|
216
|
+
result.error = new Error(result.error);
|
|
217
|
+
}
|
|
218
|
+
return result;
|
|
219
|
+
}
|
|
220
|
+
async timeTravel(params) {
|
|
221
|
+
const p = this._timeTravel(params).then((result) => {
|
|
222
|
+
if (result.status !== "suspended") {
|
|
223
|
+
this.closeStreamAction?.().catch(() => {
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return result;
|
|
227
|
+
});
|
|
228
|
+
this.executionResults = p;
|
|
229
|
+
return p;
|
|
230
|
+
}
|
|
231
|
+
async _timeTravel(params) {
|
|
232
|
+
if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
|
|
233
|
+
throw new Error("Step is required and must be a valid step or array of steps");
|
|
234
|
+
}
|
|
235
|
+
let steps = [];
|
|
236
|
+
if (typeof params.step === "string") {
|
|
237
|
+
steps = params.step.split(".");
|
|
238
|
+
} else {
|
|
239
|
+
steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
240
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
if (steps.length === 0) {
|
|
244
|
+
throw new Error("No steps provided to timeTravel");
|
|
245
|
+
}
|
|
246
|
+
const storage = this.#mastra?.getStorage();
|
|
247
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
248
|
+
workflowName: this.workflowId,
|
|
249
|
+
runId: this.runId
|
|
250
|
+
});
|
|
251
|
+
if (!snapshot) {
|
|
252
|
+
await storage?.persistWorkflowSnapshot({
|
|
253
|
+
workflowName: this.workflowId,
|
|
254
|
+
runId: this.runId,
|
|
255
|
+
resourceId: this.resourceId,
|
|
256
|
+
snapshot: {
|
|
257
|
+
runId: this.runId,
|
|
258
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
259
|
+
status: "pending",
|
|
260
|
+
value: {},
|
|
261
|
+
context: {},
|
|
262
|
+
activePaths: [],
|
|
263
|
+
suspendedPaths: {},
|
|
264
|
+
activeStepsPath: {},
|
|
265
|
+
resumeLabels: {},
|
|
266
|
+
waitingPaths: {},
|
|
267
|
+
timestamp: Date.now()
|
|
203
268
|
}
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
if (snapshot?.status === "running") {
|
|
272
|
+
throw new Error("This workflow run is still running, cannot time travel");
|
|
273
|
+
}
|
|
274
|
+
let inputDataToUse = params.inputData;
|
|
275
|
+
if (inputDataToUse && steps.length === 1) {
|
|
276
|
+
inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]]);
|
|
277
|
+
}
|
|
278
|
+
const timeTravelData = workflows.createTimeTravelExecutionParams({
|
|
279
|
+
steps,
|
|
280
|
+
inputData: inputDataToUse,
|
|
281
|
+
resumeData: params.resumeData,
|
|
282
|
+
context: params.context,
|
|
283
|
+
nestedStepsContext: params.nestedStepsContext,
|
|
284
|
+
snapshot: snapshot ?? { context: {} },
|
|
285
|
+
graph: this.executionGraph,
|
|
286
|
+
initialState: params.initialState
|
|
287
|
+
});
|
|
288
|
+
const eventOutput = await this.inngest.send({
|
|
289
|
+
name: `workflow.${this.workflowId}`,
|
|
290
|
+
data: {
|
|
291
|
+
initialState: timeTravelData.state,
|
|
292
|
+
runId: this.runId,
|
|
293
|
+
workflowId: this.workflowId,
|
|
294
|
+
stepResults: timeTravelData.stepResults,
|
|
295
|
+
timeTravel: timeTravelData,
|
|
296
|
+
tracingOptions: params.tracingOptions,
|
|
297
|
+
outputOptions: params.outputOptions
|
|
204
298
|
}
|
|
205
299
|
});
|
|
206
300
|
const eventId = eventOutput.ids[0];
|
|
@@ -214,12 +308,12 @@ var InngestRun = class extends workflows.Run {
|
|
|
214
308
|
}
|
|
215
309
|
return result;
|
|
216
310
|
}
|
|
217
|
-
watch(cb
|
|
311
|
+
watch(cb) {
|
|
218
312
|
let active = true;
|
|
219
313
|
const streamPromise = realtime.subscribe(
|
|
220
314
|
{
|
|
221
315
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
222
|
-
topics: [
|
|
316
|
+
topics: ["watch"],
|
|
223
317
|
app: this.inngest
|
|
224
318
|
},
|
|
225
319
|
(message) => {
|
|
@@ -237,7 +331,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
237
331
|
});
|
|
238
332
|
};
|
|
239
333
|
}
|
|
240
|
-
streamLegacy({ inputData,
|
|
334
|
+
streamLegacy({ inputData, requestContext } = {}) {
|
|
241
335
|
const { readable, writable } = new TransformStream();
|
|
242
336
|
const writer = writable.getWriter();
|
|
243
337
|
const unwatch = this.watch(async (event) => {
|
|
@@ -259,7 +353,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
259
353
|
await writer.write(e);
|
|
260
354
|
} catch {
|
|
261
355
|
}
|
|
262
|
-
}
|
|
356
|
+
});
|
|
263
357
|
this.closeStreamAction = async () => {
|
|
264
358
|
await writer.write({
|
|
265
359
|
type: "finish",
|
|
@@ -275,7 +369,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
275
369
|
writer.releaseLock();
|
|
276
370
|
}
|
|
277
371
|
};
|
|
278
|
-
this.executionResults = this._start({ inputData,
|
|
372
|
+
this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
|
|
279
373
|
if (result.status !== "suspended") {
|
|
280
374
|
this.closeStreamAction?.().catch(() => {
|
|
281
375
|
});
|
|
@@ -289,7 +383,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
289
383
|
}
|
|
290
384
|
stream({
|
|
291
385
|
inputData,
|
|
292
|
-
|
|
386
|
+
requestContext,
|
|
293
387
|
tracingOptions,
|
|
294
388
|
closeOnSuspend = true,
|
|
295
389
|
initialState,
|
|
@@ -313,7 +407,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
313
407
|
...payload
|
|
314
408
|
}
|
|
315
409
|
});
|
|
316
|
-
}
|
|
410
|
+
});
|
|
317
411
|
self.closeStreamAction = async () => {
|
|
318
412
|
unwatch();
|
|
319
413
|
try {
|
|
@@ -324,7 +418,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
324
418
|
};
|
|
325
419
|
const executionResultsPromise = self._start({
|
|
326
420
|
inputData,
|
|
327
|
-
|
|
421
|
+
requestContext,
|
|
328
422
|
// tracingContext, // We are not able to pass a reference to a span here, what to do?
|
|
329
423
|
initialState,
|
|
330
424
|
tracingOptions,
|
|
@@ -363,6 +457,75 @@ var InngestRun = class extends workflows.Run {
|
|
|
363
457
|
streamVNext(args = {}) {
|
|
364
458
|
return this.stream(args);
|
|
365
459
|
}
|
|
460
|
+
timeTravelStream({
|
|
461
|
+
inputData,
|
|
462
|
+
resumeData,
|
|
463
|
+
initialState,
|
|
464
|
+
step,
|
|
465
|
+
context,
|
|
466
|
+
nestedStepsContext,
|
|
467
|
+
requestContext,
|
|
468
|
+
tracingOptions,
|
|
469
|
+
outputOptions
|
|
470
|
+
}) {
|
|
471
|
+
this.closeStreamAction = async () => {
|
|
472
|
+
};
|
|
473
|
+
const self = this;
|
|
474
|
+
const stream$1 = new web.ReadableStream({
|
|
475
|
+
async start(controller) {
|
|
476
|
+
const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
|
|
477
|
+
controller.enqueue({
|
|
478
|
+
type,
|
|
479
|
+
runId: self.runId,
|
|
480
|
+
from,
|
|
481
|
+
payload: {
|
|
482
|
+
stepName: payload?.id,
|
|
483
|
+
...payload
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
});
|
|
487
|
+
self.closeStreamAction = async () => {
|
|
488
|
+
unwatch();
|
|
489
|
+
try {
|
|
490
|
+
await controller.close();
|
|
491
|
+
} catch (err) {
|
|
492
|
+
console.error("Error closing stream:", err);
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
const executionResultsPromise = self._timeTravel({
|
|
496
|
+
inputData,
|
|
497
|
+
step,
|
|
498
|
+
context,
|
|
499
|
+
nestedStepsContext,
|
|
500
|
+
resumeData,
|
|
501
|
+
initialState,
|
|
502
|
+
requestContext,
|
|
503
|
+
tracingOptions,
|
|
504
|
+
outputOptions
|
|
505
|
+
});
|
|
506
|
+
self.executionResults = executionResultsPromise;
|
|
507
|
+
let executionResults;
|
|
508
|
+
try {
|
|
509
|
+
executionResults = await executionResultsPromise;
|
|
510
|
+
self.closeStreamAction?.().catch(() => {
|
|
511
|
+
});
|
|
512
|
+
if (self.streamOutput) {
|
|
513
|
+
self.streamOutput.updateResults(executionResults);
|
|
514
|
+
}
|
|
515
|
+
} catch (err) {
|
|
516
|
+
self.streamOutput?.rejectResults(err);
|
|
517
|
+
self.closeStreamAction?.().catch(() => {
|
|
518
|
+
});
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
});
|
|
522
|
+
this.streamOutput = new stream.WorkflowRunOutput({
|
|
523
|
+
runId: this.runId,
|
|
524
|
+
workflowId: this.workflowId,
|
|
525
|
+
stream: stream$1
|
|
526
|
+
});
|
|
527
|
+
return this.streamOutput;
|
|
528
|
+
}
|
|
366
529
|
};
|
|
367
530
|
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
368
531
|
#mastra;
|
|
@@ -372,6 +535,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
372
535
|
constructor(params, inngest) {
|
|
373
536
|
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
374
537
|
super(workflowParams);
|
|
538
|
+
this.engineType = "inngest";
|
|
375
539
|
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
376
540
|
([_, value]) => value !== void 0
|
|
377
541
|
);
|
|
@@ -379,13 +543,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
379
543
|
this.#mastra = params.mastra;
|
|
380
544
|
this.inngest = inngest;
|
|
381
545
|
}
|
|
382
|
-
async
|
|
546
|
+
async listWorkflowRuns(args) {
|
|
383
547
|
const storage = this.#mastra?.getStorage();
|
|
384
548
|
if (!storage) {
|
|
385
549
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
386
550
|
return { runs: [], total: 0 };
|
|
387
551
|
}
|
|
388
|
-
return storage.
|
|
552
|
+
return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
389
553
|
}
|
|
390
554
|
async getWorkflowRunById(runId) {
|
|
391
555
|
const storage = this.#mastra?.getStorage();
|
|
@@ -414,16 +578,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
414
578
|
}
|
|
415
579
|
}
|
|
416
580
|
}
|
|
417
|
-
|
|
418
|
-
* @deprecated Use createRunAsync() instead.
|
|
419
|
-
* @throws {Error} Always throws an error directing users to use createRunAsync()
|
|
420
|
-
*/
|
|
421
|
-
createRun(_options) {
|
|
422
|
-
throw new Error(
|
|
423
|
-
"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."
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
async createRunAsync(options) {
|
|
581
|
+
async createRun(options) {
|
|
427
582
|
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
428
583
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
429
584
|
{
|
|
@@ -436,7 +591,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
436
591
|
mastra: this.#mastra,
|
|
437
592
|
retryConfig: this.retryConfig,
|
|
438
593
|
cleanup: () => this.runs.delete(runIdToUse),
|
|
439
|
-
workflowSteps: this.steps
|
|
594
|
+
workflowSteps: this.steps,
|
|
595
|
+
workflowEngineType: this.engineType,
|
|
596
|
+
validateInputs: this.options.validateInputs
|
|
440
597
|
},
|
|
441
598
|
this.inngest
|
|
442
599
|
);
|
|
@@ -457,13 +614,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
457
614
|
value: {},
|
|
458
615
|
context: {},
|
|
459
616
|
activePaths: [],
|
|
617
|
+
activeStepsPath: {},
|
|
460
618
|
waitingPaths: {},
|
|
461
619
|
serializedStepGraph: this.serializedStepGraph,
|
|
462
620
|
suspendedPaths: {},
|
|
463
621
|
resumeLabels: {},
|
|
464
622
|
result: void 0,
|
|
465
623
|
error: void 0,
|
|
466
|
-
// @ts-ignore
|
|
467
624
|
timestamp: Date.now()
|
|
468
625
|
}
|
|
469
626
|
});
|
|
@@ -477,15 +634,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
477
634
|
this.function = this.inngest.createFunction(
|
|
478
635
|
{
|
|
479
636
|
id: `workflow.${this.id}`,
|
|
480
|
-
|
|
481
|
-
retries: this.retryConfig?.attempts ?? 0,
|
|
637
|
+
retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
|
|
482
638
|
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
483
639
|
// Spread flow control configuration
|
|
484
640
|
...this.flowControlConfig
|
|
485
641
|
},
|
|
486
642
|
{ event: `workflow.${this.id}` },
|
|
487
643
|
async ({ event, step, attempt, publish }) => {
|
|
488
|
-
let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
|
|
644
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
|
|
489
645
|
if (!runId) {
|
|
490
646
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
491
647
|
return crypto.randomUUID();
|
|
@@ -524,16 +680,17 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
524
680
|
initialState,
|
|
525
681
|
emitter,
|
|
526
682
|
retryConfig: this.retryConfig,
|
|
527
|
-
|
|
683
|
+
requestContext: new di.RequestContext(),
|
|
528
684
|
// TODO
|
|
529
685
|
resume,
|
|
686
|
+
timeTravel,
|
|
530
687
|
format,
|
|
531
688
|
abortController: new AbortController(),
|
|
532
|
-
// currentSpan: undefined, // TODO: Pass actual parent
|
|
689
|
+
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
533
690
|
outputOptions,
|
|
534
|
-
writableStream: new WritableStream({
|
|
691
|
+
writableStream: new web.WritableStream({
|
|
535
692
|
write(chunk) {
|
|
536
|
-
void emitter.emit("watch
|
|
693
|
+
void emitter.emit("watch", chunk).catch(() => {
|
|
537
694
|
});
|
|
538
695
|
}
|
|
539
696
|
})
|
|
@@ -579,13 +736,11 @@ function createStep(params, agentOptions) {
|
|
|
579
736
|
return {
|
|
580
737
|
id: params.name,
|
|
581
738
|
description: params.getDescription(),
|
|
582
|
-
// @ts-ignore
|
|
583
739
|
inputSchema: zod.z.object({
|
|
584
740
|
prompt: zod.z.string()
|
|
585
741
|
// resourceId: z.string().optional(),
|
|
586
742
|
// threadId: z.string().optional(),
|
|
587
743
|
}),
|
|
588
|
-
// @ts-ignore
|
|
589
744
|
outputSchema: zod.z.object({
|
|
590
745
|
text: zod.z.string()
|
|
591
746
|
}),
|
|
@@ -593,7 +748,7 @@ function createStep(params, agentOptions) {
|
|
|
593
748
|
inputData,
|
|
594
749
|
[_constants.EMITTER_SYMBOL]: emitter,
|
|
595
750
|
[_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
|
|
596
|
-
|
|
751
|
+
requestContext,
|
|
597
752
|
tracingContext,
|
|
598
753
|
abortSignal,
|
|
599
754
|
abort,
|
|
@@ -614,7 +769,7 @@ function createStep(params, agentOptions) {
|
|
|
614
769
|
...agentOptions ?? {},
|
|
615
770
|
// resourceId: inputData.resourceId,
|
|
616
771
|
// threadId: inputData.threadId,
|
|
617
|
-
|
|
772
|
+
requestContext,
|
|
618
773
|
tracingContext,
|
|
619
774
|
onFinish: (result) => {
|
|
620
775
|
streamPromise.resolve(result.text);
|
|
@@ -626,7 +781,7 @@ function createStep(params, agentOptions) {
|
|
|
626
781
|
} else {
|
|
627
782
|
const modelOutput = await params.stream(inputData.prompt, {
|
|
628
783
|
...agentOptions ?? {},
|
|
629
|
-
|
|
784
|
+
requestContext,
|
|
630
785
|
tracingContext,
|
|
631
786
|
onFinish: (result) => {
|
|
632
787
|
streamPromise.resolve(result.text);
|
|
@@ -637,20 +792,20 @@ function createStep(params, agentOptions) {
|
|
|
637
792
|
stream = modelOutput.fullStream;
|
|
638
793
|
}
|
|
639
794
|
if (streamFormat === "legacy") {
|
|
640
|
-
await emitter.emit("watch
|
|
795
|
+
await emitter.emit("watch", {
|
|
641
796
|
type: "tool-call-streaming-start",
|
|
642
797
|
...toolData ?? {}
|
|
643
798
|
});
|
|
644
799
|
for await (const chunk of stream) {
|
|
645
800
|
if (chunk.type === "text-delta") {
|
|
646
|
-
await emitter.emit("watch
|
|
801
|
+
await emitter.emit("watch", {
|
|
647
802
|
type: "tool-call-delta",
|
|
648
803
|
...toolData ?? {},
|
|
649
804
|
argsTextDelta: chunk.textDelta
|
|
650
805
|
});
|
|
651
806
|
}
|
|
652
807
|
}
|
|
653
|
-
await emitter.emit("watch
|
|
808
|
+
await emitter.emit("watch", {
|
|
654
809
|
type: "tool-call-streaming-finish",
|
|
655
810
|
...toolData ?? {}
|
|
656
811
|
});
|
|
@@ -675,20 +830,36 @@ function createStep(params, agentOptions) {
|
|
|
675
830
|
}
|
|
676
831
|
return {
|
|
677
832
|
// TODO: tool probably should have strong id type
|
|
678
|
-
// @ts-ignore
|
|
679
833
|
id: params.id,
|
|
680
834
|
description: params.description,
|
|
681
835
|
inputSchema: params.inputSchema,
|
|
682
836
|
outputSchema: params.outputSchema,
|
|
683
|
-
execute: async ({
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
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,
|
|
688
852
|
tracingContext,
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
853
|
+
resumeData,
|
|
854
|
+
workflow: {
|
|
855
|
+
runId,
|
|
856
|
+
suspend,
|
|
857
|
+
workflowId,
|
|
858
|
+
state,
|
|
859
|
+
setState
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
return params.execute(inputData, toolContext);
|
|
692
863
|
},
|
|
693
864
|
component: "TOOL"
|
|
694
865
|
};
|
|
@@ -722,6 +893,8 @@ function init(inngest) {
|
|
|
722
893
|
suspendSchema: step.suspendSchema,
|
|
723
894
|
stateSchema: step.stateSchema,
|
|
724
895
|
execute: step.execute,
|
|
896
|
+
retries: step.retries,
|
|
897
|
+
scorers: step.scorers,
|
|
725
898
|
component: step.component
|
|
726
899
|
};
|
|
727
900
|
},
|
|
@@ -753,45 +926,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
753
926
|
steps: stepResults
|
|
754
927
|
};
|
|
755
928
|
if (lastOutput.status === "success") {
|
|
756
|
-
await emitter.emit("watch", {
|
|
757
|
-
type: "watch",
|
|
758
|
-
payload: {
|
|
759
|
-
workflowState: {
|
|
760
|
-
status: lastOutput.status,
|
|
761
|
-
steps: stepResults,
|
|
762
|
-
result: lastOutput.output
|
|
763
|
-
}
|
|
764
|
-
},
|
|
765
|
-
eventTimestamp: Date.now()
|
|
766
|
-
});
|
|
767
929
|
base.result = lastOutput.output;
|
|
768
930
|
} else if (lastOutput.status === "failed") {
|
|
769
931
|
base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
|
|
770
|
-
await emitter.emit("watch", {
|
|
771
|
-
type: "watch",
|
|
772
|
-
payload: {
|
|
773
|
-
workflowState: {
|
|
774
|
-
status: lastOutput.status,
|
|
775
|
-
steps: stepResults,
|
|
776
|
-
result: null,
|
|
777
|
-
error: base.error
|
|
778
|
-
}
|
|
779
|
-
},
|
|
780
|
-
eventTimestamp: Date.now()
|
|
781
|
-
});
|
|
782
932
|
} else if (lastOutput.status === "suspended") {
|
|
783
|
-
await emitter.emit("watch", {
|
|
784
|
-
type: "watch",
|
|
785
|
-
payload: {
|
|
786
|
-
workflowState: {
|
|
787
|
-
status: lastOutput.status,
|
|
788
|
-
steps: stepResults,
|
|
789
|
-
result: null,
|
|
790
|
-
error: null
|
|
791
|
-
}
|
|
792
|
-
},
|
|
793
|
-
eventTimestamp: Date.now()
|
|
794
|
-
});
|
|
795
933
|
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
796
934
|
if (stepResult?.status === "suspended") {
|
|
797
935
|
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
@@ -814,14 +952,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
814
952
|
stepResults,
|
|
815
953
|
emitter,
|
|
816
954
|
abortController,
|
|
817
|
-
|
|
955
|
+
requestContext,
|
|
818
956
|
executionContext,
|
|
819
957
|
writableStream,
|
|
820
958
|
tracingContext
|
|
821
959
|
}) {
|
|
822
960
|
let { duration, fn } = entry;
|
|
823
961
|
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
824
|
-
type:
|
|
962
|
+
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
825
963
|
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
826
964
|
attributes: {
|
|
827
965
|
durationMs: duration,
|
|
@@ -838,13 +976,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
838
976
|
runId,
|
|
839
977
|
workflowId,
|
|
840
978
|
mastra: this.mastra,
|
|
841
|
-
|
|
979
|
+
requestContext,
|
|
842
980
|
inputData: prevOutput,
|
|
843
981
|
state: executionContext.state,
|
|
844
982
|
setState: (state) => {
|
|
845
983
|
executionContext.state = state;
|
|
846
984
|
},
|
|
847
|
-
runCount: -1,
|
|
848
985
|
retryCount: -1,
|
|
849
986
|
tracingContext: {
|
|
850
987
|
currentSpan: sleepSpan
|
|
@@ -903,14 +1040,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
903
1040
|
stepResults,
|
|
904
1041
|
emitter,
|
|
905
1042
|
abortController,
|
|
906
|
-
|
|
1043
|
+
requestContext,
|
|
907
1044
|
executionContext,
|
|
908
1045
|
writableStream,
|
|
909
1046
|
tracingContext
|
|
910
1047
|
}) {
|
|
911
1048
|
let { date, fn } = entry;
|
|
912
1049
|
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
913
|
-
type:
|
|
1050
|
+
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
914
1051
|
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
915
1052
|
attributes: {
|
|
916
1053
|
untilDate: date,
|
|
@@ -928,13 +1065,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
928
1065
|
runId,
|
|
929
1066
|
workflowId,
|
|
930
1067
|
mastra: this.mastra,
|
|
931
|
-
|
|
1068
|
+
requestContext,
|
|
932
1069
|
inputData: prevOutput,
|
|
933
1070
|
state: executionContext.state,
|
|
934
1071
|
setState: (state) => {
|
|
935
1072
|
executionContext.state = state;
|
|
936
1073
|
},
|
|
937
|
-
runCount: -1,
|
|
938
1074
|
retryCount: -1,
|
|
939
1075
|
tracingContext: {
|
|
940
1076
|
currentSpan: sleepUntilSpan
|
|
@@ -993,32 +1129,23 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
993
1129
|
throw e;
|
|
994
1130
|
}
|
|
995
1131
|
}
|
|
996
|
-
async executeWaitForEvent({ event, timeout }) {
|
|
997
|
-
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
998
|
-
event: `user-event-${event}`,
|
|
999
|
-
timeout: timeout ?? 5e3
|
|
1000
|
-
});
|
|
1001
|
-
if (eventData === null) {
|
|
1002
|
-
throw "Timeout waiting for event";
|
|
1003
|
-
}
|
|
1004
|
-
return eventData?.data;
|
|
1005
|
-
}
|
|
1006
1132
|
async executeStep({
|
|
1007
1133
|
step,
|
|
1008
1134
|
stepResults,
|
|
1009
1135
|
executionContext,
|
|
1010
1136
|
resume,
|
|
1137
|
+
timeTravel,
|
|
1011
1138
|
prevOutput,
|
|
1012
1139
|
emitter,
|
|
1013
1140
|
abortController,
|
|
1014
|
-
|
|
1141
|
+
requestContext,
|
|
1015
1142
|
tracingContext,
|
|
1016
1143
|
writableStream,
|
|
1017
1144
|
disableScorers
|
|
1018
1145
|
}) {
|
|
1019
|
-
const
|
|
1146
|
+
const stepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1020
1147
|
name: `workflow step: '${step.id}'`,
|
|
1021
|
-
type:
|
|
1148
|
+
type: observability.SpanType.WORKFLOW_STEP,
|
|
1022
1149
|
input: prevOutput,
|
|
1023
1150
|
attributes: {
|
|
1024
1151
|
stepId: step.id
|
|
@@ -1028,34 +1155,13 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1028
1155
|
const { inputData, validationError } = await workflows.validateStepInput({
|
|
1029
1156
|
prevOutput,
|
|
1030
1157
|
step,
|
|
1031
|
-
validateInputs: this.options?.validateInputs ??
|
|
1158
|
+
validateInputs: this.options?.validateInputs ?? true
|
|
1032
1159
|
});
|
|
1033
1160
|
const startedAt = await this.inngestStep.run(
|
|
1034
1161
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
1035
1162
|
async () => {
|
|
1036
1163
|
const startedAt2 = Date.now();
|
|
1037
1164
|
await emitter.emit("watch", {
|
|
1038
|
-
type: "watch",
|
|
1039
|
-
payload: {
|
|
1040
|
-
currentStep: {
|
|
1041
|
-
id: step.id,
|
|
1042
|
-
status: "running"
|
|
1043
|
-
},
|
|
1044
|
-
workflowState: {
|
|
1045
|
-
status: "running",
|
|
1046
|
-
steps: {
|
|
1047
|
-
...stepResults,
|
|
1048
|
-
[step.id]: {
|
|
1049
|
-
status: "running"
|
|
1050
|
-
}
|
|
1051
|
-
},
|
|
1052
|
-
result: null,
|
|
1053
|
-
error: null
|
|
1054
|
-
}
|
|
1055
|
-
},
|
|
1056
|
-
eventTimestamp: Date.now()
|
|
1057
|
-
});
|
|
1058
|
-
await emitter.emit("watch-v2", {
|
|
1059
1165
|
type: "workflow-step-start",
|
|
1060
1166
|
payload: {
|
|
1061
1167
|
id: step.id,
|
|
@@ -1071,9 +1177,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1071
1177
|
const isResume = !!resume?.steps?.length;
|
|
1072
1178
|
let result;
|
|
1073
1179
|
let runId;
|
|
1180
|
+
const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
|
|
1074
1181
|
try {
|
|
1075
1182
|
if (isResume) {
|
|
1076
|
-
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1183
|
+
runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1077
1184
|
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1078
1185
|
workflowName: step.id,
|
|
1079
1186
|
runId
|
|
@@ -1089,8 +1196,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1089
1196
|
steps: resume.steps.slice(1),
|
|
1090
1197
|
stepResults: snapshot?.context,
|
|
1091
1198
|
resumePayload: resume.resumePayload,
|
|
1092
|
-
|
|
1093
|
-
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1199
|
+
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
1094
1200
|
},
|
|
1095
1201
|
outputOptions: { includeState: true }
|
|
1096
1202
|
}
|
|
@@ -1098,6 +1204,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1098
1204
|
result = invokeResp.result;
|
|
1099
1205
|
runId = invokeResp.runId;
|
|
1100
1206
|
executionContext.state = invokeResp.result.state;
|
|
1207
|
+
} else if (isTimeTravel) {
|
|
1208
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1209
|
+
workflowName: step.id,
|
|
1210
|
+
runId: executionContext.runId
|
|
1211
|
+
}) ?? { context: {} };
|
|
1212
|
+
const timeTravelParams = workflows.createTimeTravelExecutionParams({
|
|
1213
|
+
steps: timeTravel.steps.slice(1),
|
|
1214
|
+
inputData: timeTravel.inputData,
|
|
1215
|
+
resumeData: timeTravel.resumeData,
|
|
1216
|
+
context: timeTravel.nestedStepResults?.[step.id] ?? {},
|
|
1217
|
+
nestedStepsContext: timeTravel.nestedStepResults ?? {},
|
|
1218
|
+
snapshot,
|
|
1219
|
+
graph: step.buildExecutionGraph()
|
|
1220
|
+
});
|
|
1221
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1222
|
+
function: step.getFunction(),
|
|
1223
|
+
data: {
|
|
1224
|
+
timeTravel: timeTravelParams,
|
|
1225
|
+
initialState: executionContext.state ?? {},
|
|
1226
|
+
runId: executionContext.runId,
|
|
1227
|
+
outputOptions: { includeState: true }
|
|
1228
|
+
}
|
|
1229
|
+
});
|
|
1230
|
+
result = invokeResp.result;
|
|
1231
|
+
runId = invokeResp.runId;
|
|
1232
|
+
executionContext.state = invokeResp.result.state;
|
|
1101
1233
|
} else {
|
|
1102
1234
|
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1103
1235
|
function: step.getFunction(),
|
|
@@ -1131,23 +1263,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1131
1263
|
async () => {
|
|
1132
1264
|
if (result.status === "failed") {
|
|
1133
1265
|
await emitter.emit("watch", {
|
|
1134
|
-
type: "watch",
|
|
1135
|
-
payload: {
|
|
1136
|
-
currentStep: {
|
|
1137
|
-
id: step.id,
|
|
1138
|
-
status: "failed",
|
|
1139
|
-
error: result?.error
|
|
1140
|
-
},
|
|
1141
|
-
workflowState: {
|
|
1142
|
-
status: "running",
|
|
1143
|
-
steps: stepResults,
|
|
1144
|
-
result: null,
|
|
1145
|
-
error: null
|
|
1146
|
-
}
|
|
1147
|
-
},
|
|
1148
|
-
eventTimestamp: Date.now()
|
|
1149
|
-
});
|
|
1150
|
-
await emitter.emit("watch-v2", {
|
|
1151
1266
|
type: "workflow-step-result",
|
|
1152
1267
|
payload: {
|
|
1153
1268
|
id: step.id,
|
|
@@ -1166,27 +1281,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1166
1281
|
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
1167
1282
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1168
1283
|
await emitter.emit("watch", {
|
|
1169
|
-
type: "watch",
|
|
1170
|
-
payload: {
|
|
1171
|
-
currentStep: {
|
|
1172
|
-
id: step.id,
|
|
1173
|
-
status: "suspended",
|
|
1174
|
-
payload: stepResult.payload,
|
|
1175
|
-
suspendPayload: {
|
|
1176
|
-
...stepResult?.suspendPayload,
|
|
1177
|
-
__workflow_meta: { runId, path: suspendPath }
|
|
1178
|
-
}
|
|
1179
|
-
},
|
|
1180
|
-
workflowState: {
|
|
1181
|
-
status: "running",
|
|
1182
|
-
steps: stepResults,
|
|
1183
|
-
result: null,
|
|
1184
|
-
error: null
|
|
1185
|
-
}
|
|
1186
|
-
},
|
|
1187
|
-
eventTimestamp: Date.now()
|
|
1188
|
-
});
|
|
1189
|
-
await emitter.emit("watch-v2", {
|
|
1190
1284
|
type: "workflow-step-suspended",
|
|
1191
1285
|
payload: {
|
|
1192
1286
|
id: step.id,
|
|
@@ -1205,23 +1299,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1205
1299
|
}
|
|
1206
1300
|
};
|
|
1207
1301
|
}
|
|
1208
|
-
await emitter.emit("watch", {
|
|
1209
|
-
type: "watch",
|
|
1210
|
-
payload: {
|
|
1211
|
-
currentStep: {
|
|
1212
|
-
id: step.id,
|
|
1213
|
-
status: "suspended",
|
|
1214
|
-
payload: {}
|
|
1215
|
-
},
|
|
1216
|
-
workflowState: {
|
|
1217
|
-
status: "running",
|
|
1218
|
-
steps: stepResults,
|
|
1219
|
-
result: null,
|
|
1220
|
-
error: null
|
|
1221
|
-
}
|
|
1222
|
-
},
|
|
1223
|
-
eventTimestamp: Date.now()
|
|
1224
|
-
});
|
|
1225
1302
|
return {
|
|
1226
1303
|
executionContext,
|
|
1227
1304
|
result: {
|
|
@@ -1231,23 +1308,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1231
1308
|
};
|
|
1232
1309
|
}
|
|
1233
1310
|
await emitter.emit("watch", {
|
|
1234
|
-
type: "watch",
|
|
1235
|
-
payload: {
|
|
1236
|
-
currentStep: {
|
|
1237
|
-
id: step.id,
|
|
1238
|
-
status: "success",
|
|
1239
|
-
output: result?.result
|
|
1240
|
-
},
|
|
1241
|
-
workflowState: {
|
|
1242
|
-
status: "running",
|
|
1243
|
-
steps: stepResults,
|
|
1244
|
-
result: null,
|
|
1245
|
-
error: null
|
|
1246
|
-
}
|
|
1247
|
-
},
|
|
1248
|
-
eventTimestamp: Date.now()
|
|
1249
|
-
});
|
|
1250
|
-
await emitter.emit("watch-v2", {
|
|
1251
1311
|
type: "workflow-step-result",
|
|
1252
1312
|
payload: {
|
|
1253
1313
|
id: step.id,
|
|
@@ -1255,7 +1315,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1255
1315
|
output: result?.result
|
|
1256
1316
|
}
|
|
1257
1317
|
});
|
|
1258
|
-
await emitter.emit("watch
|
|
1318
|
+
await emitter.emit("watch", {
|
|
1259
1319
|
type: "workflow-step-finish",
|
|
1260
1320
|
payload: {
|
|
1261
1321
|
id: step.id,
|
|
@@ -1282,14 +1342,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1282
1342
|
let execResults;
|
|
1283
1343
|
let suspended;
|
|
1284
1344
|
let bailed;
|
|
1345
|
+
const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
|
|
1346
|
+
resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
|
|
1347
|
+
step
|
|
1348
|
+
});
|
|
1349
|
+
let resumeDataToUse;
|
|
1350
|
+
if (timeTravelResumeData && !timeTravelResumeValidationError) {
|
|
1351
|
+
resumeDataToUse = timeTravelResumeData;
|
|
1352
|
+
} else if (timeTravelResumeData && timeTravelResumeValidationError) {
|
|
1353
|
+
this.logger.warn("Time travel resume data validation failed", {
|
|
1354
|
+
stepId: step.id,
|
|
1355
|
+
error: timeTravelResumeValidationError.message
|
|
1356
|
+
});
|
|
1357
|
+
} else if (resume?.steps[0] === step.id) {
|
|
1358
|
+
resumeDataToUse = resume?.resumePayload;
|
|
1359
|
+
}
|
|
1285
1360
|
try {
|
|
1286
1361
|
if (validationError) {
|
|
1287
1362
|
throw validationError;
|
|
1288
1363
|
}
|
|
1364
|
+
const retryCount = this.getOrGenerateRetryCount(step.id);
|
|
1289
1365
|
const result = await step.execute({
|
|
1290
1366
|
runId: executionContext.runId,
|
|
1367
|
+
workflowId: executionContext.workflowId,
|
|
1291
1368
|
mastra: this.mastra,
|
|
1292
|
-
|
|
1369
|
+
requestContext,
|
|
1370
|
+
retryCount,
|
|
1293
1371
|
writer: new tools.ToolStream(
|
|
1294
1372
|
{
|
|
1295
1373
|
prefix: "workflow-step",
|
|
@@ -1304,9 +1382,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1304
1382
|
executionContext.state = state;
|
|
1305
1383
|
},
|
|
1306
1384
|
inputData,
|
|
1307
|
-
resumeData:
|
|
1385
|
+
resumeData: resumeDataToUse,
|
|
1308
1386
|
tracingContext: {
|
|
1309
|
-
currentSpan:
|
|
1387
|
+
currentSpan: stepSpan
|
|
1310
1388
|
},
|
|
1311
1389
|
getInitData: () => stepResults?.input,
|
|
1312
1390
|
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
@@ -1326,11 +1404,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1326
1404
|
bail: (result2) => {
|
|
1327
1405
|
bailed = { payload: result2 };
|
|
1328
1406
|
},
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
resumePayload: resume?.resumePayload,
|
|
1332
|
-
// @ts-ignore
|
|
1333
|
-
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1407
|
+
abort: () => {
|
|
1408
|
+
abortController?.abort();
|
|
1334
1409
|
},
|
|
1335
1410
|
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1336
1411
|
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
@@ -1346,8 +1421,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1346
1421
|
startedAt,
|
|
1347
1422
|
endedAt,
|
|
1348
1423
|
payload: inputData,
|
|
1349
|
-
resumedAt:
|
|
1350
|
-
resumePayload:
|
|
1424
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1425
|
+
resumePayload: resumeDataToUse
|
|
1351
1426
|
};
|
|
1352
1427
|
} catch (e) {
|
|
1353
1428
|
const stepFailure = {
|
|
@@ -1356,12 +1431,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1356
1431
|
error: e instanceof Error ? e.message : String(e),
|
|
1357
1432
|
endedAt: Date.now(),
|
|
1358
1433
|
startedAt,
|
|
1359
|
-
resumedAt:
|
|
1360
|
-
resumePayload:
|
|
1434
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1435
|
+
resumePayload: resumeDataToUse
|
|
1361
1436
|
};
|
|
1362
1437
|
execResults = stepFailure;
|
|
1363
1438
|
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1364
|
-
|
|
1439
|
+
stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1365
1440
|
throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1366
1441
|
cause: execResults
|
|
1367
1442
|
});
|
|
@@ -1370,11 +1445,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1370
1445
|
execResults = {
|
|
1371
1446
|
status: "suspended",
|
|
1372
1447
|
suspendPayload: suspended.payload,
|
|
1448
|
+
...execResults.output ? { suspendOutput: execResults.output } : {},
|
|
1373
1449
|
payload: inputData,
|
|
1374
1450
|
suspendedAt: Date.now(),
|
|
1375
1451
|
startedAt,
|
|
1376
|
-
resumedAt:
|
|
1377
|
-
resumePayload:
|
|
1452
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1453
|
+
resumePayload: resumeDataToUse
|
|
1378
1454
|
};
|
|
1379
1455
|
} else if (bailed) {
|
|
1380
1456
|
execResults = {
|
|
@@ -1385,24 +1461,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1385
1461
|
startedAt
|
|
1386
1462
|
};
|
|
1387
1463
|
}
|
|
1388
|
-
await emitter.emit("watch", {
|
|
1389
|
-
type: "watch",
|
|
1390
|
-
payload: {
|
|
1391
|
-
currentStep: {
|
|
1392
|
-
id: step.id,
|
|
1393
|
-
...execResults
|
|
1394
|
-
},
|
|
1395
|
-
workflowState: {
|
|
1396
|
-
status: "running",
|
|
1397
|
-
steps: { ...stepResults, [step.id]: execResults },
|
|
1398
|
-
result: null,
|
|
1399
|
-
error: null
|
|
1400
|
-
}
|
|
1401
|
-
},
|
|
1402
|
-
eventTimestamp: Date.now()
|
|
1403
|
-
});
|
|
1404
1464
|
if (execResults.status === "suspended") {
|
|
1405
|
-
await emitter.emit("watch
|
|
1465
|
+
await emitter.emit("watch", {
|
|
1406
1466
|
type: "workflow-step-suspended",
|
|
1407
1467
|
payload: {
|
|
1408
1468
|
id: step.id,
|
|
@@ -1410,14 +1470,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1410
1470
|
}
|
|
1411
1471
|
});
|
|
1412
1472
|
} else {
|
|
1413
|
-
await emitter.emit("watch
|
|
1473
|
+
await emitter.emit("watch", {
|
|
1414
1474
|
type: "workflow-step-result",
|
|
1415
1475
|
payload: {
|
|
1416
1476
|
id: step.id,
|
|
1417
1477
|
...execResults
|
|
1418
1478
|
}
|
|
1419
1479
|
});
|
|
1420
|
-
await emitter.emit("watch
|
|
1480
|
+
await emitter.emit("watch", {
|
|
1421
1481
|
type: "workflow-step-finish",
|
|
1422
1482
|
payload: {
|
|
1423
1483
|
id: step.id,
|
|
@@ -1425,7 +1485,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1425
1485
|
}
|
|
1426
1486
|
});
|
|
1427
1487
|
}
|
|
1428
|
-
|
|
1488
|
+
stepSpan?.end({ output: execResults });
|
|
1429
1489
|
return { result: execResults, executionContext, stepResults };
|
|
1430
1490
|
});
|
|
1431
1491
|
} catch (e) {
|
|
@@ -1455,15 +1515,14 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1455
1515
|
output: stepRes.result,
|
|
1456
1516
|
workflowId: executionContext.workflowId,
|
|
1457
1517
|
stepId: step.id,
|
|
1458
|
-
|
|
1518
|
+
requestContext,
|
|
1459
1519
|
disableScorers,
|
|
1460
|
-
tracingContext: { currentSpan:
|
|
1520
|
+
tracingContext: { currentSpan: stepSpan }
|
|
1461
1521
|
});
|
|
1462
1522
|
}
|
|
1463
1523
|
});
|
|
1464
1524
|
}
|
|
1465
1525
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1466
|
-
Object.assign(stepResults, stepRes.stepResults);
|
|
1467
1526
|
executionContext.state = stepRes.executionContext.state;
|
|
1468
1527
|
return stepRes.result;
|
|
1469
1528
|
}
|
|
@@ -1491,17 +1550,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1491
1550
|
resourceId,
|
|
1492
1551
|
snapshot: {
|
|
1493
1552
|
runId,
|
|
1553
|
+
status: workflowStatus,
|
|
1494
1554
|
value: executionContext.state,
|
|
1495
1555
|
context: stepResults,
|
|
1496
|
-
activePaths:
|
|
1556
|
+
activePaths: executionContext.executionPath,
|
|
1557
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1497
1558
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1498
1559
|
resumeLabels: executionContext.resumeLabels,
|
|
1499
1560
|
waitingPaths: {},
|
|
1500
1561
|
serializedStepGraph,
|
|
1501
|
-
status: workflowStatus,
|
|
1502
1562
|
result,
|
|
1503
1563
|
error,
|
|
1504
|
-
// @ts-ignore
|
|
1505
1564
|
timestamp: Date.now()
|
|
1506
1565
|
}
|
|
1507
1566
|
});
|
|
@@ -1514,17 +1573,18 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1514
1573
|
entry,
|
|
1515
1574
|
prevOutput,
|
|
1516
1575
|
stepResults,
|
|
1576
|
+
timeTravel,
|
|
1517
1577
|
resume,
|
|
1518
1578
|
executionContext,
|
|
1519
1579
|
emitter,
|
|
1520
1580
|
abortController,
|
|
1521
|
-
|
|
1581
|
+
requestContext,
|
|
1522
1582
|
writableStream,
|
|
1523
1583
|
disableScorers,
|
|
1524
1584
|
tracingContext
|
|
1525
1585
|
}) {
|
|
1526
1586
|
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1527
|
-
type:
|
|
1587
|
+
type: observability.SpanType.WORKFLOW_CONDITIONAL,
|
|
1528
1588
|
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1529
1589
|
input: prevOutput,
|
|
1530
1590
|
attributes: {
|
|
@@ -1537,7 +1597,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1537
1597
|
entry.conditions.map(
|
|
1538
1598
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1539
1599
|
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1540
|
-
type:
|
|
1600
|
+
type: observability.SpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1541
1601
|
name: `condition: '${index}'`,
|
|
1542
1602
|
input: prevOutput,
|
|
1543
1603
|
attributes: {
|
|
@@ -1552,8 +1612,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1552
1612
|
runId,
|
|
1553
1613
|
workflowId,
|
|
1554
1614
|
mastra: this.mastra,
|
|
1555
|
-
|
|
1556
|
-
runCount: -1,
|
|
1615
|
+
requestContext,
|
|
1557
1616
|
retryCount: -1,
|
|
1558
1617
|
inputData: prevOutput,
|
|
1559
1618
|
state: executionContext.state,
|
|
@@ -1633,10 +1692,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1633
1692
|
prevOutput,
|
|
1634
1693
|
stepResults,
|
|
1635
1694
|
resume,
|
|
1695
|
+
timeTravel,
|
|
1636
1696
|
executionContext: {
|
|
1637
1697
|
workflowId,
|
|
1638
1698
|
runId,
|
|
1639
1699
|
executionPath: [...executionContext.executionPath, index],
|
|
1700
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1640
1701
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1641
1702
|
resumeLabels: executionContext.resumeLabels,
|
|
1642
1703
|
retryConfig: executionContext.retryConfig,
|
|
@@ -1644,7 +1705,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1644
1705
|
},
|
|
1645
1706
|
emitter,
|
|
1646
1707
|
abortController,
|
|
1647
|
-
|
|
1708
|
+
requestContext,
|
|
1648
1709
|
writableStream,
|
|
1649
1710
|
disableScorers,
|
|
1650
1711
|
tracingContext: {
|
|
@@ -1660,13 +1721,19 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1660
1721
|
if (hasFailed) {
|
|
1661
1722
|
execResults = { status: "failed", error: hasFailed.error };
|
|
1662
1723
|
} else if (hasSuspended) {
|
|
1663
|
-
execResults = {
|
|
1724
|
+
execResults = {
|
|
1725
|
+
status: "suspended",
|
|
1726
|
+
suspendPayload: hasSuspended.suspendPayload,
|
|
1727
|
+
...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
|
|
1728
|
+
};
|
|
1664
1729
|
} else {
|
|
1665
1730
|
execResults = {
|
|
1666
1731
|
status: "success",
|
|
1667
1732
|
output: results.reduce((acc, result, index) => {
|
|
1668
1733
|
if (result.status === "success") {
|
|
1669
|
-
|
|
1734
|
+
if ("step" in stepsToRun[index]) {
|
|
1735
|
+
acc[stepsToRun[index].step.id] = result.output;
|
|
1736
|
+
}
|
|
1670
1737
|
}
|
|
1671
1738
|
return acc;
|
|
1672
1739
|
}, {})
|