@mastra/inngest 0.0.0-pgvector-index-fix-20250905222058 → 0.0.0-playground-studio-cloud-20251031080052
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 +378 -10
- package/dist/index.cjs +597 -384
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +74 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +598 -385
- package/dist/index.js.map +1 -1
- package/package.json +14 -14
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 { ChunkFrom, 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, createDeprecationProxy, getStepResult, runCountDeprecationMessage, 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
|
}
|
|
@@ -587,7 +693,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
587
693
|
});
|
|
588
694
|
return result;
|
|
589
695
|
}
|
|
590
|
-
async fmtReturnValue(
|
|
696
|
+
async fmtReturnValue(emitter, stepResults, lastOutput, error) {
|
|
591
697
|
const base = {
|
|
592
698
|
status: lastOutput.status,
|
|
593
699
|
steps: stepResults
|
|
@@ -634,14 +740,13 @@ 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 [];
|
|
641
747
|
});
|
|
642
748
|
base.suspended = suspendedStepIds;
|
|
643
749
|
}
|
|
644
|
-
executionSpan?.end();
|
|
645
750
|
return base;
|
|
646
751
|
}
|
|
647
752
|
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
@@ -667,55 +772,61 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
667
772
|
attributes: {
|
|
668
773
|
durationMs: duration,
|
|
669
774
|
sleepType: fn ? "dynamic" : "fixed"
|
|
670
|
-
}
|
|
775
|
+
},
|
|
776
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
671
777
|
});
|
|
672
778
|
if (fn) {
|
|
673
779
|
const stepCallId = randomUUID();
|
|
674
780
|
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
675
|
-
return await fn(
|
|
676
|
-
|
|
677
|
-
workflowId,
|
|
678
|
-
mastra: this.mastra,
|
|
679
|
-
runtimeContext,
|
|
680
|
-
inputData: prevOutput,
|
|
681
|
-
runCount: -1,
|
|
682
|
-
tracingContext: {
|
|
683
|
-
currentSpan: sleepSpan
|
|
684
|
-
},
|
|
685
|
-
getInitData: () => stepResults?.input,
|
|
686
|
-
getStepResult: (step) => {
|
|
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
|
-
},
|
|
696
|
-
// TODO: this function shouldn't have suspend probably?
|
|
697
|
-
suspend: async (_suspendPayload) => {
|
|
698
|
-
},
|
|
699
|
-
bail: () => {
|
|
700
|
-
},
|
|
701
|
-
abort: () => {
|
|
702
|
-
abortController?.abort();
|
|
703
|
-
},
|
|
704
|
-
[EMITTER_SYMBOL]: emitter,
|
|
705
|
-
// TODO: add streamVNext support
|
|
706
|
-
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
707
|
-
engine: { step: this.inngestStep },
|
|
708
|
-
abortSignal: abortController?.signal,
|
|
709
|
-
writer: new ToolStream(
|
|
781
|
+
return await fn(
|
|
782
|
+
createDeprecationProxy(
|
|
710
783
|
{
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
784
|
+
runId,
|
|
785
|
+
workflowId,
|
|
786
|
+
mastra: this.mastra,
|
|
787
|
+
runtimeContext,
|
|
788
|
+
inputData: prevOutput,
|
|
789
|
+
state: executionContext.state,
|
|
790
|
+
setState: (state) => {
|
|
791
|
+
executionContext.state = state;
|
|
792
|
+
},
|
|
793
|
+
runCount: -1,
|
|
794
|
+
retryCount: -1,
|
|
795
|
+
tracingContext: {
|
|
796
|
+
currentSpan: sleepSpan
|
|
797
|
+
},
|
|
798
|
+
getInitData: () => stepResults?.input,
|
|
799
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
800
|
+
// TODO: this function shouldn't have suspend probably?
|
|
801
|
+
suspend: async (_suspendPayload) => {
|
|
802
|
+
},
|
|
803
|
+
bail: () => {
|
|
804
|
+
},
|
|
805
|
+
abort: () => {
|
|
806
|
+
abortController?.abort();
|
|
807
|
+
},
|
|
808
|
+
[EMITTER_SYMBOL]: emitter,
|
|
809
|
+
// TODO: add streamVNext support
|
|
810
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
811
|
+
engine: { step: this.inngestStep },
|
|
812
|
+
abortSignal: abortController?.signal,
|
|
813
|
+
writer: new ToolStream(
|
|
814
|
+
{
|
|
815
|
+
prefix: "workflow-step",
|
|
816
|
+
callId: stepCallId,
|
|
817
|
+
name: "sleep",
|
|
818
|
+
runId
|
|
819
|
+
},
|
|
820
|
+
writableStream
|
|
821
|
+
)
|
|
715
822
|
},
|
|
716
|
-
|
|
823
|
+
{
|
|
824
|
+
paramName: "runCount",
|
|
825
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
826
|
+
logger: this.logger
|
|
827
|
+
}
|
|
717
828
|
)
|
|
718
|
-
|
|
829
|
+
);
|
|
719
830
|
});
|
|
720
831
|
sleepSpan?.update({
|
|
721
832
|
attributes: {
|
|
@@ -752,56 +863,65 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
752
863
|
untilDate: date,
|
|
753
864
|
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
754
865
|
sleepType: fn ? "dynamic" : "fixed"
|
|
755
|
-
}
|
|
866
|
+
},
|
|
867
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
756
868
|
});
|
|
757
869
|
if (fn) {
|
|
758
870
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
759
871
|
const stepCallId = randomUUID();
|
|
760
|
-
return await fn(
|
|
761
|
-
|
|
762
|
-
workflowId,
|
|
763
|
-
mastra: this.mastra,
|
|
764
|
-
runtimeContext,
|
|
765
|
-
inputData: prevOutput,
|
|
766
|
-
runCount: -1,
|
|
767
|
-
tracingContext: {
|
|
768
|
-
currentSpan: sleepUntilSpan
|
|
769
|
-
},
|
|
770
|
-
getInitData: () => stepResults?.input,
|
|
771
|
-
getStepResult: (step) => {
|
|
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
|
-
},
|
|
781
|
-
// TODO: this function shouldn't have suspend probably?
|
|
782
|
-
suspend: async (_suspendPayload) => {
|
|
783
|
-
},
|
|
784
|
-
bail: () => {
|
|
785
|
-
},
|
|
786
|
-
abort: () => {
|
|
787
|
-
abortController?.abort();
|
|
788
|
-
},
|
|
789
|
-
[EMITTER_SYMBOL]: emitter,
|
|
790
|
-
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
791
|
-
// TODO: add streamVNext support
|
|
792
|
-
engine: { step: this.inngestStep },
|
|
793
|
-
abortSignal: abortController?.signal,
|
|
794
|
-
writer: new ToolStream(
|
|
872
|
+
return await fn(
|
|
873
|
+
createDeprecationProxy(
|
|
795
874
|
{
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
875
|
+
runId,
|
|
876
|
+
workflowId,
|
|
877
|
+
mastra: this.mastra,
|
|
878
|
+
runtimeContext,
|
|
879
|
+
inputData: prevOutput,
|
|
880
|
+
state: executionContext.state,
|
|
881
|
+
setState: (state) => {
|
|
882
|
+
executionContext.state = state;
|
|
883
|
+
},
|
|
884
|
+
runCount: -1,
|
|
885
|
+
retryCount: -1,
|
|
886
|
+
tracingContext: {
|
|
887
|
+
currentSpan: sleepUntilSpan
|
|
888
|
+
},
|
|
889
|
+
getInitData: () => stepResults?.input,
|
|
890
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
891
|
+
// TODO: this function shouldn't have suspend probably?
|
|
892
|
+
suspend: async (_suspendPayload) => {
|
|
893
|
+
},
|
|
894
|
+
bail: () => {
|
|
895
|
+
},
|
|
896
|
+
abort: () => {
|
|
897
|
+
abortController?.abort();
|
|
898
|
+
},
|
|
899
|
+
[EMITTER_SYMBOL]: emitter,
|
|
900
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
901
|
+
// TODO: add streamVNext support
|
|
902
|
+
engine: { step: this.inngestStep },
|
|
903
|
+
abortSignal: abortController?.signal,
|
|
904
|
+
writer: new ToolStream(
|
|
905
|
+
{
|
|
906
|
+
prefix: "workflow-step",
|
|
907
|
+
callId: stepCallId,
|
|
908
|
+
name: "sleep",
|
|
909
|
+
runId
|
|
910
|
+
},
|
|
911
|
+
writableStream
|
|
912
|
+
)
|
|
800
913
|
},
|
|
801
|
-
|
|
914
|
+
{
|
|
915
|
+
paramName: "runCount",
|
|
916
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
917
|
+
logger: this.logger
|
|
918
|
+
}
|
|
802
919
|
)
|
|
803
|
-
|
|
920
|
+
);
|
|
804
921
|
});
|
|
922
|
+
if (date && !(date instanceof Date)) {
|
|
923
|
+
date = new Date(date);
|
|
924
|
+
}
|
|
805
925
|
const time = !date ? 0 : date.getTime() - Date.now();
|
|
806
926
|
sleepUntilSpan?.update({
|
|
807
927
|
attributes: {
|
|
@@ -850,7 +970,13 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
850
970
|
input: prevOutput,
|
|
851
971
|
attributes: {
|
|
852
972
|
stepId: step.id
|
|
853
|
-
}
|
|
973
|
+
},
|
|
974
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
975
|
+
});
|
|
976
|
+
const { inputData, validationError } = await validateStepInput({
|
|
977
|
+
prevOutput,
|
|
978
|
+
step,
|
|
979
|
+
validateInputs: this.options?.validateInputs ?? false
|
|
854
980
|
});
|
|
855
981
|
const startedAt = await this.inngestStep.run(
|
|
856
982
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
@@ -882,7 +1008,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
882
1008
|
payload: {
|
|
883
1009
|
id: step.id,
|
|
884
1010
|
status: "running",
|
|
885
|
-
payload:
|
|
1011
|
+
payload: inputData,
|
|
886
1012
|
startedAt: startedAt2
|
|
887
1013
|
}
|
|
888
1014
|
});
|
|
@@ -893,38 +1019,60 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
893
1019
|
const isResume = !!resume?.steps?.length;
|
|
894
1020
|
let result;
|
|
895
1021
|
let runId;
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
1022
|
+
try {
|
|
1023
|
+
if (isResume) {
|
|
1024
|
+
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
|
|
1025
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1026
|
+
workflowName: step.id,
|
|
1027
|
+
runId
|
|
1028
|
+
});
|
|
1029
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1030
|
+
function: step.getFunction(),
|
|
1031
|
+
data: {
|
|
1032
|
+
inputData,
|
|
1033
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
908
1034
|
runId,
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1035
|
+
resume: {
|
|
1036
|
+
runId,
|
|
1037
|
+
steps: resume.steps.slice(1),
|
|
1038
|
+
stepResults: snapshot?.context,
|
|
1039
|
+
resumePayload: resume.resumePayload,
|
|
1040
|
+
// @ts-ignore
|
|
1041
|
+
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1042
|
+
},
|
|
1043
|
+
outputOptions: { includeState: true }
|
|
914
1044
|
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1045
|
+
});
|
|
1046
|
+
result = invokeResp.result;
|
|
1047
|
+
runId = invokeResp.runId;
|
|
1048
|
+
executionContext.state = invokeResp.result.state;
|
|
1049
|
+
} else {
|
|
1050
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1051
|
+
function: step.getFunction(),
|
|
1052
|
+
data: {
|
|
1053
|
+
inputData,
|
|
1054
|
+
initialState: executionContext.state ?? {},
|
|
1055
|
+
outputOptions: { includeState: true }
|
|
1056
|
+
}
|
|
1057
|
+
});
|
|
1058
|
+
result = invokeResp.result;
|
|
1059
|
+
runId = invokeResp.runId;
|
|
1060
|
+
executionContext.state = invokeResp.result.state;
|
|
1061
|
+
}
|
|
1062
|
+
} catch (e) {
|
|
1063
|
+
const errorCause = e?.cause;
|
|
1064
|
+
if (errorCause && typeof errorCause === "object") {
|
|
1065
|
+
result = errorCause;
|
|
1066
|
+
runId = errorCause.runId || randomUUID();
|
|
1067
|
+
} else {
|
|
1068
|
+
runId = randomUUID();
|
|
1069
|
+
result = {
|
|
1070
|
+
status: "failed",
|
|
1071
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1072
|
+
steps: {},
|
|
1073
|
+
input: inputData
|
|
1074
|
+
};
|
|
1075
|
+
}
|
|
928
1076
|
}
|
|
929
1077
|
const res = await this.inngestStep.run(
|
|
930
1078
|
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
@@ -963,7 +1111,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
963
1111
|
return stepRes2?.status === "suspended";
|
|
964
1112
|
});
|
|
965
1113
|
for (const [stepName, stepResult] of suspendedSteps) {
|
|
966
|
-
const suspendPath = [stepName, ...stepResult?.
|
|
1114
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
967
1115
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
968
1116
|
await emitter.emit("watch", {
|
|
969
1117
|
type: "watch",
|
|
@@ -971,7 +1119,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
971
1119
|
currentStep: {
|
|
972
1120
|
id: step.id,
|
|
973
1121
|
status: "suspended",
|
|
974
|
-
payload:
|
|
1122
|
+
payload: stepResult.payload,
|
|
1123
|
+
suspendPayload: {
|
|
1124
|
+
...stepResult?.suspendPayload,
|
|
1125
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1126
|
+
}
|
|
975
1127
|
},
|
|
976
1128
|
workflowState: {
|
|
977
1129
|
status: "running",
|
|
@@ -993,7 +1145,11 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
993
1145
|
executionContext,
|
|
994
1146
|
result: {
|
|
995
1147
|
status: "suspended",
|
|
996
|
-
payload:
|
|
1148
|
+
payload: stepResult.payload,
|
|
1149
|
+
suspendPayload: {
|
|
1150
|
+
...stepResult?.suspendPayload,
|
|
1151
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1152
|
+
}
|
|
997
1153
|
}
|
|
998
1154
|
};
|
|
999
1155
|
}
|
|
@@ -1058,141 +1214,182 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1058
1214
|
}
|
|
1059
1215
|
);
|
|
1060
1216
|
Object.assign(executionContext, res.executionContext);
|
|
1061
|
-
return
|
|
1217
|
+
return {
|
|
1218
|
+
...res.result,
|
|
1219
|
+
startedAt,
|
|
1220
|
+
endedAt: Date.now(),
|
|
1221
|
+
payload: inputData,
|
|
1222
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1223
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1224
|
+
};
|
|
1062
1225
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1226
|
+
let stepRes;
|
|
1227
|
+
try {
|
|
1228
|
+
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1229
|
+
let execResults;
|
|
1230
|
+
let suspended;
|
|
1231
|
+
let bailed;
|
|
1232
|
+
try {
|
|
1233
|
+
if (validationError) {
|
|
1234
|
+
throw validationError;
|
|
1235
|
+
}
|
|
1236
|
+
const result = await step.execute({
|
|
1237
|
+
runId: executionContext.runId,
|
|
1238
|
+
mastra: this.mastra,
|
|
1239
|
+
runtimeContext,
|
|
1240
|
+
writableStream,
|
|
1241
|
+
state: executionContext?.state ?? {},
|
|
1242
|
+
setState: (state) => {
|
|
1243
|
+
executionContext.state = state;
|
|
1244
|
+
},
|
|
1245
|
+
inputData,
|
|
1246
|
+
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1247
|
+
tracingContext: {
|
|
1248
|
+
currentSpan: stepAISpan
|
|
1249
|
+
},
|
|
1250
|
+
getInitData: () => stepResults?.input,
|
|
1251
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
1252
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1253
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1254
|
+
if (suspendOptions?.resumeLabel) {
|
|
1255
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1256
|
+
for (const label of resumeLabel) {
|
|
1257
|
+
executionContext.resumeLabels[label] = {
|
|
1258
|
+
stepId: step.id,
|
|
1259
|
+
foreachIndex: executionContext.foreachIndex
|
|
1260
|
+
};
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
suspended = { payload: suspendPayload };
|
|
1264
|
+
},
|
|
1265
|
+
bail: (result2) => {
|
|
1266
|
+
bailed = { payload: result2 };
|
|
1267
|
+
},
|
|
1268
|
+
resume: {
|
|
1269
|
+
steps: resume?.steps?.slice(1) || [],
|
|
1270
|
+
resumePayload: resume?.resumePayload,
|
|
1271
|
+
// @ts-ignore
|
|
1272
|
+
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1273
|
+
},
|
|
1274
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1275
|
+
engine: {
|
|
1276
|
+
step: this.inngestStep
|
|
1277
|
+
},
|
|
1278
|
+
abortSignal: abortController.signal
|
|
1279
|
+
});
|
|
1280
|
+
const endedAt = Date.now();
|
|
1281
|
+
execResults = {
|
|
1282
|
+
status: "success",
|
|
1283
|
+
output: result,
|
|
1284
|
+
startedAt,
|
|
1285
|
+
endedAt,
|
|
1286
|
+
payload: inputData,
|
|
1287
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1288
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1289
|
+
};
|
|
1290
|
+
} catch (e) {
|
|
1291
|
+
const stepFailure = {
|
|
1292
|
+
status: "failed",
|
|
1293
|
+
payload: inputData,
|
|
1294
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1295
|
+
endedAt: Date.now(),
|
|
1296
|
+
startedAt,
|
|
1297
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1298
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1299
|
+
};
|
|
1300
|
+
execResults = stepFailure;
|
|
1301
|
+
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1302
|
+
stepAISpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1303
|
+
throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1304
|
+
cause: execResults
|
|
1305
|
+
});
|
|
1306
|
+
}
|
|
1307
|
+
if (suspended) {
|
|
1308
|
+
execResults = {
|
|
1309
|
+
status: "suspended",
|
|
1310
|
+
suspendPayload: suspended.payload,
|
|
1311
|
+
payload: inputData,
|
|
1312
|
+
suspendedAt: Date.now(),
|
|
1313
|
+
startedAt,
|
|
1314
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1315
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1316
|
+
};
|
|
1317
|
+
} else if (bailed) {
|
|
1318
|
+
execResults = {
|
|
1319
|
+
status: "bailed",
|
|
1320
|
+
output: bailed.payload,
|
|
1321
|
+
payload: inputData,
|
|
1322
|
+
endedAt: Date.now(),
|
|
1323
|
+
startedAt
|
|
1324
|
+
};
|
|
1325
|
+
}
|
|
1326
|
+
await emitter.emit("watch", {
|
|
1327
|
+
type: "watch",
|
|
1328
|
+
payload: {
|
|
1329
|
+
currentStep: {
|
|
1330
|
+
id: step.id,
|
|
1331
|
+
...execResults
|
|
1332
|
+
},
|
|
1333
|
+
workflowState: {
|
|
1334
|
+
status: "running",
|
|
1335
|
+
steps: { ...stepResults, [step.id]: execResults },
|
|
1336
|
+
result: null,
|
|
1337
|
+
error: null
|
|
1083
1338
|
}
|
|
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
1339
|
},
|
|
1093
|
-
|
|
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
|
-
},
|
|
1103
|
-
abortSignal: abortController.signal
|
|
1340
|
+
eventTimestamp: Date.now()
|
|
1104
1341
|
});
|
|
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;
|
|
1342
|
+
if (execResults.status === "suspended") {
|
|
1343
|
+
await emitter.emit("watch-v2", {
|
|
1344
|
+
type: "workflow-step-suspended",
|
|
1345
|
+
payload: {
|
|
1346
|
+
id: step.id,
|
|
1347
|
+
...execResults
|
|
1348
|
+
}
|
|
1349
|
+
});
|
|
1350
|
+
} else {
|
|
1351
|
+
await emitter.emit("watch-v2", {
|
|
1352
|
+
type: "workflow-step-result",
|
|
1353
|
+
payload: {
|
|
1354
|
+
id: step.id,
|
|
1355
|
+
...execResults
|
|
1356
|
+
}
|
|
1357
|
+
});
|
|
1358
|
+
await emitter.emit("watch-v2", {
|
|
1359
|
+
type: "workflow-step-finish",
|
|
1360
|
+
payload: {
|
|
1361
|
+
id: step.id,
|
|
1362
|
+
metadata: {}
|
|
1363
|
+
}
|
|
1364
|
+
});
|
|
1144
1365
|
}
|
|
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()
|
|
1366
|
+
stepAISpan?.end({ output: execResults });
|
|
1367
|
+
return { result: execResults, executionContext, stepResults };
|
|
1161
1368
|
});
|
|
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) {
|
|
1369
|
+
} catch (e) {
|
|
1370
|
+
const stepFailure = e instanceof Error ? e?.cause : {
|
|
1371
|
+
status: "failed",
|
|
1372
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1373
|
+
payload: inputData,
|
|
1374
|
+
startedAt,
|
|
1375
|
+
endedAt: Date.now()
|
|
1376
|
+
};
|
|
1377
|
+
stepRes = {
|
|
1378
|
+
result: stepFailure,
|
|
1379
|
+
executionContext,
|
|
1380
|
+
stepResults: {
|
|
1381
|
+
...stepResults,
|
|
1382
|
+
[step.id]: stepFailure
|
|
1383
|
+
}
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
if (disableScorers !== false && stepRes.result.status === "success") {
|
|
1190
1387
|
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1191
1388
|
if (step.scorers) {
|
|
1192
1389
|
await this.runScorers({
|
|
1193
1390
|
scorers: step.scorers,
|
|
1194
1391
|
runId: executionContext.runId,
|
|
1195
|
-
input:
|
|
1392
|
+
input: inputData,
|
|
1196
1393
|
output: stepRes.result,
|
|
1197
1394
|
workflowId: executionContext.workflowId,
|
|
1198
1395
|
stepId: step.id,
|
|
@@ -1205,12 +1402,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1205
1402
|
}
|
|
1206
1403
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1207
1404
|
Object.assign(stepResults, stepRes.stepResults);
|
|
1405
|
+
executionContext.state = stepRes.executionContext.state;
|
|
1208
1406
|
return stepRes.result;
|
|
1209
1407
|
}
|
|
1210
1408
|
async persistStepUpdate({
|
|
1211
1409
|
workflowId,
|
|
1212
1410
|
runId,
|
|
1213
1411
|
stepResults,
|
|
1412
|
+
resourceId,
|
|
1214
1413
|
executionContext,
|
|
1215
1414
|
serializedStepGraph,
|
|
1216
1415
|
workflowStatus,
|
|
@@ -1220,15 +1419,21 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1220
1419
|
await this.inngestStep.run(
|
|
1221
1420
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1222
1421
|
async () => {
|
|
1422
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
|
|
1423
|
+
if (!shouldPersistSnapshot) {
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
1223
1426
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1224
1427
|
workflowName: workflowId,
|
|
1225
1428
|
runId,
|
|
1429
|
+
resourceId,
|
|
1226
1430
|
snapshot: {
|
|
1227
1431
|
runId,
|
|
1228
|
-
value:
|
|
1432
|
+
value: executionContext.state,
|
|
1229
1433
|
context: stepResults,
|
|
1230
1434
|
activePaths: [],
|
|
1231
1435
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1436
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1232
1437
|
waitingPaths: {},
|
|
1233
1438
|
serializedStepGraph,
|
|
1234
1439
|
status: workflowStatus,
|
|
@@ -1260,11 +1465,12 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1260
1465
|
}) {
|
|
1261
1466
|
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1262
1467
|
type: AISpanType.WORKFLOW_CONDITIONAL,
|
|
1263
|
-
name: `conditional: ${entry.conditions.length} conditions`,
|
|
1468
|
+
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1264
1469
|
input: prevOutput,
|
|
1265
1470
|
attributes: {
|
|
1266
1471
|
conditionCount: entry.conditions.length
|
|
1267
|
-
}
|
|
1472
|
+
},
|
|
1473
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1268
1474
|
});
|
|
1269
1475
|
let execResults;
|
|
1270
1476
|
const truthyIndexes = (await Promise.all(
|
|
@@ -1272,59 +1478,65 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1272
1478
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1273
1479
|
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1274
1480
|
type: AISpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1275
|
-
name: `condition ${index}`,
|
|
1481
|
+
name: `condition: '${index}'`,
|
|
1276
1482
|
input: prevOutput,
|
|
1277
1483
|
attributes: {
|
|
1278
1484
|
conditionIndex: index
|
|
1279
|
-
}
|
|
1485
|
+
},
|
|
1486
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1280
1487
|
});
|
|
1281
1488
|
try {
|
|
1282
|
-
const result = await cond(
|
|
1283
|
-
|
|
1284
|
-
workflowId,
|
|
1285
|
-
mastra: this.mastra,
|
|
1286
|
-
runtimeContext,
|
|
1287
|
-
runCount: -1,
|
|
1288
|
-
inputData: prevOutput,
|
|
1289
|
-
tracingContext: {
|
|
1290
|
-
currentSpan: evalSpan
|
|
1291
|
-
},
|
|
1292
|
-
getInitData: () => stepResults?.input,
|
|
1293
|
-
getStepResult: (step) => {
|
|
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
|
-
},
|
|
1303
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1304
|
-
suspend: async (_suspendPayload) => {
|
|
1305
|
-
},
|
|
1306
|
-
bail: () => {
|
|
1307
|
-
},
|
|
1308
|
-
abort: () => {
|
|
1309
|
-
abortController.abort();
|
|
1310
|
-
},
|
|
1311
|
-
[EMITTER_SYMBOL]: emitter,
|
|
1312
|
-
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1313
|
-
// TODO: add streamVNext support
|
|
1314
|
-
engine: {
|
|
1315
|
-
step: this.inngestStep
|
|
1316
|
-
},
|
|
1317
|
-
abortSignal: abortController.signal,
|
|
1318
|
-
writer: new ToolStream(
|
|
1489
|
+
const result = await cond(
|
|
1490
|
+
createDeprecationProxy(
|
|
1319
1491
|
{
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1492
|
+
runId,
|
|
1493
|
+
workflowId,
|
|
1494
|
+
mastra: this.mastra,
|
|
1495
|
+
runtimeContext,
|
|
1496
|
+
runCount: -1,
|
|
1497
|
+
retryCount: -1,
|
|
1498
|
+
inputData: prevOutput,
|
|
1499
|
+
state: executionContext.state,
|
|
1500
|
+
setState: (state) => {
|
|
1501
|
+
executionContext.state = state;
|
|
1502
|
+
},
|
|
1503
|
+
tracingContext: {
|
|
1504
|
+
currentSpan: evalSpan
|
|
1505
|
+
},
|
|
1506
|
+
getInitData: () => stepResults?.input,
|
|
1507
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
1508
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1509
|
+
suspend: async (_suspendPayload) => {
|
|
1510
|
+
},
|
|
1511
|
+
bail: () => {
|
|
1512
|
+
},
|
|
1513
|
+
abort: () => {
|
|
1514
|
+
abortController.abort();
|
|
1515
|
+
},
|
|
1516
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1517
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1518
|
+
// TODO: add streamVNext support
|
|
1519
|
+
engine: {
|
|
1520
|
+
step: this.inngestStep
|
|
1521
|
+
},
|
|
1522
|
+
abortSignal: abortController.signal,
|
|
1523
|
+
writer: new ToolStream(
|
|
1524
|
+
{
|
|
1525
|
+
prefix: "workflow-step",
|
|
1526
|
+
callId: randomUUID(),
|
|
1527
|
+
name: "conditional",
|
|
1528
|
+
runId
|
|
1529
|
+
},
|
|
1530
|
+
writableStream
|
|
1531
|
+
)
|
|
1324
1532
|
},
|
|
1325
|
-
|
|
1533
|
+
{
|
|
1534
|
+
paramName: "runCount",
|
|
1535
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
1536
|
+
logger: this.logger
|
|
1537
|
+
}
|
|
1326
1538
|
)
|
|
1327
|
-
|
|
1539
|
+
);
|
|
1328
1540
|
evalSpan?.end({
|
|
1329
1541
|
output: result,
|
|
1330
1542
|
attributes: {
|
|
@@ -1366,8 +1578,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1366
1578
|
runId,
|
|
1367
1579
|
executionPath: [...executionContext.executionPath, index],
|
|
1368
1580
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1581
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1369
1582
|
retryConfig: executionContext.retryConfig,
|
|
1370
|
-
|
|
1583
|
+
state: executionContext.state
|
|
1371
1584
|
},
|
|
1372
1585
|
emitter,
|
|
1373
1586
|
abortController,
|
|
@@ -1385,7 +1598,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1385
1598
|
if (hasFailed) {
|
|
1386
1599
|
execResults = { status: "failed", error: hasFailed.result.error };
|
|
1387
1600
|
} else if (hasSuspended) {
|
|
1388
|
-
execResults = { status: "suspended",
|
|
1601
|
+
execResults = { status: "suspended", suspendPayload: hasSuspended.result.suspendPayload };
|
|
1389
1602
|
} else {
|
|
1390
1603
|
execResults = {
|
|
1391
1604
|
status: "success",
|