@mastra/inngest 1.0.0-beta.3 → 1.0.0-beta.5
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 +65 -0
- package/dist/execution-engine.d.ts +85 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/index.cjs +366 -899
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +17 -319
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +367 -901
- 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 +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1,43 +1,302 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var crypto = require('crypto');
|
|
4
|
-
var web = require('stream/web');
|
|
5
|
-
var realtime = require('@inngest/realtime');
|
|
6
|
-
var di = require('@mastra/core/di');
|
|
7
|
-
var observability = require('@mastra/core/observability');
|
|
8
|
-
var stream = require('@mastra/core/stream');
|
|
9
3
|
var tools = require('@mastra/core/tools');
|
|
10
4
|
var workflows = require('@mastra/core/workflows');
|
|
11
5
|
var _constants = require('@mastra/core/workflows/_constants');
|
|
6
|
+
var zod = require('zod');
|
|
7
|
+
var crypto = require('crypto');
|
|
8
|
+
var di = require('@mastra/core/di');
|
|
12
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
13
|
var hono = require('inngest/hono');
|
|
14
|
-
var zod = require('zod');
|
|
15
14
|
|
|
16
15
|
// src/index.ts
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
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()
|
|
30
83
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
40
|
-
|
|
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
|
+
};
|
|
41
300
|
var InngestRun = class extends workflows.Run {
|
|
42
301
|
inngest;
|
|
43
302
|
serializedStepGraph;
|
|
@@ -115,7 +374,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
115
374
|
initialState,
|
|
116
375
|
outputOptions,
|
|
117
376
|
tracingOptions,
|
|
118
|
-
format
|
|
377
|
+
format,
|
|
378
|
+
requestContext
|
|
119
379
|
}) {
|
|
120
380
|
await this.#mastra.getStorage()?.persistWorkflowSnapshot({
|
|
121
381
|
workflowName: this.workflowId,
|
|
@@ -146,7 +406,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
146
406
|
resourceId: this.resourceId,
|
|
147
407
|
outputOptions,
|
|
148
408
|
tracingOptions,
|
|
149
|
-
format
|
|
409
|
+
format,
|
|
410
|
+
requestContext: requestContext ? Object.fromEntries(requestContext.entries()) : {}
|
|
150
411
|
}
|
|
151
412
|
});
|
|
152
413
|
const eventId = eventOutput.ids[0];
|
|
@@ -190,6 +451,9 @@ var InngestRun = class extends workflows.Run {
|
|
|
190
451
|
});
|
|
191
452
|
const suspendedStep = this.workflowSteps[steps?.[0] ?? ""];
|
|
192
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 };
|
|
193
457
|
const eventOutput = await this.inngest.send({
|
|
194
458
|
name: `workflow.${this.workflowId}`,
|
|
195
459
|
data: {
|
|
@@ -203,7 +467,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
203
467
|
stepResults: snapshot?.context,
|
|
204
468
|
resumePayload: resumeDataToUse,
|
|
205
469
|
resumePath: steps?.[0] ? snapshot?.suspendedPaths?.[steps?.[0]] : void 0
|
|
206
|
-
}
|
|
470
|
+
},
|
|
471
|
+
requestContext: mergedRequestContext
|
|
207
472
|
}
|
|
208
473
|
});
|
|
209
474
|
const eventId = eventOutput.ids[0];
|
|
@@ -294,7 +559,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
294
559
|
stepResults: timeTravelData.stepResults,
|
|
295
560
|
timeTravel: timeTravelData,
|
|
296
561
|
tracingOptions: params.tracingOptions,
|
|
297
|
-
outputOptions: params.outputOptions
|
|
562
|
+
outputOptions: params.outputOptions,
|
|
563
|
+
requestContext: params.requestContext ? Object.fromEntries(params.requestContext.entries()) : {}
|
|
298
564
|
}
|
|
299
565
|
});
|
|
300
566
|
const eventId = eventOutput.ids[0];
|
|
@@ -334,14 +600,14 @@ var InngestRun = class extends workflows.Run {
|
|
|
334
600
|
streamLegacy({ inputData, requestContext } = {}) {
|
|
335
601
|
const { readable, writable } = new TransformStream();
|
|
336
602
|
const writer = writable.getWriter();
|
|
603
|
+
void writer.write({
|
|
604
|
+
// @ts-ignore
|
|
605
|
+
type: "start",
|
|
606
|
+
// @ts-ignore
|
|
607
|
+
payload: { runId: this.runId }
|
|
608
|
+
});
|
|
337
609
|
const unwatch = this.watch(async (event) => {
|
|
338
610
|
try {
|
|
339
|
-
await writer.write({
|
|
340
|
-
// @ts-ignore
|
|
341
|
-
type: "start",
|
|
342
|
-
// @ts-ignore
|
|
343
|
-
payload: { runId: this.runId }
|
|
344
|
-
});
|
|
345
611
|
const e = {
|
|
346
612
|
...event,
|
|
347
613
|
type: event.type.replace("workflow-", "")
|
|
@@ -487,7 +753,7 @@ var InngestRun = class extends workflows.Run {
|
|
|
487
753
|
self.closeStreamAction = async () => {
|
|
488
754
|
unwatch();
|
|
489
755
|
try {
|
|
490
|
-
|
|
756
|
+
controller.close();
|
|
491
757
|
} catch (err) {
|
|
492
758
|
console.error("Error closing stream:", err);
|
|
493
759
|
}
|
|
@@ -527,6 +793,8 @@ var InngestRun = class extends workflows.Run {
|
|
|
527
793
|
return this.streamOutput;
|
|
528
794
|
}
|
|
529
795
|
};
|
|
796
|
+
|
|
797
|
+
// src/workflow.ts
|
|
530
798
|
var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
531
799
|
#mastra;
|
|
532
800
|
inngest;
|
|
@@ -680,20 +948,17 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
680
948
|
initialState,
|
|
681
949
|
emitter,
|
|
682
950
|
retryConfig: this.retryConfig,
|
|
683
|
-
requestContext: new di.RequestContext(),
|
|
684
|
-
// TODO
|
|
951
|
+
requestContext: new di.RequestContext(Object.entries(event.data.requestContext ?? {})),
|
|
685
952
|
resume,
|
|
686
953
|
timeTravel,
|
|
687
954
|
format,
|
|
688
955
|
abortController: new AbortController(),
|
|
689
956
|
// currentSpan: undefined, // TODO: Pass actual parent Span from workflow execution context
|
|
690
957
|
outputOptions,
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
}
|
|
696
|
-
})
|
|
958
|
+
outputWriter: async (chunk) => {
|
|
959
|
+
void emitter.emit("watch", chunk).catch(() => {
|
|
960
|
+
});
|
|
961
|
+
}
|
|
697
962
|
});
|
|
698
963
|
await step.run(`workflow.${this.id}.finalize`, async () => {
|
|
699
964
|
if (result.status === "failed") {
|
|
@@ -725,14 +990,50 @@ var InngestWorkflow = class _InngestWorkflow extends workflows.Workflow {
|
|
|
725
990
|
return [this.getFunction(), ...this.getNestedFunctions(this.executionGraph.steps)];
|
|
726
991
|
}
|
|
727
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
|
|
728
1022
|
function isAgent(params) {
|
|
729
1023
|
return params?.component === "AGENT";
|
|
730
1024
|
}
|
|
731
1025
|
function isTool(params) {
|
|
732
1026
|
return params instanceof tools.Tool;
|
|
733
1027
|
}
|
|
1028
|
+
function isInngestWorkflow(params) {
|
|
1029
|
+
return params instanceof InngestWorkflow;
|
|
1030
|
+
}
|
|
734
1031
|
function createStep(params, agentOptions) {
|
|
1032
|
+
if (isInngestWorkflow(params)) {
|
|
1033
|
+
return params;
|
|
1034
|
+
}
|
|
735
1035
|
if (isAgent(params)) {
|
|
1036
|
+
const outputSchema = agentOptions?.structuredOutput?.schema ?? zod.z.object({ text: zod.z.string() });
|
|
736
1037
|
return {
|
|
737
1038
|
id: params.name,
|
|
738
1039
|
description: params.getDescription(),
|
|
@@ -741,9 +1042,7 @@ function createStep(params, agentOptions) {
|
|
|
741
1042
|
// resourceId: z.string().optional(),
|
|
742
1043
|
// threadId: z.string().optional(),
|
|
743
1044
|
}),
|
|
744
|
-
outputSchema
|
|
745
|
-
text: zod.z.string()
|
|
746
|
-
}),
|
|
1045
|
+
outputSchema,
|
|
747
1046
|
execute: async ({
|
|
748
1047
|
inputData,
|
|
749
1048
|
[_constants.EMITTER_SYMBOL]: emitter,
|
|
@@ -759,6 +1058,7 @@ function createStep(params, agentOptions) {
|
|
|
759
1058
|
streamPromise.resolve = resolve;
|
|
760
1059
|
streamPromise.reject = reject;
|
|
761
1060
|
});
|
|
1061
|
+
let structuredResult = null;
|
|
762
1062
|
const toolData = {
|
|
763
1063
|
name: params.name,
|
|
764
1064
|
args: inputData
|
|
@@ -772,6 +1072,10 @@ function createStep(params, agentOptions) {
|
|
|
772
1072
|
requestContext,
|
|
773
1073
|
tracingContext,
|
|
774
1074
|
onFinish: (result) => {
|
|
1075
|
+
const resultWithObject = result;
|
|
1076
|
+
if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
|
|
1077
|
+
structuredResult = resultWithObject.object;
|
|
1078
|
+
}
|
|
775
1079
|
streamPromise.resolve(result.text);
|
|
776
1080
|
void agentOptions?.onFinish?.(result);
|
|
777
1081
|
},
|
|
@@ -784,6 +1088,10 @@ function createStep(params, agentOptions) {
|
|
|
784
1088
|
requestContext,
|
|
785
1089
|
tracingContext,
|
|
786
1090
|
onFinish: (result) => {
|
|
1091
|
+
const resultWithObject = result;
|
|
1092
|
+
if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
|
|
1093
|
+
structuredResult = resultWithObject.object;
|
|
1094
|
+
}
|
|
787
1095
|
streamPromise.resolve(result.text);
|
|
788
1096
|
void agentOptions?.onFinish?.(result);
|
|
789
1097
|
},
|
|
@@ -817,6 +1125,9 @@ function createStep(params, agentOptions) {
|
|
|
817
1125
|
if (abortSignal.aborted) {
|
|
818
1126
|
return abort();
|
|
819
1127
|
}
|
|
1128
|
+
if (structuredResult !== null) {
|
|
1129
|
+
return structuredResult;
|
|
1130
|
+
}
|
|
820
1131
|
return {
|
|
821
1132
|
text: await streamPromise.promise
|
|
822
1133
|
};
|
|
@@ -906,7 +1217,8 @@ function init(inngest) {
|
|
|
906
1217
|
inputSchema: workflow.inputSchema,
|
|
907
1218
|
outputSchema: workflow.outputSchema,
|
|
908
1219
|
steps: workflow.stepDefs,
|
|
909
|
-
mastra: workflow.mastra
|
|
1220
|
+
mastra: workflow.mastra,
|
|
1221
|
+
options: workflow.options
|
|
910
1222
|
});
|
|
911
1223
|
wf.setStepFlow(workflow.stepGraph);
|
|
912
1224
|
wf.commit();
|
|
@@ -914,856 +1226,11 @@ function init(inngest) {
|
|
|
914
1226
|
}
|
|
915
1227
|
};
|
|
916
1228
|
}
|
|
917
|
-
var InngestExecutionEngine = class extends workflows.DefaultExecutionEngine {
|
|
918
|
-
inngestStep;
|
|
919
|
-
inngestAttempts;
|
|
920
|
-
constructor(mastra, inngestStep, inngestAttempts = 0, options) {
|
|
921
|
-
super({ mastra, options });
|
|
922
|
-
this.inngestStep = inngestStep;
|
|
923
|
-
this.inngestAttempts = inngestAttempts;
|
|
924
|
-
}
|
|
925
|
-
async fmtReturnValue(emitter, stepResults, lastOutput, error) {
|
|
926
|
-
const base = {
|
|
927
|
-
status: lastOutput.status,
|
|
928
|
-
steps: stepResults
|
|
929
|
-
};
|
|
930
|
-
if (lastOutput.status === "success") {
|
|
931
|
-
base.result = lastOutput.output;
|
|
932
|
-
} else if (lastOutput.status === "failed") {
|
|
933
|
-
base.error = error instanceof Error ? error?.stack ?? error.message : lastOutput?.error instanceof Error ? lastOutput.error.message : lastOutput.error ?? error ?? "Unknown error";
|
|
934
|
-
} else if (lastOutput.status === "suspended") {
|
|
935
|
-
const suspendedStepIds = Object.entries(stepResults).flatMap(([stepId, stepResult]) => {
|
|
936
|
-
if (stepResult?.status === "suspended") {
|
|
937
|
-
const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;
|
|
938
|
-
return nestedPath ? [[stepId, ...nestedPath]] : [[stepId]];
|
|
939
|
-
}
|
|
940
|
-
return [];
|
|
941
|
-
});
|
|
942
|
-
base.suspended = suspendedStepIds;
|
|
943
|
-
}
|
|
944
|
-
return base;
|
|
945
|
-
}
|
|
946
|
-
// async executeSleep({ id, duration }: { id: string; duration: number }): Promise<void> {
|
|
947
|
-
// await this.inngestStep.sleep(id, duration);
|
|
948
|
-
// }
|
|
949
|
-
async executeSleep({
|
|
950
|
-
workflowId,
|
|
951
|
-
runId,
|
|
952
|
-
entry,
|
|
953
|
-
prevOutput,
|
|
954
|
-
stepResults,
|
|
955
|
-
emitter,
|
|
956
|
-
abortController,
|
|
957
|
-
requestContext,
|
|
958
|
-
executionContext,
|
|
959
|
-
writableStream,
|
|
960
|
-
tracingContext
|
|
961
|
-
}) {
|
|
962
|
-
let { duration, fn } = entry;
|
|
963
|
-
const sleepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
964
|
-
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
965
|
-
name: `sleep: ${duration ? `${duration}ms` : "dynamic"}`,
|
|
966
|
-
attributes: {
|
|
967
|
-
durationMs: duration,
|
|
968
|
-
sleepType: fn ? "dynamic" : "fixed"
|
|
969
|
-
},
|
|
970
|
-
tracingPolicy: this.options?.tracingPolicy
|
|
971
|
-
});
|
|
972
|
-
if (fn) {
|
|
973
|
-
const stepCallId = crypto.randomUUID();
|
|
974
|
-
duration = await this.inngestStep.run(`workflow.${workflowId}.sleep.${entry.id}`, async () => {
|
|
975
|
-
return await fn(
|
|
976
|
-
workflows.createDeprecationProxy(
|
|
977
|
-
{
|
|
978
|
-
runId,
|
|
979
|
-
workflowId,
|
|
980
|
-
mastra: this.mastra,
|
|
981
|
-
requestContext,
|
|
982
|
-
inputData: prevOutput,
|
|
983
|
-
state: executionContext.state,
|
|
984
|
-
setState: (state) => {
|
|
985
|
-
executionContext.state = state;
|
|
986
|
-
},
|
|
987
|
-
retryCount: -1,
|
|
988
|
-
tracingContext: {
|
|
989
|
-
currentSpan: sleepSpan
|
|
990
|
-
},
|
|
991
|
-
getInitData: () => stepResults?.input,
|
|
992
|
-
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
993
|
-
// TODO: this function shouldn't have suspend probably?
|
|
994
|
-
suspend: async (_suspendPayload) => {
|
|
995
|
-
},
|
|
996
|
-
bail: () => {
|
|
997
|
-
},
|
|
998
|
-
abort: () => {
|
|
999
|
-
abortController?.abort();
|
|
1000
|
-
},
|
|
1001
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1002
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1003
|
-
engine: { step: this.inngestStep },
|
|
1004
|
-
abortSignal: abortController?.signal,
|
|
1005
|
-
writer: new tools.ToolStream(
|
|
1006
|
-
{
|
|
1007
|
-
prefix: "workflow-step",
|
|
1008
|
-
callId: stepCallId,
|
|
1009
|
-
name: "sleep",
|
|
1010
|
-
runId
|
|
1011
|
-
},
|
|
1012
|
-
writableStream
|
|
1013
|
-
)
|
|
1014
|
-
},
|
|
1015
|
-
{
|
|
1016
|
-
paramName: "runCount",
|
|
1017
|
-
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1018
|
-
logger: this.logger
|
|
1019
|
-
}
|
|
1020
|
-
)
|
|
1021
|
-
);
|
|
1022
|
-
});
|
|
1023
|
-
sleepSpan?.update({
|
|
1024
|
-
attributes: {
|
|
1025
|
-
durationMs: duration
|
|
1026
|
-
}
|
|
1027
|
-
});
|
|
1028
|
-
}
|
|
1029
|
-
try {
|
|
1030
|
-
await this.inngestStep.sleep(entry.id, !duration || duration < 0 ? 0 : duration);
|
|
1031
|
-
sleepSpan?.end();
|
|
1032
|
-
} catch (e) {
|
|
1033
|
-
sleepSpan?.error({ error: e });
|
|
1034
|
-
throw e;
|
|
1035
|
-
}
|
|
1036
|
-
}
|
|
1037
|
-
async executeSleepUntil({
|
|
1038
|
-
workflowId,
|
|
1039
|
-
runId,
|
|
1040
|
-
entry,
|
|
1041
|
-
prevOutput,
|
|
1042
|
-
stepResults,
|
|
1043
|
-
emitter,
|
|
1044
|
-
abortController,
|
|
1045
|
-
requestContext,
|
|
1046
|
-
executionContext,
|
|
1047
|
-
writableStream,
|
|
1048
|
-
tracingContext
|
|
1049
|
-
}) {
|
|
1050
|
-
let { date, fn } = entry;
|
|
1051
|
-
const sleepUntilSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1052
|
-
type: observability.SpanType.WORKFLOW_SLEEP,
|
|
1053
|
-
name: `sleepUntil: ${date ? date.toISOString() : "dynamic"}`,
|
|
1054
|
-
attributes: {
|
|
1055
|
-
untilDate: date,
|
|
1056
|
-
durationMs: date ? Math.max(0, date.getTime() - Date.now()) : void 0,
|
|
1057
|
-
sleepType: fn ? "dynamic" : "fixed"
|
|
1058
|
-
},
|
|
1059
|
-
tracingPolicy: this.options?.tracingPolicy
|
|
1060
|
-
});
|
|
1061
|
-
if (fn) {
|
|
1062
|
-
date = await this.inngestStep.run(`workflow.${workflowId}.sleepUntil.${entry.id}`, async () => {
|
|
1063
|
-
const stepCallId = crypto.randomUUID();
|
|
1064
|
-
return await fn(
|
|
1065
|
-
workflows.createDeprecationProxy(
|
|
1066
|
-
{
|
|
1067
|
-
runId,
|
|
1068
|
-
workflowId,
|
|
1069
|
-
mastra: this.mastra,
|
|
1070
|
-
requestContext,
|
|
1071
|
-
inputData: prevOutput,
|
|
1072
|
-
state: executionContext.state,
|
|
1073
|
-
setState: (state) => {
|
|
1074
|
-
executionContext.state = state;
|
|
1075
|
-
},
|
|
1076
|
-
retryCount: -1,
|
|
1077
|
-
tracingContext: {
|
|
1078
|
-
currentSpan: sleepUntilSpan
|
|
1079
|
-
},
|
|
1080
|
-
getInitData: () => stepResults?.input,
|
|
1081
|
-
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1082
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1083
|
-
suspend: async (_suspendPayload) => {
|
|
1084
|
-
},
|
|
1085
|
-
bail: () => {
|
|
1086
|
-
},
|
|
1087
|
-
abort: () => {
|
|
1088
|
-
abortController?.abort();
|
|
1089
|
-
},
|
|
1090
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1091
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1092
|
-
engine: { step: this.inngestStep },
|
|
1093
|
-
abortSignal: abortController?.signal,
|
|
1094
|
-
writer: new tools.ToolStream(
|
|
1095
|
-
{
|
|
1096
|
-
prefix: "workflow-step",
|
|
1097
|
-
callId: stepCallId,
|
|
1098
|
-
name: "sleep",
|
|
1099
|
-
runId
|
|
1100
|
-
},
|
|
1101
|
-
writableStream
|
|
1102
|
-
)
|
|
1103
|
-
},
|
|
1104
|
-
{
|
|
1105
|
-
paramName: "runCount",
|
|
1106
|
-
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1107
|
-
logger: this.logger
|
|
1108
|
-
}
|
|
1109
|
-
)
|
|
1110
|
-
);
|
|
1111
|
-
});
|
|
1112
|
-
if (date && !(date instanceof Date)) {
|
|
1113
|
-
date = new Date(date);
|
|
1114
|
-
}
|
|
1115
|
-
const time = !date ? 0 : date.getTime() - Date.now();
|
|
1116
|
-
sleepUntilSpan?.update({
|
|
1117
|
-
attributes: {
|
|
1118
|
-
durationMs: Math.max(0, time)
|
|
1119
|
-
}
|
|
1120
|
-
});
|
|
1121
|
-
}
|
|
1122
|
-
if (!(date instanceof Date)) {
|
|
1123
|
-
sleepUntilSpan?.end();
|
|
1124
|
-
return;
|
|
1125
|
-
}
|
|
1126
|
-
try {
|
|
1127
|
-
await this.inngestStep.sleepUntil(entry.id, date);
|
|
1128
|
-
sleepUntilSpan?.end();
|
|
1129
|
-
} catch (e) {
|
|
1130
|
-
sleepUntilSpan?.error({ error: e });
|
|
1131
|
-
throw e;
|
|
1132
|
-
}
|
|
1133
|
-
}
|
|
1134
|
-
async executeStep({
|
|
1135
|
-
step,
|
|
1136
|
-
stepResults,
|
|
1137
|
-
executionContext,
|
|
1138
|
-
resume,
|
|
1139
|
-
timeTravel,
|
|
1140
|
-
prevOutput,
|
|
1141
|
-
emitter,
|
|
1142
|
-
abortController,
|
|
1143
|
-
requestContext,
|
|
1144
|
-
tracingContext,
|
|
1145
|
-
writableStream,
|
|
1146
|
-
disableScorers
|
|
1147
|
-
}) {
|
|
1148
|
-
const stepSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1149
|
-
name: `workflow step: '${step.id}'`,
|
|
1150
|
-
type: observability.SpanType.WORKFLOW_STEP,
|
|
1151
|
-
input: prevOutput,
|
|
1152
|
-
attributes: {
|
|
1153
|
-
stepId: step.id
|
|
1154
|
-
},
|
|
1155
|
-
tracingPolicy: this.options?.tracingPolicy
|
|
1156
|
-
});
|
|
1157
|
-
const { inputData, validationError } = await workflows.validateStepInput({
|
|
1158
|
-
prevOutput,
|
|
1159
|
-
step,
|
|
1160
|
-
validateInputs: this.options?.validateInputs ?? true
|
|
1161
|
-
});
|
|
1162
|
-
const startedAt = await this.inngestStep.run(
|
|
1163
|
-
`workflow.${executionContext.workflowId}.run.${executionContext.runId}.step.${step.id}.running_ev`,
|
|
1164
|
-
async () => {
|
|
1165
|
-
const startedAt2 = Date.now();
|
|
1166
|
-
await emitter.emit("watch", {
|
|
1167
|
-
type: "workflow-step-start",
|
|
1168
|
-
payload: {
|
|
1169
|
-
id: step.id,
|
|
1170
|
-
status: "running",
|
|
1171
|
-
payload: inputData,
|
|
1172
|
-
startedAt: startedAt2
|
|
1173
|
-
}
|
|
1174
|
-
});
|
|
1175
|
-
return startedAt2;
|
|
1176
|
-
}
|
|
1177
|
-
);
|
|
1178
|
-
if (step instanceof InngestWorkflow) {
|
|
1179
|
-
const isResume = !!resume?.steps?.length;
|
|
1180
|
-
let result;
|
|
1181
|
-
let runId;
|
|
1182
|
-
const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);
|
|
1183
|
-
try {
|
|
1184
|
-
if (isResume) {
|
|
1185
|
-
runId = stepResults[resume?.steps?.[0] ?? ""]?.suspendPayload?.__workflow_meta?.runId ?? crypto.randomUUID();
|
|
1186
|
-
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1187
|
-
workflowName: step.id,
|
|
1188
|
-
runId
|
|
1189
|
-
});
|
|
1190
|
-
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1191
|
-
function: step.getFunction(),
|
|
1192
|
-
data: {
|
|
1193
|
-
inputData,
|
|
1194
|
-
initialState: executionContext.state ?? snapshot?.value ?? {},
|
|
1195
|
-
runId,
|
|
1196
|
-
resume: {
|
|
1197
|
-
runId,
|
|
1198
|
-
steps: resume.steps.slice(1),
|
|
1199
|
-
stepResults: snapshot?.context,
|
|
1200
|
-
resumePayload: resume.resumePayload,
|
|
1201
|
-
resumePath: resume.steps?.[1] ? snapshot?.suspendedPaths?.[resume.steps?.[1]] : void 0
|
|
1202
|
-
},
|
|
1203
|
-
outputOptions: { includeState: true }
|
|
1204
|
-
}
|
|
1205
|
-
});
|
|
1206
|
-
result = invokeResp.result;
|
|
1207
|
-
runId = invokeResp.runId;
|
|
1208
|
-
executionContext.state = invokeResp.result.state;
|
|
1209
|
-
} else if (isTimeTravel) {
|
|
1210
|
-
const snapshot = await this.mastra?.getStorage()?.loadWorkflowSnapshot({
|
|
1211
|
-
workflowName: step.id,
|
|
1212
|
-
runId: executionContext.runId
|
|
1213
|
-
}) ?? { context: {} };
|
|
1214
|
-
const timeTravelParams = workflows.createTimeTravelExecutionParams({
|
|
1215
|
-
steps: timeTravel.steps.slice(1),
|
|
1216
|
-
inputData: timeTravel.inputData,
|
|
1217
|
-
resumeData: timeTravel.resumeData,
|
|
1218
|
-
context: timeTravel.nestedStepResults?.[step.id] ?? {},
|
|
1219
|
-
nestedStepsContext: timeTravel.nestedStepResults ?? {},
|
|
1220
|
-
snapshot,
|
|
1221
|
-
graph: step.buildExecutionGraph()
|
|
1222
|
-
});
|
|
1223
|
-
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1224
|
-
function: step.getFunction(),
|
|
1225
|
-
data: {
|
|
1226
|
-
timeTravel: timeTravelParams,
|
|
1227
|
-
initialState: executionContext.state ?? {},
|
|
1228
|
-
runId: executionContext.runId,
|
|
1229
|
-
outputOptions: { includeState: true }
|
|
1230
|
-
}
|
|
1231
|
-
});
|
|
1232
|
-
result = invokeResp.result;
|
|
1233
|
-
runId = invokeResp.runId;
|
|
1234
|
-
executionContext.state = invokeResp.result.state;
|
|
1235
|
-
} else {
|
|
1236
|
-
const invokeResp = await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {
|
|
1237
|
-
function: step.getFunction(),
|
|
1238
|
-
data: {
|
|
1239
|
-
inputData,
|
|
1240
|
-
initialState: executionContext.state ?? {},
|
|
1241
|
-
outputOptions: { includeState: true }
|
|
1242
|
-
}
|
|
1243
|
-
});
|
|
1244
|
-
result = invokeResp.result;
|
|
1245
|
-
runId = invokeResp.runId;
|
|
1246
|
-
executionContext.state = invokeResp.result.state;
|
|
1247
|
-
}
|
|
1248
|
-
} catch (e) {
|
|
1249
|
-
const errorCause = e?.cause;
|
|
1250
|
-
if (errorCause && typeof errorCause === "object") {
|
|
1251
|
-
result = errorCause;
|
|
1252
|
-
runId = errorCause.runId || crypto.randomUUID();
|
|
1253
|
-
} else {
|
|
1254
|
-
runId = crypto.randomUUID();
|
|
1255
|
-
result = {
|
|
1256
|
-
status: "failed",
|
|
1257
|
-
error: e instanceof Error ? e : new Error(String(e)),
|
|
1258
|
-
steps: {},
|
|
1259
|
-
input: inputData
|
|
1260
|
-
};
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
const res = await this.inngestStep.run(
|
|
1264
|
-
`workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,
|
|
1265
|
-
async () => {
|
|
1266
|
-
if (result.status === "failed") {
|
|
1267
|
-
await emitter.emit("watch", {
|
|
1268
|
-
type: "workflow-step-result",
|
|
1269
|
-
payload: {
|
|
1270
|
-
id: step.id,
|
|
1271
|
-
status: "failed",
|
|
1272
|
-
error: result?.error,
|
|
1273
|
-
payload: prevOutput
|
|
1274
|
-
}
|
|
1275
|
-
});
|
|
1276
|
-
return { executionContext, result: { status: "failed", error: result?.error } };
|
|
1277
|
-
} else if (result.status === "suspended") {
|
|
1278
|
-
const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {
|
|
1279
|
-
const stepRes2 = stepResult;
|
|
1280
|
-
return stepRes2?.status === "suspended";
|
|
1281
|
-
});
|
|
1282
|
-
for (const [stepName, stepResult] of suspendedSteps) {
|
|
1283
|
-
const suspendPath = [stepName, ...stepResult?.suspendPayload?.__workflow_meta?.path ?? []];
|
|
1284
|
-
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1285
|
-
await emitter.emit("watch", {
|
|
1286
|
-
type: "workflow-step-suspended",
|
|
1287
|
-
payload: {
|
|
1288
|
-
id: step.id,
|
|
1289
|
-
status: "suspended"
|
|
1290
|
-
}
|
|
1291
|
-
});
|
|
1292
|
-
return {
|
|
1293
|
-
executionContext,
|
|
1294
|
-
result: {
|
|
1295
|
-
status: "suspended",
|
|
1296
|
-
payload: stepResult.payload,
|
|
1297
|
-
suspendPayload: {
|
|
1298
|
-
...stepResult?.suspendPayload,
|
|
1299
|
-
__workflow_meta: { runId, path: suspendPath }
|
|
1300
|
-
}
|
|
1301
|
-
}
|
|
1302
|
-
};
|
|
1303
|
-
}
|
|
1304
|
-
return {
|
|
1305
|
-
executionContext,
|
|
1306
|
-
result: {
|
|
1307
|
-
status: "suspended",
|
|
1308
|
-
payload: {}
|
|
1309
|
-
}
|
|
1310
|
-
};
|
|
1311
|
-
}
|
|
1312
|
-
await emitter.emit("watch", {
|
|
1313
|
-
type: "workflow-step-result",
|
|
1314
|
-
payload: {
|
|
1315
|
-
id: step.id,
|
|
1316
|
-
status: "success",
|
|
1317
|
-
output: result?.result
|
|
1318
|
-
}
|
|
1319
|
-
});
|
|
1320
|
-
await emitter.emit("watch", {
|
|
1321
|
-
type: "workflow-step-finish",
|
|
1322
|
-
payload: {
|
|
1323
|
-
id: step.id,
|
|
1324
|
-
metadata: {}
|
|
1325
|
-
}
|
|
1326
|
-
});
|
|
1327
|
-
return { executionContext, result: { status: "success", output: result?.result } };
|
|
1328
|
-
}
|
|
1329
|
-
);
|
|
1330
|
-
Object.assign(executionContext, res.executionContext);
|
|
1331
|
-
return {
|
|
1332
|
-
...res.result,
|
|
1333
|
-
startedAt,
|
|
1334
|
-
endedAt: Date.now(),
|
|
1335
|
-
payload: inputData,
|
|
1336
|
-
resumedAt: resume?.steps[0] === step.id ? startedAt : void 0,
|
|
1337
|
-
resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : void 0
|
|
1338
|
-
};
|
|
1339
|
-
}
|
|
1340
|
-
const stepCallId = crypto.randomUUID();
|
|
1341
|
-
let stepRes;
|
|
1342
|
-
try {
|
|
1343
|
-
stepRes = await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}`, async () => {
|
|
1344
|
-
let execResults;
|
|
1345
|
-
let suspended;
|
|
1346
|
-
let bailed;
|
|
1347
|
-
const { resumeData: timeTravelResumeData, validationError: timeTravelResumeValidationError } = await workflows.validateStepResumeData({
|
|
1348
|
-
resumeData: timeTravel?.stepResults[step.id]?.status === "suspended" ? timeTravel?.resumeData : void 0,
|
|
1349
|
-
step
|
|
1350
|
-
});
|
|
1351
|
-
let resumeDataToUse;
|
|
1352
|
-
if (timeTravelResumeData && !timeTravelResumeValidationError) {
|
|
1353
|
-
resumeDataToUse = timeTravelResumeData;
|
|
1354
|
-
} else if (timeTravelResumeData && timeTravelResumeValidationError) {
|
|
1355
|
-
this.logger.warn("Time travel resume data validation failed", {
|
|
1356
|
-
stepId: step.id,
|
|
1357
|
-
error: timeTravelResumeValidationError.message
|
|
1358
|
-
});
|
|
1359
|
-
} else if (resume?.steps[0] === step.id) {
|
|
1360
|
-
resumeDataToUse = resume?.resumePayload;
|
|
1361
|
-
}
|
|
1362
|
-
try {
|
|
1363
|
-
if (validationError) {
|
|
1364
|
-
throw validationError;
|
|
1365
|
-
}
|
|
1366
|
-
const retryCount = this.getOrGenerateRetryCount(step.id);
|
|
1367
|
-
const result = await step.execute({
|
|
1368
|
-
runId: executionContext.runId,
|
|
1369
|
-
workflowId: executionContext.workflowId,
|
|
1370
|
-
mastra: this.mastra,
|
|
1371
|
-
requestContext,
|
|
1372
|
-
retryCount,
|
|
1373
|
-
writer: new tools.ToolStream(
|
|
1374
|
-
{
|
|
1375
|
-
prefix: "workflow-step",
|
|
1376
|
-
callId: stepCallId,
|
|
1377
|
-
name: step.id,
|
|
1378
|
-
runId: executionContext.runId
|
|
1379
|
-
},
|
|
1380
|
-
writableStream
|
|
1381
|
-
),
|
|
1382
|
-
state: executionContext?.state ?? {},
|
|
1383
|
-
setState: (state) => {
|
|
1384
|
-
executionContext.state = state;
|
|
1385
|
-
},
|
|
1386
|
-
inputData,
|
|
1387
|
-
resumeData: resumeDataToUse,
|
|
1388
|
-
tracingContext: {
|
|
1389
|
-
currentSpan: stepSpan
|
|
1390
|
-
},
|
|
1391
|
-
getInitData: () => stepResults?.input,
|
|
1392
|
-
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1393
|
-
suspend: async (suspendPayload, suspendOptions) => {
|
|
1394
|
-
const { suspendData, validationError: validationError2 } = await workflows.validateStepSuspendData({
|
|
1395
|
-
suspendData: suspendPayload,
|
|
1396
|
-
step
|
|
1397
|
-
});
|
|
1398
|
-
if (validationError2) {
|
|
1399
|
-
throw validationError2;
|
|
1400
|
-
}
|
|
1401
|
-
executionContext.suspendedPaths[step.id] = executionContext.executionPath;
|
|
1402
|
-
if (suspendOptions?.resumeLabel) {
|
|
1403
|
-
const resumeLabel = Array.isArray(suspendOptions.resumeLabel) ? suspendOptions.resumeLabel : [suspendOptions.resumeLabel];
|
|
1404
|
-
for (const label of resumeLabel) {
|
|
1405
|
-
executionContext.resumeLabels[label] = {
|
|
1406
|
-
stepId: step.id,
|
|
1407
|
-
foreachIndex: executionContext.foreachIndex
|
|
1408
|
-
};
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
suspended = { payload: suspendData };
|
|
1412
|
-
},
|
|
1413
|
-
bail: (result2) => {
|
|
1414
|
-
bailed = { payload: result2 };
|
|
1415
|
-
},
|
|
1416
|
-
abort: () => {
|
|
1417
|
-
abortController?.abort();
|
|
1418
|
-
},
|
|
1419
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1420
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1421
|
-
engine: {
|
|
1422
|
-
step: this.inngestStep
|
|
1423
|
-
},
|
|
1424
|
-
abortSignal: abortController.signal
|
|
1425
|
-
});
|
|
1426
|
-
const endedAt = Date.now();
|
|
1427
|
-
execResults = {
|
|
1428
|
-
status: "success",
|
|
1429
|
-
output: result,
|
|
1430
|
-
startedAt,
|
|
1431
|
-
endedAt,
|
|
1432
|
-
payload: inputData,
|
|
1433
|
-
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1434
|
-
resumePayload: resumeDataToUse
|
|
1435
|
-
};
|
|
1436
|
-
} catch (e) {
|
|
1437
|
-
const stepFailure = {
|
|
1438
|
-
status: "failed",
|
|
1439
|
-
payload: inputData,
|
|
1440
|
-
error: e instanceof Error ? e.message : String(e),
|
|
1441
|
-
endedAt: Date.now(),
|
|
1442
|
-
startedAt,
|
|
1443
|
-
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1444
|
-
resumePayload: resumeDataToUse
|
|
1445
|
-
};
|
|
1446
|
-
execResults = stepFailure;
|
|
1447
|
-
const fallbackErrorMessage = `Step ${step.id} failed`;
|
|
1448
|
-
stepSpan?.error({ error: new Error(execResults.error ?? fallbackErrorMessage) });
|
|
1449
|
-
throw new inngest.RetryAfterError(execResults.error ?? fallbackErrorMessage, executionContext.retryConfig.delay, {
|
|
1450
|
-
cause: execResults
|
|
1451
|
-
});
|
|
1452
|
-
}
|
|
1453
|
-
if (suspended) {
|
|
1454
|
-
execResults = {
|
|
1455
|
-
status: "suspended",
|
|
1456
|
-
suspendPayload: suspended.payload,
|
|
1457
|
-
...execResults.output ? { suspendOutput: execResults.output } : {},
|
|
1458
|
-
payload: inputData,
|
|
1459
|
-
suspendedAt: Date.now(),
|
|
1460
|
-
startedAt,
|
|
1461
|
-
resumedAt: resumeDataToUse ? startedAt : void 0,
|
|
1462
|
-
resumePayload: resumeDataToUse
|
|
1463
|
-
};
|
|
1464
|
-
} else if (bailed) {
|
|
1465
|
-
execResults = {
|
|
1466
|
-
status: "bailed",
|
|
1467
|
-
output: bailed.payload,
|
|
1468
|
-
payload: inputData,
|
|
1469
|
-
endedAt: Date.now(),
|
|
1470
|
-
startedAt
|
|
1471
|
-
};
|
|
1472
|
-
}
|
|
1473
|
-
if (execResults.status === "suspended") {
|
|
1474
|
-
await emitter.emit("watch", {
|
|
1475
|
-
type: "workflow-step-suspended",
|
|
1476
|
-
payload: {
|
|
1477
|
-
id: step.id,
|
|
1478
|
-
...execResults
|
|
1479
|
-
}
|
|
1480
|
-
});
|
|
1481
|
-
} else {
|
|
1482
|
-
await emitter.emit("watch", {
|
|
1483
|
-
type: "workflow-step-result",
|
|
1484
|
-
payload: {
|
|
1485
|
-
id: step.id,
|
|
1486
|
-
...execResults
|
|
1487
|
-
}
|
|
1488
|
-
});
|
|
1489
|
-
await emitter.emit("watch", {
|
|
1490
|
-
type: "workflow-step-finish",
|
|
1491
|
-
payload: {
|
|
1492
|
-
id: step.id,
|
|
1493
|
-
metadata: {}
|
|
1494
|
-
}
|
|
1495
|
-
});
|
|
1496
|
-
}
|
|
1497
|
-
stepSpan?.end({ output: execResults });
|
|
1498
|
-
return { result: execResults, executionContext, stepResults };
|
|
1499
|
-
});
|
|
1500
|
-
} catch (e) {
|
|
1501
|
-
const stepFailure = e instanceof Error ? e?.cause : {
|
|
1502
|
-
status: "failed",
|
|
1503
|
-
error: e instanceof Error ? e.message : String(e),
|
|
1504
|
-
payload: inputData,
|
|
1505
|
-
startedAt,
|
|
1506
|
-
endedAt: Date.now()
|
|
1507
|
-
};
|
|
1508
|
-
stepRes = {
|
|
1509
|
-
result: stepFailure,
|
|
1510
|
-
executionContext,
|
|
1511
|
-
stepResults: {
|
|
1512
|
-
...stepResults,
|
|
1513
|
-
[step.id]: stepFailure
|
|
1514
|
-
}
|
|
1515
|
-
};
|
|
1516
|
-
}
|
|
1517
|
-
if (disableScorers !== false && stepRes.result.status === "success") {
|
|
1518
|
-
await this.inngestStep.run(`workflow.${executionContext.workflowId}.step.${step.id}.score`, async () => {
|
|
1519
|
-
if (step.scorers) {
|
|
1520
|
-
await this.runScorers({
|
|
1521
|
-
scorers: step.scorers,
|
|
1522
|
-
runId: executionContext.runId,
|
|
1523
|
-
input: inputData,
|
|
1524
|
-
output: stepRes.result,
|
|
1525
|
-
workflowId: executionContext.workflowId,
|
|
1526
|
-
stepId: step.id,
|
|
1527
|
-
requestContext,
|
|
1528
|
-
disableScorers,
|
|
1529
|
-
tracingContext: { currentSpan: stepSpan }
|
|
1530
|
-
});
|
|
1531
|
-
}
|
|
1532
|
-
});
|
|
1533
|
-
}
|
|
1534
|
-
Object.assign(executionContext.suspendedPaths, stepRes.executionContext.suspendedPaths);
|
|
1535
|
-
executionContext.state = stepRes.executionContext.state;
|
|
1536
|
-
return stepRes.result;
|
|
1537
|
-
}
|
|
1538
|
-
async persistStepUpdate({
|
|
1539
|
-
workflowId,
|
|
1540
|
-
runId,
|
|
1541
|
-
stepResults,
|
|
1542
|
-
resourceId,
|
|
1543
|
-
executionContext,
|
|
1544
|
-
serializedStepGraph,
|
|
1545
|
-
workflowStatus,
|
|
1546
|
-
result,
|
|
1547
|
-
error
|
|
1548
|
-
}) {
|
|
1549
|
-
await this.inngestStep.run(
|
|
1550
|
-
`workflow.${workflowId}.run.${runId}.path.${JSON.stringify(executionContext.executionPath)}.stepUpdate`,
|
|
1551
|
-
async () => {
|
|
1552
|
-
const shouldPersistSnapshot = this.options.shouldPersistSnapshot({ stepResults, workflowStatus });
|
|
1553
|
-
if (!shouldPersistSnapshot) {
|
|
1554
|
-
return;
|
|
1555
|
-
}
|
|
1556
|
-
await this.mastra?.getStorage()?.persistWorkflowSnapshot({
|
|
1557
|
-
workflowName: workflowId,
|
|
1558
|
-
runId,
|
|
1559
|
-
resourceId,
|
|
1560
|
-
snapshot: {
|
|
1561
|
-
runId,
|
|
1562
|
-
status: workflowStatus,
|
|
1563
|
-
value: executionContext.state,
|
|
1564
|
-
context: stepResults,
|
|
1565
|
-
activePaths: executionContext.executionPath,
|
|
1566
|
-
activeStepsPath: executionContext.activeStepsPath,
|
|
1567
|
-
suspendedPaths: executionContext.suspendedPaths,
|
|
1568
|
-
resumeLabels: executionContext.resumeLabels,
|
|
1569
|
-
waitingPaths: {},
|
|
1570
|
-
serializedStepGraph,
|
|
1571
|
-
result,
|
|
1572
|
-
error,
|
|
1573
|
-
timestamp: Date.now()
|
|
1574
|
-
}
|
|
1575
|
-
});
|
|
1576
|
-
}
|
|
1577
|
-
);
|
|
1578
|
-
}
|
|
1579
|
-
async executeConditional({
|
|
1580
|
-
workflowId,
|
|
1581
|
-
runId,
|
|
1582
|
-
entry,
|
|
1583
|
-
prevOutput,
|
|
1584
|
-
stepResults,
|
|
1585
|
-
timeTravel,
|
|
1586
|
-
resume,
|
|
1587
|
-
executionContext,
|
|
1588
|
-
emitter,
|
|
1589
|
-
abortController,
|
|
1590
|
-
requestContext,
|
|
1591
|
-
writableStream,
|
|
1592
|
-
disableScorers,
|
|
1593
|
-
tracingContext
|
|
1594
|
-
}) {
|
|
1595
|
-
const conditionalSpan = tracingContext?.currentSpan?.createChildSpan({
|
|
1596
|
-
type: observability.SpanType.WORKFLOW_CONDITIONAL,
|
|
1597
|
-
name: `conditional: '${entry.conditions.length} conditions'`,
|
|
1598
|
-
input: prevOutput,
|
|
1599
|
-
attributes: {
|
|
1600
|
-
conditionCount: entry.conditions.length
|
|
1601
|
-
},
|
|
1602
|
-
tracingPolicy: this.options?.tracingPolicy
|
|
1603
|
-
});
|
|
1604
|
-
let execResults;
|
|
1605
|
-
const truthyIndexes = (await Promise.all(
|
|
1606
|
-
entry.conditions.map(
|
|
1607
|
-
(cond, index) => this.inngestStep.run(`workflow.${workflowId}.conditional.${index}`, async () => {
|
|
1608
|
-
const evalSpan = conditionalSpan?.createChildSpan({
|
|
1609
|
-
type: observability.SpanType.WORKFLOW_CONDITIONAL_EVAL,
|
|
1610
|
-
name: `condition: '${index}'`,
|
|
1611
|
-
input: prevOutput,
|
|
1612
|
-
attributes: {
|
|
1613
|
-
conditionIndex: index
|
|
1614
|
-
},
|
|
1615
|
-
tracingPolicy: this.options?.tracingPolicy
|
|
1616
|
-
});
|
|
1617
|
-
try {
|
|
1618
|
-
const result = await cond(
|
|
1619
|
-
workflows.createDeprecationProxy(
|
|
1620
|
-
{
|
|
1621
|
-
runId,
|
|
1622
|
-
workflowId,
|
|
1623
|
-
mastra: this.mastra,
|
|
1624
|
-
requestContext,
|
|
1625
|
-
retryCount: -1,
|
|
1626
|
-
inputData: prevOutput,
|
|
1627
|
-
state: executionContext.state,
|
|
1628
|
-
setState: (state) => {
|
|
1629
|
-
executionContext.state = state;
|
|
1630
|
-
},
|
|
1631
|
-
tracingContext: {
|
|
1632
|
-
currentSpan: evalSpan
|
|
1633
|
-
},
|
|
1634
|
-
getInitData: () => stepResults?.input,
|
|
1635
|
-
getStepResult: workflows.getStepResult.bind(this, stepResults),
|
|
1636
|
-
// TODO: this function shouldn't have suspend probably?
|
|
1637
|
-
suspend: async (_suspendPayload) => {
|
|
1638
|
-
},
|
|
1639
|
-
bail: () => {
|
|
1640
|
-
},
|
|
1641
|
-
abort: () => {
|
|
1642
|
-
abortController.abort();
|
|
1643
|
-
},
|
|
1644
|
-
[_constants.EMITTER_SYMBOL]: emitter,
|
|
1645
|
-
[_constants.STREAM_FORMAT_SYMBOL]: executionContext.format,
|
|
1646
|
-
engine: {
|
|
1647
|
-
step: this.inngestStep
|
|
1648
|
-
},
|
|
1649
|
-
abortSignal: abortController.signal,
|
|
1650
|
-
writer: new tools.ToolStream(
|
|
1651
|
-
{
|
|
1652
|
-
prefix: "workflow-step",
|
|
1653
|
-
callId: crypto.randomUUID(),
|
|
1654
|
-
name: "conditional",
|
|
1655
|
-
runId
|
|
1656
|
-
},
|
|
1657
|
-
writableStream
|
|
1658
|
-
)
|
|
1659
|
-
},
|
|
1660
|
-
{
|
|
1661
|
-
paramName: "runCount",
|
|
1662
|
-
deprecationMessage: workflows.runCountDeprecationMessage,
|
|
1663
|
-
logger: this.logger
|
|
1664
|
-
}
|
|
1665
|
-
)
|
|
1666
|
-
);
|
|
1667
|
-
evalSpan?.end({
|
|
1668
|
-
output: result,
|
|
1669
|
-
attributes: {
|
|
1670
|
-
result: !!result
|
|
1671
|
-
}
|
|
1672
|
-
});
|
|
1673
|
-
return result ? index : null;
|
|
1674
|
-
} catch (e) {
|
|
1675
|
-
evalSpan?.error({
|
|
1676
|
-
error: e instanceof Error ? e : new Error(String(e)),
|
|
1677
|
-
attributes: {
|
|
1678
|
-
result: false
|
|
1679
|
-
}
|
|
1680
|
-
});
|
|
1681
|
-
return null;
|
|
1682
|
-
}
|
|
1683
|
-
})
|
|
1684
|
-
)
|
|
1685
|
-
)).filter((index) => index !== null);
|
|
1686
|
-
const stepsToRun = entry.steps.filter((_, index) => truthyIndexes.includes(index));
|
|
1687
|
-
conditionalSpan?.update({
|
|
1688
|
-
attributes: {
|
|
1689
|
-
truthyIndexes,
|
|
1690
|
-
selectedSteps: stepsToRun.map((s) => s.type === "step" ? s.step.id : `control-${s.type}`)
|
|
1691
|
-
}
|
|
1692
|
-
});
|
|
1693
|
-
const results = await Promise.all(
|
|
1694
|
-
stepsToRun.map(async (step, index) => {
|
|
1695
|
-
const currStepResult = stepResults[step.step.id];
|
|
1696
|
-
if (currStepResult && currStepResult.status === "success") {
|
|
1697
|
-
return currStepResult;
|
|
1698
|
-
}
|
|
1699
|
-
const result = await this.executeStep({
|
|
1700
|
-
step: step.step,
|
|
1701
|
-
prevOutput,
|
|
1702
|
-
stepResults,
|
|
1703
|
-
resume,
|
|
1704
|
-
timeTravel,
|
|
1705
|
-
executionContext: {
|
|
1706
|
-
workflowId,
|
|
1707
|
-
runId,
|
|
1708
|
-
executionPath: [...executionContext.executionPath, index],
|
|
1709
|
-
activeStepsPath: executionContext.activeStepsPath,
|
|
1710
|
-
suspendedPaths: executionContext.suspendedPaths,
|
|
1711
|
-
resumeLabels: executionContext.resumeLabels,
|
|
1712
|
-
retryConfig: executionContext.retryConfig,
|
|
1713
|
-
state: executionContext.state
|
|
1714
|
-
},
|
|
1715
|
-
emitter,
|
|
1716
|
-
abortController,
|
|
1717
|
-
requestContext,
|
|
1718
|
-
writableStream,
|
|
1719
|
-
disableScorers,
|
|
1720
|
-
tracingContext: {
|
|
1721
|
-
currentSpan: conditionalSpan
|
|
1722
|
-
}
|
|
1723
|
-
});
|
|
1724
|
-
stepResults[step.step.id] = result;
|
|
1725
|
-
return result;
|
|
1726
|
-
})
|
|
1727
|
-
);
|
|
1728
|
-
const hasFailed = results.find((result) => result.status === "failed");
|
|
1729
|
-
const hasSuspended = results.find((result) => result.status === "suspended");
|
|
1730
|
-
if (hasFailed) {
|
|
1731
|
-
execResults = { status: "failed", error: hasFailed.error };
|
|
1732
|
-
} else if (hasSuspended) {
|
|
1733
|
-
execResults = {
|
|
1734
|
-
status: "suspended",
|
|
1735
|
-
suspendPayload: hasSuspended.suspendPayload,
|
|
1736
|
-
...hasSuspended.suspendOutput ? { suspendOutput: hasSuspended.suspendOutput } : {}
|
|
1737
|
-
};
|
|
1738
|
-
} else {
|
|
1739
|
-
execResults = {
|
|
1740
|
-
status: "success",
|
|
1741
|
-
output: results.reduce((acc, result, index) => {
|
|
1742
|
-
if (result.status === "success") {
|
|
1743
|
-
if ("step" in stepsToRun[index]) {
|
|
1744
|
-
acc[stepsToRun[index].step.id] = result.output;
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1747
|
-
return acc;
|
|
1748
|
-
}, {})
|
|
1749
|
-
};
|
|
1750
|
-
}
|
|
1751
|
-
if (execResults.status === "failed") {
|
|
1752
|
-
conditionalSpan?.error({
|
|
1753
|
-
error: new Error(execResults.error)
|
|
1754
|
-
});
|
|
1755
|
-
} else {
|
|
1756
|
-
conditionalSpan?.end({
|
|
1757
|
-
output: execResults.output || execResults
|
|
1758
|
-
});
|
|
1759
|
-
}
|
|
1760
|
-
return execResults;
|
|
1761
|
-
}
|
|
1762
|
-
};
|
|
1763
1229
|
|
|
1764
1230
|
exports.InngestExecutionEngine = InngestExecutionEngine;
|
|
1765
1231
|
exports.InngestRun = InngestRun;
|
|
1766
1232
|
exports.InngestWorkflow = InngestWorkflow;
|
|
1233
|
+
exports._compatibilityCheck = _compatibilityCheck;
|
|
1767
1234
|
exports.createStep = createStep;
|
|
1768
1235
|
exports.init = init;
|
|
1769
1236
|
exports.serve = serve;
|