@mastra/inngest 0.0.0-pgvector-index-fix-20250905222058 → 0.0.0-playground-studio-again-20251114100107
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 +650 -10
- package/dist/index.cjs +706 -590
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +120 -88
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +707 -591
- package/dist/index.js.map +1 -1
- package/package.json +21 -16
package/dist/index.js
CHANGED
|
@@ -1,17 +1,25 @@
|
|
|
1
1
|
import { randomUUID } from 'crypto';
|
|
2
|
+
import { ReadableStream, WritableStream } from 'stream/web';
|
|
2
3
|
import { subscribe } from '@inngest/realtime';
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { RequestContext } from '@mastra/core/di';
|
|
5
|
+
import { wrapMastra, SpanType } from '@mastra/core/observability';
|
|
6
|
+
import { ChunkFrom, WorkflowRunOutput } from '@mastra/core/stream';
|
|
5
7
|
import { ToolStream, Tool } from '@mastra/core/tools';
|
|
6
|
-
import { Run, Workflow, DefaultExecutionEngine } 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({
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
function serve({
|
|
16
|
+
mastra,
|
|
17
|
+
inngest,
|
|
18
|
+
functions: userFunctions = [],
|
|
19
|
+
registerOptions
|
|
20
|
+
}) {
|
|
21
|
+
const wfs = mastra.listWorkflows();
|
|
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 {
|
|
@@ -48,14 +57,21 @@ var InngestRun = class extends Run {
|
|
|
48
57
|
}
|
|
49
58
|
async getRunOutput(eventId) {
|
|
50
59
|
let runs = await this.getRuns(eventId);
|
|
60
|
+
const storage = this.#mastra?.getStorage();
|
|
51
61
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
52
62
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
53
63
|
runs = await this.getRuns(eventId);
|
|
54
64
|
if (runs?.[0]?.status === "Failed") {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
65
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
66
|
+
workflowName: this.workflowId,
|
|
67
|
+
runId: this.runId
|
|
68
|
+
});
|
|
69
|
+
return {
|
|
70
|
+
output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (runs?.[0]?.status === "Cancelled") {
|
|
74
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
59
75
|
workflowName: this.workflowId,
|
|
60
76
|
runId: this.runId
|
|
61
77
|
});
|
|
@@ -64,57 +80,71 @@ var InngestRun = class extends Run {
|
|
|
64
80
|
}
|
|
65
81
|
return runs?.[0];
|
|
66
82
|
}
|
|
67
|
-
async sendEvent(event, data) {
|
|
68
|
-
await this.inngest.send({
|
|
69
|
-
name: `user-event-${event}`,
|
|
70
|
-
data
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
83
|
async cancel() {
|
|
84
|
+
const storage = this.#mastra?.getStorage();
|
|
74
85
|
await this.inngest.send({
|
|
75
86
|
name: `cancel.workflow.${this.workflowId}`,
|
|
76
87
|
data: {
|
|
77
88
|
runId: this.runId
|
|
78
89
|
}
|
|
79
90
|
});
|
|
80
|
-
const snapshot = await
|
|
91
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
81
92
|
workflowName: this.workflowId,
|
|
82
93
|
runId: this.runId
|
|
83
94
|
});
|
|
84
95
|
if (snapshot) {
|
|
85
|
-
await
|
|
96
|
+
await storage?.persistWorkflowSnapshot({
|
|
86
97
|
workflowName: this.workflowId,
|
|
87
98
|
runId: this.runId,
|
|
99
|
+
resourceId: this.resourceId,
|
|
88
100
|
snapshot: {
|
|
89
101
|
...snapshot,
|
|
90
|
-
status: "canceled"
|
|
102
|
+
status: "canceled",
|
|
103
|
+
value: snapshot.value
|
|
91
104
|
}
|
|
92
105
|
});
|
|
93
106
|
}
|
|
94
107
|
}
|
|
95
|
-
async start({
|
|
96
|
-
|
|
108
|
+
async start(params) {
|
|
109
|
+
return this._start(params);
|
|
110
|
+
}
|
|
111
|
+
async _start({
|
|
112
|
+
inputData,
|
|
113
|
+
initialState,
|
|
114
|
+
outputOptions,
|
|
115
|
+
tracingOptions,
|
|
116
|
+
format
|
|
97
117
|
}) {
|
|
98
118
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
99
119
|
workflowName: this.workflowId,
|
|
100
120
|
runId: this.runId,
|
|
121
|
+
resourceId: this.resourceId,
|
|
101
122
|
snapshot: {
|
|
102
123
|
runId: this.runId,
|
|
103
124
|
serializedStepGraph: this.serializedStepGraph,
|
|
125
|
+
status: "running",
|
|
104
126
|
value: {},
|
|
105
127
|
context: {},
|
|
106
128
|
activePaths: [],
|
|
107
129
|
suspendedPaths: {},
|
|
130
|
+
activeStepsPath: {},
|
|
131
|
+
resumeLabels: {},
|
|
108
132
|
waitingPaths: {},
|
|
109
|
-
timestamp: Date.now()
|
|
110
|
-
status: "running"
|
|
133
|
+
timestamp: Date.now()
|
|
111
134
|
}
|
|
112
135
|
});
|
|
136
|
+
const inputDataToUse = await this._validateInput(inputData);
|
|
137
|
+
const initialStateToUse = await this._validateInitialState(initialState ?? {});
|
|
113
138
|
const eventOutput = await this.inngest.send({
|
|
114
139
|
name: `workflow.${this.workflowId}`,
|
|
115
140
|
data: {
|
|
116
|
-
inputData,
|
|
117
|
-
|
|
141
|
+
inputData: inputDataToUse,
|
|
142
|
+
initialState: initialStateToUse,
|
|
143
|
+
runId: this.runId,
|
|
144
|
+
resourceId: this.resourceId,
|
|
145
|
+
outputOptions,
|
|
146
|
+
tracingOptions,
|
|
147
|
+
format
|
|
118
148
|
}
|
|
119
149
|
});
|
|
120
150
|
const eventId = eventOutput.ids[0];
|
|
@@ -143,24 +173,28 @@ var InngestRun = class extends Run {
|
|
|
143
173
|
return p;
|
|
144
174
|
}
|
|
145
175
|
async _resume(params) {
|
|
176
|
+
const storage = this.#mastra?.getStorage();
|
|
146
177
|
const steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
147
178
|
(step) => typeof step === "string" ? step : step?.id
|
|
148
179
|
);
|
|
149
|
-
const snapshot = await
|
|
180
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
150
181
|
workflowName: this.workflowId,
|
|
151
182
|
runId: this.runId
|
|
152
183
|
});
|
|
184
|
+
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
185
|
+
const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
|
|
153
186
|
const eventOutput = await this.inngest.send({
|
|
154
187
|
name: `workflow.${this.workflowId}`,
|
|
155
188
|
data: {
|
|
156
|
-
inputData:
|
|
189
|
+
inputData: resumeDataToUse,
|
|
190
|
+
initialState: snapshot?.value ?? {},
|
|
157
191
|
runId: this.runId,
|
|
158
192
|
workflowId: this.workflowId,
|
|
159
193
|
stepResults: snapshot?.context,
|
|
160
194
|
resume: {
|
|
161
195
|
steps,
|
|
162
196
|
stepResults: snapshot?.context,
|
|
163
|
-
resumePayload:
|
|
197
|
+
resumePayload: resumeDataToUse,
|
|
164
198
|
// @ts-ignore
|
|
165
199
|
resumePath: snapshot?.suspendedPaths?.[steps?.[0]]
|
|
166
200
|
}
|
|
@@ -177,12 +211,12 @@ var InngestRun = class extends Run {
|
|
|
177
211
|
}
|
|
178
212
|
return result;
|
|
179
213
|
}
|
|
180
|
-
watch(cb
|
|
214
|
+
watch(cb) {
|
|
181
215
|
let active = true;
|
|
182
216
|
const streamPromise = subscribe(
|
|
183
217
|
{
|
|
184
218
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
185
|
-
topics: [
|
|
219
|
+
topics: ["watch"],
|
|
186
220
|
app: this.inngest
|
|
187
221
|
},
|
|
188
222
|
(message) => {
|
|
@@ -200,44 +234,35 @@ var InngestRun = class extends Run {
|
|
|
200
234
|
});
|
|
201
235
|
};
|
|
202
236
|
}
|
|
203
|
-
|
|
237
|
+
streamLegacy({ inputData, requestContext } = {}) {
|
|
204
238
|
const { readable, writable } = new TransformStream();
|
|
205
|
-
let currentToolData = void 0;
|
|
206
239
|
const writer = writable.getWriter();
|
|
207
240
|
const unwatch = this.watch(async (event) => {
|
|
208
|
-
|
|
209
|
-
currentToolData = {
|
|
210
|
-
name: event.payload.name,
|
|
211
|
-
args: event.payload.args
|
|
212
|
-
};
|
|
241
|
+
try {
|
|
213
242
|
await writer.write({
|
|
214
|
-
|
|
215
|
-
type: "
|
|
243
|
+
// @ts-ignore
|
|
244
|
+
type: "start",
|
|
245
|
+
// @ts-ignore
|
|
246
|
+
payload: { runId: this.runId }
|
|
216
247
|
});
|
|
217
|
-
return;
|
|
218
|
-
}
|
|
219
|
-
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
248
|
const e = {
|
|
233
249
|
...event,
|
|
234
250
|
type: event.type.replace("workflow-", "")
|
|
235
251
|
};
|
|
252
|
+
if (e.type === "step-output") {
|
|
253
|
+
e.type = e.payload.output.type;
|
|
254
|
+
e.payload = e.payload.output.payload;
|
|
255
|
+
}
|
|
236
256
|
await writer.write(e);
|
|
237
257
|
} catch {
|
|
238
258
|
}
|
|
239
|
-
}
|
|
259
|
+
});
|
|
240
260
|
this.closeStreamAction = async () => {
|
|
261
|
+
await writer.write({
|
|
262
|
+
type: "finish",
|
|
263
|
+
// @ts-ignore
|
|
264
|
+
payload: { runId: this.runId }
|
|
265
|
+
});
|
|
241
266
|
unwatch();
|
|
242
267
|
try {
|
|
243
268
|
await writer.close();
|
|
@@ -247,7 +272,7 @@ var InngestRun = class extends Run {
|
|
|
247
272
|
writer.releaseLock();
|
|
248
273
|
}
|
|
249
274
|
};
|
|
250
|
-
this.executionResults = this.
|
|
275
|
+
this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
|
|
251
276
|
if (result.status !== "suspended") {
|
|
252
277
|
this.closeStreamAction?.().catch(() => {
|
|
253
278
|
});
|
|
@@ -259,6 +284,82 @@ var InngestRun = class extends Run {
|
|
|
259
284
|
getWorkflowState: () => this.executionResults
|
|
260
285
|
};
|
|
261
286
|
}
|
|
287
|
+
stream({
|
|
288
|
+
inputData,
|
|
289
|
+
requestContext,
|
|
290
|
+
tracingOptions,
|
|
291
|
+
closeOnSuspend = true,
|
|
292
|
+
initialState,
|
|
293
|
+
outputOptions
|
|
294
|
+
} = {}) {
|
|
295
|
+
if (this.closeStreamAction && this.streamOutput) {
|
|
296
|
+
return this.streamOutput;
|
|
297
|
+
}
|
|
298
|
+
this.closeStreamAction = async () => {
|
|
299
|
+
};
|
|
300
|
+
const self = this;
|
|
301
|
+
const stream = new ReadableStream({
|
|
302
|
+
async start(controller) {
|
|
303
|
+
const unwatch = self.watch(async ({ type, from = ChunkFrom.WORKFLOW, payload }) => {
|
|
304
|
+
controller.enqueue({
|
|
305
|
+
type,
|
|
306
|
+
runId: self.runId,
|
|
307
|
+
from,
|
|
308
|
+
payload: {
|
|
309
|
+
stepName: payload?.id,
|
|
310
|
+
...payload
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
});
|
|
314
|
+
self.closeStreamAction = async () => {
|
|
315
|
+
unwatch();
|
|
316
|
+
try {
|
|
317
|
+
await controller.close();
|
|
318
|
+
} catch (err) {
|
|
319
|
+
console.error("Error closing stream:", err);
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
const executionResultsPromise = self._start({
|
|
323
|
+
inputData,
|
|
324
|
+
requestContext,
|
|
325
|
+
// tracingContext, // We are not able to pass a reference to a span here, what to do?
|
|
326
|
+
initialState,
|
|
327
|
+
tracingOptions,
|
|
328
|
+
outputOptions,
|
|
329
|
+
format: "vnext"
|
|
330
|
+
});
|
|
331
|
+
let executionResults;
|
|
332
|
+
try {
|
|
333
|
+
executionResults = await executionResultsPromise;
|
|
334
|
+
if (closeOnSuspend) {
|
|
335
|
+
self.closeStreamAction?.().catch(() => {
|
|
336
|
+
});
|
|
337
|
+
} else if (executionResults.status !== "suspended") {
|
|
338
|
+
self.closeStreamAction?.().catch(() => {
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
if (self.streamOutput) {
|
|
342
|
+
self.streamOutput.updateResults(
|
|
343
|
+
executionResults
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
} catch (err) {
|
|
347
|
+
self.streamOutput?.rejectResults(err);
|
|
348
|
+
self.closeStreamAction?.().catch(() => {
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
this.streamOutput = new WorkflowRunOutput({
|
|
354
|
+
runId: this.runId,
|
|
355
|
+
workflowId: this.workflowId,
|
|
356
|
+
stream
|
|
357
|
+
});
|
|
358
|
+
return this.streamOutput;
|
|
359
|
+
}
|
|
360
|
+
streamVNext(args = {}) {
|
|
361
|
+
return this.stream(args);
|
|
362
|
+
}
|
|
262
363
|
};
|
|
263
364
|
var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
264
365
|
#mastra;
|
|
@@ -268,6 +369,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
268
369
|
constructor(params, inngest) {
|
|
269
370
|
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
270
371
|
super(workflowParams);
|
|
372
|
+
this.engineType = "inngest";
|
|
271
373
|
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
272
374
|
([_, value]) => value !== void 0
|
|
273
375
|
);
|
|
@@ -275,13 +377,13 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
275
377
|
this.#mastra = params.mastra;
|
|
276
378
|
this.inngest = inngest;
|
|
277
379
|
}
|
|
278
|
-
async
|
|
380
|
+
async listWorkflowRuns(args) {
|
|
279
381
|
const storage = this.#mastra?.getStorage();
|
|
280
382
|
if (!storage) {
|
|
281
383
|
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
282
384
|
return { runs: [], total: 0 };
|
|
283
385
|
}
|
|
284
|
-
return storage.
|
|
386
|
+
return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
285
387
|
}
|
|
286
388
|
async getWorkflowRunById(runId) {
|
|
287
389
|
const storage = this.#mastra?.getStorage();
|
|
@@ -310,54 +412,46 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
310
412
|
}
|
|
311
413
|
}
|
|
312
414
|
}
|
|
313
|
-
createRun(options) {
|
|
314
|
-
const runIdToUse = options?.runId || randomUUID();
|
|
315
|
-
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
316
|
-
{
|
|
317
|
-
workflowId: this.id,
|
|
318
|
-
runId: runIdToUse,
|
|
319
|
-
executionEngine: this.executionEngine,
|
|
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
|
|
327
|
-
);
|
|
328
|
-
this.runs.set(runIdToUse, run);
|
|
329
|
-
return run;
|
|
330
|
-
}
|
|
331
|
-
async createRunAsync(options) {
|
|
415
|
+
async createRun(options) {
|
|
332
416
|
const runIdToUse = options?.runId || randomUUID();
|
|
333
417
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
334
418
|
{
|
|
335
419
|
workflowId: this.id,
|
|
336
420
|
runId: runIdToUse,
|
|
421
|
+
resourceId: options?.resourceId,
|
|
337
422
|
executionEngine: this.executionEngine,
|
|
338
423
|
executionGraph: this.executionGraph,
|
|
339
424
|
serializedStepGraph: this.serializedStepGraph,
|
|
340
425
|
mastra: this.#mastra,
|
|
341
426
|
retryConfig: this.retryConfig,
|
|
342
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
427
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
428
|
+
workflowSteps: this.steps,
|
|
429
|
+
workflowEngineType: this.engineType
|
|
343
430
|
},
|
|
344
431
|
this.inngest
|
|
345
432
|
);
|
|
346
433
|
this.runs.set(runIdToUse, run);
|
|
434
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
435
|
+
workflowStatus: run.workflowRunStatus,
|
|
436
|
+
stepResults: {}
|
|
437
|
+
});
|
|
347
438
|
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
348
|
-
if (!workflowSnapshotInStorage) {
|
|
439
|
+
if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
|
|
349
440
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
350
441
|
workflowName: this.id,
|
|
351
442
|
runId: runIdToUse,
|
|
443
|
+
resourceId: options?.resourceId,
|
|
352
444
|
snapshot: {
|
|
353
445
|
runId: runIdToUse,
|
|
354
446
|
status: "pending",
|
|
355
447
|
value: {},
|
|
356
448
|
context: {},
|
|
357
449
|
activePaths: [],
|
|
450
|
+
activeStepsPath: {},
|
|
358
451
|
waitingPaths: {},
|
|
359
452
|
serializedStepGraph: this.serializedStepGraph,
|
|
360
453
|
suspendedPaths: {},
|
|
454
|
+
resumeLabels: {},
|
|
361
455
|
result: void 0,
|
|
362
456
|
error: void 0,
|
|
363
457
|
// @ts-ignore
|
|
@@ -382,7 +476,7 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
382
476
|
},
|
|
383
477
|
{ event: `workflow.${this.id}` },
|
|
384
478
|
async ({ event, step, attempt, publish }) => {
|
|
385
|
-
let { inputData, runId, resume } = event.data;
|
|
479
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format } = event.data;
|
|
386
480
|
if (!runId) {
|
|
387
481
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
388
482
|
return randomUUID();
|
|
@@ -410,21 +504,38 @@ var InngestWorkflow = class _InngestWorkflow extends Workflow {
|
|
|
410
504
|
once: (_event, _callback) => {
|
|
411
505
|
}
|
|
412
506
|
};
|
|
413
|
-
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
507
|
+
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
414
508
|
const result = await engine.execute({
|
|
415
509
|
workflowId: this.id,
|
|
416
510
|
runId,
|
|
511
|
+
resourceId,
|
|
417
512
|
graph: this.executionGraph,
|
|
418
513
|
serializedStepGraph: this.serializedStepGraph,
|
|
419
514
|
input: inputData,
|
|
515
|
+
initialState,
|
|
420
516
|
emitter,
|
|
421
517
|
retryConfig: this.retryConfig,
|
|
422
|
-
|
|
518
|
+
requestContext: new RequestContext(),
|
|
423
519
|
// TODO
|
|
424
520
|
resume,
|
|
521
|
+
format,
|
|
425
522
|
abortController: new AbortController(),
|
|
426
|
-
currentSpan:
|
|
427
|
-
|
|
523
|
+
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
524
|
+
outputOptions,
|
|
525
|
+
writableStream: new WritableStream({
|
|
526
|
+
write(chunk) {
|
|
527
|
+
void emitter.emit("watch", chunk).catch(() => {
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
})
|
|
531
|
+
});
|
|
532
|
+
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
533
|
+
if (result.status === "failed") {
|
|
534
|
+
throw new NonRetriableError(`Workflow failed`, {
|
|
535
|
+
cause: result
|
|
536
|
+
});
|
|
537
|
+
}
|
|
538
|
+
return result;
|
|
428
539
|
});
|
|
429
540
|
return { result, runId };
|
|
430
541
|
}
|
|
@@ -454,10 +565,11 @@ function isAgent(params) {
|
|
|
454
565
|
function isTool(params) {
|
|
455
566
|
return params instanceof Tool;
|
|
456
567
|
}
|
|
457
|
-
function createStep(params) {
|
|
568
|
+
function createStep(params, agentOptions) {
|
|
458
569
|
if (isAgent(params)) {
|
|
459
570
|
return {
|
|
460
571
|
id: params.name,
|
|
572
|
+
description: params.getDescription(),
|
|
461
573
|
// @ts-ignore
|
|
462
574
|
inputSchema: z.object({
|
|
463
575
|
prompt: z.string()
|
|
@@ -468,7 +580,16 @@ function createStep(params) {
|
|
|
468
580
|
outputSchema: z.object({
|
|
469
581
|
text: z.string()
|
|
470
582
|
}),
|
|
471
|
-
execute: async ({
|
|
583
|
+
execute: async ({
|
|
584
|
+
inputData,
|
|
585
|
+
[EMITTER_SYMBOL]: emitter,
|
|
586
|
+
[STREAM_FORMAT_SYMBOL]: streamFormat,
|
|
587
|
+
requestContext,
|
|
588
|
+
tracingContext,
|
|
589
|
+
abortSignal,
|
|
590
|
+
abort,
|
|
591
|
+
writer
|
|
592
|
+
}) => {
|
|
472
593
|
let streamPromise = {};
|
|
473
594
|
streamPromise.promise = new Promise((resolve, reject) => {
|
|
474
595
|
streamPromise.resolve = resolve;
|
|
@@ -478,34 +599,65 @@ function createStep(params) {
|
|
|
478
599
|
name: params.name,
|
|
479
600
|
args: inputData
|
|
480
601
|
};
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
602
|
+
let stream;
|
|
603
|
+
if ((await params.getModel()).specificationVersion === "v1") {
|
|
604
|
+
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
605
|
+
...agentOptions ?? {},
|
|
606
|
+
// resourceId: inputData.resourceId,
|
|
607
|
+
// threadId: inputData.threadId,
|
|
608
|
+
requestContext,
|
|
609
|
+
tracingContext,
|
|
610
|
+
onFinish: (result) => {
|
|
611
|
+
streamPromise.resolve(result.text);
|
|
612
|
+
void agentOptions?.onFinish?.(result);
|
|
613
|
+
},
|
|
614
|
+
abortSignal
|
|
615
|
+
});
|
|
616
|
+
stream = fullStream;
|
|
617
|
+
} else {
|
|
618
|
+
const modelOutput = await params.stream(inputData.prompt, {
|
|
619
|
+
...agentOptions ?? {},
|
|
620
|
+
requestContext,
|
|
621
|
+
tracingContext,
|
|
622
|
+
onFinish: (result) => {
|
|
623
|
+
streamPromise.resolve(result.text);
|
|
624
|
+
void agentOptions?.onFinish?.(result);
|
|
625
|
+
},
|
|
626
|
+
abortSignal
|
|
627
|
+
});
|
|
628
|
+
stream = modelOutput.fullStream;
|
|
629
|
+
}
|
|
630
|
+
if (streamFormat === "legacy") {
|
|
631
|
+
await emitter.emit("watch", {
|
|
632
|
+
type: "tool-call-streaming-start",
|
|
633
|
+
...toolData ?? {}
|
|
634
|
+
});
|
|
635
|
+
for await (const chunk of stream) {
|
|
636
|
+
if (chunk.type === "text-delta") {
|
|
637
|
+
await emitter.emit("watch", {
|
|
638
|
+
type: "tool-call-delta",
|
|
639
|
+
...toolData ?? {},
|
|
640
|
+
argsTextDelta: chunk.textDelta
|
|
641
|
+
});
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
await emitter.emit("watch", {
|
|
645
|
+
type: "tool-call-streaming-finish",
|
|
646
|
+
...toolData ?? {}
|
|
647
|
+
});
|
|
648
|
+
} else {
|
|
649
|
+
for await (const chunk of stream) {
|
|
650
|
+
await writer.write(chunk);
|
|
651
|
+
}
|
|
652
|
+
}
|
|
495
653
|
if (abortSignal.aborted) {
|
|
496
654
|
return abort();
|
|
497
655
|
}
|
|
498
|
-
for await (const chunk of fullStream) {
|
|
499
|
-
await emitter.emit("watch-v2", chunk);
|
|
500
|
-
}
|
|
501
|
-
await emitter.emit("watch-v2", {
|
|
502
|
-
type: "workflow-agent-call-finish",
|
|
503
|
-
payload: toolData
|
|
504
|
-
});
|
|
505
656
|
return {
|
|
506
657
|
text: await streamPromise.promise
|
|
507
658
|
};
|
|
508
|
-
}
|
|
659
|
+
},
|
|
660
|
+
component: params.component
|
|
509
661
|
};
|
|
510
662
|
}
|
|
511
663
|
if (isTool(params)) {
|
|
@@ -516,16 +668,20 @@ function createStep(params) {
|
|
|
516
668
|
// TODO: tool probably should have strong id type
|
|
517
669
|
// @ts-ignore
|
|
518
670
|
id: params.id,
|
|
671
|
+
description: params.description,
|
|
519
672
|
inputSchema: params.inputSchema,
|
|
520
673
|
outputSchema: params.outputSchema,
|
|
521
|
-
execute: async ({ inputData, mastra,
|
|
674
|
+
execute: async ({ inputData, mastra, requestContext, tracingContext, suspend, resumeData }) => {
|
|
522
675
|
return params.execute({
|
|
523
676
|
context: inputData,
|
|
524
677
|
mastra: wrapMastra(mastra, tracingContext),
|
|
525
|
-
|
|
526
|
-
tracingContext
|
|
678
|
+
requestContext,
|
|
679
|
+
tracingContext,
|
|
680
|
+
suspend,
|
|
681
|
+
resumeData
|
|
527
682
|
});
|
|
528
|
-
}
|
|
683
|
+
},
|
|
684
|
+
component: "TOOL"
|
|
529
685
|
};
|
|
530
686
|
}
|
|
531
687
|
return {
|
|
@@ -541,7 +697,10 @@ function createStep(params) {
|
|
|
541
697
|
function init(inngest) {
|
|
542
698
|
return {
|
|
543
699
|
createWorkflow(params) {
|
|
544
|
-
return new InngestWorkflow(
|
|
700
|
+
return new InngestWorkflow(
|
|
701
|
+
params,
|
|
702
|
+
inngest
|
|
703
|
+
);
|
|
545
704
|
},
|
|
546
705
|
createStep,
|
|
547
706
|
cloneStep(step, opts) {
|
|
@@ -550,7 +709,11 @@ function init(inngest) {
|
|
|
550
709
|
description: step.description,
|
|
551
710
|
inputSchema: step.inputSchema,
|
|
552
711
|
outputSchema: step.outputSchema,
|
|
553
|
-
|
|
712
|
+
resumeSchema: step.resumeSchema,
|
|
713
|
+
suspendSchema: step.suspendSchema,
|
|
714
|
+
stateSchema: step.stateSchema,
|
|
715
|
+
execute: step.execute,
|
|
716
|
+
component: step.component
|
|
554
717
|
};
|
|
555
718
|
},
|
|
556
719
|
cloneWorkflow(workflow, opts) {
|
|
@@ -570,78 +733,30 @@ function init(inngest) {
|
|
|
570
733
|
var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
571
734
|
inngestStep;
|
|
572
735
|
inngestAttempts;
|
|
573
|
-
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
574
|
-
super({ mastra });
|
|
736
|
+
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
737
|
+
super({ mastra, options });
|
|
575
738
|
this.inngestStep = inngestStep;
|
|
576
739
|
this.inngestAttempts = inngestAttempts;
|
|
577
740
|
}
|
|
578
|
-
async
|
|
579
|
-
await params.emitter.emit("watch-v2", {
|
|
580
|
-
type: "workflow-start",
|
|
581
|
-
payload: { runId: params.runId }
|
|
582
|
-
});
|
|
583
|
-
const result = await super.execute(params);
|
|
584
|
-
await params.emitter.emit("watch-v2", {
|
|
585
|
-
type: "workflow-finish",
|
|
586
|
-
payload: { runId: params.runId }
|
|
587
|
-
});
|
|
588
|
-
return result;
|
|
589
|
-
}
|
|
590
|
-
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
741
|
+
async fmtReturnValue(emitter, stepResults, lastOutput, error) {
|
|
591
742
|
const base = {
|
|
592
743
|
status: lastOutput.status,
|
|
593
744
|
steps: stepResults
|
|
594
745
|
};
|
|
595
746
|
if (lastOutput.status === "success") {
|
|
596
|
-
await emitter.emit("watch", {
|
|
597
|
-
type: "watch",
|
|
598
|
-
payload: {
|
|
599
|
-
workflowState: {
|
|
600
|
-
status: lastOutput.status,
|
|
601
|
-
steps: stepResults,
|
|
602
|
-
result: lastOutput.output
|
|
603
|
-
}
|
|
604
|
-
},
|
|
605
|
-
eventTimestamp: Date.now()
|
|
606
|
-
});
|
|
607
747
|
base.result = lastOutput.output;
|
|
608
748
|
} else if (lastOutput.status === "failed") {
|
|
609
749
|
base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
|
|
610
|
-
await emitter.emit("watch", {
|
|
611
|
-
type: "watch",
|
|
612
|
-
payload: {
|
|
613
|
-
workflowState: {
|
|
614
|
-
status: lastOutput.status,
|
|
615
|
-
steps: stepResults,
|
|
616
|
-
result: null,
|
|
617
|
-
error: base.error
|
|
618
|
-
}
|
|
619
|
-
},
|
|
620
|
-
eventTimestamp: Date.now()
|
|
621
|
-
});
|
|
622
750
|
} else if (lastOutput.status === "suspended") {
|
|
623
|
-
await emitter.emit("watch", {
|
|
624
|
-
type: "watch",
|
|
625
|
-
payload: {
|
|
626
|
-
workflowState: {
|
|
627
|
-
status: lastOutput.status,
|
|
628
|
-
steps: stepResults,
|
|
629
|
-
result: null,
|
|
630
|
-
error: null
|
|
631
|
-
}
|
|
632
|
-
},
|
|
633
|
-
eventTimestamp: Date.now()
|
|
634
|
-
});
|
|
635
751
|
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
636
752
|
if (stepResult?.status === "suspended") {
|
|
637
|
-
const nestedPath = stepResult?.
|
|
753
|
+
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
638
754
|
return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
|
|
639
755
|
}
|
|
640
756
|
return [];
|
|
641
757
|
});
|
|
642
758
|
base.suspended = suspendedStepIds;
|
|
643
759
|
}
|
|
644
|
-
executionSpan?.end();
|
|
645
760
|
return base;
|
|
646
761
|
}
|
|
647
762
|
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
@@ -655,67 +770,71 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
655
770
|
stepResults,
|
|
656
771
|
emitter,
|
|
657
772
|
abortController,
|
|
658
|
-
|
|
773
|
+
requestContext,
|
|
659
774
|
executionContext,
|
|
660
775
|
writableStream,
|
|
661
776
|
tracingContext
|
|
662
777
|
}) {
|
|
663
778
|
let { duration, fn } = entry;
|
|
664
779
|
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
665
|
-
type:
|
|
780
|
+
type: SpanType.WORKFLOW_SLEEP,
|
|
666
781
|
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
667
782
|
attributes: {
|
|
668
783
|
durationMs: duration,
|
|
669
784
|
sleepType: fn ? "dynamic" : "fixed"
|
|
670
|
-
}
|
|
785
|
+
},
|
|
786
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
671
787
|
});
|
|
672
788
|
if (fn) {
|
|
673
789
|
const stepCallId = randomUUID();
|
|
674
790
|
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(
|
|
791
|
+
return await fn(
|
|
792
|
+
createDeprecationProxy(
|
|
710
793
|
{
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
794
|
+
runId,
|
|
795
|
+
workflowId,
|
|
796
|
+
mastra: this.mastra,
|
|
797
|
+
requestContext,
|
|
798
|
+
inputData: prevOutput,
|
|
799
|
+
state: executionContext.state,
|
|
800
|
+
setState: (state) => {
|
|
801
|
+
executionContext.state = state;
|
|
802
|
+
},
|
|
803
|
+
retryCount: -1,
|
|
804
|
+
tracingContext: {
|
|
805
|
+
currentSpan: sleepSpan
|
|
806
|
+
},
|
|
807
|
+
getInitData: () => stepResults?.input,
|
|
808
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
809
|
+
// TODO: this function shouldn't have suspend probably?
|
|
810
|
+
suspend: async (_suspendPayload) => {
|
|
811
|
+
},
|
|
812
|
+
bail: () => {
|
|
813
|
+
},
|
|
814
|
+
abort: () => {
|
|
815
|
+
abortController?.abort();
|
|
816
|
+
},
|
|
817
|
+
[EMITTER_SYMBOL]: emitter,
|
|
818
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
819
|
+
engine: { step: this.inngestStep },
|
|
820
|
+
abortSignal: abortController?.signal,
|
|
821
|
+
writer: new ToolStream(
|
|
822
|
+
{
|
|
823
|
+
prefix: "workflow-step",
|
|
824
|
+
callId: stepCallId,
|
|
825
|
+
name: "sleep",
|
|
826
|
+
runId
|
|
827
|
+
},
|
|
828
|
+
writableStream
|
|
829
|
+
)
|
|
715
830
|
},
|
|
716
|
-
|
|
831
|
+
{
|
|
832
|
+
paramName: "runCount",
|
|
833
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
834
|
+
logger: this.logger
|
|
835
|
+
}
|
|
717
836
|
)
|
|
718
|
-
|
|
837
|
+
);
|
|
719
838
|
});
|
|
720
839
|
sleepSpan?.update({
|
|
721
840
|
attributes: {
|
|
@@ -739,69 +858,76 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
739
858
|
stepResults,
|
|
740
859
|
emitter,
|
|
741
860
|
abortController,
|
|
742
|
-
|
|
861
|
+
requestContext,
|
|
743
862
|
executionContext,
|
|
744
863
|
writableStream,
|
|
745
864
|
tracingContext
|
|
746
865
|
}) {
|
|
747
866
|
let { date, fn } = entry;
|
|
748
867
|
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
749
|
-
type:
|
|
868
|
+
type: SpanType.WORKFLOW_SLEEP,
|
|
750
869
|
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
751
870
|
attributes: {
|
|
752
871
|
untilDate: date,
|
|
753
872
|
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
754
873
|
sleepType: fn ? "dynamic" : "fixed"
|
|
755
|
-
}
|
|
874
|
+
},
|
|
875
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
756
876
|
});
|
|
757
877
|
if (fn) {
|
|
758
878
|
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
759
879
|
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(
|
|
880
|
+
return await fn(
|
|
881
|
+
createDeprecationProxy(
|
|
795
882
|
{
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
883
|
+
runId,
|
|
884
|
+
workflowId,
|
|
885
|
+
mastra: this.mastra,
|
|
886
|
+
requestContext,
|
|
887
|
+
inputData: prevOutput,
|
|
888
|
+
state: executionContext.state,
|
|
889
|
+
setState: (state) => {
|
|
890
|
+
executionContext.state = state;
|
|
891
|
+
},
|
|
892
|
+
retryCount: -1,
|
|
893
|
+
tracingContext: {
|
|
894
|
+
currentSpan: sleepUntilSpan
|
|
895
|
+
},
|
|
896
|
+
getInitData: () => stepResults?.input,
|
|
897
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
898
|
+
// TODO: this function shouldn't have suspend probably?
|
|
899
|
+
suspend: async (_suspendPayload) => {
|
|
900
|
+
},
|
|
901
|
+
bail: () => {
|
|
902
|
+
},
|
|
903
|
+
abort: () => {
|
|
904
|
+
abortController?.abort();
|
|
905
|
+
},
|
|
906
|
+
[EMITTER_SYMBOL]: emitter,
|
|
907
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
908
|
+
engine: { step: this.inngestStep },
|
|
909
|
+
abortSignal: abortController?.signal,
|
|
910
|
+
writer: new ToolStream(
|
|
911
|
+
{
|
|
912
|
+
prefix: "workflow-step",
|
|
913
|
+
callId: stepCallId,
|
|
914
|
+
name: "sleep",
|
|
915
|
+
runId
|
|
916
|
+
},
|
|
917
|
+
writableStream
|
|
918
|
+
)
|
|
800
919
|
},
|
|
801
|
-
|
|
920
|
+
{
|
|
921
|
+
paramName: "runCount",
|
|
922
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
923
|
+
logger: this.logger
|
|
924
|
+
}
|
|
802
925
|
)
|
|
803
|
-
|
|
926
|
+
);
|
|
804
927
|
});
|
|
928
|
+
if (date && !(date instanceof Date)) {
|
|
929
|
+
date = new Date(date);
|
|
930
|
+
}
|
|
805
931
|
const time = !date ? 0 : date.getTime() - Date.now();
|
|
806
932
|
sleepUntilSpan?.update({
|
|
807
933
|
attributes: {
|
|
@@ -821,16 +947,6 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
821
947
|
throw e;
|
|
822
948
|
}
|
|
823
949
|
}
|
|
824
|
-
async executeWaitForEvent({ event, timeout }) {
|
|
825
|
-
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
826
|
-
event: `user-event-${event}`,
|
|
827
|
-
timeout: timeout ?? 5e3
|
|
828
|
-
});
|
|
829
|
-
if (eventData === null) {
|
|
830
|
-
throw "Timeout waiting for event";
|
|
831
|
-
}
|
|
832
|
-
return eventData?.data;
|
|
833
|
-
}
|
|
834
950
|
async executeStep({
|
|
835
951
|
step,
|
|
836
952
|
stepResults,
|
|
@@ -839,50 +955,35 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
839
955
|
prevOutput,
|
|
840
956
|
emitter,
|
|
841
957
|
abortController,
|
|
842
|
-
|
|
958
|
+
requestContext,
|
|
843
959
|
tracingContext,
|
|
844
960
|
writableStream,
|
|
845
961
|
disableScorers
|
|
846
962
|
}) {
|
|
847
|
-
const
|
|
963
|
+
const stepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
848
964
|
name: `workflow step: '${step.id}'`,
|
|
849
|
-
type:
|
|
965
|
+
type: SpanType.WORKFLOW_STEP,
|
|
850
966
|
input: prevOutput,
|
|
851
967
|
attributes: {
|
|
852
968
|
stepId: step.id
|
|
853
|
-
}
|
|
969
|
+
},
|
|
970
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
971
|
+
});
|
|
972
|
+
const { inputData, validationError } = await validateStepInput({
|
|
973
|
+
prevOutput,
|
|
974
|
+
step,
|
|
975
|
+
validateInputs: this.options?.validateInputs ?? false
|
|
854
976
|
});
|
|
855
977
|
const startedAt = await this.inngestStep.run(
|
|
856
978
|
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
857
979
|
async () => {
|
|
858
980
|
const startedAt2 = Date.now();
|
|
859
981
|
await emitter.emit("watch", {
|
|
860
|
-
type: "watch",
|
|
861
|
-
payload: {
|
|
862
|
-
currentStep: {
|
|
863
|
-
id: step.id,
|
|
864
|
-
status: "running"
|
|
865
|
-
},
|
|
866
|
-
workflowState: {
|
|
867
|
-
status: "running",
|
|
868
|
-
steps: {
|
|
869
|
-
...stepResults,
|
|
870
|
-
[step.id]: {
|
|
871
|
-
status: "running"
|
|
872
|
-
}
|
|
873
|
-
},
|
|
874
|
-
result: null,
|
|
875
|
-
error: null
|
|
876
|
-
}
|
|
877
|
-
},
|
|
878
|
-
eventTimestamp: Date.now()
|
|
879
|
-
});
|
|
880
|
-
await emitter.emit("watch-v2", {
|
|
881
982
|
type: "workflow-step-start",
|
|
882
983
|
payload: {
|
|
883
984
|
id: step.id,
|
|
884
985
|
status: "running",
|
|
885
|
-
payload:
|
|
986
|
+
payload: inputData,
|
|
886
987
|
startedAt: startedAt2
|
|
887
988
|
}
|
|
888
989
|
});
|
|
@@ -893,61 +994,66 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
893
994
|
const isResume = !!resume?.steps?.length;
|
|
894
995
|
let result;
|
|
895
996
|
let runId;
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
997
|
+
try {
|
|
998
|
+
if (isResume) {
|
|
999
|
+
runId = stepResults[resume?.steps?.[0]]?.suspendPayload?.__workflow_meta?.runId ?? randomUUID();
|
|
1000
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1001
|
+
workflowName: step.id,
|
|
1002
|
+
runId
|
|
1003
|
+
});
|
|
1004
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1005
|
+
function: step.getFunction(),
|
|
1006
|
+
data: {
|
|
1007
|
+
inputData,
|
|
1008
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
908
1009
|
runId,
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
1010
|
+
resume: {
|
|
1011
|
+
runId,
|
|
1012
|
+
steps: resume.steps.slice(1),
|
|
1013
|
+
stepResults: snapshot?.context,
|
|
1014
|
+
resumePayload: resume.resumePayload,
|
|
1015
|
+
// @ts-ignore
|
|
1016
|
+
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
1017
|
+
},
|
|
1018
|
+
outputOptions: { includeState: true }
|
|
914
1019
|
}
|
|
915
|
-
}
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
1020
|
+
});
|
|
1021
|
+
result = invokeResp.result;
|
|
1022
|
+
runId = invokeResp.runId;
|
|
1023
|
+
executionContext.state = invokeResp.result.state;
|
|
1024
|
+
} else {
|
|
1025
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1026
|
+
function: step.getFunction(),
|
|
1027
|
+
data: {
|
|
1028
|
+
inputData,
|
|
1029
|
+
initialState: executionContext.state ?? {},
|
|
1030
|
+
outputOptions: { includeState: true }
|
|
1031
|
+
}
|
|
1032
|
+
});
|
|
1033
|
+
result = invokeResp.result;
|
|
1034
|
+
runId = invokeResp.runId;
|
|
1035
|
+
executionContext.state = invokeResp.result.state;
|
|
1036
|
+
}
|
|
1037
|
+
} catch (e) {
|
|
1038
|
+
const errorCause = e?.cause;
|
|
1039
|
+
if (errorCause && typeof errorCause === "object") {
|
|
1040
|
+
result = errorCause;
|
|
1041
|
+
runId = errorCause.runId || randomUUID();
|
|
1042
|
+
} else {
|
|
1043
|
+
runId = randomUUID();
|
|
1044
|
+
result = {
|
|
1045
|
+
status: "failed",
|
|
1046
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
1047
|
+
steps: {},
|
|
1048
|
+
input: inputData
|
|
1049
|
+
};
|
|
1050
|
+
}
|
|
928
1051
|
}
|
|
929
1052
|
const res = await this.inngestStep.run(
|
|
930
1053
|
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
931
1054
|
async () => {
|
|
932
1055
|
if (result.status === "failed") {
|
|
933
1056
|
await emitter.emit("watch", {
|
|
934
|
-
type: "watch",
|
|
935
|
-
payload: {
|
|
936
|
-
currentStep: {
|
|
937
|
-
id: step.id,
|
|
938
|
-
status: "failed",
|
|
939
|
-
error: result?.error
|
|
940
|
-
},
|
|
941
|
-
workflowState: {
|
|
942
|
-
status: "running",
|
|
943
|
-
steps: stepResults,
|
|
944
|
-
result: null,
|
|
945
|
-
error: null
|
|
946
|
-
}
|
|
947
|
-
},
|
|
948
|
-
eventTimestamp: Date.now()
|
|
949
|
-
});
|
|
950
|
-
await emitter.emit("watch-v2", {
|
|
951
1057
|
type: "workflow-step-result",
|
|
952
1058
|
payload: {
|
|
953
1059
|
id: step.id,
|
|
@@ -963,26 +1069,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
963
1069
|
return stepRes2?.status === "suspended";
|
|
964
1070
|
});
|
|
965
1071
|
for (const [stepName, stepResult] of suspendedSteps) {
|
|
966
|
-
const suspendPath = [stepName, ...stepResult?.
|
|
1072
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
967
1073
|
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
968
1074
|
await emitter.emit("watch", {
|
|
969
|
-
type: "watch",
|
|
970
|
-
payload: {
|
|
971
|
-
currentStep: {
|
|
972
|
-
id: step.id,
|
|
973
|
-
status: "suspended",
|
|
974
|
-
payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
|
|
975
|
-
},
|
|
976
|
-
workflowState: {
|
|
977
|
-
status: "running",
|
|
978
|
-
steps: stepResults,
|
|
979
|
-
result: null,
|
|
980
|
-
error: null
|
|
981
|
-
}
|
|
982
|
-
},
|
|
983
|
-
eventTimestamp: Date.now()
|
|
984
|
-
});
|
|
985
|
-
await emitter.emit("watch-v2", {
|
|
986
1075
|
type: "workflow-step-suspended",
|
|
987
1076
|
payload: {
|
|
988
1077
|
id: step.id,
|
|
@@ -993,27 +1082,14 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
993
1082
|
executionContext,
|
|
994
1083
|
result: {
|
|
995
1084
|
status: "suspended",
|
|
996
|
-
payload:
|
|
1085
|
+
payload: stepResult.payload,
|
|
1086
|
+
suspendPayload: {
|
|
1087
|
+
...stepResult?.suspendPayload,
|
|
1088
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
1089
|
+
}
|
|
997
1090
|
}
|
|
998
1091
|
};
|
|
999
1092
|
}
|
|
1000
|
-
await emitter.emit("watch", {
|
|
1001
|
-
type: "watch",
|
|
1002
|
-
payload: {
|
|
1003
|
-
currentStep: {
|
|
1004
|
-
id: step.id,
|
|
1005
|
-
status: "suspended",
|
|
1006
|
-
payload: {}
|
|
1007
|
-
},
|
|
1008
|
-
workflowState: {
|
|
1009
|
-
status: "running",
|
|
1010
|
-
steps: stepResults,
|
|
1011
|
-
result: null,
|
|
1012
|
-
error: null
|
|
1013
|
-
}
|
|
1014
|
-
},
|
|
1015
|
-
eventTimestamp: Date.now()
|
|
1016
|
-
});
|
|
1017
1093
|
return {
|
|
1018
1094
|
executionContext,
|
|
1019
1095
|
result: {
|
|
@@ -1023,23 +1099,6 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1023
1099
|
};
|
|
1024
1100
|
}
|
|
1025
1101
|
await emitter.emit("watch", {
|
|
1026
|
-
type: "watch",
|
|
1027
|
-
payload: {
|
|
1028
|
-
currentStep: {
|
|
1029
|
-
id: step.id,
|
|
1030
|
-
status: "success",
|
|
1031
|
-
output: result?.result
|
|
1032
|
-
},
|
|
1033
|
-
workflowState: {
|
|
1034
|
-
status: "running",
|
|
1035
|
-
steps: stepResults,
|
|
1036
|
-
result: null,
|
|
1037
|
-
error: null
|
|
1038
|
-
}
|
|
1039
|
-
},
|
|
1040
|
-
eventTimestamp: Date.now()
|
|
1041
|
-
});
|
|
1042
|
-
await emitter.emit("watch-v2", {
|
|
1043
1102
|
type: "workflow-step-result",
|
|
1044
1103
|
payload: {
|
|
1045
1104
|
id: step.id,
|
|
@@ -1047,7 +1106,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1047
1106
|
output: result?.result
|
|
1048
1107
|
}
|
|
1049
1108
|
});
|
|
1050
|
-
await emitter.emit("watch
|
|
1109
|
+
await emitter.emit("watch", {
|
|
1051
1110
|
type: "workflow-step-finish",
|
|
1052
1111
|
payload: {
|
|
1053
1112
|
id: step.id,
|
|
@@ -1058,159 +1117,197 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1058
1117
|
}
|
|
1059
1118
|
);
|
|
1060
1119
|
Object.assign(executionContext, res.executionContext);
|
|
1061
|
-
return
|
|
1120
|
+
return {
|
|
1121
|
+
...res.result,
|
|
1122
|
+
startedAt,
|
|
1123
|
+
endedAt: Date.now(),
|
|
1124
|
+
payload: inputData,
|
|
1125
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1126
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1127
|
+
};
|
|
1062
1128
|
}
|
|
1063
|
-
const
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1129
|
+
const stepCallId = randomUUID();
|
|
1130
|
+
let stepRes;
|
|
1131
|
+
try {
|
|
1132
|
+
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1133
|
+
let execResults;
|
|
1134
|
+
let suspended;
|
|
1135
|
+
let bailed;
|
|
1136
|
+
try {
|
|
1137
|
+
if (validationError) {
|
|
1138
|
+
throw validationError;
|
|
1139
|
+
}
|
|
1140
|
+
const result = await step.execute({
|
|
1141
|
+
runId: executionContext.runId,
|
|
1142
|
+
mastra: this.mastra,
|
|
1143
|
+
requestContext,
|
|
1144
|
+
writer: new ToolStream(
|
|
1145
|
+
{
|
|
1146
|
+
prefix: "workflow-step",
|
|
1147
|
+
callId: stepCallId,
|
|
1148
|
+
name: step.id,
|
|
1149
|
+
runId: executionContext.runId
|
|
1150
|
+
},
|
|
1151
|
+
writableStream
|
|
1152
|
+
),
|
|
1153
|
+
state: executionContext?.state ?? {},
|
|
1154
|
+
setState: (state) => {
|
|
1155
|
+
executionContext.state = state;
|
|
1156
|
+
},
|
|
1157
|
+
inputData,
|
|
1158
|
+
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1159
|
+
tracingContext: {
|
|
1160
|
+
currentSpan: stepSpan
|
|
1161
|
+
},
|
|
1162
|
+
getInitData: () => stepResults?.input,
|
|
1163
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
1164
|
+
suspend: async (suspendPayload, suspendOptions) => {
|
|
1165
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1166
|
+
if (suspendOptions?.resumeLabel) {
|
|
1167
|
+
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1168
|
+
for (const label of resumeLabel) {
|
|
1169
|
+
executionContext.resumeLabels[label] = {
|
|
1170
|
+
stepId: step.id,
|
|
1171
|
+
foreachIndex: executionContext.foreachIndex
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
suspended = { payload: suspendPayload };
|
|
1176
|
+
},
|
|
1177
|
+
bail: (result2) => {
|
|
1178
|
+
bailed = { payload: result2 };
|
|
1179
|
+
},
|
|
1180
|
+
resume: {
|
|
1181
|
+
steps: resume?.steps?.slice(1) || [],
|
|
1182
|
+
resumePayload: resume?.resumePayload,
|
|
1183
|
+
// @ts-ignore
|
|
1184
|
+
runId: stepResults[step.id]?.suspendPayload?.__workflow_meta?.runId
|
|
1185
|
+
},
|
|
1186
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1187
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1188
|
+
engine: {
|
|
1189
|
+
step: this.inngestStep
|
|
1190
|
+
},
|
|
1191
|
+
abortSignal: abortController.signal
|
|
1192
|
+
});
|
|
1193
|
+
const endedAt = Date.now();
|
|
1194
|
+
execResults = {
|
|
1195
|
+
status: "success",
|
|
1196
|
+
output: result,
|
|
1197
|
+
startedAt,
|
|
1198
|
+
endedAt,
|
|
1199
|
+
payload: inputData,
|
|
1200
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1201
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1202
|
+
};
|
|
1203
|
+
} catch (e) {
|
|
1204
|
+
const stepFailure = {
|
|
1205
|
+
status: "failed",
|
|
1206
|
+
payload: inputData,
|
|
1207
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1208
|
+
endedAt: Date.now(),
|
|
1209
|
+
startedAt,
|
|
1210
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1211
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1212
|
+
};
|
|
1213
|
+
execResults = stepFailure;
|
|
1214
|
+
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1215
|
+
stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1216
|
+
throw new RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1217
|
+
cause: execResults
|
|
1218
|
+
});
|
|
1219
|
+
}
|
|
1220
|
+
if (suspended) {
|
|
1221
|
+
execResults = {
|
|
1222
|
+
status: "suspended",
|
|
1223
|
+
suspendPayload: suspended.payload,
|
|
1224
|
+
...execResults.output ? { suspendOutput: execResults.output } : {},
|
|
1225
|
+
payload: inputData,
|
|
1226
|
+
suspendedAt: Date.now(),
|
|
1227
|
+
startedAt,
|
|
1228
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1229
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1230
|
+
};
|
|
1231
|
+
} else if (bailed) {
|
|
1232
|
+
execResults = {
|
|
1233
|
+
status: "bailed",
|
|
1234
|
+
output: bailed.payload,
|
|
1235
|
+
payload: inputData,
|
|
1236
|
+
endedAt: Date.now(),
|
|
1237
|
+
startedAt
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
if (execResults.status === "suspended") {
|
|
1241
|
+
await emitter.emit("watch", {
|
|
1242
|
+
type: "workflow-step-suspended",
|
|
1243
|
+
payload: {
|
|
1244
|
+
id: step.id,
|
|
1245
|
+
...execResults
|
|
1083
1246
|
}
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
engine: {
|
|
1101
|
-
step: this.inngestStep
|
|
1102
|
-
},
|
|
1103
|
-
abortSignal: abortController.signal
|
|
1104
|
-
});
|
|
1105
|
-
const endedAt = Date.now();
|
|
1106
|
-
execResults = {
|
|
1107
|
-
status: "success",
|
|
1108
|
-
output: result,
|
|
1109
|
-
startedAt,
|
|
1110
|
-
endedAt,
|
|
1111
|
-
payload: prevOutput,
|
|
1112
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1113
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1114
|
-
};
|
|
1115
|
-
} catch (e) {
|
|
1116
|
-
execResults = {
|
|
1117
|
-
status: "failed",
|
|
1118
|
-
payload: prevOutput,
|
|
1119
|
-
error: e instanceof Error ? e.message : String(e),
|
|
1120
|
-
endedAt: Date.now(),
|
|
1121
|
-
startedAt,
|
|
1122
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1123
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
if (suspended) {
|
|
1127
|
-
execResults = {
|
|
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;
|
|
1247
|
+
});
|
|
1248
|
+
} else {
|
|
1249
|
+
await emitter.emit("watch", {
|
|
1250
|
+
type: "workflow-step-result",
|
|
1251
|
+
payload: {
|
|
1252
|
+
id: step.id,
|
|
1253
|
+
...execResults
|
|
1254
|
+
}
|
|
1255
|
+
});
|
|
1256
|
+
await emitter.emit("watch", {
|
|
1257
|
+
type: "workflow-step-finish",
|
|
1258
|
+
payload: {
|
|
1259
|
+
id: step.id,
|
|
1260
|
+
metadata: {}
|
|
1261
|
+
}
|
|
1262
|
+
});
|
|
1144
1263
|
}
|
|
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()
|
|
1264
|
+
stepSpan?.end({ output: execResults });
|
|
1265
|
+
return { result: execResults, executionContext, stepResults };
|
|
1161
1266
|
});
|
|
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) {
|
|
1267
|
+
} catch (e) {
|
|
1268
|
+
const stepFailure = e instanceof Error ? e?.cause : {
|
|
1269
|
+
status: "failed",
|
|
1270
|
+
error: e instanceof Error ? e.message : String(e),
|
|
1271
|
+
payload: inputData,
|
|
1272
|
+
startedAt,
|
|
1273
|
+
endedAt: Date.now()
|
|
1274
|
+
};
|
|
1275
|
+
stepRes = {
|
|
1276
|
+
result: stepFailure,
|
|
1277
|
+
executionContext,
|
|
1278
|
+
stepResults: {
|
|
1279
|
+
...stepResults,
|
|
1280
|
+
[step.id]: stepFailure
|
|
1281
|
+
}
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1284
|
+
if (disableScorers !== false && stepRes.result.status === "success") {
|
|
1190
1285
|
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1191
1286
|
if (step.scorers) {
|
|
1192
1287
|
await this.runScorers({
|
|
1193
1288
|
scorers: step.scorers,
|
|
1194
1289
|
runId: executionContext.runId,
|
|
1195
|
-
input:
|
|
1290
|
+
input: inputData,
|
|
1196
1291
|
output: stepRes.result,
|
|
1197
1292
|
workflowId: executionContext.workflowId,
|
|
1198
1293
|
stepId: step.id,
|
|
1199
|
-
|
|
1294
|
+
requestContext,
|
|
1200
1295
|
disableScorers,
|
|
1201
|
-
tracingContext: { currentSpan:
|
|
1296
|
+
tracingContext: { currentSpan: stepSpan }
|
|
1202
1297
|
});
|
|
1203
1298
|
}
|
|
1204
1299
|
});
|
|
1205
1300
|
}
|
|
1206
1301
|
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1207
1302
|
Object.assign(stepResults, stepRes.stepResults);
|
|
1303
|
+
executionContext.state = stepRes.executionContext.state;
|
|
1208
1304
|
return stepRes.result;
|
|
1209
1305
|
}
|
|
1210
1306
|
async persistStepUpdate({
|
|
1211
1307
|
workflowId,
|
|
1212
1308
|
runId,
|
|
1213
1309
|
stepResults,
|
|
1310
|
+
resourceId,
|
|
1214
1311
|
executionContext,
|
|
1215
1312
|
serializedStepGraph,
|
|
1216
1313
|
workflowStatus,
|
|
@@ -1220,18 +1317,25 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1220
1317
|
await this.inngestStep.run(
|
|
1221
1318
|
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1222
1319
|
async () => {
|
|
1320
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
|
|
1321
|
+
if (!shouldPersistSnapshot) {
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1223
1324
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1224
1325
|
workflowName: workflowId,
|
|
1225
1326
|
runId,
|
|
1327
|
+
resourceId,
|
|
1226
1328
|
snapshot: {
|
|
1227
1329
|
runId,
|
|
1228
|
-
|
|
1330
|
+
status: workflowStatus,
|
|
1331
|
+
value: executionContext.state,
|
|
1229
1332
|
context: stepResults,
|
|
1230
|
-
activePaths:
|
|
1333
|
+
activePaths: executionContext.executionPath,
|
|
1334
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1231
1335
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1336
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1232
1337
|
waitingPaths: {},
|
|
1233
1338
|
serializedStepGraph,
|
|
1234
|
-
status: workflowStatus,
|
|
1235
1339
|
result,
|
|
1236
1340
|
error,
|
|
1237
1341
|
// @ts-ignore
|
|
@@ -1246,85 +1350,88 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1246
1350
|
runId,
|
|
1247
1351
|
entry,
|
|
1248
1352
|
prevOutput,
|
|
1249
|
-
prevStep,
|
|
1250
1353
|
stepResults,
|
|
1251
|
-
serializedStepGraph,
|
|
1252
1354
|
resume,
|
|
1253
1355
|
executionContext,
|
|
1254
1356
|
emitter,
|
|
1255
1357
|
abortController,
|
|
1256
|
-
|
|
1358
|
+
requestContext,
|
|
1257
1359
|
writableStream,
|
|
1258
1360
|
disableScorers,
|
|
1259
1361
|
tracingContext
|
|
1260
1362
|
}) {
|
|
1261
1363
|
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1262
|
-
type:
|
|
1263
|
-
name: `conditional: ${entry.conditions.length} conditions`,
|
|
1364
|
+
type: SpanType.WORKFLOW_CONDITIONAL,
|
|
1365
|
+
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1264
1366
|
input: prevOutput,
|
|
1265
1367
|
attributes: {
|
|
1266
1368
|
conditionCount: entry.conditions.length
|
|
1267
|
-
}
|
|
1369
|
+
},
|
|
1370
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1268
1371
|
});
|
|
1269
1372
|
let execResults;
|
|
1270
1373
|
const truthyIndexes = (await Promise.all(
|
|
1271
1374
|
entry.conditions.map(
|
|
1272
1375
|
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1273
1376
|
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1274
|
-
type:
|
|
1275
|
-
name: `condition ${index}`,
|
|
1377
|
+
type: SpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1378
|
+
name: `condition: '${index}'`,
|
|
1276
1379
|
input: prevOutput,
|
|
1277
1380
|
attributes: {
|
|
1278
1381
|
conditionIndex: index
|
|
1279
|
-
}
|
|
1382
|
+
},
|
|
1383
|
+
tracingPolicy: this.options?.tracingPolicy
|
|
1280
1384
|
});
|
|
1281
1385
|
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(
|
|
1386
|
+
const result = await cond(
|
|
1387
|
+
createDeprecationProxy(
|
|
1319
1388
|
{
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1389
|
+
runId,
|
|
1390
|
+
workflowId,
|
|
1391
|
+
mastra: this.mastra,
|
|
1392
|
+
requestContext,
|
|
1393
|
+
retryCount: -1,
|
|
1394
|
+
inputData: prevOutput,
|
|
1395
|
+
state: executionContext.state,
|
|
1396
|
+
setState: (state) => {
|
|
1397
|
+
executionContext.state = state;
|
|
1398
|
+
},
|
|
1399
|
+
tracingContext: {
|
|
1400
|
+
currentSpan: evalSpan
|
|
1401
|
+
},
|
|
1402
|
+
getInitData: () => stepResults?.input,
|
|
1403
|
+
getStepResult: getStepResult.bind(this, stepResults),
|
|
1404
|
+
// TODO: this function shouldn't have suspend probably?
|
|
1405
|
+
suspend: async (_suspendPayload) => {
|
|
1406
|
+
},
|
|
1407
|
+
bail: () => {
|
|
1408
|
+
},
|
|
1409
|
+
abort: () => {
|
|
1410
|
+
abortController.abort();
|
|
1411
|
+
},
|
|
1412
|
+
[EMITTER_SYMBOL]: emitter,
|
|
1413
|
+
[STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1414
|
+
engine: {
|
|
1415
|
+
step: this.inngestStep
|
|
1416
|
+
},
|
|
1417
|
+
abortSignal: abortController.signal,
|
|
1418
|
+
writer: new ToolStream(
|
|
1419
|
+
{
|
|
1420
|
+
prefix: "workflow-step",
|
|
1421
|
+
callId: randomUUID(),
|
|
1422
|
+
name: "conditional",
|
|
1423
|
+
runId
|
|
1424
|
+
},
|
|
1425
|
+
writableStream
|
|
1426
|
+
)
|
|
1324
1427
|
},
|
|
1325
|
-
|
|
1428
|
+
{
|
|
1429
|
+
paramName: "runCount",
|
|
1430
|
+
deprecationMessage: runCountDeprecationMessage,
|
|
1431
|
+
logger: this.logger
|
|
1432
|
+
}
|
|
1326
1433
|
)
|
|
1327
|
-
|
|
1434
|
+
);
|
|
1328
1435
|
evalSpan?.end({
|
|
1329
1436
|
output: result,
|
|
1330
1437
|
attributes: {
|
|
@@ -1352,45 +1459,54 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
|
|
|
1352
1459
|
}
|
|
1353
1460
|
});
|
|
1354
1461
|
const results = await Promise.all(
|
|
1355
|
-
stepsToRun.map(
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1462
|
+
stepsToRun.map(async (step, index) => {
|
|
1463
|
+
const currStepResult = stepResults[step.step.id];
|
|
1464
|
+
if (currStepResult && currStepResult.status === "success") {
|
|
1465
|
+
return currStepResult;
|
|
1466
|
+
}
|
|
1467
|
+
const result = await this.executeStep({
|
|
1468
|
+
step: step.step,
|
|
1469
|
+
prevOutput,
|
|
1362
1470
|
stepResults,
|
|
1363
1471
|
resume,
|
|
1364
1472
|
executionContext: {
|
|
1365
1473
|
workflowId,
|
|
1366
1474
|
runId,
|
|
1367
1475
|
executionPath: [...executionContext.executionPath, index],
|
|
1476
|
+
activeStepsPath: executionContext.activeStepsPath,
|
|
1368
1477
|
suspendedPaths: executionContext.suspendedPaths,
|
|
1478
|
+
resumeLabels: executionContext.resumeLabels,
|
|
1369
1479
|
retryConfig: executionContext.retryConfig,
|
|
1370
|
-
|
|
1480
|
+
state: executionContext.state
|
|
1371
1481
|
},
|
|
1372
1482
|
emitter,
|
|
1373
1483
|
abortController,
|
|
1374
|
-
|
|
1484
|
+
requestContext,
|
|
1375
1485
|
writableStream,
|
|
1376
1486
|
disableScorers,
|
|
1377
1487
|
tracingContext: {
|
|
1378
1488
|
currentSpan: conditionalSpan
|
|
1379
1489
|
}
|
|
1380
|
-
})
|
|
1381
|
-
|
|
1490
|
+
});
|
|
1491
|
+
stepResults[step.step.id] = result;
|
|
1492
|
+
return result;
|
|
1493
|
+
})
|
|
1382
1494
|
);
|
|
1383
|
-
const hasFailed = results.find((result) => result.
|
|
1384
|
-
const hasSuspended = results.find((result) => result.
|
|
1495
|
+
const hasFailed = results.find((result) => result.status === "failed");
|
|
1496
|
+
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1385
1497
|
if (hasFailed) {
|
|
1386
|
-
execResults = { status: "failed", error: hasFailed.
|
|
1498
|
+
execResults = { status: "failed", error: hasFailed.error };
|
|
1387
1499
|
} else if (hasSuspended) {
|
|
1388
|
-
execResults = {
|
|
1500
|
+
execResults = {
|
|
1501
|
+
status: "suspended",
|
|
1502
|
+
suspendPayload: hasSuspended.suspendPayload,
|
|
1503
|
+
...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
|
|
1504
|
+
};
|
|
1389
1505
|
} else {
|
|
1390
1506
|
execResults = {
|
|
1391
1507
|
status: "success",
|
|
1392
1508
|
output: results.reduce((acc, result, index) => {
|
|
1393
|
-
if (result.
|
|
1509
|
+
if (result.status === "success") {
|
|
1394
1510
|
acc[stepsToRun[index].step.id] = result.output;
|
|
1395
1511
|
}
|
|
1396
1512
|
return acc;
|