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