@mastra/inngest 1.0.0-beta.1 → 1.0.0-beta.2
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 +45 -0
- package/dist/index.cjs +276 -45
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +56 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +278 -47
- package/dist/index.js.map +1 -1
- package/package.json +11 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,50 @@
|
|
|
1
1
|
# @mastra/inngest
|
|
2
2
|
|
|
3
|
+
## 1.0.0-beta.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- dependencies updates: ([#10120](https://github.com/mastra-ai/mastra/pull/10120))
|
|
8
|
+
- Updated dependency [`@inngest/realtime@^0.4.5` ↗︎](https://www.npmjs.com/package/@inngest/realtime/v/0.4.5) (from `^0.4.4`, in `dependencies`)
|
|
9
|
+
|
|
10
|
+
- fix resumeStream type to use resumeSchema ([#10202](https://github.com/mastra-ai/mastra/pull/10202))
|
|
11
|
+
|
|
12
|
+
- Add restart method to workflow run that allows restarting an active workflow run ([#9750](https://github.com/mastra-ai/mastra/pull/9750))
|
|
13
|
+
Add status filter to `listWorkflowRuns`
|
|
14
|
+
Add automatic restart to restart active workflow runs when server starts
|
|
15
|
+
|
|
16
|
+
- Validate schemas by default in workflow. Previously, if you want schemas in the workflow to be validated, you'd have to add `validateInputs` option, now, this will be done by default but can be disabled. ([#10186](https://github.com/mastra-ai/mastra/pull/10186))
|
|
17
|
+
|
|
18
|
+
For workflows whose schemas and step schemas you don't want validated, do this
|
|
19
|
+
|
|
20
|
+
```diff
|
|
21
|
+
createWorkflow({
|
|
22
|
+
+ options: {
|
|
23
|
+
+ validateInputs: false
|
|
24
|
+
+ }
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
- Fix inngest parallel workflow ([#10169](https://github.com/mastra-ai/mastra/pull/10169))
|
|
29
|
+
Fix tool as step in inngest
|
|
30
|
+
Fix inngest nested workflow
|
|
31
|
+
|
|
32
|
+
- Add timeTravel to workflows. This makes it possible to start a workflow run from a particular step in the workflow ([#9994](https://github.com/mastra-ai/mastra/pull/9994))
|
|
33
|
+
|
|
34
|
+
Example code:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
const result = await run.timeTravel({
|
|
38
|
+
step: 'step2',
|
|
39
|
+
inputData: {
|
|
40
|
+
value: 'input',
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- Updated dependencies [[`2319326`](https://github.com/mastra-ai/mastra/commit/2319326f8c64e503a09bbcf14be2dd65405445e0), [`d629361`](https://github.com/mastra-ai/mastra/commit/d629361a60f6565b5bfb11976fdaf7308af858e2), [`08c31c1`](https://github.com/mastra-ai/mastra/commit/08c31c188ebccd598acaf55e888b6397d01f7eae), [`fd3d338`](https://github.com/mastra-ai/mastra/commit/fd3d338a2c362174ed5b383f1f011ad9fb0302aa), [`c30400a`](https://github.com/mastra-ai/mastra/commit/c30400a49b994b1b97256fe785eb6c906fc2b232), [`69e0a87`](https://github.com/mastra-ai/mastra/commit/69e0a878896a2da9494945d86e056a5f8f05b851), [`01f8878`](https://github.com/mastra-ai/mastra/commit/01f88783de25e4de048c1c8aace43e26373c6ea5), [`4c77209`](https://github.com/mastra-ai/mastra/commit/4c77209e6c11678808b365d545845918c40045c8), [`d827d08`](https://github.com/mastra-ai/mastra/commit/d827d0808ffe1f3553a84e975806cc989b9735dd), [`23c10a1`](https://github.com/mastra-ai/mastra/commit/23c10a1efdd9a693c405511ab2dc8a1236603162), [`676ccc7`](https://github.com/mastra-ai/mastra/commit/676ccc7fe92468d2d45d39c31a87825c89fd1ea0), [`c10398d`](https://github.com/mastra-ai/mastra/commit/c10398d5b88f1d4af556f4267ff06f1d11e89179), [`00c2387`](https://github.com/mastra-ai/mastra/commit/00c2387f5f04a365316f851e58666ac43f8c4edf), [`ad6250d`](https://github.com/mastra-ai/mastra/commit/ad6250dbdaad927e29f74a27b83f6c468b50a705), [`3a73998`](https://github.com/mastra-ai/mastra/commit/3a73998fa4ebeb7f3dc9301afe78095fc63e7999), [`e16d553`](https://github.com/mastra-ai/mastra/commit/e16d55338403c7553531cc568125c63d53653dff), [`4d59f58`](https://github.com/mastra-ai/mastra/commit/4d59f58de2d90d6e2810a19d4518e38ddddb9038), [`e1bb9c9`](https://github.com/mastra-ai/mastra/commit/e1bb9c94b4eb68b019ae275981be3feb769b5365), [`351a11f`](https://github.com/mastra-ai/mastra/commit/351a11fcaf2ed1008977fa9b9a489fc422e51cd4)]:
|
|
46
|
+
- @mastra/core@1.0.0-beta.3
|
|
47
|
+
|
|
3
48
|
## 1.0.0-beta.1
|
|
4
49
|
|
|
5
50
|
### Patch Changes
|
package/dist/index.cjs
CHANGED
|
@@ -101,7 +101,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
101
101
|
resourceId: this.resourceId,
|
|
102
102
|
snapshot: {
|
|
103
103
|
...snapshot,
|
|
104
|
-
status: "canceled"
|
|
104
|
+
status: "canceled",
|
|
105
|
+
value: snapshot.value
|
|
105
106
|
}
|
|
106
107
|
});
|
|
107
108
|
}
|
|
@@ -123,14 +124,15 @@ var InngestRun = class extends workflows.Run {
|
|
|
123
124
|
snapshot: {
|
|
124
125
|
runId: this.runId,
|
|
125
126
|
serializedStepGraph: this.serializedStepGraph,
|
|
127
|
+
status: "running",
|
|
126
128
|
value: {},
|
|
127
129
|
context: {},
|
|
128
130
|
activePaths: [],
|
|
129
131
|
suspendedPaths: {},
|
|
132
|
+
activeStepsPath: {},
|
|
130
133
|
resumeLabels: {},
|
|
131
134
|
waitingPaths: {},
|
|
132
|
-
timestamp: Date.now()
|
|
133
|
-
status: "running"
|
|
135
|
+
timestamp: Date.now()
|
|
134
136
|
}
|
|
135
137
|
});
|
|
136
138
|
const inputDataToUse = await this._validateInput(inputData);
|
|
@@ -174,9 +176,14 @@ var InngestRun = class extends workflows.Run {
|
|
|
174
176
|
}
|
|
175
177
|
async _resume(params) {
|
|
176
178
|
const storage = this.#mastra?.getStorage();
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
+
}
|
|
180
187
|
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
181
188
|
workflowName: this.workflowId,
|
|
182
189
|
runId: this.runId
|
|
@@ -195,9 +202,99 @@ var InngestRun = class extends workflows.Run {
|
|
|
195
202
|
steps,
|
|
196
203
|
stepResults: snapshot?.context,
|
|
197
204
|
resumePayload: resumeDataToUse,
|
|
198
|
-
|
|
199
|
-
|
|
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()
|
|
200
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
|
|
201
298
|
}
|
|
202
299
|
});
|
|
203
300
|
const eventId = eventOutput.ids[0];
|
|
@@ -360,6 +457,75 @@ var InngestRun = class extends workflows.Run {
|
|
|
360
457
|
streamVNext(args = {}) {
|
|
361
458
|
return this.stream(args);
|
|
362
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
|
+
}
|
|
363
529
|
};
|
|
364
530
|
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
365
531
|
#mastra;
|
|
@@ -369,6 +535,7 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
369
535
|
constructor(params, inngest) {
|
|
370
536
|
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
371
537
|
super(workflowParams);
|
|
538
|
+
this.engineType = "inngest";
|
|
372
539
|
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
373
540
|
([_, value]) => value !== void 0
|
|
374
541
|
);
|
|
@@ -424,7 +591,9 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
424
591
|
mastra: this.#mastra,
|
|
425
592
|
retryConfig: this.retryConfig,
|
|
426
593
|
cleanup: () => this.runs.delete(runIdToUse),
|
|
427
|
-
workflowSteps: this.steps
|
|
594
|
+
workflowSteps: this.steps,
|
|
595
|
+
workflowEngineType: this.engineType,
|
|
596
|
+
validateInputs: this.options.validateInputs
|
|
428
597
|
},
|
|
429
598
|
this.inngest
|
|
430
599
|
);
|
|
@@ -445,13 +614,13 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
445
614
|
value: {},
|
|
446
615
|
context: {},
|
|
447
616
|
activePaths: [],
|
|
617
|
+
activeStepsPath: {},
|
|
448
618
|
waitingPaths: {},
|
|
449
619
|
serializedStepGraph: this.serializedStepGraph,
|
|
450
620
|
suspendedPaths: {},
|
|
451
621
|
resumeLabels: {},
|
|
452
622
|
result: void 0,
|
|
453
623
|
error: void 0,
|
|
454
|
-
// @ts-ignore
|
|
455
624
|
timestamp: Date.now()
|
|
456
625
|
}
|
|
457
626
|
});
|
|
@@ -465,15 +634,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
465
634
|
this.function = this.inngest.createFunction(
|
|
466
635
|
{
|
|
467
636
|
id: `workflow.${this.id}`,
|
|
468
|
-
|
|
469
|
-
retries: this.retryConfig?.attempts ?? 0,
|
|
637
|
+
retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
|
|
470
638
|
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
471
639
|
// Spread flow control configuration
|
|
472
640
|
...this.flowControlConfig
|
|
473
641
|
},
|
|
474
642
|
{ event: `workflow.${this.id}` },
|
|
475
643
|
async ({ event, step, attempt, publish }) => {
|
|
476
|
-
let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
|
|
644
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
|
|
477
645
|
if (!runId) {
|
|
478
646
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
479
647
|
return crypto.randomUUID();
|
|
@@ -515,11 +683,12 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
515
683
|
requestContext: new di.RequestContext(),
|
|
516
684
|
// TODO
|
|
517
685
|
resume,
|
|
686
|
+
timeTravel,
|
|
518
687
|
format,
|
|
519
688
|
abortController: new AbortController(),
|
|
520
689
|
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
521
690
|
outputOptions,
|
|
522
|
-
writableStream: new WritableStream({
|
|
691
|
+
writableStream: new web.WritableStream({
|
|
523
692
|
write(chunk) {
|
|
524
693
|
void emitter.emit("watch", chunk).catch(() => {
|
|
525
694
|
});
|
|
@@ -567,13 +736,11 @@ function createStep(params, agentOptions) {
|
|
|
567
736
|
return {
|
|
568
737
|
id: params.name,
|
|
569
738
|
description: params.getDescription(),
|
|
570
|
-
// @ts-ignore
|
|
571
739
|
inputSchema: zod.z.object({
|
|
572
740
|
prompt: zod.z.string()
|
|
573
741
|
// resourceId: z.string().optional(),
|
|
574
742
|
// threadId: z.string().optional(),
|
|
575
743
|
}),
|
|
576
|
-
// @ts-ignore
|
|
577
744
|
outputSchema: zod.z.object({
|
|
578
745
|
text: zod.z.string()
|
|
579
746
|
}),
|
|
@@ -663,20 +830,36 @@ function createStep(params, agentOptions) {
|
|
|
663
830
|
}
|
|
664
831
|
return {
|
|
665
832
|
// TODO: tool probably should have strong id type
|
|
666
|
-
// @ts-ignore
|
|
667
833
|
id: params.id,
|
|
668
834
|
description: params.description,
|
|
669
835
|
inputSchema: params.inputSchema,
|
|
670
836
|
outputSchema: params.outputSchema,
|
|
671
|
-
execute: async ({
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
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,
|
|
675
851
|
requestContext,
|
|
676
852
|
tracingContext,
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
853
|
+
resumeData,
|
|
854
|
+
workflow: {
|
|
855
|
+
runId,
|
|
856
|
+
suspend,
|
|
857
|
+
workflowId,
|
|
858
|
+
state,
|
|
859
|
+
setState
|
|
860
|
+
}
|
|
861
|
+
};
|
|
862
|
+
return params.execute(inputData, toolContext);
|
|
680
863
|
},
|
|
681
864
|
component: "TOOL"
|
|
682
865
|
};
|
|
@@ -710,6 +893,8 @@ function init(inngest) {
|
|
|
710
893
|
suspendSchema: step.suspendSchema,
|
|
711
894
|
stateSchema: step.stateSchema,
|
|
712
895
|
execute: step.execute,
|
|
896
|
+
retries: step.retries,
|
|
897
|
+
scorers: step.scorers,
|
|
713
898
|
component: step.component
|
|
714
899
|
};
|
|
715
900
|
},
|
|
@@ -949,6 +1134,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
949
1134
|
stepResults,
|
|
950
1135
|
executionContext,
|
|
951
1136
|
resume,
|
|
1137
|
+
timeTravel,
|
|
952
1138
|
prevOutput,
|
|
953
1139
|
emitter,
|
|
954
1140
|
abortController,
|
|
@@ -969,7 +1155,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
969
1155
|
const { inputData, validationError } = await workflows.validateStepInput({
|
|
970
1156
|
prevOutput,
|
|
971
1157
|
step,
|
|
972
|
-
validateInputs: this.options?.validateInputs ??
|
|
1158
|
+
validateInputs: this.options?.validateInputs ?? true
|
|
973
1159
|
});
|
|
974
1160
|
const startedAt = await this.inngestStep.run(
|
|
975
1161
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
@@ -991,9 +1177,10 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
991
1177
|
const isResume = !!resume?.steps?.length;
|
|
992
1178
|
let result;
|
|
993
1179
|
let runId;
|
|
1180
|
+
const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
|
|
994
1181
|
try {
|
|
995
1182
|
if (isResume) {
|
|
996
|
-
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1183
|
+
runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
997
1184
|
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
998
1185
|
workflowName: step.id,
|
|
999
1186
|
runId
|
|
@@ -1009,8 +1196,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1009
1196
|
steps: resume.steps.slice(1),
|
|
1010
1197
|
stepResults: snapshot?.context,
|
|
1011
1198
|
resumePayload: resume.resumePayload,
|
|
1012
|
-
|
|
1013
|
-
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1199
|
+
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
1014
1200
|
},
|
|
1015
1201
|
outputOptions: { includeState: true }
|
|
1016
1202
|
}
|
|
@@ -1018,6 +1204,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1018
1204
|
result = invokeResp.result;
|
|
1019
1205
|
runId = invokeResp.runId;
|
|
1020
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;
|
|
1021
1233
|
} else {
|
|
1022
1234
|
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1023
1235
|
function: step.getFunction(),
|
|
@@ -1130,14 +1342,32 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1130
1342
|
let execResults;
|
|
1131
1343
|
let suspended;
|
|
1132
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
|
+
}
|
|
1133
1360
|
try {
|
|
1134
1361
|
if (validationError) {
|
|
1135
1362
|
throw validationError;
|
|
1136
1363
|
}
|
|
1364
|
+
const retryCount = this.getOrGenerateRetryCount(step.id);
|
|
1137
1365
|
const result = await step.execute({
|
|
1138
1366
|
runId: executionContext.runId,
|
|
1367
|
+
workflowId: executionContext.workflowId,
|
|
1139
1368
|
mastra: this.mastra,
|
|
1140
1369
|
requestContext,
|
|
1370
|
+
retryCount,
|
|
1141
1371
|
writer: new tools.ToolStream(
|
|
1142
1372
|
{
|
|
1143
1373
|
prefix: "workflow-step",
|
|
@@ -1152,7 +1382,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1152
1382
|
executionContext.state = state;
|
|
1153
1383
|
},
|
|
1154
1384
|
inputData,
|
|
1155
|
-
resumeData:
|
|
1385
|
+
resumeData: resumeDataToUse,
|
|
1156
1386
|
tracingContext: {
|
|
1157
1387
|
currentSpan: stepSpan
|
|
1158
1388
|
},
|
|
@@ -1174,11 +1404,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1174
1404
|
bail: (result2) => {
|
|
1175
1405
|
bailed = { payload: result2 };
|
|
1176
1406
|
},
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
resumePayload: resume?.resumePayload,
|
|
1180
|
-
// @ts-ignore
|
|
1181
|
-
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1407
|
+
abort: () => {
|
|
1408
|
+
abortController?.abort();
|
|
1182
1409
|
},
|
|
1183
1410
|
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1184
1411
|
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
@@ -1194,8 +1421,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1194
1421
|
startedAt,
|
|
1195
1422
|
endedAt,
|
|
1196
1423
|
payload: inputData,
|
|
1197
|
-
resumedAt:
|
|
1198
|
-
resumePayload:
|
|
1424
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1425
|
+
resumePayload: resumeDataToUse
|
|
1199
1426
|
};
|
|
1200
1427
|
} catch (e) {
|
|
1201
1428
|
const stepFailure = {
|
|
@@ -1204,8 +1431,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1204
1431
|
error: e instanceof Error ? e.message : String(e),
|
|
1205
1432
|
endedAt: Date.now(),
|
|
1206
1433
|
startedAt,
|
|
1207
|
-
resumedAt:
|
|
1208
|
-
resumePayload:
|
|
1434
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1435
|
+
resumePayload: resumeDataToUse
|
|
1209
1436
|
};
|
|
1210
1437
|
execResults = stepFailure;
|
|
1211
1438
|
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
@@ -1222,8 +1449,8 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1222
1449
|
payload: inputData,
|
|
1223
1450
|
suspendedAt: Date.now(),
|
|
1224
1451
|
startedAt,
|
|
1225
|
-
resumedAt:
|
|
1226
|
-
resumePayload:
|
|
1452
|
+
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1453
|
+
resumePayload: resumeDataToUse
|
|
1227
1454
|
};
|
|
1228
1455
|
} else if (bailed) {
|
|
1229
1456
|
execResults = {
|
|
@@ -1296,7 +1523,6 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1296
1523
|
});
|
|
1297
1524
|
}
|
|
1298
1525
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1299
|
-
Object.assign(stepResults, stepRes.stepResults);
|
|
1300
1526
|
executionContext.state = stepRes.executionContext.state;
|
|
1301
1527
|
return stepRes.result;
|
|
1302
1528
|
}
|
|
@@ -1324,17 +1550,17 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1324
1550
|
resourceId,
|
|
1325
1551
|
snapshot: {
|
|
1326
1552
|
runId,
|
|
1553
|
+
status: workflowStatus,
|
|
1327
1554
|
value: executionContext.state,
|
|
1328
1555
|
context: stepResults,
|
|
1329
|
-
activePaths:
|
|
1556
|
+
activePaths: executionContext.executionPath,
|
|
1557
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1330
1558
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1331
1559
|
resumeLabels: executionContext.resumeLabels,
|
|
1332
1560
|
waitingPaths: {},
|
|
1333
1561
|
serializedStepGraph,
|
|
1334
|
-
status: workflowStatus,
|
|
1335
1562
|
result,
|
|
1336
1563
|
error,
|
|
1337
|
-
// @ts-ignore
|
|
1338
1564
|
timestamp: Date.now()
|
|
1339
1565
|
}
|
|
1340
1566
|
});
|
|
@@ -1347,6 +1573,7 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1347
1573
|
entry,
|
|
1348
1574
|
prevOutput,
|
|
1349
1575
|
stepResults,
|
|
1576
|
+
timeTravel,
|
|
1350
1577
|
resume,
|
|
1351
1578
|
executionContext,
|
|
1352
1579
|
emitter,
|
|
@@ -1465,10 +1692,12 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1465
1692
|
prevOutput,
|
|
1466
1693
|
stepResults,
|
|
1467
1694
|
resume,
|
|
1695
|
+
timeTravel,
|
|
1468
1696
|
executionContext: {
|
|
1469
1697
|
workflowId,
|
|
1470
1698
|
runId,
|
|
1471
1699
|
executionPath: [...executionContext.executionPath, index],
|
|
1700
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1472
1701
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1473
1702
|
resumeLabels: executionContext.resumeLabels,
|
|
1474
1703
|
retryConfig: executionContext.retryConfig,
|
|
@@ -1502,7 +1731,9 @@ var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
|
1502
1731
|
status: "success",
|
|
1503
1732
|
output: results.reduce((acc, result, index) => {
|
|
1504
1733
|
if (result.status === "success") {
|
|
1505
|
-
|
|
1734
|
+
if ("step" in stepsToRun[index]) {
|
|
1735
|
+
acc[stepsToRun[index].step.id] = result.output;
|
|
1736
|
+
}
|
|
1506
1737
|
}
|
|
1507
1738
|
return acc;
|
|
1508
1739
|
}, {})
|