@mastra/inngest 0.0.0-feat-support-ai-sdk-5-again-20250813225910 → 0.0.0-feat-add-query-option-to-playground-20251209160219
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 +1034 -4
- package/dist/execution-engine.d.ts +85 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/index.cjs +836 -910
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +28 -271
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +812 -887
- package/dist/index.js.map +1 -1
- package/dist/run.d.ts +144 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/serve.d.ts +13 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/workflow.d.ts +51 -0
- package/dist/workflow.d.ts.map +1 -0
- package/package.json +37 -19
- package/docker-compose.yaml +0 -10
- package/eslint.config.js +0 -6
- package/src/index.test.ts +0 -7827
- package/src/index.ts +0 -1784
- package/tsconfig.build.json +0 -9
- package/tsconfig.json +0 -5
- package/tsup.config.ts +0 -17
- package/vitest.config.ts +0 -14
package/dist/index.cjs
CHANGED
|
@@ -1,33 +1,302 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var crypto = require('crypto');
|
|
4
|
-
var realtime = require('@inngest/realtime');
|
|
5
|
-
var di = require('@mastra/core/di');
|
|
6
3
|
var tools = require('@mastra/core/tools');
|
|
7
4
|
var workflows = require('@mastra/core/workflows');
|
|
8
5
|
var _constants = require('@mastra/core/workflows/_constants');
|
|
9
|
-
var hono = require('inngest/hono');
|
|
10
6
|
var zod = require('zod');
|
|
7
|
+
var crypto = require('crypto');
|
|
8
|
+
var di = require('@mastra/core/di');
|
|
9
|
+
var inngest = require('inngest');
|
|
10
|
+
var web = require('stream/web');
|
|
11
|
+
var realtime = require('@inngest/realtime');
|
|
12
|
+
var stream = require('@mastra/core/stream');
|
|
13
|
+
var hono = require('inngest/hono');
|
|
11
14
|
|
|
12
15
|
// src/index.ts
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
17
|
+
inngestStep;
|
|
18
|
+
inngestAttempts;
|
|
19
|
+
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
20
|
+
super({ mastra, options });
|
|
21
|
+
this.inngestStep = inngestStep;
|
|
22
|
+
this.inngestAttempts = inngestAttempts;
|
|
23
|
+
}
|
|
24
|
+
// =============================================================================
|
|
25
|
+
// Hook Overrides
|
|
26
|
+
// =============================================================================
|
|
27
|
+
/**
|
|
28
|
+
* Format errors with stack traces for better debugging in Inngest
|
|
29
|
+
*/
|
|
30
|
+
formatResultError(error, lastOutput) {
|
|
31
|
+
if (error instanceof Error) {
|
|
32
|
+
return error.stack ?? error.message;
|
|
33
|
+
}
|
|
34
|
+
const outputError = lastOutput?.error;
|
|
35
|
+
if (outputError instanceof Error) {
|
|
36
|
+
return outputError.message;
|
|
37
|
+
}
|
|
38
|
+
return outputError ?? error ?? "Unknown error";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Detect InngestWorkflow instances for special nested workflow handling
|
|
42
|
+
*/
|
|
43
|
+
isNestedWorkflowStep(step) {
|
|
44
|
+
return step instanceof InngestWorkflow;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Inngest requires requestContext serialization for memoization.
|
|
48
|
+
* When steps are replayed, the original function doesn't re-execute,
|
|
49
|
+
* so requestContext modifications must be captured and restored.
|
|
50
|
+
*/
|
|
51
|
+
requiresDurableContextSerialization() {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute a step with retry logic for Inngest.
|
|
56
|
+
* Retries are handled via step-level retry (RetryAfterError thrown INSIDE step.run()).
|
|
57
|
+
* After retries exhausted, error propagates here and we return a failed result.
|
|
58
|
+
*/
|
|
59
|
+
async executeStepWithRetry(stepId, runStep, params) {
|
|
60
|
+
try {
|
|
61
|
+
const result = await this.wrapDurableOperation(stepId, runStep, { delay: params.delay });
|
|
62
|
+
return { ok: true, result };
|
|
63
|
+
} catch (e) {
|
|
64
|
+
const cause = e?.cause;
|
|
65
|
+
if (cause?.status === "failed") {
|
|
66
|
+
params.stepSpan?.error({
|
|
67
|
+
error: e,
|
|
68
|
+
attributes: { status: "failed" }
|
|
69
|
+
});
|
|
70
|
+
return { ok: false, error: cause };
|
|
71
|
+
}
|
|
72
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
73
|
+
params.stepSpan?.error({
|
|
74
|
+
error: e,
|
|
75
|
+
attributes: { status: "failed" }
|
|
76
|
+
});
|
|
77
|
+
return {
|
|
78
|
+
ok: false,
|
|
79
|
+
error: {
|
|
80
|
+
status: "failed",
|
|
81
|
+
error: `Error: ${errorMessage}`,
|
|
82
|
+
endedAt: Date.now()
|
|
21
83
|
}
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
}
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Use Inngest's sleep primitive for durability
|
|
89
|
+
*/
|
|
90
|
+
async executeSleepDuration(duration, sleepId, workflowId) {
|
|
91
|
+
await this.inngestStep.sleep(`workflow.${workflowId}.sleep.${sleepId}`, duration < 0 ? 0 : duration);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Use Inngest's sleepUntil primitive for durability
|
|
95
|
+
*/
|
|
96
|
+
async executeSleepUntilDate(date, sleepUntilId, workflowId) {
|
|
97
|
+
await this.inngestStep.sleepUntil(`workflow.${workflowId}.sleepUntil.${sleepUntilId}`, date);
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Wrap durable operations in Inngest step.run() for durability.
|
|
101
|
+
* If retryConfig is provided, throws RetryAfterError INSIDE step.run() to trigger
|
|
102
|
+
* Inngest's step-level retry mechanism (not function-level retry).
|
|
103
|
+
*/
|
|
104
|
+
async wrapDurableOperation(operationId, operationFn, retryConfig) {
|
|
105
|
+
return this.inngestStep.run(operationId, async () => {
|
|
106
|
+
try {
|
|
107
|
+
return await operationFn();
|
|
108
|
+
} catch (e) {
|
|
109
|
+
if (retryConfig) {
|
|
110
|
+
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
111
|
+
throw new inngest.RetryAfterError(errorMessage, retryConfig.delay, {
|
|
112
|
+
cause: {
|
|
113
|
+
status: "failed",
|
|
114
|
+
error: `Error: ${errorMessage}`,
|
|
115
|
+
endedAt: Date.now()
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
throw e;
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Provide Inngest step primitive in engine context
|
|
125
|
+
*/
|
|
126
|
+
getEngineContext() {
|
|
127
|
+
return { step: this.inngestStep };
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Execute nested InngestWorkflow using inngestStep.invoke() for durability.
|
|
131
|
+
* This MUST be called directly (not inside step.run()) due to Inngest constraints.
|
|
132
|
+
*/
|
|
133
|
+
async executeWorkflowStep(params) {
|
|
134
|
+
if (!(params.step instanceof InngestWorkflow)) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
const { step, stepResults, executionContext, resume, timeTravel, prevOutput, inputData, emitter, startedAt } = params;
|
|
138
|
+
const isResume = !!resume?.steps?.length;
|
|
139
|
+
let result;
|
|
140
|
+
let runId;
|
|
141
|
+
const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
|
|
142
|
+
try {
|
|
143
|
+
if (isResume) {
|
|
144
|
+
runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
145
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
146
|
+
workflowName: step.id,
|
|
147
|
+
runId
|
|
148
|
+
});
|
|
149
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
150
|
+
function: step.getFunction(),
|
|
151
|
+
data: {
|
|
152
|
+
inputData,
|
|
153
|
+
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
154
|
+
runId,
|
|
155
|
+
resume: {
|
|
156
|
+
runId,
|
|
157
|
+
steps: resume.steps.slice(1),
|
|
158
|
+
stepResults: snapshot?.context,
|
|
159
|
+
resumePayload: resume.resumePayload,
|
|
160
|
+
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
161
|
+
},
|
|
162
|
+
outputOptions: { includeState: true }
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
result = invokeResp.result;
|
|
166
|
+
runId = invokeResp.runId;
|
|
167
|
+
executionContext.state = invokeResp.result.state;
|
|
168
|
+
} else if (isTimeTravel) {
|
|
169
|
+
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
170
|
+
workflowName: step.id,
|
|
171
|
+
runId: executionContext.runId
|
|
172
|
+
}) ?? { context: {} };
|
|
173
|
+
const timeTravelParams = workflows.createTimeTravelExecutionParams({
|
|
174
|
+
steps: timeTravel.steps.slice(1),
|
|
175
|
+
inputData: timeTravel.inputData,
|
|
176
|
+
resumeData: timeTravel.resumeData,
|
|
177
|
+
context: timeTravel.nestedStepResults?.[step.id] ?? {},
|
|
178
|
+
nestedStepsContext: timeTravel.nestedStepResults ?? {},
|
|
179
|
+
snapshot,
|
|
180
|
+
graph: step.buildExecutionGraph()
|
|
181
|
+
});
|
|
182
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
183
|
+
function: step.getFunction(),
|
|
184
|
+
data: {
|
|
185
|
+
timeTravel: timeTravelParams,
|
|
186
|
+
initialState: executionContext.state ?? {},
|
|
187
|
+
runId: executionContext.runId,
|
|
188
|
+
outputOptions: { includeState: true }
|
|
189
|
+
}
|
|
190
|
+
});
|
|
191
|
+
result = invokeResp.result;
|
|
192
|
+
runId = invokeResp.runId;
|
|
193
|
+
executionContext.state = invokeResp.result.state;
|
|
194
|
+
} else {
|
|
195
|
+
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
196
|
+
function: step.getFunction(),
|
|
197
|
+
data: {
|
|
198
|
+
inputData,
|
|
199
|
+
initialState: executionContext.state ?? {},
|
|
200
|
+
outputOptions: { includeState: true }
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
result = invokeResp.result;
|
|
204
|
+
runId = invokeResp.runId;
|
|
205
|
+
executionContext.state = invokeResp.result.state;
|
|
206
|
+
}
|
|
207
|
+
} catch (e) {
|
|
208
|
+
const errorCause = e?.cause;
|
|
209
|
+
if (errorCause && typeof errorCause === "object") {
|
|
210
|
+
result = errorCause;
|
|
211
|
+
runId = errorCause.runId || crypto.randomUUID();
|
|
212
|
+
} else {
|
|
213
|
+
runId = crypto.randomUUID();
|
|
214
|
+
result = {
|
|
215
|
+
status: "failed",
|
|
216
|
+
error: e instanceof Error ? e : new Error(String(e)),
|
|
217
|
+
steps: {},
|
|
218
|
+
input: inputData
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
const res = await this.inngestStep.run(
|
|
223
|
+
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
224
|
+
async () => {
|
|
225
|
+
if (result.status === "failed") {
|
|
226
|
+
await emitter.emit("watch", {
|
|
227
|
+
type: "workflow-step-result",
|
|
228
|
+
payload: {
|
|
229
|
+
id: step.id,
|
|
230
|
+
status: "failed",
|
|
231
|
+
error: result?.error,
|
|
232
|
+
payload: prevOutput
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
236
|
+
} else if (result.status === "suspended") {
|
|
237
|
+
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
238
|
+
const stepRes = stepResult;
|
|
239
|
+
return stepRes?.status === "suspended";
|
|
240
|
+
});
|
|
241
|
+
for (const [stepName, stepResult] of suspendedSteps) {
|
|
242
|
+
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
243
|
+
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
244
|
+
await emitter.emit("watch", {
|
|
245
|
+
type: "workflow-step-suspended",
|
|
246
|
+
payload: {
|
|
247
|
+
id: step.id,
|
|
248
|
+
status: "suspended"
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
return {
|
|
252
|
+
executionContext,
|
|
253
|
+
result: {
|
|
254
|
+
status: "suspended",
|
|
255
|
+
payload: stepResult.payload,
|
|
256
|
+
suspendPayload: {
|
|
257
|
+
...stepResult?.suspendPayload,
|
|
258
|
+
__workflow_meta: { runId, path: suspendPath }
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
return {
|
|
264
|
+
executionContext,
|
|
265
|
+
result: {
|
|
266
|
+
status: "suspended",
|
|
267
|
+
payload: {}
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}
|
|
271
|
+
await emitter.emit("watch", {
|
|
272
|
+
type: "workflow-step-result",
|
|
273
|
+
payload: {
|
|
274
|
+
id: step.id,
|
|
275
|
+
status: "success",
|
|
276
|
+
output: result?.result
|
|
277
|
+
}
|
|
278
|
+
});
|
|
279
|
+
await emitter.emit("watch", {
|
|
280
|
+
type: "workflow-step-finish",
|
|
281
|
+
payload: {
|
|
282
|
+
id: step.id,
|
|
283
|
+
metadata: {}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
return { executionContext, result: { status: "success", output: result?.result } };
|
|
287
|
+
}
|
|
288
|
+
);
|
|
289
|
+
Object.assign(executionContext, res.executionContext);
|
|
290
|
+
return {
|
|
291
|
+
...res.result,
|
|
292
|
+
startedAt,
|
|
293
|
+
endedAt: Date.now(),
|
|
294
|
+
payload: inputData,
|
|
295
|
+
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
296
|
+
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
};
|
|
31
300
|
var InngestRun = class extends workflows.Run {
|
|
32
301
|
inngest;
|
|
33
302
|
serializedStepGraph;
|
|
@@ -49,14 +318,21 @@ var InngestRun = class extends workflows.Run {
|
|
|
49
318
|
}
|
|
50
319
|
async getRunOutput(eventId) {
|
|
51
320
|
let runs = await this.getRuns(eventId);
|
|
321
|
+
const storage = this.#mastra?.getStorage();
|
|
52
322
|
while (runs?.[0]?.status !== "Completed" || runs?.[0]?.event_id !== eventId) {
|
|
53
323
|
await new Promise((resolve) => setTimeout(resolve, 1e3));
|
|
54
324
|
runs = await this.getRuns(eventId);
|
|
55
325
|
if (runs?.[0]?.status === "Failed") {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
326
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
327
|
+
workflowName: this.workflowId,
|
|
328
|
+
runId: this.runId
|
|
329
|
+
});
|
|
330
|
+
return {
|
|
331
|
+
output: { result: { steps: snapshot?.context, status: "failed", error: runs?.[0]?.output?.message } }
|
|
332
|
+
};
|
|
333
|
+
}
|
|
334
|
+
if (runs?.[0]?.status === "Cancelled") {
|
|
335
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
60
336
|
workflowName: this.workflowId,
|
|
61
337
|
runId: this.runId
|
|
62
338
|
});
|
|
@@ -65,56 +341,73 @@ var InngestRun = class extends workflows.Run {
|
|
|
65
341
|
}
|
|
66
342
|
return runs?.[0];
|
|
67
343
|
}
|
|
68
|
-
async sendEvent(event, data) {
|
|
69
|
-
await this.inngest.send({
|
|
70
|
-
name: `user-event-${event}`,
|
|
71
|
-
data
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
344
|
async cancel() {
|
|
345
|
+
const storage = this.#mastra?.getStorage();
|
|
75
346
|
await this.inngest.send({
|
|
76
347
|
name: `cancel.workflow.${this.workflowId}`,
|
|
77
348
|
data: {
|
|
78
349
|
runId: this.runId
|
|
79
350
|
}
|
|
80
351
|
});
|
|
81
|
-
const snapshot = await
|
|
352
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
82
353
|
workflowName: this.workflowId,
|
|
83
354
|
runId: this.runId
|
|
84
355
|
});
|
|
85
356
|
if (snapshot) {
|
|
86
|
-
await
|
|
357
|
+
await storage?.persistWorkflowSnapshot({
|
|
87
358
|
workflowName: this.workflowId,
|
|
88
359
|
runId: this.runId,
|
|
360
|
+
resourceId: this.resourceId,
|
|
89
361
|
snapshot: {
|
|
90
362
|
...snapshot,
|
|
91
|
-
status: "canceled"
|
|
363
|
+
status: "canceled",
|
|
364
|
+
value: snapshot.value
|
|
92
365
|
}
|
|
93
366
|
});
|
|
94
367
|
}
|
|
95
368
|
}
|
|
96
|
-
async start({
|
|
97
|
-
|
|
369
|
+
async start(params) {
|
|
370
|
+
return this._start(params);
|
|
371
|
+
}
|
|
372
|
+
async _start({
|
|
373
|
+
inputData,
|
|
374
|
+
initialState,
|
|
375
|
+
outputOptions,
|
|
376
|
+
tracingOptions,
|
|
377
|
+
format,
|
|
378
|
+
requestContext
|
|
98
379
|
}) {
|
|
99
380
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
100
381
|
workflowName: this.workflowId,
|
|
101
382
|
runId: this.runId,
|
|
383
|
+
resourceId: this.resourceId,
|
|
102
384
|
snapshot: {
|
|
103
385
|
runId: this.runId,
|
|
104
386
|
serializedStepGraph: this.serializedStepGraph,
|
|
387
|
+
status: "running",
|
|
105
388
|
value: {},
|
|
106
389
|
context: {},
|
|
107
390
|
activePaths: [],
|
|
108
391
|
suspendedPaths: {},
|
|
109
|
-
|
|
110
|
-
|
|
392
|
+
activeStepsPath: {},
|
|
393
|
+
resumeLabels: {},
|
|
394
|
+
waitingPaths: {},
|
|
395
|
+
timestamp: Date.now()
|
|
111
396
|
}
|
|
112
397
|
});
|
|
398
|
+
const inputDataToUse = await this._validateInput(inputData);
|
|
399
|
+
const initialStateToUse = await this._validateInitialState(initialState ?? {});
|
|
113
400
|
const eventOutput = await this.inngest.send({
|
|
114
401
|
name: `workflow.${this.workflowId}`,
|
|
115
402
|
data: {
|
|
116
|
-
inputData,
|
|
117
|
-
|
|
403
|
+
inputData: inputDataToUse,
|
|
404
|
+
initialState: initialStateToUse,
|
|
405
|
+
runId: this.runId,
|
|
406
|
+
resourceId: this.resourceId,
|
|
407
|
+
outputOptions,
|
|
408
|
+
tracingOptions,
|
|
409
|
+
format,
|
|
410
|
+
requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {}
|
|
118
411
|
}
|
|
119
412
|
});
|
|
120
413
|
const eventId = eventOutput.ids[0];
|
|
@@ -143,27 +436,131 @@ var InngestRun = class extends workflows.Run {
|
|
|
143
436
|
return p;
|
|
144
437
|
}
|
|
145
438
|
async _resume(params) {
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
)
|
|
149
|
-
|
|
439
|
+
const storage = this.#mastra?.getStorage();
|
|
440
|
+
let steps = [];
|
|
441
|
+
if (typeof params.step === "string") {
|
|
442
|
+
steps = params.step.split(".");
|
|
443
|
+
} else {
|
|
444
|
+
steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
445
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
150
449
|
workflowName: this.workflowId,
|
|
151
450
|
runId: this.runId
|
|
152
451
|
});
|
|
452
|
+
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
453
|
+
const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);
|
|
454
|
+
const persistedRequestContext = snapshot?.requestContext ?? {};
|
|
455
|
+
const newRequestContext = params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {};
|
|
456
|
+
const mergedRequestContext = { ...persistedRequestContext, ...newRequestContext };
|
|
153
457
|
const eventOutput = await this.inngest.send({
|
|
154
458
|
name: `workflow.${this.workflowId}`,
|
|
155
459
|
data: {
|
|
156
|
-
inputData:
|
|
460
|
+
inputData: resumeDataToUse,
|
|
461
|
+
initialState: snapshot?.value ?? {},
|
|
157
462
|
runId: this.runId,
|
|
158
463
|
workflowId: this.workflowId,
|
|
159
464
|
stepResults: snapshot?.context,
|
|
160
465
|
resume: {
|
|
161
466
|
steps,
|
|
162
467
|
stepResults: snapshot?.context,
|
|
163
|
-
resumePayload:
|
|
164
|
-
|
|
165
|
-
|
|
468
|
+
resumePayload: resumeDataToUse,
|
|
469
|
+
resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
|
|
470
|
+
},
|
|
471
|
+
requestContext: mergedRequestContext
|
|
472
|
+
}
|
|
473
|
+
});
|
|
474
|
+
const eventId = eventOutput.ids[0];
|
|
475
|
+
if (!eventId) {
|
|
476
|
+
throw new Error("Event ID is not set");
|
|
477
|
+
}
|
|
478
|
+
const runOutput = await this.getRunOutput(eventId);
|
|
479
|
+
const result = runOutput?.output?.result;
|
|
480
|
+
if (result.status === "failed") {
|
|
481
|
+
result.error = new Error(result.error);
|
|
482
|
+
}
|
|
483
|
+
return result;
|
|
484
|
+
}
|
|
485
|
+
async timeTravel(params) {
|
|
486
|
+
const p = this._timeTravel(params).then((result) => {
|
|
487
|
+
if (result.status !== "suspended") {
|
|
488
|
+
this.closeStreamAction?.().catch(() => {
|
|
489
|
+
});
|
|
490
|
+
}
|
|
491
|
+
return result;
|
|
492
|
+
});
|
|
493
|
+
this.executionResults = p;
|
|
494
|
+
return p;
|
|
495
|
+
}
|
|
496
|
+
async _timeTravel(params) {
|
|
497
|
+
if (!params.step || Array.isArray(params.step) && params.step?.length === 0) {
|
|
498
|
+
throw new Error("Step is required and must be a valid step or array of steps");
|
|
499
|
+
}
|
|
500
|
+
let steps = [];
|
|
501
|
+
if (typeof params.step === "string") {
|
|
502
|
+
steps = params.step.split(".");
|
|
503
|
+
} else {
|
|
504
|
+
steps = (Array.isArray(params.step) ? params.step : [params.step]).map(
|
|
505
|
+
(step) => typeof step === "string" ? step : step?.id
|
|
506
|
+
);
|
|
507
|
+
}
|
|
508
|
+
if (steps.length === 0) {
|
|
509
|
+
throw new Error("No steps provided to timeTravel");
|
|
510
|
+
}
|
|
511
|
+
const storage = this.#mastra?.getStorage();
|
|
512
|
+
const snapshot = await storage?.loadWorkflowSnapshot({
|
|
513
|
+
workflowName: this.workflowId,
|
|
514
|
+
runId: this.runId
|
|
515
|
+
});
|
|
516
|
+
if (!snapshot) {
|
|
517
|
+
await storage?.persistWorkflowSnapshot({
|
|
518
|
+
workflowName: this.workflowId,
|
|
519
|
+
runId: this.runId,
|
|
520
|
+
resourceId: this.resourceId,
|
|
521
|
+
snapshot: {
|
|
522
|
+
runId: this.runId,
|
|
523
|
+
serializedStepGraph: this.serializedStepGraph,
|
|
524
|
+
status: "pending",
|
|
525
|
+
value: {},
|
|
526
|
+
context: {},
|
|
527
|
+
activePaths: [],
|
|
528
|
+
suspendedPaths: {},
|
|
529
|
+
activeStepsPath: {},
|
|
530
|
+
resumeLabels: {},
|
|
531
|
+
waitingPaths: {},
|
|
532
|
+
timestamp: Date.now()
|
|
166
533
|
}
|
|
534
|
+
});
|
|
535
|
+
}
|
|
536
|
+
if (snapshot?.status === "running") {
|
|
537
|
+
throw new Error("This workflow run is still running, cannot time travel");
|
|
538
|
+
}
|
|
539
|
+
let inputDataToUse = params.inputData;
|
|
540
|
+
if (inputDataToUse && steps.length === 1) {
|
|
541
|
+
inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]]);
|
|
542
|
+
}
|
|
543
|
+
const timeTravelData = workflows.createTimeTravelExecutionParams({
|
|
544
|
+
steps,
|
|
545
|
+
inputData: inputDataToUse,
|
|
546
|
+
resumeData: params.resumeData,
|
|
547
|
+
context: params.context,
|
|
548
|
+
nestedStepsContext: params.nestedStepsContext,
|
|
549
|
+
snapshot: snapshot ?? { context: {} },
|
|
550
|
+
graph: this.executionGraph,
|
|
551
|
+
initialState: params.initialState
|
|
552
|
+
});
|
|
553
|
+
const eventOutput = await this.inngest.send({
|
|
554
|
+
name: `workflow.${this.workflowId}`,
|
|
555
|
+
data: {
|
|
556
|
+
initialState: timeTravelData.state,
|
|
557
|
+
runId: this.runId,
|
|
558
|
+
workflowId: this.workflowId,
|
|
559
|
+
stepResults: timeTravelData.stepResults,
|
|
560
|
+
timeTravel: timeTravelData,
|
|
561
|
+
tracingOptions: params.tracingOptions,
|
|
562
|
+
outputOptions: params.outputOptions,
|
|
563
|
+
requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
|
|
167
564
|
}
|
|
168
565
|
});
|
|
169
566
|
const eventId = eventOutput.ids[0];
|
|
@@ -177,12 +574,12 @@ var InngestRun = class extends workflows.Run {
|
|
|
177
574
|
}
|
|
178
575
|
return result;
|
|
179
576
|
}
|
|
180
|
-
watch(cb
|
|
577
|
+
watch(cb) {
|
|
181
578
|
let active = true;
|
|
182
579
|
const streamPromise = realtime.subscribe(
|
|
183
580
|
{
|
|
184
581
|
channel: `workflow:${this.workflowId}:${this.runId}`,
|
|
185
|
-
topics: [
|
|
582
|
+
topics: ["watch"],
|
|
186
583
|
app: this.inngest
|
|
187
584
|
},
|
|
188
585
|
(message) => {
|
|
@@ -200,16 +597,35 @@ var InngestRun = class extends workflows.Run {
|
|
|
200
597
|
});
|
|
201
598
|
};
|
|
202
599
|
}
|
|
203
|
-
|
|
600
|
+
streamLegacy({ inputData, requestContext } = {}) {
|
|
204
601
|
const { readable, writable } = new TransformStream();
|
|
205
602
|
const writer = writable.getWriter();
|
|
603
|
+
void writer.write({
|
|
604
|
+
// @ts-ignore
|
|
605
|
+
type: "start",
|
|
606
|
+
// @ts-ignore
|
|
607
|
+
payload: { runId: this.runId }
|
|
608
|
+
});
|
|
206
609
|
const unwatch = this.watch(async (event) => {
|
|
207
610
|
try {
|
|
208
|
-
|
|
611
|
+
const e = {
|
|
612
|
+
...event,
|
|
613
|
+
type: event.type.replace("workflow-", "")
|
|
614
|
+
};
|
|
615
|
+
if (e.type === "step-output") {
|
|
616
|
+
e.type = e.payload.output.type;
|
|
617
|
+
e.payload = e.payload.output.payload;
|
|
618
|
+
}
|
|
619
|
+
await writer.write(e);
|
|
209
620
|
} catch {
|
|
210
621
|
}
|
|
211
|
-
}
|
|
622
|
+
});
|
|
212
623
|
this.closeStreamAction = async () => {
|
|
624
|
+
await writer.write({
|
|
625
|
+
type: "finish",
|
|
626
|
+
// @ts-ignore
|
|
627
|
+
payload: { runId: this.runId }
|
|
628
|
+
});
|
|
213
629
|
unwatch();
|
|
214
630
|
try {
|
|
215
631
|
await writer.close();
|
|
@@ -219,7 +635,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
219
635
|
writer.releaseLock();
|
|
220
636
|
}
|
|
221
637
|
};
|
|
222
|
-
this.executionResults = this.
|
|
638
|
+
this.executionResults = this._start({ inputData, requestContext, format: "legacy" }).then((result) => {
|
|
223
639
|
if (result.status !== "suspended") {
|
|
224
640
|
this.closeStreamAction?.().catch(() => {
|
|
225
641
|
});
|
|
@@ -231,57 +647,190 @@ var InngestRun = class extends workflows.Run {
|
|
|
231
647
|
getWorkflowState: () => this.executionResults
|
|
232
648
|
};
|
|
233
649
|
}
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
this.
|
|
243
|
-
|
|
244
|
-
async getWorkflowRuns(args) {
|
|
245
|
-
const storage = this.#mastra?.getStorage();
|
|
246
|
-
if (!storage) {
|
|
247
|
-
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
248
|
-
return { runs: [], total: 0 };
|
|
249
|
-
}
|
|
250
|
-
return storage.getWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
251
|
-
}
|
|
252
|
-
async getWorkflowRunById(runId) {
|
|
253
|
-
const storage = this.#mastra?.getStorage();
|
|
254
|
-
if (!storage) {
|
|
255
|
-
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
256
|
-
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
257
|
-
}
|
|
258
|
-
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
259
|
-
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
260
|
-
}
|
|
261
|
-
async getWorkflowRunExecutionResult(runId) {
|
|
262
|
-
const storage = this.#mastra?.getStorage();
|
|
263
|
-
if (!storage) {
|
|
264
|
-
this.logger.debug("Cannot get workflow run execution result. Mastra storage is not initialized");
|
|
265
|
-
return null;
|
|
266
|
-
}
|
|
267
|
-
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
268
|
-
if (!run?.snapshot) {
|
|
269
|
-
return null;
|
|
650
|
+
stream({
|
|
651
|
+
inputData,
|
|
652
|
+
requestContext,
|
|
653
|
+
tracingOptions,
|
|
654
|
+
closeOnSuspend = true,
|
|
655
|
+
initialState,
|
|
656
|
+
outputOptions
|
|
657
|
+
} = {}) {
|
|
658
|
+
if (this.closeStreamAction && this.streamOutput) {
|
|
659
|
+
return this.streamOutput;
|
|
270
660
|
}
|
|
271
|
-
|
|
272
|
-
return null;
|
|
273
|
-
}
|
|
274
|
-
return {
|
|
275
|
-
status: run.snapshot.status,
|
|
276
|
-
result: run.snapshot.result,
|
|
277
|
-
error: run.snapshot.error,
|
|
278
|
-
payload: run.snapshot.context?.input,
|
|
279
|
-
steps: run.snapshot.context
|
|
661
|
+
this.closeStreamAction = async () => {
|
|
280
662
|
};
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
663
|
+
const self = this;
|
|
664
|
+
const stream$1 = new web.ReadableStream({
|
|
665
|
+
async start(controller) {
|
|
666
|
+
const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
|
|
667
|
+
controller.enqueue({
|
|
668
|
+
type,
|
|
669
|
+
runId: self.runId,
|
|
670
|
+
from,
|
|
671
|
+
payload: {
|
|
672
|
+
stepName: payload?.id,
|
|
673
|
+
...payload
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
});
|
|
677
|
+
self.closeStreamAction = async () => {
|
|
678
|
+
unwatch();
|
|
679
|
+
try {
|
|
680
|
+
await controller.close();
|
|
681
|
+
} catch (err) {
|
|
682
|
+
console.error("Error closing stream:", err);
|
|
683
|
+
}
|
|
684
|
+
};
|
|
685
|
+
const executionResultsPromise = self._start({
|
|
686
|
+
inputData,
|
|
687
|
+
requestContext,
|
|
688
|
+
// tracingContext, // We are not able to pass a reference to a span here, what to do?
|
|
689
|
+
initialState,
|
|
690
|
+
tracingOptions,
|
|
691
|
+
outputOptions,
|
|
692
|
+
format: "vnext"
|
|
693
|
+
});
|
|
694
|
+
let executionResults;
|
|
695
|
+
try {
|
|
696
|
+
executionResults = await executionResultsPromise;
|
|
697
|
+
if (closeOnSuspend) {
|
|
698
|
+
self.closeStreamAction?.().catch(() => {
|
|
699
|
+
});
|
|
700
|
+
} else if (executionResults.status !== "suspended") {
|
|
701
|
+
self.closeStreamAction?.().catch(() => {
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
if (self.streamOutput) {
|
|
705
|
+
self.streamOutput.updateResults(
|
|
706
|
+
executionResults
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
} catch (err) {
|
|
710
|
+
self.streamOutput?.rejectResults(err);
|
|
711
|
+
self.closeStreamAction?.().catch(() => {
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
this.streamOutput = new stream.WorkflowRunOutput({
|
|
717
|
+
runId: this.runId,
|
|
718
|
+
workflowId: this.workflowId,
|
|
719
|
+
stream: stream$1
|
|
720
|
+
});
|
|
721
|
+
return this.streamOutput;
|
|
722
|
+
}
|
|
723
|
+
streamVNext(args = {}) {
|
|
724
|
+
return this.stream(args);
|
|
725
|
+
}
|
|
726
|
+
timeTravelStream({
|
|
727
|
+
inputData,
|
|
728
|
+
resumeData,
|
|
729
|
+
initialState,
|
|
730
|
+
step,
|
|
731
|
+
context,
|
|
732
|
+
nestedStepsContext,
|
|
733
|
+
requestContext,
|
|
734
|
+
tracingOptions,
|
|
735
|
+
outputOptions
|
|
736
|
+
}) {
|
|
737
|
+
this.closeStreamAction = async () => {
|
|
738
|
+
};
|
|
739
|
+
const self = this;
|
|
740
|
+
const stream$1 = new web.ReadableStream({
|
|
741
|
+
async start(controller) {
|
|
742
|
+
const unwatch = self.watch(async ({ type, from = stream.ChunkFrom.WORKFLOW, payload }) => {
|
|
743
|
+
controller.enqueue({
|
|
744
|
+
type,
|
|
745
|
+
runId: self.runId,
|
|
746
|
+
from,
|
|
747
|
+
payload: {
|
|
748
|
+
stepName: payload?.id,
|
|
749
|
+
...payload
|
|
750
|
+
}
|
|
751
|
+
});
|
|
752
|
+
});
|
|
753
|
+
self.closeStreamAction = async () => {
|
|
754
|
+
unwatch();
|
|
755
|
+
try {
|
|
756
|
+
controller.close();
|
|
757
|
+
} catch (err) {
|
|
758
|
+
console.error("Error closing stream:", err);
|
|
759
|
+
}
|
|
760
|
+
};
|
|
761
|
+
const executionResultsPromise = self._timeTravel({
|
|
762
|
+
inputData,
|
|
763
|
+
step,
|
|
764
|
+
context,
|
|
765
|
+
nestedStepsContext,
|
|
766
|
+
resumeData,
|
|
767
|
+
initialState,
|
|
768
|
+
requestContext,
|
|
769
|
+
tracingOptions,
|
|
770
|
+
outputOptions
|
|
771
|
+
});
|
|
772
|
+
self.executionResults = executionResultsPromise;
|
|
773
|
+
let executionResults;
|
|
774
|
+
try {
|
|
775
|
+
executionResults = await executionResultsPromise;
|
|
776
|
+
self.closeStreamAction?.().catch(() => {
|
|
777
|
+
});
|
|
778
|
+
if (self.streamOutput) {
|
|
779
|
+
self.streamOutput.updateResults(executionResults);
|
|
780
|
+
}
|
|
781
|
+
} catch (err) {
|
|
782
|
+
self.streamOutput?.rejectResults(err);
|
|
783
|
+
self.closeStreamAction?.().catch(() => {
|
|
784
|
+
});
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
});
|
|
788
|
+
this.streamOutput = new stream.WorkflowRunOutput({
|
|
789
|
+
runId: this.runId,
|
|
790
|
+
workflowId: this.workflowId,
|
|
791
|
+
stream: stream$1
|
|
792
|
+
});
|
|
793
|
+
return this.streamOutput;
|
|
794
|
+
}
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
// src/workflow.ts
|
|
798
|
+
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
799
|
+
#mastra;
|
|
800
|
+
inngest;
|
|
801
|
+
function;
|
|
802
|
+
flowControlConfig;
|
|
803
|
+
constructor(params, inngest) {
|
|
804
|
+
const { concurrency, rateLimit, throttle, debounce, priority, ...workflowParams } = params;
|
|
805
|
+
super(workflowParams);
|
|
806
|
+
this.engineType = "inngest";
|
|
807
|
+
const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(
|
|
808
|
+
([_, value]) => value !== void 0
|
|
809
|
+
);
|
|
810
|
+
this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : void 0;
|
|
811
|
+
this.#mastra = params.mastra;
|
|
812
|
+
this.inngest = inngest;
|
|
813
|
+
}
|
|
814
|
+
async listWorkflowRuns(args) {
|
|
815
|
+
const storage = this.#mastra?.getStorage();
|
|
816
|
+
if (!storage) {
|
|
817
|
+
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
818
|
+
return { runs: [], total: 0 };
|
|
819
|
+
}
|
|
820
|
+
return storage.listWorkflowRuns({ workflowName: this.id, ...args ?? {} });
|
|
821
|
+
}
|
|
822
|
+
async getWorkflowRunById(runId) {
|
|
823
|
+
const storage = this.#mastra?.getStorage();
|
|
824
|
+
if (!storage) {
|
|
825
|
+
this.logger.debug("Cannot get workflow runs. Mastra engine is not initialized");
|
|
826
|
+
return this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null;
|
|
827
|
+
}
|
|
828
|
+
const run = await storage.getWorkflowRunById({ runId, workflowName: this.id });
|
|
829
|
+
return run ?? (this.runs.get(runId) ? { ...this.runs.get(runId), workflowName: this.id } : null);
|
|
830
|
+
}
|
|
831
|
+
__registerMastra(mastra) {
|
|
832
|
+
this.#mastra = mastra;
|
|
833
|
+
this.executionEngine.__registerMastra(mastra);
|
|
285
834
|
const updateNested = (step) => {
|
|
286
835
|
if ((step.type === "step" || step.type === "loop" || step.type === "foreach") && step.step instanceof _InngestWorkflow) {
|
|
287
836
|
step.step.__registerMastra(mastra);
|
|
@@ -297,56 +846,49 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
297
846
|
}
|
|
298
847
|
}
|
|
299
848
|
}
|
|
300
|
-
createRun(options) {
|
|
849
|
+
async createRun(options) {
|
|
301
850
|
const runIdToUse = options?.runId || crypto.randomUUID();
|
|
302
851
|
const run = this.runs.get(runIdToUse) ?? new InngestRun(
|
|
303
852
|
{
|
|
304
853
|
workflowId: this.id,
|
|
305
854
|
runId: runIdToUse,
|
|
855
|
+
resourceId: options?.resourceId,
|
|
306
856
|
executionEngine: this.executionEngine,
|
|
307
857
|
executionGraph: this.executionGraph,
|
|
308
858
|
serializedStepGraph: this.serializedStepGraph,
|
|
309
859
|
mastra: this.#mastra,
|
|
310
860
|
retryConfig: this.retryConfig,
|
|
311
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
861
|
+
cleanup: () => this.runs.delete(runIdToUse),
|
|
862
|
+
workflowSteps: this.steps,
|
|
863
|
+
workflowEngineType: this.engineType,
|
|
864
|
+
validateInputs: this.options.validateInputs
|
|
312
865
|
},
|
|
313
866
|
this.inngest
|
|
314
867
|
);
|
|
315
868
|
this.runs.set(runIdToUse, run);
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
const
|
|
321
|
-
|
|
322
|
-
workflowId: this.id,
|
|
323
|
-
runId: runIdToUse,
|
|
324
|
-
executionEngine: this.executionEngine,
|
|
325
|
-
executionGraph: this.executionGraph,
|
|
326
|
-
serializedStepGraph: this.serializedStepGraph,
|
|
327
|
-
mastra: this.#mastra,
|
|
328
|
-
retryConfig: this.retryConfig,
|
|
329
|
-
cleanup: () => this.runs.delete(runIdToUse)
|
|
330
|
-
},
|
|
331
|
-
this.inngest
|
|
332
|
-
);
|
|
333
|
-
this.runs.set(runIdToUse, run);
|
|
334
|
-
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse);
|
|
335
|
-
if (!workflowSnapshotInStorage) {
|
|
869
|
+
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({
|
|
870
|
+
workflowStatus: run.workflowRunStatus,
|
|
871
|
+
stepResults: {}
|
|
872
|
+
});
|
|
873
|
+
const workflowSnapshotInStorage = await this.getWorkflowRunExecutionResult(runIdToUse, false);
|
|
874
|
+
if (!workflowSnapshotInStorage && shouldPersistSnapshot) {
|
|
336
875
|
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
337
876
|
workflowName: this.id,
|
|
338
877
|
runId: runIdToUse,
|
|
878
|
+
resourceId: options?.resourceId,
|
|
339
879
|
snapshot: {
|
|
340
880
|
runId: runIdToUse,
|
|
341
881
|
status: "pending",
|
|
342
882
|
value: {},
|
|
343
883
|
context: {},
|
|
344
884
|
activePaths: [],
|
|
885
|
+
activeStepsPath: {},
|
|
886
|
+
waitingPaths: {},
|
|
345
887
|
serializedStepGraph: this.serializedStepGraph,
|
|
346
888
|
suspendedPaths: {},
|
|
889
|
+
resumeLabels: {},
|
|
347
890
|
result: void 0,
|
|
348
891
|
error: void 0,
|
|
349
|
-
// @ts-ignore
|
|
350
892
|
timestamp: Date.now()
|
|
351
893
|
}
|
|
352
894
|
});
|
|
@@ -360,13 +902,14 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
360
902
|
this.function = this.inngest.createFunction(
|
|
361
903
|
{
|
|
362
904
|
id: `workflow.${this.id}`,
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
905
|
+
retries: Math.min(this.retryConfig?.attempts ?? 0, 20),
|
|
906
|
+
cancelOn: [{ event: `cancel.workflow.${this.id}` }],
|
|
907
|
+
// Spread flow control configuration
|
|
908
|
+
...this.flowControlConfig
|
|
366
909
|
},
|
|
367
910
|
{ event: `workflow.${this.id}` },
|
|
368
911
|
async ({ event, step, attempt, publish }) => {
|
|
369
|
-
let { inputData, runId, resume } = event.data;
|
|
912
|
+
let { inputData, initialState, runId, resourceId, resume, outputOptions, format, timeTravel } = event.data;
|
|
370
913
|
if (!runId) {
|
|
371
914
|
runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {
|
|
372
915
|
return crypto.randomUUID();
|
|
@@ -394,19 +937,36 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
394
937
|
once: (_event, _callback) => {
|
|
395
938
|
}
|
|
396
939
|
};
|
|
397
|
-
const engine = new InngestExecutionEngine(this.#mastra, step, attempt);
|
|
940
|
+
const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options);
|
|
398
941
|
const result = await engine.execute({
|
|
399
942
|
workflowId: this.id,
|
|
400
943
|
runId,
|
|
944
|
+
resourceId,
|
|
401
945
|
graph: this.executionGraph,
|
|
402
946
|
serializedStepGraph: this.serializedStepGraph,
|
|
403
947
|
input: inputData,
|
|
948
|
+
initialState,
|
|
404
949
|
emitter,
|
|
405
950
|
retryConfig: this.retryConfig,
|
|
406
|
-
|
|
407
|
-
// TODO
|
|
951
|
+
requestContext: new di.RequestContext(Object.entries(event.data.requestContext ?? {})),
|
|
408
952
|
resume,
|
|
409
|
-
|
|
953
|
+
timeTravel,
|
|
954
|
+
format,
|
|
955
|
+
abortController: new AbortController(),
|
|
956
|
+
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
957
|
+
outputOptions,
|
|
958
|
+
outputWriter: async (chunk) => {
|
|
959
|
+
void emitter.emit("watch", chunk).catch(() => {
|
|
960
|
+
});
|
|
961
|
+
}
|
|
962
|
+
});
|
|
963
|
+
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
964
|
+
if (result.status === "failed") {
|
|
965
|
+
throw new inngest.NonRetriableError(`Workflow failed`, {
|
|
966
|
+
cause: result
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
return result;
|
|
410
970
|
});
|
|
411
971
|
return { result, runId };
|
|
412
972
|
}
|
|
@@ -430,27 +990,70 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
430
990
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
431
991
|
}
|
|
432
992
|
};
|
|
993
|
+
function serve({
|
|
994
|
+
mastra,
|
|
995
|
+
inngest,
|
|
996
|
+
functions: userFunctions = [],
|
|
997
|
+
registerOptions
|
|
998
|
+
}) {
|
|
999
|
+
const wfs = mastra.listWorkflows();
|
|
1000
|
+
const workflowFunctions = Array.from(
|
|
1001
|
+
new Set(
|
|
1002
|
+
Object.values(wfs).flatMap((wf) => {
|
|
1003
|
+
if (wf instanceof InngestWorkflow) {
|
|
1004
|
+
wf.__registerMastra(mastra);
|
|
1005
|
+
return wf.getFunctions();
|
|
1006
|
+
}
|
|
1007
|
+
return [];
|
|
1008
|
+
})
|
|
1009
|
+
)
|
|
1010
|
+
);
|
|
1011
|
+
return hono.serve({
|
|
1012
|
+
...registerOptions,
|
|
1013
|
+
client: inngest,
|
|
1014
|
+
functions: [...workflowFunctions, ...userFunctions]
|
|
1015
|
+
});
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
// src/types.ts
|
|
1019
|
+
var _compatibilityCheck = true;
|
|
1020
|
+
|
|
1021
|
+
// src/index.ts
|
|
433
1022
|
function isAgent(params) {
|
|
434
1023
|
return params?.component === "AGENT";
|
|
435
1024
|
}
|
|
436
1025
|
function isTool(params) {
|
|
437
1026
|
return params instanceof tools.Tool;
|
|
438
1027
|
}
|
|
439
|
-
function
|
|
1028
|
+
function isInngestWorkflow(params) {
|
|
1029
|
+
return params instanceof InngestWorkflow;
|
|
1030
|
+
}
|
|
1031
|
+
function createStep(params, agentOptions) {
|
|
1032
|
+
if (isInngestWorkflow(params)) {
|
|
1033
|
+
return params;
|
|
1034
|
+
}
|
|
440
1035
|
if (isAgent(params)) {
|
|
441
1036
|
return {
|
|
442
1037
|
id: params.name,
|
|
443
|
-
|
|
1038
|
+
description: params.getDescription(),
|
|
444
1039
|
inputSchema: zod.z.object({
|
|
445
1040
|
prompt: zod.z.string()
|
|
446
1041
|
// resourceId: z.string().optional(),
|
|
447
1042
|
// threadId: z.string().optional(),
|
|
448
1043
|
}),
|
|
449
|
-
// @ts-ignore
|
|
450
1044
|
outputSchema: zod.z.object({
|
|
451
1045
|
text: zod.z.string()
|
|
452
1046
|
}),
|
|
453
|
-
execute: async ({
|
|
1047
|
+
execute: async ({
|
|
1048
|
+
inputData,
|
|
1049
|
+
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1050
|
+
[_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
|
|
1051
|
+
requestContext,
|
|
1052
|
+
tracingContext,
|
|
1053
|
+
abortSignal,
|
|
1054
|
+
abort,
|
|
1055
|
+
writer
|
|
1056
|
+
}) => {
|
|
454
1057
|
let streamPromise = {};
|
|
455
1058
|
streamPromise.promise = new Promise((resolve, reject) => {
|
|
456
1059
|
streamPromise.resolve = resolve;
|
|
@@ -460,50 +1063,65 @@ function createStep(params) {
|
|
|
460
1063
|
name: params.name,
|
|
461
1064
|
args: inputData
|
|
462
1065
|
};
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
1066
|
+
let stream;
|
|
1067
|
+
if ((await params.getModel()).specificationVersion === "v1") {
|
|
1068
|
+
const { fullStream } = await params.streamLegacy(inputData.prompt, {
|
|
1069
|
+
...agentOptions ?? {},
|
|
1070
|
+
// resourceId: inputData.resourceId,
|
|
1071
|
+
// threadId: inputData.threadId,
|
|
1072
|
+
requestContext,
|
|
1073
|
+
tracingContext,
|
|
1074
|
+
onFinish: (result) => {
|
|
1075
|
+
streamPromise.resolve(result.text);
|
|
1076
|
+
void agentOptions?.onFinish?.(result);
|
|
1077
|
+
},
|
|
1078
|
+
abortSignal
|
|
1079
|
+
});
|
|
1080
|
+
stream = fullStream;
|
|
1081
|
+
} else {
|
|
1082
|
+
const modelOutput = await params.stream(inputData.prompt, {
|
|
1083
|
+
...agentOptions ?? {},
|
|
1084
|
+
requestContext,
|
|
1085
|
+
tracingContext,
|
|
1086
|
+
onFinish: (result) => {
|
|
1087
|
+
streamPromise.resolve(result.text);
|
|
1088
|
+
void agentOptions?.onFinish?.(result);
|
|
1089
|
+
},
|
|
1090
|
+
abortSignal
|
|
1091
|
+
});
|
|
1092
|
+
stream = modelOutput.fullStream;
|
|
478
1093
|
}
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
1094
|
+
if (streamFormat === "legacy") {
|
|
1095
|
+
await emitter.emit("watch", {
|
|
1096
|
+
type: "tool-call-streaming-start",
|
|
1097
|
+
...toolData ?? {}
|
|
1098
|
+
});
|
|
1099
|
+
for await (const chunk of stream) {
|
|
1100
|
+
if (chunk.type === "text-delta") {
|
|
1101
|
+
await emitter.emit("watch", {
|
|
483
1102
|
type: "tool-call-delta",
|
|
484
|
-
...toolData,
|
|
485
|
-
argsTextDelta: chunk.
|
|
1103
|
+
...toolData ?? {},
|
|
1104
|
+
argsTextDelta: chunk.textDelta
|
|
486
1105
|
});
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
case "source":
|
|
497
|
-
case "file":
|
|
498
|
-
default:
|
|
499
|
-
await emitter.emit("watch-v2", chunk);
|
|
500
|
-
break;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
await emitter.emit("watch", {
|
|
1109
|
+
type: "tool-call-streaming-finish",
|
|
1110
|
+
...toolData ?? {}
|
|
1111
|
+
});
|
|
1112
|
+
} else {
|
|
1113
|
+
for await (const chunk of stream) {
|
|
1114
|
+
await writer.write(chunk);
|
|
501
1115
|
}
|
|
502
1116
|
}
|
|
1117
|
+
if (abortSignal.aborted) {
|
|
1118
|
+
return abort();
|
|
1119
|
+
}
|
|
503
1120
|
return {
|
|
504
1121
|
text: await streamPromise.promise
|
|
505
1122
|
};
|
|
506
|
-
}
|
|
1123
|
+
},
|
|
1124
|
+
component: params.component
|
|
507
1125
|
};
|
|
508
1126
|
}
|
|
509
1127
|
if (isTool(params)) {
|
|
@@ -512,17 +1130,40 @@ function createStep(params) {
|
|
|
512
1130
|
}
|
|
513
1131
|
return {
|
|
514
1132
|
// TODO: tool probably should have strong id type
|
|
515
|
-
// @ts-ignore
|
|
516
1133
|
id: params.id,
|
|
1134
|
+
description: params.description,
|
|
517
1135
|
inputSchema: params.inputSchema,
|
|
518
1136
|
outputSchema: params.outputSchema,
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
1137
|
+
suspendSchema: params.suspendSchema,
|
|
1138
|
+
resumeSchema: params.resumeSchema,
|
|
1139
|
+
execute: async ({
|
|
1140
|
+
inputData,
|
|
1141
|
+
mastra,
|
|
1142
|
+
requestContext,
|
|
1143
|
+
tracingContext,
|
|
1144
|
+
suspend,
|
|
1145
|
+
resumeData,
|
|
1146
|
+
runId,
|
|
1147
|
+
workflowId,
|
|
1148
|
+
state,
|
|
1149
|
+
setState
|
|
1150
|
+
}) => {
|
|
1151
|
+
const toolContext = {
|
|
522
1152
|
mastra,
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
1153
|
+
requestContext,
|
|
1154
|
+
tracingContext,
|
|
1155
|
+
workflow: {
|
|
1156
|
+
runId,
|
|
1157
|
+
resumeData,
|
|
1158
|
+
suspend,
|
|
1159
|
+
workflowId,
|
|
1160
|
+
state,
|
|
1161
|
+
setState
|
|
1162
|
+
}
|
|
1163
|
+
};
|
|
1164
|
+
return params.execute(inputData, toolContext);
|
|
1165
|
+
},
|
|
1166
|
+
component: "TOOL"
|
|
526
1167
|
};
|
|
527
1168
|
}
|
|
528
1169
|
return {
|
|
@@ -538,7 +1179,10 @@ function createStep(params) {
|
|
|
538
1179
|
function init(inngest) {
|
|
539
1180
|
return {
|
|
540
1181
|
createWorkflow(params) {
|
|
541
|
-
return new InngestWorkflow(
|
|
1182
|
+
return new InngestWorkflow(
|
|
1183
|
+
params,
|
|
1184
|
+
inngest
|
|
1185
|
+
);
|
|
542
1186
|
},
|
|
543
1187
|
createStep,
|
|
544
1188
|
cloneStep(step, opts) {
|
|
@@ -547,7 +1191,13 @@ function init(inngest) {
|
|
|
547
1191
|
description: step.description,
|
|
548
1192
|
inputSchema: step.inputSchema,
|
|
549
1193
|
outputSchema: step.outputSchema,
|
|
550
|
-
|
|
1194
|
+
resumeSchema: step.resumeSchema,
|
|
1195
|
+
suspendSchema: step.suspendSchema,
|
|
1196
|
+
stateSchema: step.stateSchema,
|
|
1197
|
+
execute: step.execute,
|
|
1198
|
+
retries: step.retries,
|
|
1199
|
+
scorers: step.scorers,
|
|
1200
|
+
component: step.component
|
|
551
1201
|
};
|
|
552
1202
|
},
|
|
553
1203
|
cloneWorkflow(workflow, opts) {
|
|
@@ -556,7 +1206,8 @@ function init(inngest) {
|
|
|
556
1206
|
inputSchema: workflow.inputSchema,
|
|
557
1207
|
outputSchema: workflow.outputSchema,
|
|
558
1208
|
steps: workflow.stepDefs,
|
|
559
|
-
mastra: workflow.mastra
|
|
1209
|
+
mastra: workflow.mastra,
|
|
1210
|
+
options: workflow.options
|
|
560
1211
|
});
|
|
561
1212
|
wf.setStepFlow(workflow.stepGraph);
|
|
562
1213
|
wf.commit();
|
|
@@ -564,736 +1215,11 @@ function init(inngest) {
|
|
|
564
1215
|
}
|
|
565
1216
|
};
|
|
566
1217
|
}
|
|
567
|
-
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
568
|
-
inngestStep;
|
|
569
|
-
inngestAttempts;
|
|
570
|
-
constructor(mastra, inngestStep, inngestAttempts = 0) {
|
|
571
|
-
super({ mastra });
|
|
572
|
-
this.inngestStep = inngestStep;
|
|
573
|
-
this.inngestAttempts = inngestAttempts;
|
|
574
|
-
}
|
|
575
|
-
async execute(params) {
|
|
576
|
-
await params.emitter.emit("watch-v2", {
|
|
577
|
-
type: "start",
|
|
578
|
-
payload: { runId: params.runId }
|
|
579
|
-
});
|
|
580
|
-
const result = await super.execute(params);
|
|
581
|
-
await params.emitter.emit("watch-v2", {
|
|
582
|
-
type: "finish",
|
|
583
|
-
payload: { runId: params.runId }
|
|
584
|
-
});
|
|
585
|
-
return result;
|
|
586
|
-
}
|
|
587
|
-
async fmtReturnValue(executionSpan, emitter, stepResults, lastOutput, error) {
|
|
588
|
-
const base = {
|
|
589
|
-
status: lastOutput.status,
|
|
590
|
-
steps: stepResults
|
|
591
|
-
};
|
|
592
|
-
if (lastOutput.status === "success") {
|
|
593
|
-
await emitter.emit("watch", {
|
|
594
|
-
type: "watch",
|
|
595
|
-
payload: {
|
|
596
|
-
workflowState: {
|
|
597
|
-
status: lastOutput.status,
|
|
598
|
-
steps: stepResults,
|
|
599
|
-
result: lastOutput.output
|
|
600
|
-
}
|
|
601
|
-
},
|
|
602
|
-
eventTimestamp: Date.now()
|
|
603
|
-
});
|
|
604
|
-
base.result = lastOutput.output;
|
|
605
|
-
} else if (lastOutput.status === "failed") {
|
|
606
|
-
base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
|
|
607
|
-
await emitter.emit("watch", {
|
|
608
|
-
type: "watch",
|
|
609
|
-
payload: {
|
|
610
|
-
workflowState: {
|
|
611
|
-
status: lastOutput.status,
|
|
612
|
-
steps: stepResults,
|
|
613
|
-
result: null,
|
|
614
|
-
error: base.error
|
|
615
|
-
}
|
|
616
|
-
},
|
|
617
|
-
eventTimestamp: Date.now()
|
|
618
|
-
});
|
|
619
|
-
} else if (lastOutput.status === "suspended") {
|
|
620
|
-
await emitter.emit("watch", {
|
|
621
|
-
type: "watch",
|
|
622
|
-
payload: {
|
|
623
|
-
workflowState: {
|
|
624
|
-
status: lastOutput.status,
|
|
625
|
-
steps: stepResults,
|
|
626
|
-
result: null,
|
|
627
|
-
error: null
|
|
628
|
-
}
|
|
629
|
-
},
|
|
630
|
-
eventTimestamp: Date.now()
|
|
631
|
-
});
|
|
632
|
-
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
633
|
-
if (stepResult?.status === "suspended") {
|
|
634
|
-
const nestedPath = stepResult?.payload?.__workflow_meta?.path;
|
|
635
|
-
return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
|
|
636
|
-
}
|
|
637
|
-
return [];
|
|
638
|
-
});
|
|
639
|
-
base.suspended = suspendedStepIds;
|
|
640
|
-
}
|
|
641
|
-
executionSpan?.end();
|
|
642
|
-
return base;
|
|
643
|
-
}
|
|
644
|
-
async superExecuteStep({
|
|
645
|
-
workflowId,
|
|
646
|
-
runId,
|
|
647
|
-
step,
|
|
648
|
-
stepResults,
|
|
649
|
-
executionContext,
|
|
650
|
-
resume,
|
|
651
|
-
prevOutput,
|
|
652
|
-
emitter,
|
|
653
|
-
abortController,
|
|
654
|
-
runtimeContext,
|
|
655
|
-
writableStream
|
|
656
|
-
}) {
|
|
657
|
-
return super.executeStep({
|
|
658
|
-
workflowId,
|
|
659
|
-
runId,
|
|
660
|
-
step,
|
|
661
|
-
stepResults,
|
|
662
|
-
executionContext,
|
|
663
|
-
resume,
|
|
664
|
-
prevOutput,
|
|
665
|
-
emitter,
|
|
666
|
-
abortController,
|
|
667
|
-
runtimeContext,
|
|
668
|
-
writableStream
|
|
669
|
-
});
|
|
670
|
-
}
|
|
671
|
-
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
672
|
-
// await this.inngestStep.sleep(id, duration);
|
|
673
|
-
// }
|
|
674
|
-
async executeSleep({
|
|
675
|
-
workflowId,
|
|
676
|
-
runId,
|
|
677
|
-
entry,
|
|
678
|
-
prevOutput,
|
|
679
|
-
stepResults,
|
|
680
|
-
emitter,
|
|
681
|
-
abortController,
|
|
682
|
-
runtimeContext,
|
|
683
|
-
writableStream
|
|
684
|
-
}) {
|
|
685
|
-
let { duration, fn } = entry;
|
|
686
|
-
if (fn) {
|
|
687
|
-
const stepCallId = crypto.randomUUID();
|
|
688
|
-
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
689
|
-
return await fn({
|
|
690
|
-
runId,
|
|
691
|
-
workflowId,
|
|
692
|
-
mastra: this.mastra,
|
|
693
|
-
runtimeContext,
|
|
694
|
-
inputData: prevOutput,
|
|
695
|
-
runCount: -1,
|
|
696
|
-
getInitData: () => stepResults?.input,
|
|
697
|
-
getStepResult: (step) => {
|
|
698
|
-
if (!step?.id) {
|
|
699
|
-
return null;
|
|
700
|
-
}
|
|
701
|
-
const result = stepResults[step.id];
|
|
702
|
-
if (result?.status === "success") {
|
|
703
|
-
return result.output;
|
|
704
|
-
}
|
|
705
|
-
return null;
|
|
706
|
-
},
|
|
707
|
-
// TODO: this function shouldn't have suspend probably?
|
|
708
|
-
suspend: async (_suspendPayload) => {
|
|
709
|
-
},
|
|
710
|
-
bail: () => {
|
|
711
|
-
},
|
|
712
|
-
abort: () => {
|
|
713
|
-
abortController?.abort();
|
|
714
|
-
},
|
|
715
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
716
|
-
engine: { step: this.inngestStep },
|
|
717
|
-
abortSignal: abortController?.signal,
|
|
718
|
-
writer: new tools.ToolStream(
|
|
719
|
-
{
|
|
720
|
-
prefix: "step",
|
|
721
|
-
callId: stepCallId,
|
|
722
|
-
name: "sleep",
|
|
723
|
-
runId
|
|
724
|
-
},
|
|
725
|
-
writableStream
|
|
726
|
-
)
|
|
727
|
-
});
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
731
|
-
}
|
|
732
|
-
async executeSleepUntil({
|
|
733
|
-
workflowId,
|
|
734
|
-
runId,
|
|
735
|
-
entry,
|
|
736
|
-
prevOutput,
|
|
737
|
-
stepResults,
|
|
738
|
-
emitter,
|
|
739
|
-
abortController,
|
|
740
|
-
runtimeContext,
|
|
741
|
-
writableStream
|
|
742
|
-
}) {
|
|
743
|
-
let { date, fn } = entry;
|
|
744
|
-
if (fn) {
|
|
745
|
-
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
746
|
-
const stepCallId = crypto.randomUUID();
|
|
747
|
-
return await fn({
|
|
748
|
-
runId,
|
|
749
|
-
workflowId,
|
|
750
|
-
mastra: this.mastra,
|
|
751
|
-
runtimeContext,
|
|
752
|
-
inputData: prevOutput,
|
|
753
|
-
runCount: -1,
|
|
754
|
-
getInitData: () => stepResults?.input,
|
|
755
|
-
getStepResult: (step) => {
|
|
756
|
-
if (!step?.id) {
|
|
757
|
-
return null;
|
|
758
|
-
}
|
|
759
|
-
const result = stepResults[step.id];
|
|
760
|
-
if (result?.status === "success") {
|
|
761
|
-
return result.output;
|
|
762
|
-
}
|
|
763
|
-
return null;
|
|
764
|
-
},
|
|
765
|
-
// TODO: this function shouldn't have suspend probably?
|
|
766
|
-
suspend: async (_suspendPayload) => {
|
|
767
|
-
},
|
|
768
|
-
bail: () => {
|
|
769
|
-
},
|
|
770
|
-
abort: () => {
|
|
771
|
-
abortController?.abort();
|
|
772
|
-
},
|
|
773
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
774
|
-
engine: { step: this.inngestStep },
|
|
775
|
-
abortSignal: abortController?.signal,
|
|
776
|
-
writer: new tools.ToolStream(
|
|
777
|
-
{
|
|
778
|
-
prefix: "step",
|
|
779
|
-
callId: stepCallId,
|
|
780
|
-
name: "sleep",
|
|
781
|
-
runId
|
|
782
|
-
},
|
|
783
|
-
writableStream
|
|
784
|
-
)
|
|
785
|
-
});
|
|
786
|
-
});
|
|
787
|
-
}
|
|
788
|
-
if (!(date instanceof Date)) {
|
|
789
|
-
return;
|
|
790
|
-
}
|
|
791
|
-
await this.inngestStep.sleepUntil(entry.id, date);
|
|
792
|
-
}
|
|
793
|
-
async executeWaitForEvent({ event, timeout }) {
|
|
794
|
-
const eventData = await this.inngestStep.waitForEvent(`user-event-${event}`, {
|
|
795
|
-
event: `user-event-${event}`,
|
|
796
|
-
timeout: timeout ?? 5e3
|
|
797
|
-
});
|
|
798
|
-
if (eventData === null) {
|
|
799
|
-
throw "Timeout waiting for event";
|
|
800
|
-
}
|
|
801
|
-
return eventData?.data;
|
|
802
|
-
}
|
|
803
|
-
async executeStep({
|
|
804
|
-
step,
|
|
805
|
-
stepResults,
|
|
806
|
-
executionContext,
|
|
807
|
-
resume,
|
|
808
|
-
prevOutput,
|
|
809
|
-
emitter,
|
|
810
|
-
abortController,
|
|
811
|
-
runtimeContext,
|
|
812
|
-
writableStream
|
|
813
|
-
}) {
|
|
814
|
-
const startedAt = await this.inngestStep.run(
|
|
815
|
-
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
816
|
-
async () => {
|
|
817
|
-
const startedAt2 = Date.now();
|
|
818
|
-
await emitter.emit("watch", {
|
|
819
|
-
type: "watch",
|
|
820
|
-
payload: {
|
|
821
|
-
currentStep: {
|
|
822
|
-
id: step.id,
|
|
823
|
-
status: "running"
|
|
824
|
-
},
|
|
825
|
-
workflowState: {
|
|
826
|
-
status: "running",
|
|
827
|
-
steps: {
|
|
828
|
-
...stepResults,
|
|
829
|
-
[step.id]: {
|
|
830
|
-
status: "running"
|
|
831
|
-
}
|
|
832
|
-
},
|
|
833
|
-
result: null,
|
|
834
|
-
error: null
|
|
835
|
-
}
|
|
836
|
-
},
|
|
837
|
-
eventTimestamp: Date.now()
|
|
838
|
-
});
|
|
839
|
-
await emitter.emit("watch-v2", {
|
|
840
|
-
type: "step-start",
|
|
841
|
-
payload: {
|
|
842
|
-
id: step.id,
|
|
843
|
-
status: "running",
|
|
844
|
-
payload: prevOutput,
|
|
845
|
-
startedAt: startedAt2
|
|
846
|
-
}
|
|
847
|
-
});
|
|
848
|
-
return startedAt2;
|
|
849
|
-
}
|
|
850
|
-
);
|
|
851
|
-
if (step instanceof InngestWorkflow) {
|
|
852
|
-
const isResume = !!resume?.steps?.length;
|
|
853
|
-
let result;
|
|
854
|
-
let runId;
|
|
855
|
-
if (isResume) {
|
|
856
|
-
runId = stepResults[resume?.steps?.[0]]?.payload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
857
|
-
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
858
|
-
workflowName: step.id,
|
|
859
|
-
runId
|
|
860
|
-
});
|
|
861
|
-
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
862
|
-
function: step.getFunction(),
|
|
863
|
-
data: {
|
|
864
|
-
inputData: prevOutput,
|
|
865
|
-
runId,
|
|
866
|
-
resume: {
|
|
867
|
-
runId,
|
|
868
|
-
steps: resume.steps.slice(1),
|
|
869
|
-
stepResults: snapshot?.context,
|
|
870
|
-
resumePayload: resume.resumePayload,
|
|
871
|
-
// @ts-ignore
|
|
872
|
-
resumePath: snapshot?.suspendedPaths?.[resume.steps?.[1]]
|
|
873
|
-
}
|
|
874
|
-
}
|
|
875
|
-
});
|
|
876
|
-
result = invokeResp.result;
|
|
877
|
-
runId = invokeResp.runId;
|
|
878
|
-
} else {
|
|
879
|
-
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
880
|
-
function: step.getFunction(),
|
|
881
|
-
data: {
|
|
882
|
-
inputData: prevOutput
|
|
883
|
-
}
|
|
884
|
-
});
|
|
885
|
-
result = invokeResp.result;
|
|
886
|
-
runId = invokeResp.runId;
|
|
887
|
-
}
|
|
888
|
-
const res = await this.inngestStep.run(
|
|
889
|
-
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
890
|
-
async () => {
|
|
891
|
-
if (result.status === "failed") {
|
|
892
|
-
await emitter.emit("watch", {
|
|
893
|
-
type: "watch",
|
|
894
|
-
payload: {
|
|
895
|
-
currentStep: {
|
|
896
|
-
id: step.id,
|
|
897
|
-
status: "failed",
|
|
898
|
-
error: result?.error
|
|
899
|
-
},
|
|
900
|
-
workflowState: {
|
|
901
|
-
status: "running",
|
|
902
|
-
steps: stepResults,
|
|
903
|
-
result: null,
|
|
904
|
-
error: null
|
|
905
|
-
}
|
|
906
|
-
},
|
|
907
|
-
eventTimestamp: Date.now()
|
|
908
|
-
});
|
|
909
|
-
await emitter.emit("watch-v2", {
|
|
910
|
-
type: "step-result",
|
|
911
|
-
payload: {
|
|
912
|
-
id: step.id,
|
|
913
|
-
status: "failed",
|
|
914
|
-
error: result?.error,
|
|
915
|
-
payload: prevOutput
|
|
916
|
-
}
|
|
917
|
-
});
|
|
918
|
-
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
919
|
-
} else if (result.status === "suspended") {
|
|
920
|
-
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
921
|
-
const stepRes2 = stepResult;
|
|
922
|
-
return stepRes2?.status === "suspended";
|
|
923
|
-
});
|
|
924
|
-
for (const [stepName, stepResult] of suspendedSteps) {
|
|
925
|
-
const suspendPath = [stepName, ...stepResult?.payload?.__workflow_meta?.path ?? []];
|
|
926
|
-
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
927
|
-
await emitter.emit("watch", {
|
|
928
|
-
type: "watch",
|
|
929
|
-
payload: {
|
|
930
|
-
currentStep: {
|
|
931
|
-
id: step.id,
|
|
932
|
-
status: "suspended",
|
|
933
|
-
payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
|
|
934
|
-
},
|
|
935
|
-
workflowState: {
|
|
936
|
-
status: "running",
|
|
937
|
-
steps: stepResults,
|
|
938
|
-
result: null,
|
|
939
|
-
error: null
|
|
940
|
-
}
|
|
941
|
-
},
|
|
942
|
-
eventTimestamp: Date.now()
|
|
943
|
-
});
|
|
944
|
-
await emitter.emit("watch-v2", {
|
|
945
|
-
type: "step-suspended",
|
|
946
|
-
payload: {
|
|
947
|
-
id: step.id,
|
|
948
|
-
status: "suspended"
|
|
949
|
-
}
|
|
950
|
-
});
|
|
951
|
-
return {
|
|
952
|
-
executionContext,
|
|
953
|
-
result: {
|
|
954
|
-
status: "suspended",
|
|
955
|
-
payload: { ...stepResult?.payload, __workflow_meta: { runId, path: suspendPath } }
|
|
956
|
-
}
|
|
957
|
-
};
|
|
958
|
-
}
|
|
959
|
-
await emitter.emit("watch", {
|
|
960
|
-
type: "watch",
|
|
961
|
-
payload: {
|
|
962
|
-
currentStep: {
|
|
963
|
-
id: step.id,
|
|
964
|
-
status: "suspended",
|
|
965
|
-
payload: {}
|
|
966
|
-
},
|
|
967
|
-
workflowState: {
|
|
968
|
-
status: "running",
|
|
969
|
-
steps: stepResults,
|
|
970
|
-
result: null,
|
|
971
|
-
error: null
|
|
972
|
-
}
|
|
973
|
-
},
|
|
974
|
-
eventTimestamp: Date.now()
|
|
975
|
-
});
|
|
976
|
-
return {
|
|
977
|
-
executionContext,
|
|
978
|
-
result: {
|
|
979
|
-
status: "suspended",
|
|
980
|
-
payload: {}
|
|
981
|
-
}
|
|
982
|
-
};
|
|
983
|
-
}
|
|
984
|
-
await emitter.emit("watch", {
|
|
985
|
-
type: "watch",
|
|
986
|
-
payload: {
|
|
987
|
-
currentStep: {
|
|
988
|
-
id: step.id,
|
|
989
|
-
status: "success",
|
|
990
|
-
output: result?.result
|
|
991
|
-
},
|
|
992
|
-
workflowState: {
|
|
993
|
-
status: "running",
|
|
994
|
-
steps: stepResults,
|
|
995
|
-
result: null,
|
|
996
|
-
error: null
|
|
997
|
-
}
|
|
998
|
-
},
|
|
999
|
-
eventTimestamp: Date.now()
|
|
1000
|
-
});
|
|
1001
|
-
await emitter.emit("watch-v2", {
|
|
1002
|
-
type: "step-result",
|
|
1003
|
-
payload: {
|
|
1004
|
-
id: step.id,
|
|
1005
|
-
status: "success",
|
|
1006
|
-
output: result?.result
|
|
1007
|
-
}
|
|
1008
|
-
});
|
|
1009
|
-
await emitter.emit("watch-v2", {
|
|
1010
|
-
type: "step-finish",
|
|
1011
|
-
payload: {
|
|
1012
|
-
id: step.id,
|
|
1013
|
-
metadata: {}
|
|
1014
|
-
}
|
|
1015
|
-
});
|
|
1016
|
-
return { executionContext, result: { status: "success", output: result?.result } };
|
|
1017
|
-
}
|
|
1018
|
-
);
|
|
1019
|
-
Object.assign(executionContext, res.executionContext);
|
|
1020
|
-
return res.result;
|
|
1021
|
-
}
|
|
1022
|
-
const stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1023
|
-
let execResults;
|
|
1024
|
-
let suspended;
|
|
1025
|
-
let bailed;
|
|
1026
|
-
try {
|
|
1027
|
-
const result = await step.execute({
|
|
1028
|
-
runId: executionContext.runId,
|
|
1029
|
-
mastra: this.mastra,
|
|
1030
|
-
runtimeContext,
|
|
1031
|
-
writableStream,
|
|
1032
|
-
inputData: prevOutput,
|
|
1033
|
-
resumeData: resume?.steps[0] === step.id ? resume?.resumePayload : void 0,
|
|
1034
|
-
getInitData: () => stepResults?.input,
|
|
1035
|
-
getStepResult: (step2) => {
|
|
1036
|
-
const result2 = stepResults[step2.id];
|
|
1037
|
-
if (result2?.status === "success") {
|
|
1038
|
-
return result2.output;
|
|
1039
|
-
}
|
|
1040
|
-
return null;
|
|
1041
|
-
},
|
|
1042
|
-
suspend: async (suspendPayload) => {
|
|
1043
|
-
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1044
|
-
suspended = { payload: suspendPayload };
|
|
1045
|
-
},
|
|
1046
|
-
bail: (result2) => {
|
|
1047
|
-
bailed = { payload: result2 };
|
|
1048
|
-
},
|
|
1049
|
-
resume: {
|
|
1050
|
-
steps: resume?.steps?.slice(1) || [],
|
|
1051
|
-
resumePayload: resume?.resumePayload,
|
|
1052
|
-
// @ts-ignore
|
|
1053
|
-
runId: stepResults[step.id]?.payload?.__workflow_meta?.runId
|
|
1054
|
-
},
|
|
1055
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1056
|
-
engine: {
|
|
1057
|
-
step: this.inngestStep
|
|
1058
|
-
},
|
|
1059
|
-
abortSignal: abortController.signal
|
|
1060
|
-
});
|
|
1061
|
-
const endedAt = Date.now();
|
|
1062
|
-
execResults = {
|
|
1063
|
-
status: "success",
|
|
1064
|
-
output: result,
|
|
1065
|
-
startedAt,
|
|
1066
|
-
endedAt,
|
|
1067
|
-
payload: prevOutput,
|
|
1068
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1069
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1070
|
-
};
|
|
1071
|
-
} catch (e) {
|
|
1072
|
-
execResults = {
|
|
1073
|
-
status: "failed",
|
|
1074
|
-
payload: prevOutput,
|
|
1075
|
-
error: e instanceof Error ? e.message : String(e),
|
|
1076
|
-
endedAt: Date.now(),
|
|
1077
|
-
startedAt,
|
|
1078
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1079
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1080
|
-
};
|
|
1081
|
-
}
|
|
1082
|
-
if (suspended) {
|
|
1083
|
-
execResults = {
|
|
1084
|
-
status: "suspended",
|
|
1085
|
-
suspendedPayload: suspended.payload,
|
|
1086
|
-
payload: prevOutput,
|
|
1087
|
-
suspendedAt: Date.now(),
|
|
1088
|
-
startedAt,
|
|
1089
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1090
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1091
|
-
};
|
|
1092
|
-
} else if (bailed) {
|
|
1093
|
-
execResults = { status: "bailed", output: bailed.payload, payload: prevOutput, endedAt: Date.now(), startedAt };
|
|
1094
|
-
}
|
|
1095
|
-
if (execResults.status === "failed") {
|
|
1096
|
-
if (executionContext.retryConfig.attempts > 0 && this.inngestAttempts < executionContext.retryConfig.attempts) {
|
|
1097
|
-
throw execResults.error;
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
await emitter.emit("watch", {
|
|
1101
|
-
type: "watch",
|
|
1102
|
-
payload: {
|
|
1103
|
-
currentStep: {
|
|
1104
|
-
id: step.id,
|
|
1105
|
-
...execResults
|
|
1106
|
-
},
|
|
1107
|
-
workflowState: {
|
|
1108
|
-
status: "running",
|
|
1109
|
-
steps: { ...stepResults, [step.id]: execResults },
|
|
1110
|
-
result: null,
|
|
1111
|
-
error: null
|
|
1112
|
-
}
|
|
1113
|
-
},
|
|
1114
|
-
eventTimestamp: Date.now()
|
|
1115
|
-
});
|
|
1116
|
-
if (execResults.status === "suspended") {
|
|
1117
|
-
await emitter.emit("watch-v2", {
|
|
1118
|
-
type: "step-suspended",
|
|
1119
|
-
payload: {
|
|
1120
|
-
id: step.id,
|
|
1121
|
-
...execResults
|
|
1122
|
-
}
|
|
1123
|
-
});
|
|
1124
|
-
} else {
|
|
1125
|
-
await emitter.emit("watch-v2", {
|
|
1126
|
-
type: "step-result",
|
|
1127
|
-
payload: {
|
|
1128
|
-
id: step.id,
|
|
1129
|
-
...execResults
|
|
1130
|
-
}
|
|
1131
|
-
});
|
|
1132
|
-
await emitter.emit("watch-v2", {
|
|
1133
|
-
type: "step-finish",
|
|
1134
|
-
payload: {
|
|
1135
|
-
id: step.id,
|
|
1136
|
-
metadata: {}
|
|
1137
|
-
}
|
|
1138
|
-
});
|
|
1139
|
-
}
|
|
1140
|
-
return { result: execResults, executionContext, stepResults };
|
|
1141
|
-
});
|
|
1142
|
-
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1143
|
-
Object.assign(stepResults, stepRes.stepResults);
|
|
1144
|
-
return stepRes.result;
|
|
1145
|
-
}
|
|
1146
|
-
async persistStepUpdate({
|
|
1147
|
-
workflowId,
|
|
1148
|
-
runId,
|
|
1149
|
-
stepResults,
|
|
1150
|
-
executionContext,
|
|
1151
|
-
serializedStepGraph,
|
|
1152
|
-
workflowStatus,
|
|
1153
|
-
result,
|
|
1154
|
-
error
|
|
1155
|
-
}) {
|
|
1156
|
-
await this.inngestStep.run(
|
|
1157
|
-
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1158
|
-
async () => {
|
|
1159
|
-
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1160
|
-
workflowName: workflowId,
|
|
1161
|
-
runId,
|
|
1162
|
-
snapshot: {
|
|
1163
|
-
runId,
|
|
1164
|
-
value: {},
|
|
1165
|
-
context: stepResults,
|
|
1166
|
-
activePaths: [],
|
|
1167
|
-
suspendedPaths: executionContext.suspendedPaths,
|
|
1168
|
-
serializedStepGraph,
|
|
1169
|
-
status: workflowStatus,
|
|
1170
|
-
result,
|
|
1171
|
-
error,
|
|
1172
|
-
// @ts-ignore
|
|
1173
|
-
timestamp: Date.now()
|
|
1174
|
-
}
|
|
1175
|
-
});
|
|
1176
|
-
}
|
|
1177
|
-
);
|
|
1178
|
-
}
|
|
1179
|
-
async executeConditional({
|
|
1180
|
-
workflowId,
|
|
1181
|
-
runId,
|
|
1182
|
-
entry,
|
|
1183
|
-
prevOutput,
|
|
1184
|
-
prevStep,
|
|
1185
|
-
stepResults,
|
|
1186
|
-
serializedStepGraph,
|
|
1187
|
-
resume,
|
|
1188
|
-
executionContext,
|
|
1189
|
-
emitter,
|
|
1190
|
-
abortController,
|
|
1191
|
-
runtimeContext,
|
|
1192
|
-
writableStream
|
|
1193
|
-
}) {
|
|
1194
|
-
let execResults;
|
|
1195
|
-
const truthyIndexes = (await Promise.all(
|
|
1196
|
-
entry.conditions.map(
|
|
1197
|
-
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1198
|
-
try {
|
|
1199
|
-
const result = await cond({
|
|
1200
|
-
runId,
|
|
1201
|
-
workflowId,
|
|
1202
|
-
mastra: this.mastra,
|
|
1203
|
-
runtimeContext,
|
|
1204
|
-
runCount: -1,
|
|
1205
|
-
inputData: prevOutput,
|
|
1206
|
-
getInitData: () => stepResults?.input,
|
|
1207
|
-
getStepResult: (step) => {
|
|
1208
|
-
if (!step?.id) {
|
|
1209
|
-
return null;
|
|
1210
|
-
}
|
|
1211
|
-
const result2 = stepResults[step.id];
|
|
1212
|
-
if (result2?.status === "success") {
|
|
1213
|
-
return result2.output;
|
|
1214
|
-
}
|
|
1215
|
-
return null;
|
|
1216
|
-
},
|
|
1217
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1218
|
-
suspend: async (_suspendPayload) => {
|
|
1219
|
-
},
|
|
1220
|
-
bail: () => {
|
|
1221
|
-
},
|
|
1222
|
-
abort: () => {
|
|
1223
|
-
abortController.abort();
|
|
1224
|
-
},
|
|
1225
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1226
|
-
engine: {
|
|
1227
|
-
step: this.inngestStep
|
|
1228
|
-
},
|
|
1229
|
-
abortSignal: abortController.signal,
|
|
1230
|
-
writer: new tools.ToolStream(
|
|
1231
|
-
{
|
|
1232
|
-
prefix: "step",
|
|
1233
|
-
callId: crypto.randomUUID(),
|
|
1234
|
-
name: "conditional",
|
|
1235
|
-
runId
|
|
1236
|
-
},
|
|
1237
|
-
writableStream
|
|
1238
|
-
)
|
|
1239
|
-
});
|
|
1240
|
-
return result ? index : null;
|
|
1241
|
-
} catch (e) {
|
|
1242
|
-
return null;
|
|
1243
|
-
}
|
|
1244
|
-
})
|
|
1245
|
-
)
|
|
1246
|
-
)).filter((index) => index !== null);
|
|
1247
|
-
const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
|
|
1248
|
-
const results = await Promise.all(
|
|
1249
|
-
stepsToRun.map(
|
|
1250
|
-
(step, index) => this.executeEntry({
|
|
1251
|
-
workflowId,
|
|
1252
|
-
runId,
|
|
1253
|
-
entry: step,
|
|
1254
|
-
prevStep,
|
|
1255
|
-
stepResults,
|
|
1256
|
-
resume,
|
|
1257
|
-
serializedStepGraph,
|
|
1258
|
-
executionContext: {
|
|
1259
|
-
workflowId,
|
|
1260
|
-
runId,
|
|
1261
|
-
executionPath: [...executionContext.executionPath, index],
|
|
1262
|
-
suspendedPaths: executionContext.suspendedPaths,
|
|
1263
|
-
retryConfig: executionContext.retryConfig,
|
|
1264
|
-
executionSpan: executionContext.executionSpan
|
|
1265
|
-
},
|
|
1266
|
-
emitter,
|
|
1267
|
-
abortController,
|
|
1268
|
-
runtimeContext,
|
|
1269
|
-
writableStream
|
|
1270
|
-
})
|
|
1271
|
-
)
|
|
1272
|
-
);
|
|
1273
|
-
const hasFailed = results.find((result) => result.result.status === "failed");
|
|
1274
|
-
const hasSuspended = results.find((result) => result.result.status === "suspended");
|
|
1275
|
-
if (hasFailed) {
|
|
1276
|
-
execResults = { status: "failed", error: hasFailed.result.error };
|
|
1277
|
-
} else if (hasSuspended) {
|
|
1278
|
-
execResults = { status: "suspended", payload: hasSuspended.result.suspendPayload };
|
|
1279
|
-
} else {
|
|
1280
|
-
execResults = {
|
|
1281
|
-
status: "success",
|
|
1282
|
-
output: results.reduce((acc, result, index) => {
|
|
1283
|
-
if (result.result.status === "success") {
|
|
1284
|
-
acc[stepsToRun[index].step.id] = result.output;
|
|
1285
|
-
}
|
|
1286
|
-
return acc;
|
|
1287
|
-
}, {})
|
|
1288
|
-
};
|
|
1289
|
-
}
|
|
1290
|
-
return execResults;
|
|
1291
|
-
}
|
|
1292
|
-
};
|
|
1293
1218
|
|
|
1294
1219
|
exports.InngestExecutionEngine = InngestExecutionEngine;
|
|
1295
1220
|
exports.InngestRun = InngestRun;
|
|
1296
1221
|
exports.InngestWorkflow = InngestWorkflow;
|
|
1222
|
+
exports._compatibilityCheck = _compatibilityCheck;
|
|
1297
1223
|
exports.createStep = createStep;
|
|
1298
1224
|
exports.init = init;
|
|
1299
1225
|
exports.serve = serve;
|