@cchevli/inngest 1.8.1-walton.0
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 +3981 -0
- package/dist/__tests__/adapters/_utils.d.ts +18 -0
- package/dist/__tests__/adapters/_utils.d.ts.map +1 -0
- package/dist/__tests__/durable-agent.test.utils.d.ts +43 -0
- package/dist/__tests__/durable-agent.test.utils.d.ts.map +1 -0
- package/dist/chunk-MICZJLEE.cjs +1977 -0
- package/dist/chunk-MICZJLEE.cjs.map +1 -0
- package/dist/chunk-SE7QPBOX.js +1970 -0
- package/dist/chunk-SE7QPBOX.js.map +1 -0
- package/dist/connect.cjs +12 -0
- package/dist/connect.cjs.map +1 -0
- package/dist/connect.d.ts +43 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/connect.js +3 -0
- package/dist/connect.js.map +1 -0
- package/dist/durable-agent/create-inngest-agent.d.ts +425 -0
- package/dist/durable-agent/create-inngest-agent.d.ts.map +1 -0
- package/dist/durable-agent/create-inngest-agentic-workflow.d.ts +56 -0
- package/dist/durable-agent/create-inngest-agentic-workflow.d.ts.map +1 -0
- package/dist/durable-agent/index.d.ts +48 -0
- package/dist/durable-agent/index.d.ts.map +1 -0
- package/dist/execution-engine.d.ts +209 -0
- package/dist/execution-engine.d.ts.map +1 -0
- package/dist/functions.d.ts +7 -0
- package/dist/functions.d.ts.map +1 -0
- package/dist/index.cjs +1576 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +117 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1548 -0
- package/dist/index.js.map +1 -0
- package/dist/nested-workflow-output.d.ts +21 -0
- package/dist/nested-workflow-output.d.ts.map +1 -0
- package/dist/pubsub.d.ts +60 -0
- package/dist/pubsub.d.ts.map +1 -0
- package/dist/run.d.ts +234 -0
- package/dist/run.d.ts.map +1 -0
- package/dist/serve.d.ts +77 -0
- package/dist/serve.d.ts.map +1 -0
- package/dist/types.d.ts +16 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/workflow.d.ts +58 -0
- package/dist/workflow.d.ts.map +1 -0
- package/package.json +98 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,1576 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkMICZJLEE_cjs = require('./chunk-MICZJLEE.cjs');
|
|
4
|
+
var agent = require('@mastra/core/agent');
|
|
5
|
+
var error = require('@mastra/core/error');
|
|
6
|
+
var observability = require('@mastra/core/observability');
|
|
7
|
+
var processors = require('@mastra/core/processors');
|
|
8
|
+
var schema = require('@mastra/core/schema');
|
|
9
|
+
var tools = require('@mastra/core/tools');
|
|
10
|
+
var workflows = require('@mastra/core/workflows');
|
|
11
|
+
var _constants = require('@mastra/core/workflows/_constants');
|
|
12
|
+
var zod = require('zod');
|
|
13
|
+
var hono = require('inngest/hono');
|
|
14
|
+
var durable = require('@mastra/core/agent/durable');
|
|
15
|
+
var cache = require('@mastra/core/cache');
|
|
16
|
+
var events = require('@mastra/core/events');
|
|
17
|
+
|
|
18
|
+
function prepareServeOptions({ mastra, inngest, functions: userFunctions = [], registerOptions }) {
|
|
19
|
+
return {
|
|
20
|
+
...registerOptions,
|
|
21
|
+
client: inngest,
|
|
22
|
+
functions: chunkMICZJLEE_cjs.collectInngestFunctions({ mastra, functions: userFunctions })
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
function createServe(adapter) {
|
|
26
|
+
return (options) => {
|
|
27
|
+
const serveOptions = prepareServeOptions(options);
|
|
28
|
+
return adapter(serveOptions);
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
var serve = createServe(hono.serve);
|
|
32
|
+
|
|
33
|
+
// src/types.ts
|
|
34
|
+
var _compatibilityCheck = true;
|
|
35
|
+
var durableAgenticInputSchema = zod.z.object({
|
|
36
|
+
runId: zod.z.string(),
|
|
37
|
+
agentId: zod.z.string(),
|
|
38
|
+
agentName: zod.z.string().optional(),
|
|
39
|
+
messageListState: zod.z.any(),
|
|
40
|
+
toolsMetadata: zod.z.array(zod.z.any()),
|
|
41
|
+
modelConfig: durable.modelConfigSchema,
|
|
42
|
+
options: zod.z.any(),
|
|
43
|
+
state: zod.z.any(),
|
|
44
|
+
messageId: zod.z.string(),
|
|
45
|
+
// Observability fields (Inngest-specific)
|
|
46
|
+
agentSpanData: zod.z.any().optional(),
|
|
47
|
+
modelSpanData: zod.z.any().optional(),
|
|
48
|
+
stepIndex: zod.z.number().optional()
|
|
49
|
+
});
|
|
50
|
+
var iterationStateSchema = durable.baseIterationStateSchema.extend({
|
|
51
|
+
// Observability - exported span data for agent run
|
|
52
|
+
agentSpanData: zod.z.any().optional(),
|
|
53
|
+
// Observability - exported span data for model generation (ONE span for entire run)
|
|
54
|
+
modelSpanData: zod.z.any().optional(),
|
|
55
|
+
// Step index for continuation across iterations (maintains step: 0, 1, 2, ...)
|
|
56
|
+
stepIndex: zod.z.number()
|
|
57
|
+
});
|
|
58
|
+
var INNGEST_ENGINE_PREFIX = "inngest";
|
|
59
|
+
var InngestDurableStepIds = {
|
|
60
|
+
AGENTIC_EXECUTION: `${INNGEST_ENGINE_PREFIX}:${durable.DurableStepIds.AGENTIC_EXECUTION}`,
|
|
61
|
+
AGENTIC_LOOP: `${INNGEST_ENGINE_PREFIX}:${durable.DurableStepIds.AGENTIC_LOOP}`
|
|
62
|
+
};
|
|
63
|
+
function createInngestDurableAgenticWorkflow(options) {
|
|
64
|
+
const { inngest, maxSteps = durable.DurableAgentDefaults.MAX_STEPS } = options;
|
|
65
|
+
const { createWorkflow } = init(inngest);
|
|
66
|
+
const llmExecutionStep = durable.createDurableLLMExecutionStep();
|
|
67
|
+
const toolCallStep = durable.createDurableToolCallStep();
|
|
68
|
+
const llmMappingStep = durable.createDurableLLMMappingStep();
|
|
69
|
+
const backgroundTaskCheckStep = durable.createDurableBackgroundTaskCheckStep();
|
|
70
|
+
const singleIterationWorkflow = createWorkflow({
|
|
71
|
+
id: InngestDurableStepIds.AGENTIC_EXECUTION,
|
|
72
|
+
inputSchema: iterationStateSchema,
|
|
73
|
+
outputSchema: iterationStateSchema,
|
|
74
|
+
options: {
|
|
75
|
+
tracingPolicy: {
|
|
76
|
+
// Mark all workflow spans as internal so they're hidden in traces
|
|
77
|
+
// This makes the trace structure match regular agents (agent_run -> model_generation -> tool_call)
|
|
78
|
+
internal: observability.InternalSpans.WORKFLOW
|
|
79
|
+
},
|
|
80
|
+
shouldPersistSnapshot: ({ workflowStatus }) => workflowStatus === "suspended",
|
|
81
|
+
validateInputs: false
|
|
82
|
+
},
|
|
83
|
+
steps: []
|
|
84
|
+
}).map(
|
|
85
|
+
async ({ inputData }) => {
|
|
86
|
+
const state = inputData;
|
|
87
|
+
return {
|
|
88
|
+
runId: state.runId,
|
|
89
|
+
agentId: state.agentId,
|
|
90
|
+
agentName: state.agentName,
|
|
91
|
+
messageListState: state.messageListState,
|
|
92
|
+
toolsMetadata: state.toolsMetadata,
|
|
93
|
+
modelConfig: state.modelConfig,
|
|
94
|
+
options: state.options,
|
|
95
|
+
state: state.state,
|
|
96
|
+
messageId: state.messageId,
|
|
97
|
+
// Pass agent span data so model spans can use it as parent
|
|
98
|
+
agentSpanData: state.agentSpanData,
|
|
99
|
+
// Pass model span data (ONE span for entire agent run)
|
|
100
|
+
modelSpanData: state.modelSpanData,
|
|
101
|
+
// Pass step index for continuation (step: 0, 1, 2, ...)
|
|
102
|
+
stepIndex: state.stepIndex
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
{ id: "map-to-llm-input" }
|
|
106
|
+
).then(llmExecutionStep).map(
|
|
107
|
+
async ({ inputData }) => {
|
|
108
|
+
const llmOutput = inputData;
|
|
109
|
+
return llmOutput.toolCalls ?? [];
|
|
110
|
+
},
|
|
111
|
+
{ id: "extract-tool-calls" }
|
|
112
|
+
).foreach(toolCallStep).map(
|
|
113
|
+
async ({ inputData, getStepResult, getInitData, mastra }) => {
|
|
114
|
+
const toolResults = inputData;
|
|
115
|
+
const llmOutput = getStepResult(llmExecutionStep.id);
|
|
116
|
+
const initData = getInitData();
|
|
117
|
+
const observability$1 = mastra?.observability?.getSelectedInstance({});
|
|
118
|
+
const modelSpanData = llmOutput?.modelSpanData;
|
|
119
|
+
const stepSpanData = llmOutput?.stepSpanData;
|
|
120
|
+
const modelSpan = modelSpanData ? observability$1?.rebuildSpan(modelSpanData) : void 0;
|
|
121
|
+
const stepSpan = stepSpanData ? observability$1?.rebuildSpan(stepSpanData) : void 0;
|
|
122
|
+
const agentSpan = initData.agentSpanData ? observability$1?.rebuildSpan(initData.agentSpanData) : void 0;
|
|
123
|
+
const toolParentSpan = stepSpan ?? modelSpan ?? agentSpan;
|
|
124
|
+
for (const tr of toolResults) {
|
|
125
|
+
const toolSpan = toolParentSpan?.createChildSpan({
|
|
126
|
+
type: observability.SpanType.TOOL_CALL,
|
|
127
|
+
name: `tool: '${tr.toolName}'`,
|
|
128
|
+
entityType: observability.EntityType.TOOL,
|
|
129
|
+
entityId: tr.toolName,
|
|
130
|
+
entityName: tr.toolName,
|
|
131
|
+
input: tr.args
|
|
132
|
+
});
|
|
133
|
+
if (tr.error) {
|
|
134
|
+
toolSpan?.error({ error: new Error(tr.error.message) });
|
|
135
|
+
} else {
|
|
136
|
+
toolSpan?.end({ output: tr.result });
|
|
137
|
+
}
|
|
138
|
+
if (!tr.error) {
|
|
139
|
+
stepSpan?.createEventSpan({
|
|
140
|
+
type: observability.SpanType.MODEL_CHUNK,
|
|
141
|
+
name: `chunk: 'tool-result'`,
|
|
142
|
+
output: {
|
|
143
|
+
toolCallId: tr.toolCallId,
|
|
144
|
+
toolName: tr.toolName,
|
|
145
|
+
result: tr.result
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
const toolCalls = llmOutput?.toolCalls ?? [];
|
|
151
|
+
if (stepSpan) {
|
|
152
|
+
const stepFinishPayload = llmOutput.stepFinishPayload;
|
|
153
|
+
stepSpan.end({
|
|
154
|
+
output: {
|
|
155
|
+
toolCalls: toolCalls.map((tc) => ({
|
|
156
|
+
toolCallId: tc.toolCallId,
|
|
157
|
+
toolName: tc.toolName,
|
|
158
|
+
args: tc.args
|
|
159
|
+
})),
|
|
160
|
+
toolResults: toolResults.map((tr) => ({
|
|
161
|
+
toolCallId: tr.toolCallId,
|
|
162
|
+
toolName: tr.toolName,
|
|
163
|
+
result: tr.result,
|
|
164
|
+
error: tr.error
|
|
165
|
+
}))
|
|
166
|
+
},
|
|
167
|
+
attributes: {
|
|
168
|
+
usage: stepFinishPayload?.output?.usage,
|
|
169
|
+
finishReason: stepFinishPayload?.stepResult?.reason,
|
|
170
|
+
isContinued: stepFinishPayload?.stepResult?.isContinued
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
llmOutput,
|
|
176
|
+
toolResults,
|
|
177
|
+
runId: initData.runId,
|
|
178
|
+
agentId: initData.agentId,
|
|
179
|
+
messageId: initData.messageId,
|
|
180
|
+
state: llmOutput?.state ?? initData.state
|
|
181
|
+
};
|
|
182
|
+
},
|
|
183
|
+
{ id: "collect-tool-results" }
|
|
184
|
+
).then(llmMappingStep).then(backgroundTaskCheckStep).map(
|
|
185
|
+
async ({ inputData, getInitData }) => {
|
|
186
|
+
const executionOutput = inputData;
|
|
187
|
+
const initData = getInitData();
|
|
188
|
+
const baseUpdate = durable.createBaseIterationStateUpdate({
|
|
189
|
+
currentState: initData,
|
|
190
|
+
executionOutput
|
|
191
|
+
});
|
|
192
|
+
const newIterationState = {
|
|
193
|
+
...baseUpdate,
|
|
194
|
+
// Preserve agent span data for observability
|
|
195
|
+
agentSpanData: initData.agentSpanData,
|
|
196
|
+
// Preserve model span data (ONE span for entire agent run)
|
|
197
|
+
modelSpanData: initData.modelSpanData,
|
|
198
|
+
// Increment step index for next iteration (step: 0 → 1 → 2 → ...)
|
|
199
|
+
stepIndex: initData.stepIndex + 1
|
|
200
|
+
};
|
|
201
|
+
return newIterationState;
|
|
202
|
+
},
|
|
203
|
+
{ id: "update-iteration-state" }
|
|
204
|
+
).commit();
|
|
205
|
+
return createWorkflow({
|
|
206
|
+
id: InngestDurableStepIds.AGENTIC_LOOP,
|
|
207
|
+
inputSchema: durableAgenticInputSchema,
|
|
208
|
+
outputSchema: durable.durableAgenticOutputSchema,
|
|
209
|
+
options: {
|
|
210
|
+
tracingPolicy: {
|
|
211
|
+
// Mark all workflow spans as internal so they're hidden in traces
|
|
212
|
+
// This makes the trace structure match regular agents (agent_run -> model_generation -> tool_call)
|
|
213
|
+
internal: observability.InternalSpans.WORKFLOW
|
|
214
|
+
},
|
|
215
|
+
shouldPersistSnapshot: ({ workflowStatus }) => workflowStatus === "suspended",
|
|
216
|
+
validateInputs: false
|
|
217
|
+
},
|
|
218
|
+
steps: []
|
|
219
|
+
}).map(
|
|
220
|
+
async ({ inputData }) => {
|
|
221
|
+
const input = inputData;
|
|
222
|
+
const agentSpanData = input.agentSpanData;
|
|
223
|
+
const modelSpanData = input.modelSpanData;
|
|
224
|
+
const iterationState = {
|
|
225
|
+
...input,
|
|
226
|
+
iterationCount: 0,
|
|
227
|
+
accumulatedSteps: [],
|
|
228
|
+
accumulatedUsage: {
|
|
229
|
+
inputTokens: 0,
|
|
230
|
+
outputTokens: 0,
|
|
231
|
+
totalTokens: 0
|
|
232
|
+
},
|
|
233
|
+
lastStepResult: void 0,
|
|
234
|
+
agentSpanData,
|
|
235
|
+
modelSpanData,
|
|
236
|
+
stepIndex: input.stepIndex ?? 0
|
|
237
|
+
};
|
|
238
|
+
return iterationState;
|
|
239
|
+
},
|
|
240
|
+
{ id: "init-iteration-state" }
|
|
241
|
+
).dowhile(singleIterationWorkflow, async ({ inputData }) => {
|
|
242
|
+
const state = inputData;
|
|
243
|
+
const shouldContinue = state.lastStepResult?.isContinued === true;
|
|
244
|
+
const effectiveMaxSteps = state.options?.maxSteps ?? maxSteps;
|
|
245
|
+
const underMaxSteps = state.iterationCount < effectiveMaxSteps;
|
|
246
|
+
return shouldContinue && underMaxSteps;
|
|
247
|
+
}).map(
|
|
248
|
+
async (params) => {
|
|
249
|
+
const { inputData, mastra } = params;
|
|
250
|
+
const state = inputData;
|
|
251
|
+
const pubsub = params[_constants.PUBSUB_SYMBOL];
|
|
252
|
+
const lastStep = state.accumulatedSteps[state.accumulatedSteps.length - 1];
|
|
253
|
+
const finalText = lastStep?.text;
|
|
254
|
+
const finalOutput = {
|
|
255
|
+
messageListState: state.messageListState,
|
|
256
|
+
messageId: state.messageId,
|
|
257
|
+
stepResult: state.lastStepResult || {
|
|
258
|
+
reason: "stop",
|
|
259
|
+
warnings: [],
|
|
260
|
+
isContinued: false
|
|
261
|
+
},
|
|
262
|
+
output: {
|
|
263
|
+
text: finalText,
|
|
264
|
+
usage: state.accumulatedUsage,
|
|
265
|
+
steps: state.accumulatedSteps
|
|
266
|
+
},
|
|
267
|
+
state: state.state
|
|
268
|
+
};
|
|
269
|
+
const observability = mastra?.observability?.getSelectedInstance({});
|
|
270
|
+
if (state.modelSpanData) {
|
|
271
|
+
const modelSpan = observability?.rebuildSpan(state.modelSpanData);
|
|
272
|
+
modelSpan?.end({
|
|
273
|
+
output: {
|
|
274
|
+
text: finalText,
|
|
275
|
+
usage: state.accumulatedUsage
|
|
276
|
+
},
|
|
277
|
+
attributes: {
|
|
278
|
+
finishReason: state.lastStepResult?.reason || "stop"
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
if (state.agentSpanData) {
|
|
283
|
+
const agentSpan = observability?.rebuildSpan(state.agentSpanData);
|
|
284
|
+
agentSpan?.end({
|
|
285
|
+
output: finalOutput.output
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
if (pubsub) {
|
|
289
|
+
await durable.emitFinishEvent(pubsub, state.runId, {
|
|
290
|
+
output: finalOutput.output,
|
|
291
|
+
stepResult: finalOutput.stepResult
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
return finalOutput;
|
|
295
|
+
},
|
|
296
|
+
{ id: "map-final-output" }
|
|
297
|
+
).commit();
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
// src/durable-agent/create-inngest-agent.ts
|
|
301
|
+
var CLOSE_ON_SUSPEND = /* @__PURE__ */ Symbol("mastra.durable.inngest.closeOnSuspend");
|
|
302
|
+
var STREAM_CLEANUP = /* @__PURE__ */ Symbol("mastra.durable.inngest.streamCleanup");
|
|
303
|
+
function createInngestAgent(options) {
|
|
304
|
+
const {
|
|
305
|
+
agent,
|
|
306
|
+
inngest,
|
|
307
|
+
id: idOverride,
|
|
308
|
+
name: nameOverride,
|
|
309
|
+
pubsub: customPubsub,
|
|
310
|
+
cache: cache$1,
|
|
311
|
+
mastra: mastraOption
|
|
312
|
+
} = options;
|
|
313
|
+
const agentId = idOverride ?? agent.id;
|
|
314
|
+
const agentName = nameOverride ?? agent.name;
|
|
315
|
+
let mastra = mastraOption;
|
|
316
|
+
const activeStreamUntilIdle = /* @__PURE__ */ new Map();
|
|
317
|
+
let proxyRef;
|
|
318
|
+
const workflow = createInngestDurableAgenticWorkflow({ inngest });
|
|
319
|
+
let _customCache = cache$1;
|
|
320
|
+
let innerPubsub = customPubsub ?? new chunkMICZJLEE_cjs.InngestPubSub(inngest, InngestDurableStepIds.AGENTIC_LOOP);
|
|
321
|
+
let _cachingPubsub = null;
|
|
322
|
+
function resolveCache() {
|
|
323
|
+
const resolved = _customCache ?? mastra?.serverCache ?? new cache.InMemoryServerCache();
|
|
324
|
+
_customCache = resolved;
|
|
325
|
+
return resolved;
|
|
326
|
+
}
|
|
327
|
+
function getPubsub() {
|
|
328
|
+
if (!_cachingPubsub) {
|
|
329
|
+
if (innerPubsub instanceof events.CachingPubSub) {
|
|
330
|
+
_cachingPubsub = innerPubsub;
|
|
331
|
+
_customCache = _customCache ?? mastra?.serverCache;
|
|
332
|
+
} else {
|
|
333
|
+
_cachingPubsub = new events.CachingPubSub(innerPubsub, resolveCache());
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
return _cachingPubsub;
|
|
337
|
+
}
|
|
338
|
+
workflow.__setPubsubFactory((defaultPubsub) => {
|
|
339
|
+
if (defaultPubsub instanceof events.CachingPubSub) return defaultPubsub;
|
|
340
|
+
getPubsub();
|
|
341
|
+
return new events.CachingPubSub(defaultPubsub, resolveCache());
|
|
342
|
+
});
|
|
343
|
+
function getCache() {
|
|
344
|
+
getPubsub();
|
|
345
|
+
return _customCache;
|
|
346
|
+
}
|
|
347
|
+
async function triggerWorkflow(runId, workflowInput, tracingOptions) {
|
|
348
|
+
const eventName = `workflow.${InngestDurableStepIds.AGENTIC_LOOP}`;
|
|
349
|
+
await inngest.send({
|
|
350
|
+
name: eventName,
|
|
351
|
+
data: {
|
|
352
|
+
inputData: workflowInput,
|
|
353
|
+
runId,
|
|
354
|
+
resourceId: workflowInput.state?.resourceId,
|
|
355
|
+
requestContext: workflowInput.requestContextEntries ?? {},
|
|
356
|
+
tracingOptions
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
async function emitError(runId, error) {
|
|
361
|
+
await durable.emitErrorEvent(getPubsub(), runId, error);
|
|
362
|
+
}
|
|
363
|
+
const inngestAgent = {
|
|
364
|
+
get id() {
|
|
365
|
+
return agentId;
|
|
366
|
+
},
|
|
367
|
+
get name() {
|
|
368
|
+
return agentName;
|
|
369
|
+
},
|
|
370
|
+
get agent() {
|
|
371
|
+
return agent;
|
|
372
|
+
},
|
|
373
|
+
get inngest() {
|
|
374
|
+
return inngest;
|
|
375
|
+
},
|
|
376
|
+
get cache() {
|
|
377
|
+
return getCache();
|
|
378
|
+
},
|
|
379
|
+
get pubsub() {
|
|
380
|
+
return getPubsub();
|
|
381
|
+
},
|
|
382
|
+
async stream(messages, streamOptions) {
|
|
383
|
+
if (streamOptions?.untilIdle) {
|
|
384
|
+
const { untilIdle, ...rest } = streamOptions;
|
|
385
|
+
const maxIdleMs = typeof untilIdle === "object" ? untilIdle.maxIdleMs : void 0;
|
|
386
|
+
return durable.runDurableStreamUntilIdle(proxyRef, messages, { ...rest, maxIdleMs }, {
|
|
387
|
+
activeStreams: activeStreamUntilIdle,
|
|
388
|
+
bgManager: mastra?.backgroundTaskManager
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
const preparation = await durable.prepareForDurableExecution({
|
|
392
|
+
agent,
|
|
393
|
+
messages,
|
|
394
|
+
options: streamOptions,
|
|
395
|
+
runId: streamOptions?.runId,
|
|
396
|
+
requestContext: streamOptions?.requestContext,
|
|
397
|
+
methodType: streamOptions?.__methodType ?? "stream"
|
|
398
|
+
});
|
|
399
|
+
const { runId, messageId, workflowInput, registryEntry, threadId, resourceId } = preparation;
|
|
400
|
+
workflowInput.agentId = agentId;
|
|
401
|
+
workflowInput.agentName = agentName;
|
|
402
|
+
const abortController = new AbortController();
|
|
403
|
+
if (streamOptions?.abortSignal) {
|
|
404
|
+
const external = streamOptions.abortSignal;
|
|
405
|
+
if (external.aborted) {
|
|
406
|
+
abortController.abort(external.reason);
|
|
407
|
+
} else {
|
|
408
|
+
external.addEventListener(
|
|
409
|
+
"abort",
|
|
410
|
+
() => abortController.abort(external.reason),
|
|
411
|
+
{ once: true }
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
registryEntry.abortController = abortController;
|
|
416
|
+
registryEntry.abortSignal = abortController.signal;
|
|
417
|
+
durable.globalRunRegistry.set(runId, registryEntry);
|
|
418
|
+
const observability$1 = mastra?.observability?.getSelectedInstance({
|
|
419
|
+
requestContext: streamOptions?.requestContext
|
|
420
|
+
});
|
|
421
|
+
const agentSpan = observability$1?.startSpan({
|
|
422
|
+
type: observability.SpanType.AGENT_RUN,
|
|
423
|
+
name: `agent run: '${agentId}'`,
|
|
424
|
+
entityType: observability.EntityType.AGENT,
|
|
425
|
+
entityId: agentId,
|
|
426
|
+
entityName: agentName,
|
|
427
|
+
input: workflowInput.messageListState,
|
|
428
|
+
metadata: {
|
|
429
|
+
runId,
|
|
430
|
+
threadId,
|
|
431
|
+
resourceId
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
const agentSpanData = agentSpan?.exportSpan();
|
|
435
|
+
const modelSpan = agentSpan?.createChildSpan({
|
|
436
|
+
type: observability.SpanType.MODEL_GENERATION,
|
|
437
|
+
name: `llm: '${workflowInput.modelConfig.modelId}'`,
|
|
438
|
+
input: { messages: workflowInput.messageListState },
|
|
439
|
+
attributes: {
|
|
440
|
+
model: workflowInput.modelConfig.modelId,
|
|
441
|
+
provider: workflowInput.modelConfig.provider,
|
|
442
|
+
streaming: true,
|
|
443
|
+
parameters: {
|
|
444
|
+
temperature: workflowInput.options?.modelSettings?.temperature
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
});
|
|
448
|
+
const modelSpanData = modelSpan?.exportSpan();
|
|
449
|
+
workflowInput.agentSpanData = agentSpanData;
|
|
450
|
+
workflowInput.modelSpanData = modelSpanData;
|
|
451
|
+
workflowInput.stepIndex = 0;
|
|
452
|
+
let cleanedUp = false;
|
|
453
|
+
const finalizeGlobalRegistry = () => {
|
|
454
|
+
if (cleanedUp) return;
|
|
455
|
+
cleanedUp = true;
|
|
456
|
+
durable.globalRunRegistry.delete(runId);
|
|
457
|
+
};
|
|
458
|
+
const {
|
|
459
|
+
output,
|
|
460
|
+
cleanup: streamCleanup,
|
|
461
|
+
ready
|
|
462
|
+
} = durable.createDurableAgentStream({
|
|
463
|
+
pubsub: getPubsub(),
|
|
464
|
+
runId,
|
|
465
|
+
messageId,
|
|
466
|
+
model: {
|
|
467
|
+
modelId: workflowInput.modelConfig.modelId,
|
|
468
|
+
provider: workflowInput.modelConfig.provider,
|
|
469
|
+
version: "v3"
|
|
470
|
+
},
|
|
471
|
+
threadId,
|
|
472
|
+
resourceId,
|
|
473
|
+
onChunk: streamOptions?.onChunk,
|
|
474
|
+
onStepFinish: streamOptions?.onStepFinish,
|
|
475
|
+
onFinish: async (result3) => {
|
|
476
|
+
try {
|
|
477
|
+
await streamOptions?.onFinish?.(result3);
|
|
478
|
+
} finally {
|
|
479
|
+
finalizeGlobalRegistry();
|
|
480
|
+
}
|
|
481
|
+
},
|
|
482
|
+
onError: async (errorArg) => {
|
|
483
|
+
try {
|
|
484
|
+
await streamOptions?.onError?.(errorArg);
|
|
485
|
+
} finally {
|
|
486
|
+
finalizeGlobalRegistry();
|
|
487
|
+
}
|
|
488
|
+
},
|
|
489
|
+
onSuspended: streamOptions?.onSuspended,
|
|
490
|
+
onAbort: async (data) => {
|
|
491
|
+
try {
|
|
492
|
+
await streamOptions?.onAbort?.(data);
|
|
493
|
+
} finally {
|
|
494
|
+
finalizeGlobalRegistry();
|
|
495
|
+
}
|
|
496
|
+
},
|
|
497
|
+
onIterationComplete: streamOptions?.onIterationComplete ? async (data) => {
|
|
498
|
+
await streamOptions.onIterationComplete?.(data);
|
|
499
|
+
} : void 0,
|
|
500
|
+
closeOnSuspend: streamOptions?.[CLOSE_ON_SUSPEND] === true
|
|
501
|
+
});
|
|
502
|
+
const tracingOptions = agentSpanData ? { traceId: agentSpanData.traceId, parentSpanId: agentSpanData.id } : void 0;
|
|
503
|
+
const workflowExecution = ready.then(() => triggerWorkflow(runId, workflowInput, tracingOptions)).catch((error) => {
|
|
504
|
+
void emitError(runId, error);
|
|
505
|
+
});
|
|
506
|
+
const trackedEntry = durable.globalRunRegistry.get(runId);
|
|
507
|
+
if (trackedEntry) {
|
|
508
|
+
trackedEntry.workflowExecution = workflowExecution;
|
|
509
|
+
}
|
|
510
|
+
const cleanup = () => {
|
|
511
|
+
streamCleanup();
|
|
512
|
+
finalizeGlobalRegistry();
|
|
513
|
+
};
|
|
514
|
+
const abort = (reason) => {
|
|
515
|
+
if (!abortController.signal.aborted) {
|
|
516
|
+
abortController.abort(reason);
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
const result2 = {
|
|
520
|
+
output,
|
|
521
|
+
runId,
|
|
522
|
+
threadId,
|
|
523
|
+
resourceId,
|
|
524
|
+
cleanup,
|
|
525
|
+
abort,
|
|
526
|
+
// Also expose fullStream directly for server compatibility
|
|
527
|
+
get fullStream() {
|
|
528
|
+
return output.fullStream;
|
|
529
|
+
},
|
|
530
|
+
// Internal: stream-only cleanup for generate()/resumeGenerate() to
|
|
531
|
+
// release the subscription on suspend without dropping the registry.
|
|
532
|
+
[STREAM_CLEANUP]: streamCleanup
|
|
533
|
+
};
|
|
534
|
+
return result2;
|
|
535
|
+
},
|
|
536
|
+
async resume(runId, resumeData, resumeOptions) {
|
|
537
|
+
if (resumeOptions?.untilIdle) {
|
|
538
|
+
const { untilIdle, ...rest } = resumeOptions;
|
|
539
|
+
const maxIdleMs = typeof untilIdle === "object" ? untilIdle.maxIdleMs : void 0;
|
|
540
|
+
return durable.runResumeDurableStreamUntilIdle(
|
|
541
|
+
proxyRef,
|
|
542
|
+
runId,
|
|
543
|
+
resumeData,
|
|
544
|
+
{ ...rest, maxIdleMs },
|
|
545
|
+
{
|
|
546
|
+
activeStreams: activeStreamUntilIdle,
|
|
547
|
+
bgManager: mastra?.backgroundTaskManager
|
|
548
|
+
}
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
const abortController = new AbortController();
|
|
552
|
+
if (resumeOptions?.abortSignal) {
|
|
553
|
+
const external = resumeOptions.abortSignal;
|
|
554
|
+
if (external.aborted) {
|
|
555
|
+
abortController.abort(external.reason);
|
|
556
|
+
} else {
|
|
557
|
+
external.addEventListener(
|
|
558
|
+
"abort",
|
|
559
|
+
() => abortController.abort(external.reason),
|
|
560
|
+
{ once: true }
|
|
561
|
+
);
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
let existingEntry = durable.globalRunRegistry.get(runId);
|
|
565
|
+
if (!existingEntry) {
|
|
566
|
+
existingEntry = {
|
|
567
|
+
// Minimal placeholder fields. The durable LLM step recreates tools
|
|
568
|
+
// and model from the workflow input; this slot exists primarily to
|
|
569
|
+
// carry the abort controller across the resumed segment.
|
|
570
|
+
tools: {},
|
|
571
|
+
model: void 0
|
|
572
|
+
};
|
|
573
|
+
durable.globalRunRegistry.set(runId, existingEntry);
|
|
574
|
+
}
|
|
575
|
+
existingEntry.abortController = abortController;
|
|
576
|
+
existingEntry.abortSignal = abortController.signal;
|
|
577
|
+
let resumeCleanedUp = false;
|
|
578
|
+
const finalizeResumeRegistry = () => {
|
|
579
|
+
if (resumeCleanedUp) return;
|
|
580
|
+
resumeCleanedUp = true;
|
|
581
|
+
durable.globalRunRegistry.delete(runId);
|
|
582
|
+
};
|
|
583
|
+
const {
|
|
584
|
+
output,
|
|
585
|
+
cleanup: streamCleanup,
|
|
586
|
+
ready
|
|
587
|
+
} = durable.createDurableAgentStream({
|
|
588
|
+
pubsub: getPubsub(),
|
|
589
|
+
runId,
|
|
590
|
+
messageId: crypto.randomUUID(),
|
|
591
|
+
model: {
|
|
592
|
+
modelId: void 0,
|
|
593
|
+
provider: void 0,
|
|
594
|
+
version: "v3"
|
|
595
|
+
},
|
|
596
|
+
threadId: resumeOptions?.threadId,
|
|
597
|
+
resourceId: resumeOptions?.resourceId,
|
|
598
|
+
onChunk: resumeOptions?.onChunk,
|
|
599
|
+
onStepFinish: resumeOptions?.onStepFinish,
|
|
600
|
+
onFinish: async (result2) => {
|
|
601
|
+
try {
|
|
602
|
+
await resumeOptions?.onFinish?.(result2);
|
|
603
|
+
} finally {
|
|
604
|
+
finalizeResumeRegistry();
|
|
605
|
+
}
|
|
606
|
+
},
|
|
607
|
+
onError: async (errorArg) => {
|
|
608
|
+
try {
|
|
609
|
+
await resumeOptions?.onError?.(errorArg);
|
|
610
|
+
} finally {
|
|
611
|
+
finalizeResumeRegistry();
|
|
612
|
+
}
|
|
613
|
+
},
|
|
614
|
+
onSuspended: resumeOptions?.onSuspended,
|
|
615
|
+
onAbort: async (data) => {
|
|
616
|
+
try {
|
|
617
|
+
await resumeOptions?.onAbort?.(data);
|
|
618
|
+
} finally {
|
|
619
|
+
finalizeResumeRegistry();
|
|
620
|
+
}
|
|
621
|
+
},
|
|
622
|
+
closeOnSuspend: resumeOptions?.[CLOSE_ON_SUSPEND] === true
|
|
623
|
+
});
|
|
624
|
+
const eventName = `workflow.${InngestDurableStepIds.AGENTIC_LOOP}`;
|
|
625
|
+
const workflowExecution = ready.then(async () => {
|
|
626
|
+
const workflowsStore = await mastra?.getStorage()?.getStore("workflows");
|
|
627
|
+
const snapshot = await workflowsStore?.loadWorkflowSnapshot({
|
|
628
|
+
workflowName: InngestDurableStepIds.AGENTIC_LOOP,
|
|
629
|
+
runId
|
|
630
|
+
});
|
|
631
|
+
const suspendedStepIds = snapshot?.suspendedPaths ? Object.keys(snapshot.suspendedPaths) : [];
|
|
632
|
+
const steps = suspendedStepIds.length > 0 ? suspendedStepIds : [];
|
|
633
|
+
await inngest.send({
|
|
634
|
+
name: eventName,
|
|
635
|
+
data: {
|
|
636
|
+
inputData: resumeData,
|
|
637
|
+
initialState: snapshot?.value ?? {},
|
|
638
|
+
runId,
|
|
639
|
+
resourceId: resumeOptions?.resourceId,
|
|
640
|
+
requestContext: snapshot?.requestContext ?? {},
|
|
641
|
+
stepResults: snapshot?.context,
|
|
642
|
+
resume: {
|
|
643
|
+
steps,
|
|
644
|
+
stepResults: snapshot?.context,
|
|
645
|
+
resumePayload: resumeData,
|
|
646
|
+
resumePath: steps[0] ? snapshot?.suspendedPaths?.[steps[0]] : void 0
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
});
|
|
650
|
+
}).catch((error) => {
|
|
651
|
+
void emitError(runId, error);
|
|
652
|
+
});
|
|
653
|
+
existingEntry.workflowExecution = workflowExecution;
|
|
654
|
+
const abort = (reason) => {
|
|
655
|
+
if (!abortController.signal.aborted) {
|
|
656
|
+
abortController.abort(reason);
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
const cleanup = () => {
|
|
660
|
+
streamCleanup();
|
|
661
|
+
finalizeResumeRegistry();
|
|
662
|
+
};
|
|
663
|
+
return {
|
|
664
|
+
output,
|
|
665
|
+
get fullStream() {
|
|
666
|
+
return output.fullStream;
|
|
667
|
+
},
|
|
668
|
+
runId,
|
|
669
|
+
threadId: resumeOptions?.threadId,
|
|
670
|
+
resourceId: resumeOptions?.resourceId,
|
|
671
|
+
cleanup,
|
|
672
|
+
abort,
|
|
673
|
+
// Internal: stream-only cleanup for resumeGenerate() to release the
|
|
674
|
+
// subscription on suspend without dropping the resumed registry entry.
|
|
675
|
+
[STREAM_CLEANUP]: streamCleanup
|
|
676
|
+
};
|
|
677
|
+
},
|
|
678
|
+
async prepare(messages, prepareOptions) {
|
|
679
|
+
const preparation = await durable.prepareForDurableExecution({
|
|
680
|
+
agent,
|
|
681
|
+
messages,
|
|
682
|
+
options: prepareOptions,
|
|
683
|
+
requestContext: prepareOptions?.requestContext
|
|
684
|
+
});
|
|
685
|
+
preparation.workflowInput.agentId = agentId;
|
|
686
|
+
preparation.workflowInput.agentName = agentName;
|
|
687
|
+
return {
|
|
688
|
+
runId: preparation.runId,
|
|
689
|
+
messageId: preparation.messageId,
|
|
690
|
+
workflowInput: preparation.workflowInput,
|
|
691
|
+
threadId: preparation.threadId,
|
|
692
|
+
resourceId: preparation.resourceId
|
|
693
|
+
};
|
|
694
|
+
},
|
|
695
|
+
async observe(runId, observeOptions) {
|
|
696
|
+
const {
|
|
697
|
+
output,
|
|
698
|
+
cleanup: streamCleanup,
|
|
699
|
+
ready
|
|
700
|
+
} = durable.createDurableAgentStream({
|
|
701
|
+
pubsub: getPubsub(),
|
|
702
|
+
runId,
|
|
703
|
+
messageId: crypto.randomUUID(),
|
|
704
|
+
model: {
|
|
705
|
+
modelId: void 0,
|
|
706
|
+
provider: void 0,
|
|
707
|
+
version: "v3"
|
|
708
|
+
},
|
|
709
|
+
offset: observeOptions?.offset,
|
|
710
|
+
onChunk: observeOptions?.onChunk,
|
|
711
|
+
onStepFinish: observeOptions?.onStepFinish,
|
|
712
|
+
onFinish: observeOptions?.onFinish,
|
|
713
|
+
onError: observeOptions?.onError,
|
|
714
|
+
onSuspended: observeOptions?.onSuspended
|
|
715
|
+
});
|
|
716
|
+
await ready;
|
|
717
|
+
const abort = (_reason) => {
|
|
718
|
+
streamCleanup();
|
|
719
|
+
};
|
|
720
|
+
return {
|
|
721
|
+
output,
|
|
722
|
+
get fullStream() {
|
|
723
|
+
return output.fullStream;
|
|
724
|
+
},
|
|
725
|
+
runId,
|
|
726
|
+
cleanup: streamCleanup,
|
|
727
|
+
abort
|
|
728
|
+
};
|
|
729
|
+
},
|
|
730
|
+
async generate(messages, generateOptions) {
|
|
731
|
+
const { untilIdle, ...rest } = generateOptions ?? {};
|
|
732
|
+
const streamOpts = {
|
|
733
|
+
...rest,
|
|
734
|
+
[CLOSE_ON_SUSPEND]: true,
|
|
735
|
+
__methodType: "generate"
|
|
736
|
+
};
|
|
737
|
+
const result2 = await proxyRef.stream(messages, streamOpts);
|
|
738
|
+
let suspended = false;
|
|
739
|
+
try {
|
|
740
|
+
const fullOutput = await result2.output.getFullOutput();
|
|
741
|
+
if (fullOutput.error) {
|
|
742
|
+
throw fullOutput.error;
|
|
743
|
+
}
|
|
744
|
+
suspended = fullOutput.finishReason === "suspended";
|
|
745
|
+
if (suspended) {
|
|
746
|
+
await durable.globalRunRegistry.get(result2.runId)?.workflowExecution;
|
|
747
|
+
}
|
|
748
|
+
if (!fullOutput.runId) {
|
|
749
|
+
fullOutput.runId = result2.runId;
|
|
750
|
+
}
|
|
751
|
+
return fullOutput;
|
|
752
|
+
} finally {
|
|
753
|
+
if (suspended) {
|
|
754
|
+
const streamOnlyCleanup = result2[STREAM_CLEANUP];
|
|
755
|
+
streamOnlyCleanup?.();
|
|
756
|
+
} else {
|
|
757
|
+
result2.cleanup();
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
},
|
|
761
|
+
async resumeGenerate(runId, resumeData, resumeOptions) {
|
|
762
|
+
const { untilIdle, ...rest } = resumeOptions ?? {};
|
|
763
|
+
const result2 = await proxyRef.resume(runId, resumeData, {
|
|
764
|
+
...rest,
|
|
765
|
+
[CLOSE_ON_SUSPEND]: true
|
|
766
|
+
});
|
|
767
|
+
let suspended = false;
|
|
768
|
+
try {
|
|
769
|
+
const fullOutput = await result2.output.getFullOutput();
|
|
770
|
+
if (fullOutput.error) {
|
|
771
|
+
throw fullOutput.error;
|
|
772
|
+
}
|
|
773
|
+
suspended = fullOutput.finishReason === "suspended";
|
|
774
|
+
if (suspended) {
|
|
775
|
+
await durable.globalRunRegistry.get(result2.runId)?.workflowExecution;
|
|
776
|
+
}
|
|
777
|
+
if (!fullOutput.runId) {
|
|
778
|
+
fullOutput.runId = result2.runId;
|
|
779
|
+
}
|
|
780
|
+
return fullOutput;
|
|
781
|
+
} finally {
|
|
782
|
+
if (suspended) {
|
|
783
|
+
const streamOnlyCleanup = result2[STREAM_CLEANUP];
|
|
784
|
+
streamOnlyCleanup?.();
|
|
785
|
+
} else {
|
|
786
|
+
result2.cleanup();
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
},
|
|
790
|
+
getDurableWorkflows() {
|
|
791
|
+
return [workflow];
|
|
792
|
+
},
|
|
793
|
+
__setMastra(mastraInstance) {
|
|
794
|
+
mastra = mastraInstance;
|
|
795
|
+
}
|
|
796
|
+
};
|
|
797
|
+
const result = new Proxy(inngestAgent, {
|
|
798
|
+
get(target, prop, receiver) {
|
|
799
|
+
if (prop in target) {
|
|
800
|
+
return Reflect.get(target, prop, receiver);
|
|
801
|
+
}
|
|
802
|
+
const agentValue = agent[prop];
|
|
803
|
+
if (typeof agentValue === "function") {
|
|
804
|
+
return agentValue.bind(agent);
|
|
805
|
+
}
|
|
806
|
+
return agentValue;
|
|
807
|
+
},
|
|
808
|
+
has(target, prop) {
|
|
809
|
+
return prop in target || prop in agent;
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
proxyRef = result;
|
|
813
|
+
return result;
|
|
814
|
+
}
|
|
815
|
+
function isInngestAgent(obj) {
|
|
816
|
+
if (!obj) return false;
|
|
817
|
+
return typeof obj.id === "string" && typeof obj.name === "string" && "agent" in obj && "inngest" in obj && typeof obj.stream === "function" && typeof obj.getDurableWorkflows === "function";
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// src/index.ts
|
|
821
|
+
function isInngestWorkflow(input) {
|
|
822
|
+
return input instanceof chunkMICZJLEE_cjs.InngestWorkflow;
|
|
823
|
+
}
|
|
824
|
+
function isAgentCompatible(input) {
|
|
825
|
+
return typeof input === "object" && input !== null && "generate" in input && typeof input.generate === "function" && "stream" in input && typeof input.stream === "function" && "getDescription" in input && typeof input.getDescription === "function" && "getModel" in input && typeof input.getModel === "function";
|
|
826
|
+
}
|
|
827
|
+
function isToolStep(input) {
|
|
828
|
+
return input instanceof tools.Tool;
|
|
829
|
+
}
|
|
830
|
+
function isStepParams(input) {
|
|
831
|
+
return input !== null && typeof input === "object" && "id" in input && "execute" in input && !(input instanceof agent.Agent) && !(input instanceof tools.Tool) && !(input instanceof chunkMICZJLEE_cjs.InngestWorkflow);
|
|
832
|
+
}
|
|
833
|
+
function isProcessor(obj) {
|
|
834
|
+
return obj !== null && typeof obj === "object" && "id" in obj && typeof obj.id === "string" && !(obj instanceof agent.Agent) && !(obj instanceof tools.Tool) && !(obj instanceof chunkMICZJLEE_cjs.InngestWorkflow) && (typeof obj.processInput === "function" || typeof obj.processInputStep === "function" || typeof obj.processOutputStream === "function" || typeof obj.processOutputResult === "function" || typeof obj.processOutputStep === "function");
|
|
835
|
+
}
|
|
836
|
+
function createStep(params, agentOrToolOptions) {
|
|
837
|
+
if (isInngestWorkflow(params)) {
|
|
838
|
+
return params;
|
|
839
|
+
}
|
|
840
|
+
if (isAgentCompatible(params)) {
|
|
841
|
+
return createStepFromAgent(params, agentOrToolOptions);
|
|
842
|
+
}
|
|
843
|
+
if (isToolStep(params)) {
|
|
844
|
+
return createStepFromTool(params, agentOrToolOptions);
|
|
845
|
+
}
|
|
846
|
+
if (isStepParams(params)) {
|
|
847
|
+
return createStepFromParams(params);
|
|
848
|
+
}
|
|
849
|
+
if (isProcessor(params)) {
|
|
850
|
+
return createStepFromProcessor(params);
|
|
851
|
+
}
|
|
852
|
+
throw new Error("Invalid input: expected StepParams, Agent, ToolStep, Processor, or InngestWorkflow");
|
|
853
|
+
}
|
|
854
|
+
function createStepFromParams(params) {
|
|
855
|
+
return {
|
|
856
|
+
id: params.id,
|
|
857
|
+
description: params.description,
|
|
858
|
+
inputSchema: schema.toStandardSchema(params.inputSchema),
|
|
859
|
+
stateSchema: params.stateSchema ? schema.toStandardSchema(params.stateSchema) : void 0,
|
|
860
|
+
outputSchema: schema.toStandardSchema(params.outputSchema),
|
|
861
|
+
resumeSchema: params.resumeSchema ? schema.toStandardSchema(params.resumeSchema) : void 0,
|
|
862
|
+
suspendSchema: params.suspendSchema ? schema.toStandardSchema(params.suspendSchema) : void 0,
|
|
863
|
+
scorers: params.scorers,
|
|
864
|
+
retries: params.retries,
|
|
865
|
+
metadata: params.metadata,
|
|
866
|
+
execute: params.execute.bind(params)
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
function createStepFromAgent(params, agentOrToolOptions) {
|
|
870
|
+
const options = agentOrToolOptions ?? {};
|
|
871
|
+
const outputSchema = options?.structuredOutput?.schema ?? zod.z.object({ text: zod.z.string() });
|
|
872
|
+
const { retries, scorers, metadata, ...agentOptions } = options ?? {};
|
|
873
|
+
return {
|
|
874
|
+
id: params.id,
|
|
875
|
+
description: params.getDescription(),
|
|
876
|
+
inputSchema: schema.toStandardSchema(
|
|
877
|
+
zod.z.object({
|
|
878
|
+
prompt: zod.z.string()
|
|
879
|
+
})
|
|
880
|
+
),
|
|
881
|
+
outputSchema: schema.toStandardSchema(outputSchema),
|
|
882
|
+
retries,
|
|
883
|
+
scorers,
|
|
884
|
+
metadata,
|
|
885
|
+
execute: async ({
|
|
886
|
+
inputData,
|
|
887
|
+
runId,
|
|
888
|
+
[_constants.PUBSUB_SYMBOL]: pubsub,
|
|
889
|
+
[_constants.STREAM_FORMAT_SYMBOL]: streamFormat,
|
|
890
|
+
requestContext,
|
|
891
|
+
tracingContext,
|
|
892
|
+
abortSignal,
|
|
893
|
+
abort,
|
|
894
|
+
writer
|
|
895
|
+
}) => {
|
|
896
|
+
let streamPromise = {};
|
|
897
|
+
streamPromise.promise = new Promise((resolve, reject) => {
|
|
898
|
+
streamPromise.resolve = resolve;
|
|
899
|
+
streamPromise.reject = reject;
|
|
900
|
+
});
|
|
901
|
+
let structuredResult = null;
|
|
902
|
+
const toolData = {
|
|
903
|
+
name: params.name ?? params.id,
|
|
904
|
+
args: inputData
|
|
905
|
+
};
|
|
906
|
+
let stream;
|
|
907
|
+
if ((await params.getModel()).specificationVersion === "v1") {
|
|
908
|
+
if (typeof params.streamLegacy !== "function") {
|
|
909
|
+
throw new Error(`Agent step ${params.id} returned a v1 model but does not implement streamLegacy`);
|
|
910
|
+
}
|
|
911
|
+
const modelOutput = await params.streamLegacy(inputData.prompt, {
|
|
912
|
+
...agentOptions ?? {},
|
|
913
|
+
requestContext,
|
|
914
|
+
tracingContext,
|
|
915
|
+
onFinish: (result) => {
|
|
916
|
+
const resultWithObject = result;
|
|
917
|
+
if (agentOptions?.structuredOutput?.schema && resultWithObject.object) {
|
|
918
|
+
structuredResult = resultWithObject.object;
|
|
919
|
+
}
|
|
920
|
+
streamPromise.resolve(result.text);
|
|
921
|
+
void agentOptions?.onFinish?.(result);
|
|
922
|
+
},
|
|
923
|
+
abortSignal
|
|
924
|
+
});
|
|
925
|
+
if ("text" in modelOutput) {
|
|
926
|
+
void modelOutput.text.then(streamPromise.resolve, streamPromise.reject);
|
|
927
|
+
}
|
|
928
|
+
stream = modelOutput.fullStream;
|
|
929
|
+
} else {
|
|
930
|
+
const { structuredOutput, ...restAgentOptions } = agentOptions ?? {};
|
|
931
|
+
const baseOptions = {
|
|
932
|
+
...restAgentOptions,
|
|
933
|
+
requestContext,
|
|
934
|
+
tracingContext,
|
|
935
|
+
onFinish: (result) => {
|
|
936
|
+
const resultWithObject = result;
|
|
937
|
+
if (structuredOutput?.schema && resultWithObject.object) {
|
|
938
|
+
structuredResult = resultWithObject.object;
|
|
939
|
+
}
|
|
940
|
+
streamPromise.resolve(result.text);
|
|
941
|
+
void agentOptions?.onFinish?.(result);
|
|
942
|
+
},
|
|
943
|
+
abortSignal
|
|
944
|
+
};
|
|
945
|
+
const modelOutput = structuredOutput ? await params.stream(inputData.prompt, {
|
|
946
|
+
...baseOptions,
|
|
947
|
+
structuredOutput
|
|
948
|
+
}) : await params.stream(inputData.prompt, baseOptions);
|
|
949
|
+
stream = modelOutput.fullStream;
|
|
950
|
+
void modelOutput.text.then(streamPromise.resolve, streamPromise.reject);
|
|
951
|
+
}
|
|
952
|
+
if (streamFormat === "legacy") {
|
|
953
|
+
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
954
|
+
type: "watch",
|
|
955
|
+
runId,
|
|
956
|
+
data: { type: "tool-call-streaming-start", ...toolData ?? {} }
|
|
957
|
+
});
|
|
958
|
+
for await (const chunk of stream) {
|
|
959
|
+
if (chunk.type === "text-delta") {
|
|
960
|
+
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
961
|
+
type: "watch",
|
|
962
|
+
runId,
|
|
963
|
+
data: { type: "tool-call-delta", ...toolData ?? {}, argsTextDelta: chunk.textDelta }
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
await pubsub.publish(`workflow.events.v2.${runId}`, {
|
|
968
|
+
type: "watch",
|
|
969
|
+
runId,
|
|
970
|
+
data: { type: "tool-call-streaming-finish", ...toolData ?? {} }
|
|
971
|
+
});
|
|
972
|
+
} else {
|
|
973
|
+
for await (const chunk of stream) {
|
|
974
|
+
await writer.write(chunk);
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
if (abortSignal.aborted) {
|
|
978
|
+
return abort();
|
|
979
|
+
}
|
|
980
|
+
if (structuredResult !== null) {
|
|
981
|
+
return structuredResult;
|
|
982
|
+
}
|
|
983
|
+
return {
|
|
984
|
+
text: await streamPromise.promise
|
|
985
|
+
};
|
|
986
|
+
},
|
|
987
|
+
component: "AGENT"
|
|
988
|
+
};
|
|
989
|
+
}
|
|
990
|
+
function createStepFromTool(params, agentOrToolOptions) {
|
|
991
|
+
const toolOpts = agentOrToolOptions;
|
|
992
|
+
if (!params.inputSchema || !params.outputSchema) {
|
|
993
|
+
throw new Error("Tool must have input and output schemas defined");
|
|
994
|
+
}
|
|
995
|
+
return {
|
|
996
|
+
id: params.id,
|
|
997
|
+
description: params.description,
|
|
998
|
+
inputSchema: params.inputSchema,
|
|
999
|
+
outputSchema: params.outputSchema,
|
|
1000
|
+
resumeSchema: params.resumeSchema,
|
|
1001
|
+
suspendSchema: params.suspendSchema,
|
|
1002
|
+
retries: toolOpts?.retries,
|
|
1003
|
+
scorers: toolOpts?.scorers,
|
|
1004
|
+
metadata: toolOpts?.metadata,
|
|
1005
|
+
execute: async ({
|
|
1006
|
+
inputData,
|
|
1007
|
+
mastra,
|
|
1008
|
+
requestContext,
|
|
1009
|
+
tracingContext,
|
|
1010
|
+
suspend,
|
|
1011
|
+
resumeData,
|
|
1012
|
+
runId,
|
|
1013
|
+
workflowId,
|
|
1014
|
+
state,
|
|
1015
|
+
setState
|
|
1016
|
+
}) => {
|
|
1017
|
+
const toolContext = {
|
|
1018
|
+
mastra,
|
|
1019
|
+
requestContext,
|
|
1020
|
+
tracingContext,
|
|
1021
|
+
workflow: {
|
|
1022
|
+
runId,
|
|
1023
|
+
resumeData,
|
|
1024
|
+
suspend,
|
|
1025
|
+
workflowId,
|
|
1026
|
+
state,
|
|
1027
|
+
setState
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
return params.execute(inputData, toolContext);
|
|
1031
|
+
},
|
|
1032
|
+
component: "TOOL"
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
function createStepFromProcessor(processor) {
|
|
1036
|
+
const getProcessorEntityType = (phase) => {
|
|
1037
|
+
switch (phase) {
|
|
1038
|
+
case "input":
|
|
1039
|
+
return observability.EntityType.INPUT_PROCESSOR;
|
|
1040
|
+
case "inputStep":
|
|
1041
|
+
return observability.EntityType.INPUT_STEP_PROCESSOR;
|
|
1042
|
+
case "outputStream":
|
|
1043
|
+
case "outputResult":
|
|
1044
|
+
return observability.EntityType.OUTPUT_PROCESSOR;
|
|
1045
|
+
case "outputStep":
|
|
1046
|
+
return observability.EntityType.OUTPUT_STEP_PROCESSOR;
|
|
1047
|
+
default:
|
|
1048
|
+
return observability.EntityType.OUTPUT_PROCESSOR;
|
|
1049
|
+
}
|
|
1050
|
+
};
|
|
1051
|
+
const getSpanNamePrefix = (phase) => {
|
|
1052
|
+
switch (phase) {
|
|
1053
|
+
case "input":
|
|
1054
|
+
return "input processor";
|
|
1055
|
+
case "inputStep":
|
|
1056
|
+
return "input step processor";
|
|
1057
|
+
case "outputStream":
|
|
1058
|
+
return "output stream processor";
|
|
1059
|
+
case "outputResult":
|
|
1060
|
+
return "output processor";
|
|
1061
|
+
case "outputStep":
|
|
1062
|
+
return "output step processor";
|
|
1063
|
+
default:
|
|
1064
|
+
return "processor";
|
|
1065
|
+
}
|
|
1066
|
+
};
|
|
1067
|
+
const hasPhaseMethod = (phase) => {
|
|
1068
|
+
switch (phase) {
|
|
1069
|
+
case "input":
|
|
1070
|
+
return !!processor.processInput;
|
|
1071
|
+
case "inputStep":
|
|
1072
|
+
return !!processor.processInputStep;
|
|
1073
|
+
case "outputStream":
|
|
1074
|
+
return !!processor.processOutputStream;
|
|
1075
|
+
case "outputResult":
|
|
1076
|
+
return !!processor.processOutputResult;
|
|
1077
|
+
case "outputStep":
|
|
1078
|
+
return !!processor.processOutputStep;
|
|
1079
|
+
default:
|
|
1080
|
+
return false;
|
|
1081
|
+
}
|
|
1082
|
+
};
|
|
1083
|
+
return {
|
|
1084
|
+
id: `processor:${processor.id}`,
|
|
1085
|
+
description: processor.name ?? `Processor ${processor.id}`,
|
|
1086
|
+
inputSchema: processors.ProcessorStepSchema,
|
|
1087
|
+
outputSchema: processors.ProcessorStepOutputSchema,
|
|
1088
|
+
execute: async ({ inputData, requestContext, tracingContext }) => {
|
|
1089
|
+
const input = inputData;
|
|
1090
|
+
const {
|
|
1091
|
+
phase,
|
|
1092
|
+
messages,
|
|
1093
|
+
messageList,
|
|
1094
|
+
stepNumber,
|
|
1095
|
+
systemMessages,
|
|
1096
|
+
part,
|
|
1097
|
+
streamParts,
|
|
1098
|
+
state,
|
|
1099
|
+
result,
|
|
1100
|
+
finishReason,
|
|
1101
|
+
toolCalls,
|
|
1102
|
+
text,
|
|
1103
|
+
retryCount,
|
|
1104
|
+
// inputStep phase fields for model/tools configuration
|
|
1105
|
+
model,
|
|
1106
|
+
tools,
|
|
1107
|
+
toolChoice,
|
|
1108
|
+
activeTools,
|
|
1109
|
+
providerOptions,
|
|
1110
|
+
modelSettings,
|
|
1111
|
+
structuredOutput,
|
|
1112
|
+
steps,
|
|
1113
|
+
usage
|
|
1114
|
+
} = input;
|
|
1115
|
+
const abort = (reason, options) => {
|
|
1116
|
+
throw new agent.TripWire(reason || `Tripwire triggered by ${processor.id}`, options, processor.id);
|
|
1117
|
+
};
|
|
1118
|
+
if (!hasPhaseMethod(phase)) {
|
|
1119
|
+
return input;
|
|
1120
|
+
}
|
|
1121
|
+
const currentSpan = tracingContext?.currentSpan;
|
|
1122
|
+
const parentSpan = phase === "inputStep" || phase === "outputStep" ? currentSpan?.findParent(observability.SpanType.MODEL_STEP) || currentSpan : currentSpan?.findParent(observability.SpanType.AGENT_RUN) || currentSpan;
|
|
1123
|
+
const processorSpan = phase !== "outputStream" ? parentSpan?.createChildSpan({
|
|
1124
|
+
type: observability.SpanType.PROCESSOR_RUN,
|
|
1125
|
+
name: `${getSpanNamePrefix(phase)}: ${processor.id}`,
|
|
1126
|
+
entityType: getProcessorEntityType(phase),
|
|
1127
|
+
entityId: processor.id,
|
|
1128
|
+
entityName: processor.name ?? processor.id,
|
|
1129
|
+
input: { phase, messageCount: messages?.length },
|
|
1130
|
+
attributes: {
|
|
1131
|
+
processorExecutor: "workflow",
|
|
1132
|
+
// Read processorIndex from processor (set in combineProcessorsIntoWorkflow)
|
|
1133
|
+
processorIndex: processor.processorIndex
|
|
1134
|
+
}
|
|
1135
|
+
}) : void 0;
|
|
1136
|
+
const processorTracingContext = processorSpan ? { currentSpan: processorSpan } : tracingContext;
|
|
1137
|
+
const baseContext = {
|
|
1138
|
+
abort,
|
|
1139
|
+
retryCount: retryCount ?? 0,
|
|
1140
|
+
requestContext,
|
|
1141
|
+
tracingContext: processorTracingContext
|
|
1142
|
+
};
|
|
1143
|
+
const passThrough = {
|
|
1144
|
+
phase,
|
|
1145
|
+
// Auto-create MessageList from messages if not provided
|
|
1146
|
+
// This enables running processor workflows from the UI where messageList can't be serialized
|
|
1147
|
+
messageList: messageList ?? (Array.isArray(messages) ? new agent.MessageList().add(messages, "input").addSystem(systemMessages ?? []) : void 0),
|
|
1148
|
+
stepNumber,
|
|
1149
|
+
systemMessages,
|
|
1150
|
+
streamParts,
|
|
1151
|
+
state,
|
|
1152
|
+
result,
|
|
1153
|
+
finishReason,
|
|
1154
|
+
toolCalls,
|
|
1155
|
+
text,
|
|
1156
|
+
retryCount,
|
|
1157
|
+
// inputStep phase fields for model/tools configuration
|
|
1158
|
+
model,
|
|
1159
|
+
tools,
|
|
1160
|
+
toolChoice,
|
|
1161
|
+
activeTools,
|
|
1162
|
+
providerOptions,
|
|
1163
|
+
modelSettings,
|
|
1164
|
+
structuredOutput,
|
|
1165
|
+
steps,
|
|
1166
|
+
usage
|
|
1167
|
+
};
|
|
1168
|
+
const executePhaseWithSpan = async (fn) => {
|
|
1169
|
+
try {
|
|
1170
|
+
const result2 = await fn();
|
|
1171
|
+
processorSpan?.end({ output: result2 });
|
|
1172
|
+
return result2;
|
|
1173
|
+
} catch (error) {
|
|
1174
|
+
if (error instanceof agent.TripWire) {
|
|
1175
|
+
processorSpan?.end({ output: { tripwire: error.message } });
|
|
1176
|
+
} else {
|
|
1177
|
+
processorSpan?.error({ error, endSpan: true });
|
|
1178
|
+
}
|
|
1179
|
+
throw error;
|
|
1180
|
+
}
|
|
1181
|
+
};
|
|
1182
|
+
return executePhaseWithSpan(async () => {
|
|
1183
|
+
switch (phase) {
|
|
1184
|
+
case "input": {
|
|
1185
|
+
if (processor.processInput) {
|
|
1186
|
+
if (!passThrough.messageList) {
|
|
1187
|
+
throw new error.MastraError({
|
|
1188
|
+
category: error.ErrorCategory.USER,
|
|
1189
|
+
domain: error.ErrorDomain.MASTRA_WORKFLOW,
|
|
1190
|
+
id: "PROCESSOR_MISSING_MESSAGE_LIST",
|
|
1191
|
+
text: `Processor ${processor.id} requires messageList or messages for processInput phase`
|
|
1192
|
+
});
|
|
1193
|
+
}
|
|
1194
|
+
const idsBeforeProcessing = messages.map((m) => m.id);
|
|
1195
|
+
const check = passThrough.messageList.makeMessageSourceChecker();
|
|
1196
|
+
const result2 = await processor.processInput({
|
|
1197
|
+
...baseContext,
|
|
1198
|
+
messages,
|
|
1199
|
+
messageList: passThrough.messageList,
|
|
1200
|
+
systemMessages: systemMessages ?? [],
|
|
1201
|
+
state: {}
|
|
1202
|
+
});
|
|
1203
|
+
if (result2 instanceof agent.MessageList) {
|
|
1204
|
+
if (result2 !== passThrough.messageList) {
|
|
1205
|
+
throw new error.MastraError({
|
|
1206
|
+
category: error.ErrorCategory.USER,
|
|
1207
|
+
domain: error.ErrorDomain.MASTRA_WORKFLOW,
|
|
1208
|
+
id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
|
|
1209
|
+
text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
|
|
1210
|
+
});
|
|
1211
|
+
}
|
|
1212
|
+
return {
|
|
1213
|
+
...passThrough,
|
|
1214
|
+
messages: result2.get.all.db(),
|
|
1215
|
+
systemMessages: result2.getSystemMessages()
|
|
1216
|
+
};
|
|
1217
|
+
} else if (Array.isArray(result2)) {
|
|
1218
|
+
processors.ProcessorRunner.applyMessagesToMessageList(
|
|
1219
|
+
result2,
|
|
1220
|
+
passThrough.messageList,
|
|
1221
|
+
idsBeforeProcessing,
|
|
1222
|
+
check,
|
|
1223
|
+
"input"
|
|
1224
|
+
);
|
|
1225
|
+
return { ...passThrough, messages: result2 };
|
|
1226
|
+
} else if (result2 && "messages" in result2 && "systemMessages" in result2) {
|
|
1227
|
+
const typedResult = result2;
|
|
1228
|
+
processors.ProcessorRunner.applyMessagesToMessageList(
|
|
1229
|
+
typedResult.messages,
|
|
1230
|
+
passThrough.messageList,
|
|
1231
|
+
idsBeforeProcessing,
|
|
1232
|
+
check,
|
|
1233
|
+
"input"
|
|
1234
|
+
);
|
|
1235
|
+
passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
|
|
1236
|
+
return {
|
|
1237
|
+
...passThrough,
|
|
1238
|
+
messages: typedResult.messages,
|
|
1239
|
+
systemMessages: passThrough.messageList.getSystemMessages()
|
|
1240
|
+
};
|
|
1241
|
+
}
|
|
1242
|
+
return { ...passThrough, messages };
|
|
1243
|
+
}
|
|
1244
|
+
return { ...passThrough, messages };
|
|
1245
|
+
}
|
|
1246
|
+
case "inputStep": {
|
|
1247
|
+
if (processor.processInputStep) {
|
|
1248
|
+
if (!passThrough.messageList) {
|
|
1249
|
+
throw new error.MastraError({
|
|
1250
|
+
category: error.ErrorCategory.USER,
|
|
1251
|
+
domain: error.ErrorDomain.MASTRA_WORKFLOW,
|
|
1252
|
+
id: "PROCESSOR_MISSING_MESSAGE_LIST",
|
|
1253
|
+
text: `Processor ${processor.id} requires messageList or messages for processInputStep phase`
|
|
1254
|
+
});
|
|
1255
|
+
}
|
|
1256
|
+
const idsBeforeProcessing = messages.map((m) => m.id);
|
|
1257
|
+
const check = passThrough.messageList.makeMessageSourceChecker();
|
|
1258
|
+
const result2 = await processor.processInputStep({
|
|
1259
|
+
...baseContext,
|
|
1260
|
+
messages,
|
|
1261
|
+
messageList: passThrough.messageList,
|
|
1262
|
+
stepNumber: stepNumber ?? 0,
|
|
1263
|
+
systemMessages: systemMessages ?? [],
|
|
1264
|
+
// Pass model/tools configuration fields - types match ProcessInputStepArgs
|
|
1265
|
+
model,
|
|
1266
|
+
tools,
|
|
1267
|
+
toolChoice,
|
|
1268
|
+
activeTools,
|
|
1269
|
+
providerOptions,
|
|
1270
|
+
modelSettings,
|
|
1271
|
+
structuredOutput,
|
|
1272
|
+
steps: steps ?? [],
|
|
1273
|
+
state: {}
|
|
1274
|
+
});
|
|
1275
|
+
const validatedResult = await processors.ProcessorRunner.validateAndFormatProcessInputStepResult(result2, {
|
|
1276
|
+
messageList: passThrough.messageList,
|
|
1277
|
+
processor,
|
|
1278
|
+
stepNumber: stepNumber ?? 0
|
|
1279
|
+
});
|
|
1280
|
+
if (validatedResult.messages) {
|
|
1281
|
+
processors.ProcessorRunner.applyMessagesToMessageList(
|
|
1282
|
+
validatedResult.messages,
|
|
1283
|
+
passThrough.messageList,
|
|
1284
|
+
idsBeforeProcessing,
|
|
1285
|
+
check
|
|
1286
|
+
);
|
|
1287
|
+
}
|
|
1288
|
+
if (validatedResult.systemMessages) {
|
|
1289
|
+
passThrough.messageList.replaceAllSystemMessages(validatedResult.systemMessages);
|
|
1290
|
+
}
|
|
1291
|
+
return {
|
|
1292
|
+
...passThrough,
|
|
1293
|
+
messages,
|
|
1294
|
+
...validatedResult,
|
|
1295
|
+
systemMessages: passThrough.messageList.getSystemMessages()
|
|
1296
|
+
};
|
|
1297
|
+
}
|
|
1298
|
+
return { ...passThrough, messages };
|
|
1299
|
+
}
|
|
1300
|
+
case "outputStream": {
|
|
1301
|
+
if (processor.processOutputStream) {
|
|
1302
|
+
const spanKey = `__outputStreamSpan_${processor.id}`;
|
|
1303
|
+
const mutableState = state ?? {};
|
|
1304
|
+
let processorSpan2 = mutableState[spanKey];
|
|
1305
|
+
if (!processorSpan2 && parentSpan) {
|
|
1306
|
+
processorSpan2 = parentSpan.createChildSpan({
|
|
1307
|
+
type: observability.SpanType.PROCESSOR_RUN,
|
|
1308
|
+
name: `output stream processor: ${processor.id}`,
|
|
1309
|
+
entityType: observability.EntityType.OUTPUT_PROCESSOR,
|
|
1310
|
+
entityId: processor.id,
|
|
1311
|
+
entityName: processor.name ?? processor.id,
|
|
1312
|
+
input: { phase, streamParts: [] },
|
|
1313
|
+
attributes: {
|
|
1314
|
+
processorExecutor: "workflow",
|
|
1315
|
+
processorIndex: processor.processorIndex
|
|
1316
|
+
}
|
|
1317
|
+
});
|
|
1318
|
+
mutableState[spanKey] = processorSpan2;
|
|
1319
|
+
}
|
|
1320
|
+
if (processorSpan2) {
|
|
1321
|
+
processorSpan2.input = {
|
|
1322
|
+
phase,
|
|
1323
|
+
streamParts: streamParts ?? [],
|
|
1324
|
+
totalChunks: (streamParts ?? []).length
|
|
1325
|
+
};
|
|
1326
|
+
}
|
|
1327
|
+
const processorTracingContext2 = processorSpan2 ? { currentSpan: processorSpan2 } : baseContext.tracingContext;
|
|
1328
|
+
let result2;
|
|
1329
|
+
try {
|
|
1330
|
+
result2 = await processor.processOutputStream({
|
|
1331
|
+
...baseContext,
|
|
1332
|
+
tracingContext: processorTracingContext2,
|
|
1333
|
+
part,
|
|
1334
|
+
streamParts: streamParts ?? [],
|
|
1335
|
+
state: mutableState,
|
|
1336
|
+
messageList: passThrough.messageList
|
|
1337
|
+
// Optional for stream processing
|
|
1338
|
+
});
|
|
1339
|
+
if (part && part.type === "finish") {
|
|
1340
|
+
processorSpan2?.end({ output: result2 });
|
|
1341
|
+
delete mutableState[spanKey];
|
|
1342
|
+
}
|
|
1343
|
+
} catch (error) {
|
|
1344
|
+
if (error instanceof agent.TripWire) {
|
|
1345
|
+
processorSpan2?.end({ output: { tripwire: error.message } });
|
|
1346
|
+
} else {
|
|
1347
|
+
processorSpan2?.error({ error, endSpan: true });
|
|
1348
|
+
}
|
|
1349
|
+
delete mutableState[spanKey];
|
|
1350
|
+
throw error;
|
|
1351
|
+
}
|
|
1352
|
+
return { ...passThrough, state: mutableState, part: result2 };
|
|
1353
|
+
}
|
|
1354
|
+
return { ...passThrough, part };
|
|
1355
|
+
}
|
|
1356
|
+
case "outputResult": {
|
|
1357
|
+
if (processor.processOutputResult) {
|
|
1358
|
+
if (!passThrough.messageList) {
|
|
1359
|
+
throw new error.MastraError({
|
|
1360
|
+
category: error.ErrorCategory.USER,
|
|
1361
|
+
domain: error.ErrorDomain.MASTRA_WORKFLOW,
|
|
1362
|
+
id: "PROCESSOR_MISSING_MESSAGE_LIST",
|
|
1363
|
+
text: `Processor ${processor.id} requires messageList or messages for processOutputResult phase`
|
|
1364
|
+
});
|
|
1365
|
+
}
|
|
1366
|
+
const idsBeforeProcessing = messages.map((m) => m.id);
|
|
1367
|
+
const check = passThrough.messageList.makeMessageSourceChecker();
|
|
1368
|
+
const outputResult = passThrough.result ?? {
|
|
1369
|
+
text: "",
|
|
1370
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },
|
|
1371
|
+
finishReason: "unknown",
|
|
1372
|
+
steps: []
|
|
1373
|
+
};
|
|
1374
|
+
const processResult = await processor.processOutputResult({
|
|
1375
|
+
...baseContext,
|
|
1376
|
+
messages,
|
|
1377
|
+
messageList: passThrough.messageList,
|
|
1378
|
+
state: passThrough.state ?? {},
|
|
1379
|
+
result: outputResult
|
|
1380
|
+
});
|
|
1381
|
+
if (processResult instanceof agent.MessageList) {
|
|
1382
|
+
if (processResult !== passThrough.messageList) {
|
|
1383
|
+
throw new error.MastraError({
|
|
1384
|
+
category: error.ErrorCategory.USER,
|
|
1385
|
+
domain: error.ErrorDomain.MASTRA_WORKFLOW,
|
|
1386
|
+
id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
|
|
1387
|
+
text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
|
|
1388
|
+
});
|
|
1389
|
+
}
|
|
1390
|
+
return {
|
|
1391
|
+
...passThrough,
|
|
1392
|
+
messages: processResult.get.all.db(),
|
|
1393
|
+
systemMessages: processResult.getSystemMessages()
|
|
1394
|
+
};
|
|
1395
|
+
} else if (Array.isArray(processResult)) {
|
|
1396
|
+
processors.ProcessorRunner.applyMessagesToMessageList(
|
|
1397
|
+
processResult,
|
|
1398
|
+
passThrough.messageList,
|
|
1399
|
+
idsBeforeProcessing,
|
|
1400
|
+
check,
|
|
1401
|
+
"response"
|
|
1402
|
+
);
|
|
1403
|
+
return { ...passThrough, messages: processResult };
|
|
1404
|
+
} else if (processResult && "messages" in processResult && "systemMessages" in processResult) {
|
|
1405
|
+
const typedResult = processResult;
|
|
1406
|
+
processors.ProcessorRunner.applyMessagesToMessageList(
|
|
1407
|
+
typedResult.messages,
|
|
1408
|
+
passThrough.messageList,
|
|
1409
|
+
idsBeforeProcessing,
|
|
1410
|
+
check,
|
|
1411
|
+
"response"
|
|
1412
|
+
);
|
|
1413
|
+
passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
|
|
1414
|
+
return {
|
|
1415
|
+
...passThrough,
|
|
1416
|
+
messages: typedResult.messages,
|
|
1417
|
+
systemMessages: passThrough.messageList.getSystemMessages()
|
|
1418
|
+
};
|
|
1419
|
+
}
|
|
1420
|
+
return { ...passThrough, messages };
|
|
1421
|
+
}
|
|
1422
|
+
return { ...passThrough, messages };
|
|
1423
|
+
}
|
|
1424
|
+
case "outputStep": {
|
|
1425
|
+
if (processor.processOutputStep) {
|
|
1426
|
+
if (!passThrough.messageList) {
|
|
1427
|
+
throw new error.MastraError({
|
|
1428
|
+
category: error.ErrorCategory.USER,
|
|
1429
|
+
domain: error.ErrorDomain.MASTRA_WORKFLOW,
|
|
1430
|
+
id: "PROCESSOR_MISSING_MESSAGE_LIST",
|
|
1431
|
+
text: `Processor ${processor.id} requires messageList or messages for processOutputStep phase`
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
const idsBeforeProcessing = messages.map((m) => m.id);
|
|
1435
|
+
const check = passThrough.messageList.makeMessageSourceChecker();
|
|
1436
|
+
const defaultUsage = {
|
|
1437
|
+
inputTokens: void 0,
|
|
1438
|
+
outputTokens: void 0,
|
|
1439
|
+
totalTokens: void 0
|
|
1440
|
+
};
|
|
1441
|
+
const result2 = await processor.processOutputStep({
|
|
1442
|
+
...baseContext,
|
|
1443
|
+
messages,
|
|
1444
|
+
messageList: passThrough.messageList,
|
|
1445
|
+
stepNumber: stepNumber ?? 0,
|
|
1446
|
+
finishReason,
|
|
1447
|
+
toolCalls,
|
|
1448
|
+
text,
|
|
1449
|
+
usage: usage ?? defaultUsage,
|
|
1450
|
+
systemMessages: systemMessages ?? [],
|
|
1451
|
+
steps: steps ?? [],
|
|
1452
|
+
state: {}
|
|
1453
|
+
});
|
|
1454
|
+
if (result2 instanceof agent.MessageList) {
|
|
1455
|
+
if (result2 !== passThrough.messageList) {
|
|
1456
|
+
throw new error.MastraError({
|
|
1457
|
+
category: error.ErrorCategory.USER,
|
|
1458
|
+
domain: error.ErrorDomain.MASTRA_WORKFLOW,
|
|
1459
|
+
id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
|
|
1460
|
+
text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
|
|
1461
|
+
});
|
|
1462
|
+
}
|
|
1463
|
+
return {
|
|
1464
|
+
...passThrough,
|
|
1465
|
+
messages: result2.get.all.db(),
|
|
1466
|
+
systemMessages: result2.getSystemMessages()
|
|
1467
|
+
};
|
|
1468
|
+
} else if (Array.isArray(result2)) {
|
|
1469
|
+
processors.ProcessorRunner.applyMessagesToMessageList(
|
|
1470
|
+
result2,
|
|
1471
|
+
passThrough.messageList,
|
|
1472
|
+
idsBeforeProcessing,
|
|
1473
|
+
check,
|
|
1474
|
+
"response"
|
|
1475
|
+
);
|
|
1476
|
+
return { ...passThrough, messages: result2 };
|
|
1477
|
+
} else if (result2 && "messages" in result2 && "systemMessages" in result2) {
|
|
1478
|
+
const typedResult = result2;
|
|
1479
|
+
processors.ProcessorRunner.applyMessagesToMessageList(
|
|
1480
|
+
typedResult.messages,
|
|
1481
|
+
passThrough.messageList,
|
|
1482
|
+
idsBeforeProcessing,
|
|
1483
|
+
check,
|
|
1484
|
+
"response"
|
|
1485
|
+
);
|
|
1486
|
+
passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
|
|
1487
|
+
return {
|
|
1488
|
+
...passThrough,
|
|
1489
|
+
messages: typedResult.messages,
|
|
1490
|
+
systemMessages: passThrough.messageList.getSystemMessages()
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
return { ...passThrough, messages };
|
|
1494
|
+
}
|
|
1495
|
+
return { ...passThrough, messages };
|
|
1496
|
+
}
|
|
1497
|
+
default:
|
|
1498
|
+
return { ...passThrough, messages };
|
|
1499
|
+
}
|
|
1500
|
+
});
|
|
1501
|
+
},
|
|
1502
|
+
component: "PROCESSOR"
|
|
1503
|
+
};
|
|
1504
|
+
}
|
|
1505
|
+
function init(inngest) {
|
|
1506
|
+
return {
|
|
1507
|
+
createTool: tools.createTool,
|
|
1508
|
+
createWorkflow(params) {
|
|
1509
|
+
return new chunkMICZJLEE_cjs.InngestWorkflow(
|
|
1510
|
+
params,
|
|
1511
|
+
inngest
|
|
1512
|
+
);
|
|
1513
|
+
},
|
|
1514
|
+
createStep,
|
|
1515
|
+
cloneStep(step, opts) {
|
|
1516
|
+
return {
|
|
1517
|
+
id: opts.id,
|
|
1518
|
+
description: step.description,
|
|
1519
|
+
inputSchema: step.inputSchema,
|
|
1520
|
+
outputSchema: step.outputSchema,
|
|
1521
|
+
resumeSchema: step.resumeSchema,
|
|
1522
|
+
suspendSchema: step.suspendSchema,
|
|
1523
|
+
stateSchema: step.stateSchema,
|
|
1524
|
+
metadata: step.metadata,
|
|
1525
|
+
execute: step.execute,
|
|
1526
|
+
retries: step.retries,
|
|
1527
|
+
scorers: step.scorers,
|
|
1528
|
+
component: step.component
|
|
1529
|
+
};
|
|
1530
|
+
},
|
|
1531
|
+
cloneWorkflow(workflow, opts) {
|
|
1532
|
+
const wf = new workflows.Workflow({
|
|
1533
|
+
id: opts.id,
|
|
1534
|
+
inputSchema: workflow.inputSchema,
|
|
1535
|
+
outputSchema: workflow.outputSchema,
|
|
1536
|
+
steps: workflow.stepDefs,
|
|
1537
|
+
mastra: workflow.mastra,
|
|
1538
|
+
options: workflow.options
|
|
1539
|
+
});
|
|
1540
|
+
wf.setStepFlow(workflow.stepGraph);
|
|
1541
|
+
wf.commit();
|
|
1542
|
+
return wf;
|
|
1543
|
+
}
|
|
1544
|
+
};
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
Object.defineProperty(exports, "InngestExecutionEngine", {
|
|
1548
|
+
enumerable: true,
|
|
1549
|
+
get: function () { return chunkMICZJLEE_cjs.InngestExecutionEngine; }
|
|
1550
|
+
});
|
|
1551
|
+
Object.defineProperty(exports, "InngestPubSub", {
|
|
1552
|
+
enumerable: true,
|
|
1553
|
+
get: function () { return chunkMICZJLEE_cjs.InngestPubSub; }
|
|
1554
|
+
});
|
|
1555
|
+
Object.defineProperty(exports, "InngestRun", {
|
|
1556
|
+
enumerable: true,
|
|
1557
|
+
get: function () { return chunkMICZJLEE_cjs.InngestRun; }
|
|
1558
|
+
});
|
|
1559
|
+
Object.defineProperty(exports, "InngestWorkflow", {
|
|
1560
|
+
enumerable: true,
|
|
1561
|
+
get: function () { return chunkMICZJLEE_cjs.InngestWorkflow; }
|
|
1562
|
+
});
|
|
1563
|
+
Object.defineProperty(exports, "connect", {
|
|
1564
|
+
enumerable: true,
|
|
1565
|
+
get: function () { return chunkMICZJLEE_cjs.connect; }
|
|
1566
|
+
});
|
|
1567
|
+
exports._compatibilityCheck = _compatibilityCheck;
|
|
1568
|
+
exports.createInngestAgent = createInngestAgent;
|
|
1569
|
+
exports.createInngestDurableAgenticWorkflow = createInngestDurableAgenticWorkflow;
|
|
1570
|
+
exports.createServe = createServe;
|
|
1571
|
+
exports.createStep = createStep;
|
|
1572
|
+
exports.init = init;
|
|
1573
|
+
exports.isInngestAgent = isInngestAgent;
|
|
1574
|
+
exports.serve = serve;
|
|
1575
|
+
//# sourceMappingURL=index.cjs.map
|
|
1576
|
+
//# sourceMappingURL=index.cjs.map
|