@mastra/inngest 0.0.0-add-libsql-changeset-20250910154739 → 0.0.0-agent-error-handling-20251023180025
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 +332 -3
- package/dist/index.cjs +470 -285
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +73 -39
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +471 -286
- package/dist/index.js.map +1 -1
- package/package.json +13 -13
package/dist/index.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
+
import { ReadableStream } from 'stream/web';
|
|
2
3
|
import { subscribe } from '@inngest/realtime';
|
|
3
4
|
import { wrapMastra, AISpanType } from '@mastra/core/ai-tracing';
|
|
4
5
|
import { RuntimeContext } from '@mastra/core/di';
|
|
6
|
+
import { WorkflowRunOutput } from '@mastra/core/stream';
|
|
5
7
|
import { ToolStream, Tool } from '@mastra/core/tools';
|
|
6
|
-
import { Run, Workflow, DefaultExecutionEngine } from '@mastra/core/workflows';
|
|
8
|
+
import { Run, Workflow, DefaultExecutionEngine, getStepResult, validateStepInput } from '@mastra/core/workflows';
|
|
7
9
|
import { EMITTER_SYMBOL, STREAM_FORMAT_SYMBOL } from '@mastra/core/workflows/_constants';
|
|
10
|
+
import { NonRetriableError, RetryAfterError } from 'inngest';
|
|
8
11
|
import { serve as serve$1 } from 'inngest/hono';
|
|
9
12
|
import { z } from 'zod';
|
|
10
13
|
|
|
11
14
|
// src/index.ts
|
|
12
|
-
function serve({
|
|
15
|
+
function serve({
|
|
16
|
+
mastra,
|
|
17
|
+
inngest,
|
|
18
|
+
functions: userFunctions = [],
|
|
19
|
+
registerOptions
|
|
20
|
+
}) {
|
|
13
21
|
const wfs = mastra.getWorkflows();
|
|
14
|
-
const
|
|
22
|
+
const workflowFunctions = Array.from(
|
|
15
23
|
new Set(
|
|
16
24
|
Object.values(wfs).flatMap((wf) => {
|
|
17
25
|
if (wf instanceof InngestWorkflow) {
|
|
@@ -23,8 +31,9 @@ function serve({ mastra, inngest }) {
|
|
|
23
31
|
)
|
|
24
32
|
);
|
|
25
33
|
return serve$1({
|
|
34
|
+
...registerOptions,
|
|
26
35
|
client: inngest,
|
|
27
|
-
functions
|
|
36
|
+
functions: [...workflowFunctions, ...userFunctions]
|
|
28
37
|
});
|
|
29
38
|
}
|
|
30
39
|
var InngestRun = class extends Run {
|
|
@@ -52,9 +61,15 @@ var InngestRun = class extends Run {
|
|
|
52
61
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
53
62
|
runs = await this.getRuns(eventId);
|
|
54
63
|
if (runs?.[0]?.status === "Failed") {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
65
|
+
workflowName: this.workflowId,
|
|
66
|
+
runId: this.runId
|
|
67
|
+
});
|
|
68
|
+
return {
|
|
69
|
+
output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
if (runs?.[0]?.status === "Cancelled") {
|
|
58
73
|
const snapshot = await this.#mastra?.storage?.loadWorkflowSnapshot({
|
|
59
74
|
workflowName: this.workflowId,
|
|
60
75
|
runId: this.runId
|
|
@@ -85,6 +100,7 @@ var InngestRun = class extends Run {
|
|
|
85
100
|
await this.#mastra?.storage?.persistWorkflowSnapshot({
|
|
86
101
|
workflowName: this.workflowId,
|
|
87
102
|
runId: this.runId,
|
|
103
|
+
resourceId: this.resourceId,
|
|
88
104
|
snapshot: {
|
|
89
105
|
...snapshot,
|
|
90
106
|
status: "canceled"
|
|
@@ -93,11 +109,13 @@ var InngestRun = class extends Run {
|
|
|
93
109
|
}
|
|
94
110
|
}
|
|
95
111
|
async start({
|
|
96
|
-
inputData
|
|
112
|
+
inputData,
|
|
113
|
+
initialState
|
|
97
114
|
}) {
|
|
98
115
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
99
116
|
workflowName: this.workflowId,
|
|
100
117
|
runId: this.runId,
|
|
118
|
+
resourceId: this.resourceId,
|
|
101
119
|
snapshot: {
|
|
102
120
|
runId: this.runId,
|
|
103
121
|
serializedStepGraph: this.serializedStepGraph,
|
|
@@ -105,16 +123,21 @@ var InngestRun = class extends Run {
|
|
|
105
123
|
context: {},
|
|
106
124
|
activePaths: [],
|
|
107
125
|
suspendedPaths: {},
|
|
126
|
+
resumeLabels: {},
|
|
108
127
|
waitingPaths: {},
|
|
109
128
|
timestamp: Date.now(),
|
|
110
129
|
status: "running"
|
|
111
130
|
}
|
|
112
131
|
});
|
|
132
|
+
const inputDataToUse = await this._validateInput(inputData);
|
|
133
|
+
const initialStateToUse = await this._validateInitialState(initialState ?? {});
|
|
113
134
|
const eventOutput = await this.inngest.send({
|
|
114
135
|
name: `workflow.${this.workflowId}`,
|
|
115
136
|
data: {
|
|
116
|
-
inputData,
|
|
117
|
-
|
|
137
|
+
inputData: inputDataToUse,
|
|
138
|
+
initialState: initialStateToUse,
|
|
139
|
+
runId: this.runId,
|
|
140
|
+
resourceId: this.resourceId
|
|
118
141
|
}
|
|
119
142
|
});
|
|
120
143
|
const eventId = eventOutput.ids[0];
|
|
@@ -150,17 +173,20 @@ var InngestRun = class extends Run {
|
|
|
150
173
|
workflowName: this.workflowId,
|
|
151
174
|
runId: this.runId
|
|
152
175
|
});
|
|
176
|
+
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
177
|
+
const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
|
|
153
178
|
const eventOutput = await this.inngest.send({
|
|
154
179
|
name: `workflow.${this.workflowId}`,
|
|
155
180
|
data: {
|
|
156
|
-
inputData:
|
|
181
|
+
inputData: resumeDataToUse,
|
|
182
|
+
initialState: snapshot?.value ?? {},
|
|
157
183
|
runId: this.runId,
|
|
158
184
|
workflowId: this.workflowId,
|
|
159
185
|
stepResults: snapshot?.context,
|
|
160
186
|
resume: {
|
|
161
187
|
steps,
|
|
162
188
|
stepResults: snapshot?.context,
|
|
163
|
-
resumePayload:
|
|
189
|
+
resumePayload: resumeDataToUse,
|
|
164
190
|
// @ts-ignore
|
|
165
191
|
resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
|
|
166
192
|
}
|
|
@@ -200,35 +226,11 @@ var InngestRun = class extends Run {
|
|
|
200
226
|
});
|
|
201
227
|
};
|
|
202
228
|
}
|
|
203
|
-
|
|
229
|
+
streamLegacy({ inputData, runtimeContext } = {}) {
|
|
204
230
|
const { readable, writable } = new TransformStream();
|
|
205
|
-
let currentToolData = void 0;
|
|
206
231
|
const writer = writable.getWriter();
|
|
207
232
|
const unwatch = this.watch(async (event) => {
|
|
208
|
-
if (event.type === "workflow-agent-call-start") {
|
|
209
|
-
currentToolData = {
|
|
210
|
-
name: event.payload.name,
|
|
211
|
-
args: event.payload.args
|
|
212
|
-
};
|
|
213
|
-
await writer.write({
|
|
214
|
-
...event.payload,
|
|
215
|
-
type: "tool-call-streaming-start"
|
|
216
|
-
});
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
233
|
try {
|
|
220
|
-
if (event.type === "workflow-agent-call-finish") {
|
|
221
|
-
return;
|
|
222
|
-
} else if (!event.type.startsWith("workflow-")) {
|
|
223
|
-
if (event.type === "text-delta") {
|
|
224
|
-
await writer.write({
|
|
225
|
-
type: "tool-call-delta",
|
|
226
|
-
...currentToolData ?? {},
|
|
227
|
-
argsTextDelta: event.textDelta
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
return;
|
|
231
|
-
}
|
|
232
234
|
const e = {
|
|
233
235
|
...event,
|
|
234
236
|
type: event.type.replace("workflow-", "")
|
|
@@ -259,6 +261,58 @@ var InngestRun = class extends Run {
|
|
|
259
261
|
getWorkflowState: () => this.executionResults
|
|
260
262
|
};
|
|
261
263
|
}
|
|
264
|
+
stream({
|
|
265
|
+
inputData,
|
|
266
|
+
runtimeContext,
|
|
267
|
+
closeOnSuspend = true
|
|
268
|
+
} = {}) {
|
|
269
|
+
const self = this;
|
|
270
|
+
let streamOutput;
|
|
271
|
+
const stream = new ReadableStream({
|
|
272
|
+
async start(controller) {
|
|
273
|
+
const unwatch = self.watch(async ({ type, from = ChunkFrom.WORKFLOW, payload }) => {
|
|
274
|
+
controller.enqueue({
|
|
275
|
+
type,
|
|
276
|
+
runId: self.runId,
|
|
277
|
+
from,
|
|
278
|
+
payload: {
|
|
279
|
+
stepName: payload.id,
|
|
280
|
+
...payload
|
|
281
|
+
}
|
|
282
|
+
});
|
|
283
|
+
}, "watch-v2");
|
|
284
|
+
self.closeStreamAction = async () => {
|
|
285
|
+
unwatch();
|
|
286
|
+
try {
|
|
287
|
+
await controller.close();
|
|
288
|
+
} catch (err) {
|
|
289
|
+
console.error("Error closing stream:", err);
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
const executionResultsPromise = self.start({
|
|
293
|
+
inputData,
|
|
294
|
+
runtimeContext
|
|
295
|
+
});
|
|
296
|
+
const executionResults = await executionResultsPromise;
|
|
297
|
+
if (closeOnSuspend) {
|
|
298
|
+
self.closeStreamAction?.().catch(() => {
|
|
299
|
+
});
|
|
300
|
+
} else if (executionResults.status !== "suspended") {
|
|
301
|
+
self.closeStreamAction?.().catch(() => {
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
if (streamOutput) {
|
|
305
|
+
streamOutput.updateResults(executionResults);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
streamOutput = new WorkflowRunOutput({
|
|
310
|
+
runId: this.runId,
|
|
311
|
+
workflowId: this.workflowId,
|
|
312
|
+
stream
|
|
313
|
+
});
|
|
314
|
+
return streamOutput;
|
|
315
|
+
}
|
|
262
316
|
};
|
|
263
317
|
var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
264
318
|
#mastra;
|
|
@@ -310,23 +364,14 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
310
364
|
}
|
|
311
365
|
}
|
|
312
366
|
}
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
executionGraph: this.executionGraph,
|
|
321
|
-
serializedStepGraph: this.serializedStepGraph,
|
|
322
|
-
mastra: this.#mastra,
|
|
323
|
-
retryConfig: this.retryConfig,
|
|
324
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
325
|
-
},
|
|
326
|
-
this.inngest
|
|
367
|
+
/**
|
|
368
|
+
* @deprecated Use createRunAsync() instead.
|
|
369
|
+
* @throws {Error} Always throws an error directing users to use createRunAsync()
|
|
370
|
+
*/
|
|
371
|
+
createRun(_options) {
|
|
372
|
+
throw new Error(
|
|
373
|
+
"createRun() has been deprecated. Please use createRunAsync() instead.\n\nMigration guide:\n Before: const run = workflow.createRun();\n After: const run = await workflow.createRunAsync();\n\nNote: createRunAsync() is an async method, so make sure your calling function is async."
|
|
327
374
|
);
|
|
328
|
-
this.runs.set(runIdToUse, run);
|
|
329
|
-
return run;
|
|
330
375
|
}
|
|
331
376
|
async createRunAsync(options) {
|
|
332
377
|
const runIdToUse = options?.runId || randomUUID();
|
|
@@ -334,21 +379,28 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
334
379
|
{
|
|
335
380
|
workflowId: this.id,
|
|
336
381
|
runId: runIdToUse,
|
|
382
|
+
resourceId: options?.resourceId,
|
|
337
383
|
executionEngine: this.executionEngine,
|
|
338
384
|
executionGraph: this.executionGraph,
|
|
339
385
|
serializedStepGraph: this.serializedStepGraph,
|
|
340
386
|
mastra: this.#mastra,
|
|
341
387
|
retryConfig: this.retryConfig,
|
|
342
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
388
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
389
|
+
workflowSteps: this.steps
|
|
343
390
|
},
|
|
344
391
|
this.inngest
|
|
345
392
|
);
|
|
346
393
|
this.runs.set(runIdToUse, run);
|
|
394
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
395
|
+
workflowStatus: run.workflowRunStatus,
|
|
396
|
+
stepResults: {}
|
|
397
|
+
});
|
|
347
398
|
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
348
|
-
if (!workflowSnapshotInStorage) {
|
|
399
|
+
if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
|
|
349
400
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
350
401
|
workflowName: this.id,
|
|
351
402
|
runId: runIdToUse,
|
|
403
|
+
resourceId: options?.resourceId,
|
|
352
404
|
snapshot: {
|
|
353
405
|
runId: runIdToUse,
|
|
354
406
|
status: "pending",
|
|
@@ -358,6 +410,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
358
410
|
waitingPaths: {},
|
|
359
411
|
serializedStepGraph: this.serializedStepGraph,
|
|
360
412
|
suspendedPaths: {},
|
|
413
|
+
resumeLabels: {},
|
|
361
414
|
result: void 0,
|
|
362
415
|
error: void 0,
|
|
363
416
|
// @ts-ignore
|
|
@@ -382,7 +435,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
382
435
|
},
|
|
383
436
|
{ event: `workflow.${this.id}` },
|
|
384
437
|
async ({ event, step, attempt, publish }) => {
|
|
385
|
-
let { inputData, runId, resume } = event.data;
|
|
438
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions } = event.data;
|
|
386
439
|
if (!runId) {
|
|
387
440
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
388
441
|
return randomUUID();
|
|
@@ -410,21 +463,32 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
410
463
|
once: (_event, _callback) => {
|
|
411
464
|
}
|
|
412
465
|
};
|
|
413
|
-
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
466
|
+
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
414
467
|
const result = await engine.execute({
|
|
415
468
|
workflowId: this.id,
|
|
416
469
|
runId,
|
|
470
|
+
resourceId,
|
|
417
471
|
graph: this.executionGraph,
|
|
418
472
|
serializedStepGraph: this.serializedStepGraph,
|
|
419
473
|
input: inputData,
|
|
474
|
+
initialState,
|
|
420
475
|
emitter,
|
|
421
476
|
retryConfig: this.retryConfig,
|
|
422
477
|
runtimeContext: new RuntimeContext(),
|
|
423
478
|
// TODO
|
|
424
479
|
resume,
|
|
425
480
|
abortController: new AbortController(),
|
|
426
|
-
currentSpan: void 0
|
|
481
|
+
currentSpan: void 0,
|
|
427
482
|
// TODO: Pass actual parent AI span from workflow execution context
|
|
483
|
+
outputOptions
|
|
484
|
+
});
|
|
485
|
+
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
486
|
+
if (result.status === "failed") {
|
|
487
|
+
throw new NonRetriableError(`Workflow failed`, {
|
|
488
|
+
cause: result
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
return result;
|
|
428
492
|
});
|
|
429
493
|
return { result, runId };
|
|
430
494
|
}
|
|
@@ -458,11 +522,10 @@ function createStep(params) {
|
|
|
458
522
|
if (isAgent(params)) {
|
|
459
523
|
return {
|
|
460
524
|
id: params.name,
|
|
525
|
+
description: params.getDescription(),
|
|
461
526
|
// @ts-ignore
|
|
462
527
|
inputSchema: z.object({
|
|
463
528
|
prompt: z.string()
|
|
464
|
-
// resourceId: z.string().optional(),
|
|
465
|
-
// threadId: z.string().optional(),
|
|
466
529
|
}),
|
|
467
530
|
// @ts-ignore
|
|
468
531
|
outputSchema: z.object({
|
|
@@ -478,34 +541,66 @@ function createStep(params) {
|
|
|
478
541
|
name: params.name,
|
|
479
542
|
args: inputData
|
|
480
543
|
};
|
|
481
|
-
await
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
544
|
+
if ((await params.getLLM()).getModel().specificationVersion === `v2`) {
|
|
545
|
+
const { fullStream } = await params.stream(inputData.prompt, {
|
|
546
|
+
runtimeContext,
|
|
547
|
+
tracingContext,
|
|
548
|
+
onFinish: (result) => {
|
|
549
|
+
streamPromise.resolve(result.text);
|
|
550
|
+
},
|
|
551
|
+
abortSignal
|
|
552
|
+
});
|
|
553
|
+
if (abortSignal.aborted) {
|
|
554
|
+
return abort();
|
|
555
|
+
}
|
|
556
|
+
await emitter.emit("watch-v2", {
|
|
557
|
+
type: "tool-call-streaming-start",
|
|
558
|
+
...toolData ?? {}
|
|
559
|
+
});
|
|
560
|
+
for await (const chunk of fullStream) {
|
|
561
|
+
if (chunk.type === "text-delta") {
|
|
562
|
+
await emitter.emit("watch-v2", {
|
|
563
|
+
type: "tool-call-delta",
|
|
564
|
+
...toolData ?? {},
|
|
565
|
+
argsTextDelta: chunk.payload.text
|
|
566
|
+
});
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
} else {
|
|
570
|
+
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
571
|
+
runtimeContext,
|
|
572
|
+
tracingContext,
|
|
573
|
+
onFinish: (result) => {
|
|
574
|
+
streamPromise.resolve(result.text);
|
|
575
|
+
},
|
|
576
|
+
abortSignal
|
|
577
|
+
});
|
|
578
|
+
if (abortSignal.aborted) {
|
|
579
|
+
return abort();
|
|
580
|
+
}
|
|
581
|
+
await emitter.emit("watch-v2", {
|
|
582
|
+
type: "tool-call-streaming-start",
|
|
583
|
+
...toolData ?? {}
|
|
584
|
+
});
|
|
585
|
+
for await (const chunk of fullStream) {
|
|
586
|
+
if (chunk.type === "text-delta") {
|
|
587
|
+
await emitter.emit("watch-v2", {
|
|
588
|
+
type: "tool-call-delta",
|
|
589
|
+
...toolData ?? {},
|
|
590
|
+
argsTextDelta: chunk.textDelta
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
500
594
|
}
|
|
501
595
|
await emitter.emit("watch-v2", {
|
|
502
|
-
type: "
|
|
503
|
-
|
|
596
|
+
type: "tool-call-streaming-finish",
|
|
597
|
+
...toolData ?? {}
|
|
504
598
|
});
|
|
505
599
|
return {
|
|
506
600
|
text: await streamPromise.promise
|
|
507
601
|
};
|
|
508
|
-
}
|
|
602
|
+
},
|
|
603
|
+
component: params.component
|
|
509
604
|
};
|
|
510
605
|
}
|
|
511
606
|
if (isTool(params)) {
|
|
@@ -516,16 +611,20 @@ function createStep(params) {
|
|
|
516
611
|
// TODO: tool probably should have strong id type
|
|
517
612
|
// @ts-ignore
|
|
518
613
|
id: params.id,
|
|
614
|
+
description: params.description,
|
|
519
615
|
inputSchema: params.inputSchema,
|
|
520
616
|
outputSchema: params.outputSchema,
|
|
521
|
-
execute: async ({ inputData, mastra, runtimeContext, tracingContext }) => {
|
|
617
|
+
execute: async ({ inputData, mastra, runtimeContext, tracingContext, suspend, resumeData }) => {
|
|
522
618
|
return params.execute({
|
|
523
619
|
context: inputData,
|
|
524
620
|
mastra: wrapMastra(mastra, tracingContext),
|
|
525
621
|
runtimeContext,
|
|
526
|
-
tracingContext
|
|
622
|
+
tracingContext,
|
|
623
|
+
suspend,
|
|
624
|
+
resumeData
|
|
527
625
|
});
|
|
528
|
-
}
|
|
626
|
+
},
|
|
627
|
+
component: "TOOL"
|
|
529
628
|
};
|
|
530
629
|
}
|
|
531
630
|
return {
|
|
@@ -541,7 +640,10 @@ function createStep(params) {
|
|
|
541
640
|
function init(inngest) {
|
|
542
641
|
return {
|
|
543
642
|
createWorkflow(params) {
|
|
544
|
-
return new InngestWorkflow(
|
|
643
|
+
return new InngestWorkflow(
|
|
644
|
+
params,
|
|
645
|
+
inngest
|
|
646
|
+
);
|
|
545
647
|
},
|
|
546
648
|
createStep,
|
|
547
649
|
cloneStep(step, opts) {
|
|
@@ -550,7 +652,11 @@ function init(inngest) {
|
|
|
550
652
|
description: step.description,
|
|
551
653
|
inputSchema: step.inputSchema,
|
|
552
654
|
outputSchema: step.outputSchema,
|
|
553
|
-
|
|
655
|
+
resumeSchema: step.resumeSchema,
|
|
656
|
+
suspendSchema: step.suspendSchema,
|
|
657
|
+
stateSchema: step.stateSchema,
|
|
658
|
+
execute: step.execute,
|
|
659
|
+
component: step.component
|
|
554
660
|
};
|
|
555
661
|
},
|
|
556
662
|
cloneWorkflow(workflow, opts) {
|
|
@@ -570,8 +676,8 @@ function init(inngest) {
|
|
|
570
676
|
var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
571
677
|
inngestStep;
|
|
572
678
|
inngestAttempts;
|
|
573
|
-
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
574
|
-
super({ mastra });
|
|
679
|
+
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
680
|
+
super({ mastra, options });
|
|
575
681
|
this.inngestStep = inngestStep;
|
|
576
682
|
this.inngestAttempts = inngestAttempts;
|
|
577
683
|
}
|
|
@@ -634,7 +740,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
634
740
|
});
|
|
635
741
|
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
636
742
|
if (stepResult?.status === "suspended") {
|
|
637
|
-
const nestedPath = stepResult?.
|
|
743
|
+
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
638
744
|
return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
|
|
639
745
|
}
|
|
640
746
|
return [];
|
|
@@ -667,7 +773,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
667
773
|
attributes: {
|
|
668
774
|
durationMs: duration,
|
|
669
775
|
sleepType: fn ? "dynamic" : "fixed"
|
|
670
|
-
}
|
|
776
|
+
},
|
|
777
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
671
778
|
});
|
|
672
779
|
if (fn) {
|
|
673
780
|
const stepCallId = randomUUID();
|
|
@@ -678,21 +785,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
678
785
|
mastra: this.mastra,
|
|
679
786
|
runtimeContext,
|
|
680
787
|
inputData: prevOutput,
|
|
788
|
+
state: executionContext.state,
|
|
789
|
+
setState: (state) => {
|
|
790
|
+
executionContext.state = state;
|
|
791
|
+
},
|
|
681
792
|
runCount: -1,
|
|
682
793
|
tracingContext: {
|
|
683
794
|
currentSpan: sleepSpan
|
|
684
795
|
},
|
|
685
796
|
getInitData: () => stepResults?.input,
|
|
686
|
-
getStepResult: (
|
|
687
|
-
if (!step?.id) {
|
|
688
|
-
return null;
|
|
689
|
-
}
|
|
690
|
-
const result = stepResults[step.id];
|
|
691
|
-
if (result?.status === "success") {
|
|
692
|
-
return result.output;
|
|
693
|
-
}
|
|
694
|
-
return null;
|
|
695
|
-
},
|
|
797
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
696
798
|
// TODO: this function shouldn't have suspend probably?
|
|
697
799
|
suspend: async (_suspendPayload) => {
|
|
698
800
|
},
|
|
@@ -752,7 +854,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
752
854
|
untilDate: date,
|
|
753
855
|
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
754
856
|
sleepType: fn ? "dynamic" : "fixed"
|
|
755
|
-
}
|
|
857
|
+
},
|
|
858
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
756
859
|
});
|
|
757
860
|
if (fn) {
|
|
758
861
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
@@ -763,21 +866,16 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
763
866
|
mastra: this.mastra,
|
|
764
867
|
runtimeContext,
|
|
765
868
|
inputData: prevOutput,
|
|
869
|
+
state: executionContext.state,
|
|
870
|
+
setState: (state) => {
|
|
871
|
+
executionContext.state = state;
|
|
872
|
+
},
|
|
766
873
|
runCount: -1,
|
|
767
874
|
tracingContext: {
|
|
768
875
|
currentSpan: sleepUntilSpan
|
|
769
876
|
},
|
|
770
877
|
getInitData: () => stepResults?.input,
|
|
771
|
-
getStepResult: (
|
|
772
|
-
if (!step?.id) {
|
|
773
|
-
return null;
|
|
774
|
-
}
|
|
775
|
-
const result = stepResults[step.id];
|
|
776
|
-
if (result?.status === "success") {
|
|
777
|
-
return result.output;
|
|
778
|
-
}
|
|
779
|
-
return null;
|
|
780
|
-
},
|
|
878
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
781
879
|
// TODO: this function shouldn't have suspend probably?
|
|
782
880
|
suspend: async (_suspendPayload) => {
|
|
783
881
|
},
|
|
@@ -802,6 +900,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
802
900
|
)
|
|
803
901
|
});
|
|
804
902
|
});
|
|
903
|
+
if (date && !(date instanceof Date)) {
|
|
904
|
+
date = new Date(date);
|
|
905
|
+
}
|
|
805
906
|
const time = !date ? 0 : date.getTime() - Date.now();
|
|
806
907
|
sleepUntilSpan?.update({
|
|
807
908
|
attributes: {
|
|
@@ -850,7 +951,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
850
951
|
input: prevOutput,
|
|
851
952
|
attributes: {
|
|
852
953
|
stepId: step.id
|
|
853
|
-
}
|
|
954
|
+
},
|
|
955
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
956
|
+
});
|
|
957
|
+
const { inputData, validationError } = await validateStepInput({
|
|
958
|
+
prevOutput,
|
|
959
|
+
step,
|
|
960
|
+
validateInputs: this.options?.validateInputs ?? false
|
|
854
961
|
});
|
|
855
962
|
const startedAt = await this.inngestStep.run(
|
|
856
963
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
@@ -882,7 +989,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
882
989
|
payload: {
|
|
883
990
|
id: step.id,
|
|
884
991
|
status: "running",
|
|
885
|
-
payload:
|
|
992
|
+
payload: inputData,
|
|
886
993
|
startedAt: startedAt2
|
|
887
994
|
}
|
|
888
995
|
});
|
|
@@ -893,38 +1000,60 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
893
1000
|
const isResume = !!resume?.steps?.length;
|
|
894
1001
|
let result;
|
|
895
1002
|
let runId;
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1003
|
+
try {
|
|
1004
|
+
if (isResume) {
|
|
1005
|
+
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
|
|
1006
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1007
|
+
workflowName: step.id,
|
|
1008
|
+
runId
|
|
1009
|
+
});
|
|
1010
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1011
|
+
function: step.getFunction(),
|
|
1012
|
+
data: {
|
|
1013
|
+
inputData,
|
|
1014
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
908
1015
|
runId,
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1016
|
+
resume: {
|
|
1017
|
+
runId,
|
|
1018
|
+
steps: resume.steps.slice(1),
|
|
1019
|
+
stepResults: snapshot?.context,
|
|
1020
|
+
resumePayload: resume.resumePayload,
|
|
1021
|
+
// @ts-ignore
|
|
1022
|
+
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1023
|
+
},
|
|
1024
|
+
outputOptions: { includeState: true }
|
|
914
1025
|
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1026
|
+
});
|
|
1027
|
+
result = invokeResp.result;
|
|
1028
|
+
runId = invokeResp.runId;
|
|
1029
|
+
executionContext.state = invokeResp.result.state;
|
|
1030
|
+
} else {
|
|
1031
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1032
|
+
function: step.getFunction(),
|
|
1033
|
+
data: {
|
|
1034
|
+
inputData,
|
|
1035
|
+
initialState: executionContext.state ?? {},
|
|
1036
|
+
outputOptions: { includeState: true }
|
|
1037
|
+
}
|
|
1038
|
+
});
|
|
1039
|
+
result = invokeResp.result;
|
|
1040
|
+
runId = invokeResp.runId;
|
|
1041
|
+
executionContext.state = invokeResp.result.state;
|
|
1042
|
+
}
|
|
1043
|
+
} catch (e) {
|
|
1044
|
+
const errorCause = e?.cause;
|
|
1045
|
+
if (errorCause && typeof errorCause === "object") {
|
|
1046
|
+
result = errorCause;
|
|
1047
|
+
runId = errorCause.runId || randomUUID();
|
|
1048
|
+
} else {
|
|
1049
|
+
runId = randomUUID();
|
|
1050
|
+
result = {
|
|
1051
|
+
status: "failed",
|
|
1052
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1053
|
+
steps: {},
|
|
1054
|
+
input: inputData
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
928
1057
|
}
|
|
929
1058
|
const res = await this.inngestStep.run(
|
|
930
1059
|
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
@@ -963,7 +1092,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
963
1092
|
return stepRes2?.status === "suspended";
|
|
964
1093
|
});
|
|
965
1094
|
for (const [stepName, stepResult] of suspendedSteps) {
|
|
966
|
-
const suspendPath = [stepName, ...stepResult?.
|
|
1095
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
967
1096
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
968
1097
|
await emitter.emit("watch", {
|
|
969
1098
|
type: "watch",
|
|
@@ -971,7 +1100,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
971
1100
|
currentStep: {
|
|
972
1101
|
id: step.id,
|
|
973
1102
|
status: "suspended",
|
|
974
|
-
payload:
|
|
1103
|
+
payload: stepResult.payload,
|
|
1104
|
+
suspendPayload: {
|
|
1105
|
+
...stepResult?.suspendPayload,
|
|
1106
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1107
|
+
}
|
|
975
1108
|
},
|
|
976
1109
|
workflowState: {
|
|
977
1110
|
status: "running",
|
|
@@ -993,7 +1126,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
993
1126
|
executionContext,
|
|
994
1127
|
result: {
|
|
995
1128
|
status: "suspended",
|
|
996
|
-
payload:
|
|
1129
|
+
payload: stepResult.payload,
|
|
1130
|
+
suspendPayload: {
|
|
1131
|
+
...stepResult?.suspendPayload,
|
|
1132
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1133
|
+
}
|
|
997
1134
|
}
|
|
998
1135
|
};
|
|
999
1136
|
}
|
|
@@ -1058,141 +1195,182 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1058
1195
|
}
|
|
1059
1196
|
);
|
|
1060
1197
|
Object.assign(executionContext, res.executionContext);
|
|
1061
|
-
return
|
|
1198
|
+
return {
|
|
1199
|
+
...res.result,
|
|
1200
|
+
startedAt,
|
|
1201
|
+
endedAt: Date.now(),
|
|
1202
|
+
payload: inputData,
|
|
1203
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1204
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1205
|
+
};
|
|
1062
1206
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1207
|
+
let stepRes;
|
|
1208
|
+
try {
|
|
1209
|
+
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1210
|
+
let execResults;
|
|
1211
|
+
let suspended;
|
|
1212
|
+
let bailed;
|
|
1213
|
+
try {
|
|
1214
|
+
if (validationError) {
|
|
1215
|
+
throw validationError;
|
|
1216
|
+
}
|
|
1217
|
+
const result = await step.execute({
|
|
1218
|
+
runId: executionContext.runId,
|
|
1219
|
+
mastra: this.mastra,
|
|
1220
|
+
runtimeContext,
|
|
1221
|
+
writableStream,
|
|
1222
|
+
state: executionContext?.state ?? {},
|
|
1223
|
+
setState: (state) => {
|
|
1224
|
+
executionContext.state = state;
|
|
1225
|
+
},
|
|
1226
|
+
inputData,
|
|
1227
|
+
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1228
|
+
tracingContext: {
|
|
1229
|
+
currentSpan: stepAISpan
|
|
1230
|
+
},
|
|
1231
|
+
getInitData: () => stepResults?.input,
|
|
1232
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
1233
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1234
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1235
|
+
if (suspendOptions?.resumeLabel) {
|
|
1236
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1237
|
+
for (const label of resumeLabel) {
|
|
1238
|
+
executionContext.resumeLabels[label] = {
|
|
1239
|
+
stepId: step.id,
|
|
1240
|
+
foreachIndex: executionContext.foreachIndex
|
|
1241
|
+
};
|
|
1242
|
+
}
|
|
1243
|
+
}
|
|
1244
|
+
suspended = { payload: suspendPayload };
|
|
1245
|
+
},
|
|
1246
|
+
bail: (result2) => {
|
|
1247
|
+
bailed = { payload: result2 };
|
|
1248
|
+
},
|
|
1249
|
+
resume: {
|
|
1250
|
+
steps: resume?.steps?.slice(1) || [],
|
|
1251
|
+
resumePayload: resume?.resumePayload,
|
|
1252
|
+
// @ts-ignore
|
|
1253
|
+
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1254
|
+
},
|
|
1255
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1256
|
+
engine: {
|
|
1257
|
+
step: this.inngestStep
|
|
1258
|
+
},
|
|
1259
|
+
abortSignal: abortController.signal
|
|
1260
|
+
});
|
|
1261
|
+
const endedAt = Date.now();
|
|
1262
|
+
execResults = {
|
|
1263
|
+
status: "success",
|
|
1264
|
+
output: result,
|
|
1265
|
+
startedAt,
|
|
1266
|
+
endedAt,
|
|
1267
|
+
payload: inputData,
|
|
1268
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1269
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1270
|
+
};
|
|
1271
|
+
} catch (e) {
|
|
1272
|
+
const stepFailure = {
|
|
1273
|
+
status: "failed",
|
|
1274
|
+
payload: inputData,
|
|
1275
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1276
|
+
endedAt: Date.now(),
|
|
1277
|
+
startedAt,
|
|
1278
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1279
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1280
|
+
};
|
|
1281
|
+
execResults = stepFailure;
|
|
1282
|
+
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1283
|
+
stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1284
|
+
throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1285
|
+
cause: execResults
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
if (suspended) {
|
|
1289
|
+
execResults = {
|
|
1290
|
+
status: "suspended",
|
|
1291
|
+
suspendPayload: suspended.payload,
|
|
1292
|
+
payload: inputData,
|
|
1293
|
+
suspendedAt: Date.now(),
|
|
1294
|
+
startedAt,
|
|
1295
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1296
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1297
|
+
};
|
|
1298
|
+
} else if (bailed) {
|
|
1299
|
+
execResults = {
|
|
1300
|
+
status: "bailed",
|
|
1301
|
+
output: bailed.payload,
|
|
1302
|
+
payload: inputData,
|
|
1303
|
+
endedAt: Date.now(),
|
|
1304
|
+
startedAt
|
|
1305
|
+
};
|
|
1306
|
+
}
|
|
1307
|
+
await emitter.emit("watch", {
|
|
1308
|
+
type: "watch",
|
|
1309
|
+
payload: {
|
|
1310
|
+
currentStep: {
|
|
1311
|
+
id: step.id,
|
|
1312
|
+
...execResults
|
|
1313
|
+
},
|
|
1314
|
+
workflowState: {
|
|
1315
|
+
status: "running",
|
|
1316
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
1317
|
+
result: null,
|
|
1318
|
+
error: null
|
|
1083
1319
|
}
|
|
1084
|
-
return null;
|
|
1085
|
-
},
|
|
1086
|
-
suspend: async (suspendPayload) => {
|
|
1087
|
-
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1088
|
-
suspended = { payload: suspendPayload };
|
|
1089
|
-
},
|
|
1090
|
-
bail: (result2) => {
|
|
1091
|
-
bailed = { payload: result2 };
|
|
1092
|
-
},
|
|
1093
|
-
resume: {
|
|
1094
|
-
steps: resume?.steps?.slice(1) || [],
|
|
1095
|
-
resumePayload: resume?.resumePayload,
|
|
1096
|
-
// @ts-ignore
|
|
1097
|
-
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
1098
|
-
},
|
|
1099
|
-
[EMITTER_SYMBOL]: emitter,
|
|
1100
|
-
engine: {
|
|
1101
|
-
step: this.inngestStep
|
|
1102
1320
|
},
|
|
1103
|
-
|
|
1321
|
+
eventTimestamp: Date.now()
|
|
1104
1322
|
});
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
status: "suspended",
|
|
1129
|
-
suspendedPayload: suspended.payload,
|
|
1130
|
-
payload: prevOutput,
|
|
1131
|
-
suspendedAt: Date.now(),
|
|
1132
|
-
startedAt,
|
|
1133
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1134
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1135
|
-
};
|
|
1136
|
-
} else if (bailed) {
|
|
1137
|
-
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
1138
|
-
}
|
|
1139
|
-
if (execResults.status === "failed") {
|
|
1140
|
-
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
1141
|
-
const error = new Error(execResults.error);
|
|
1142
|
-
stepAISpan?.error({ error });
|
|
1143
|
-
throw error;
|
|
1323
|
+
if (execResults.status === "suspended") {
|
|
1324
|
+
await emitter.emit("watch-v2", {
|
|
1325
|
+
type: "workflow-step-suspended",
|
|
1326
|
+
payload: {
|
|
1327
|
+
id: step.id,
|
|
1328
|
+
...execResults
|
|
1329
|
+
}
|
|
1330
|
+
});
|
|
1331
|
+
} else {
|
|
1332
|
+
await emitter.emit("watch-v2", {
|
|
1333
|
+
type: "workflow-step-result",
|
|
1334
|
+
payload: {
|
|
1335
|
+
id: step.id,
|
|
1336
|
+
...execResults
|
|
1337
|
+
}
|
|
1338
|
+
});
|
|
1339
|
+
await emitter.emit("watch-v2", {
|
|
1340
|
+
type: "workflow-step-finish",
|
|
1341
|
+
payload: {
|
|
1342
|
+
id: step.id,
|
|
1343
|
+
metadata: {}
|
|
1344
|
+
}
|
|
1345
|
+
});
|
|
1144
1346
|
}
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
type: "watch",
|
|
1148
|
-
payload: {
|
|
1149
|
-
currentStep: {
|
|
1150
|
-
id: step.id,
|
|
1151
|
-
...execResults
|
|
1152
|
-
},
|
|
1153
|
-
workflowState: {
|
|
1154
|
-
status: "running",
|
|
1155
|
-
steps: { ...stepResults, [step.id]: execResults },
|
|
1156
|
-
result: null,
|
|
1157
|
-
error: null
|
|
1158
|
-
}
|
|
1159
|
-
},
|
|
1160
|
-
eventTimestamp: Date.now()
|
|
1347
|
+
stepAISpan?.end({ output: execResults });
|
|
1348
|
+
return { result: execResults, executionContext, stepResults };
|
|
1161
1349
|
});
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
payload: {
|
|
1181
|
-
id: step.id,
|
|
1182
|
-
metadata: {}
|
|
1183
|
-
}
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
stepAISpan?.end({ output: execResults });
|
|
1187
|
-
return { result: execResults, executionContext, stepResults };
|
|
1188
|
-
});
|
|
1189
|
-
if (disableScorers !== false) {
|
|
1350
|
+
} catch (e) {
|
|
1351
|
+
const stepFailure = e instanceof Error ? e?.cause : {
|
|
1352
|
+
status: "failed",
|
|
1353
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1354
|
+
payload: inputData,
|
|
1355
|
+
startedAt,
|
|
1356
|
+
endedAt: Date.now()
|
|
1357
|
+
};
|
|
1358
|
+
stepRes = {
|
|
1359
|
+
result: stepFailure,
|
|
1360
|
+
executionContext,
|
|
1361
|
+
stepResults: {
|
|
1362
|
+
...stepResults,
|
|
1363
|
+
[step.id]: stepFailure
|
|
1364
|
+
}
|
|
1365
|
+
};
|
|
1366
|
+
}
|
|
1367
|
+
if (disableScorers !== false && stepRes.result.status === "success") {
|
|
1190
1368
|
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1191
1369
|
if (step.scorers) {
|
|
1192
1370
|
await this.runScorers({
|
|
1193
1371
|
scorers: step.scorers,
|
|
1194
1372
|
runId: executionContext.runId,
|
|
1195
|
-
input:
|
|
1373
|
+
input: inputData,
|
|
1196
1374
|
output: stepRes.result,
|
|
1197
1375
|
workflowId: executionContext.workflowId,
|
|
1198
1376
|
stepId: step.id,
|
|
@@ -1205,12 +1383,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1205
1383
|
}
|
|
1206
1384
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1207
1385
|
Object.assign(stepResults, stepRes.stepResults);
|
|
1386
|
+
executionContext.state = stepRes.executionContext.state;
|
|
1208
1387
|
return stepRes.result;
|
|
1209
1388
|
}
|
|
1210
1389
|
async persistStepUpdate({
|
|
1211
1390
|
workflowId,
|
|
1212
1391
|
runId,
|
|
1213
1392
|
stepResults,
|
|
1393
|
+
resourceId,
|
|
1214
1394
|
executionContext,
|
|
1215
1395
|
serializedStepGraph,
|
|
1216
1396
|
workflowStatus,
|
|
@@ -1220,15 +1400,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1220
1400
|
await this.inngestStep.run(
|
|
1221
1401
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1222
1402
|
async () => {
|
|
1403
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
|
|
1404
|
+
if (!shouldPersistSnapshot) {
|
|
1405
|
+
return;
|
|
1406
|
+
}
|
|
1223
1407
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1224
1408
|
workflowName: workflowId,
|
|
1225
1409
|
runId,
|
|
1410
|
+
resourceId,
|
|
1226
1411
|
snapshot: {
|
|
1227
1412
|
runId,
|
|
1228
|
-
value:
|
|
1413
|
+
value: executionContext.state,
|
|
1229
1414
|
context: stepResults,
|
|
1230
1415
|
activePaths: [],
|
|
1231
1416
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1417
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1232
1418
|
waitingPaths: {},
|
|
1233
1419
|
serializedStepGraph,
|
|
1234
1420
|
status: workflowStatus,
|
|
@@ -1264,7 +1450,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1264
1450
|
input: prevOutput,
|
|
1265
1451
|
attributes: {
|
|
1266
1452
|
conditionCount: entry.conditions.length
|
|
1267
|
-
}
|
|
1453
|
+
},
|
|
1454
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1268
1455
|
});
|
|
1269
1456
|
let execResults;
|
|
1270
1457
|
const truthyIndexes = (await Promise.all(
|
|
@@ -1276,7 +1463,8 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1276
1463
|
input: prevOutput,
|
|
1277
1464
|
attributes: {
|
|
1278
1465
|
conditionIndex: index
|
|
1279
|
-
}
|
|
1466
|
+
},
|
|
1467
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1280
1468
|
});
|
|
1281
1469
|
try {
|
|
1282
1470
|
const result = await cond({
|
|
@@ -1286,20 +1474,15 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1286
1474
|
runtimeContext,
|
|
1287
1475
|
runCount: -1,
|
|
1288
1476
|
inputData: prevOutput,
|
|
1477
|
+
state: executionContext.state,
|
|
1478
|
+
setState: (state) => {
|
|
1479
|
+
executionContext.state = state;
|
|
1480
|
+
},
|
|
1289
1481
|
tracingContext: {
|
|
1290
1482
|
currentSpan: evalSpan
|
|
1291
1483
|
},
|
|
1292
1484
|
getInitData: () => stepResults?.input,
|
|
1293
|
-
getStepResult: (
|
|
1294
|
-
if (!step?.id) {
|
|
1295
|
-
return null;
|
|
1296
|
-
}
|
|
1297
|
-
const result2 = stepResults[step.id];
|
|
1298
|
-
if (result2?.status === "success") {
|
|
1299
|
-
return result2.output;
|
|
1300
|
-
}
|
|
1301
|
-
return null;
|
|
1302
|
-
},
|
|
1485
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
1303
1486
|
// TODO: this function shouldn't have suspend probably?
|
|
1304
1487
|
suspend: async (_suspendPayload) => {
|
|
1305
1488
|
},
|
|
@@ -1366,8 +1549,10 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1366
1549
|
runId,
|
|
1367
1550
|
executionPath: [...executionContext.executionPath, index],
|
|
1368
1551
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1552
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1369
1553
|
retryConfig: executionContext.retryConfig,
|
|
1370
|
-
executionSpan: executionContext.executionSpan
|
|
1554
|
+
executionSpan: executionContext.executionSpan,
|
|
1555
|
+
state: executionContext.state
|
|
1371
1556
|
},
|
|
1372
1557
|
emitter,
|
|
1373
1558
|
abortController,
|
|
@@ -1385,7 +1570,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1385
1570
|
if (hasFailed) {
|
|
1386
1571
|
execResults = { status: "failed", error: hasFailed.result.error };
|
|
1387
1572
|
} else if (hasSuspended) {
|
|
1388
|
-
execResults = { status: "suspended",
|
|
1573
|
+
execResults = { status: "suspended", suspendPayload: hasSuspended.result.suspendPayload };
|
|
1389
1574
|
} else {
|
|
1390
1575
|
execResults = {
|
|
1391
1576
|
status: "success",
|