@mastra/inngest 1.9.1 → 1.9.2-alpha.1

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.
@@ -1,16 +1,24 @@
1
- import { MastraNonRetryableError, getErrorFromUnknown } from "@mastra/core/error";
2
- import { EntityType, SpanType } from "@mastra/core/observability";
3
- import { DefaultExecutionEngine, Run, Workflow, createTimeTravelExecutionParams, getEntryWorkflow, hydrateSerializedStepErrors, isSingleStepEntry } from "@mastra/core/workflows";
1
+ import { Agent, MessageList, TripWire } from "@mastra/core/agent";
2
+ import { ErrorCategory, ErrorDomain, MastraError, MastraNonRetryableError, getErrorFromUnknown } from "@mastra/core/error";
3
+ import { EntityType, InternalSpans, SpanType } from "@mastra/core/observability";
4
+ import { ProcessorRunner, ProcessorState, ProcessorStepOutputSchema, ProcessorStepSchema } from "@mastra/core/processors";
5
+ import { toStandardSchema } from "@mastra/core/schema";
6
+ import { Tool, createTool } from "@mastra/core/tools";
7
+ import { DefaultExecutionEngine, Run, Workflow, createStepFromAgent, createStepFromTool, createTimeTravelExecutionParams, getEntryWorkflow, hydrateSerializedStepErrors, isSingleStepEntry } from "@mastra/core/workflows";
4
8
  import { randomUUID } from "crypto";
5
- import { emitErrorEvent } from "@mastra/core/agent/durable";
9
+ import { AGENT_STREAM_TOPIC, DurableAgentDefaults, DurableStepIds, agentThreadStreamRuntime, baseIterationStateSchema, createBaseIterationStateUpdate, createDurableAgentStream, createDurableBackgroundTaskCheckStep, createDurableLLMExecutionStep, createDurableLLMMappingStep, createDurableToolCallStep, durableAgenticOutputSchema, emitErrorEvent, emitFinishEvent, executeDurableAgentScorers, globalRunRegistry, modelConfigSchema, prepareForDurableExecution, publishAbortRequest, resolveDurableToolCallConcurrency, runDurableFinishSideEffects, runDurableStreamUntilIdle, runResumeDurableStreamUntilIdle } from "@mastra/core/agent/durable";
6
10
  import { RequestContext } from "@mastra/core/di";
7
11
  import { NonRetriableError } from "inngest";
8
12
  import { AsyncLocalStorage } from "async_hooks";
9
- import { PubSub } from "@mastra/core/events";
13
+ import { CachingPubSub, PubSub } from "@mastra/core/events";
10
14
  import { subscribe } from "inngest/realtime";
11
15
  import { ReadableStream } from "stream/web";
12
16
  import { ChunkFrom, WorkflowRunOutput } from "@mastra/core/stream";
13
17
  import { MASTRA_AUTH_TOKEN_KEY } from "@mastra/core/request-context";
18
+ import { serve } from "inngest/hono";
19
+ import { InMemoryServerCache } from "@mastra/core/cache";
20
+ import { PUBSUB_SYMBOL } from "@mastra/core/workflows/_constants";
21
+ import { z } from "zod";
14
22
  //#region src/nested-workflow-output.ts
15
23
  const NESTED_WORKFLOW_OUTPUT_MODE = {
16
24
  DEFAULT: "default",
@@ -77,6 +85,15 @@ function isNonRetryableStepFailure(error) {
77
85
  return false;
78
86
  }
79
87
  const retryCountStorage = new AsyncLocalStorage();
88
+ const BUILTIN_ERROR_TYPES = [
89
+ TypeError,
90
+ RangeError,
91
+ ReferenceError,
92
+ SyntaxError,
93
+ EvalError,
94
+ URIError,
95
+ AggregateError
96
+ ];
80
97
  var InngestExecutionEngine = class extends DefaultExecutionEngine {
81
98
  parentStream;
82
99
  inngestStep;
@@ -120,8 +137,9 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
120
137
  }
121
138
  /**
122
139
  * Execute a step with retry logic for Inngest.
123
- * Retries are handled via step-level retry (RetryAfterError thrown INSIDE step.run()).
124
- * After retries exhausted, error propagates here and we return a failed result.
140
+ * Each attempt is its own step.run() that fails as NonRetriableError, so Inngest never
141
+ * retries step code; this loop owns the retries. After retries are exhausted we return
142
+ * a failed result instead of rethrowing.
125
143
  */
126
144
  async executeStepWithRetry(stepId, runStep, params) {
127
145
  for (let i = 0; i < params.retries + 1; i++) {
@@ -129,12 +147,12 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
129
147
  try {
130
148
  return {
131
149
  ok: true,
132
- result: await retryCountStorage.run(i, () => this.wrapDurableOperation(stepId, runStep))
150
+ result: await retryCountStorage.run(i, () => this.runDurably(stepId, runStep, NonRetriableError))
133
151
  };
134
152
  } catch (e) {
135
- const isNonRetryable = isNonRetryableStepFailure(e);
153
+ const cause = e?.cause;
154
+ const isNonRetryable = isNonRetryableStepFailure(cause?.status === "failed" ? cause : e);
136
155
  if (isNonRetryable || i === params.retries) {
137
- const cause = e?.cause;
138
156
  if (cause?.status === "failed") {
139
157
  params.stepSpan?.error({
140
158
  error: e,
@@ -201,23 +219,39 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
201
219
  * in the cause property, we ensure custom properties survive serialization.
202
220
  * The cause property is in serialize-error-cjs's allowlist, and when the cause
203
221
  * object is finally JSON.stringify'd, our error's toJSON() is called.
222
+ *
223
+ * Failures here stay retriable, so a non-zero function-level `retries` covers
224
+ * transient errors in these operations (spans, event publishing, conditions).
204
225
  */
205
226
  async wrapDurableOperation(operationId, operationFn) {
227
+ return this.runDurably(operationId, operationFn, Error);
228
+ }
229
+ /**
230
+ * Runs `operationFn` in step.run() and throws failures as `ErrorType` with the
231
+ * serialized failure in the cause. Step code passes NonRetriableError because Inngest
232
+ * applies the function-level `retries` to every step.run() that throws, and step
233
+ * retries are already handled by executeStepWithRetry.
234
+ */
235
+ async runDurably(operationId, operationFn, ErrorType) {
206
236
  return await this.inngestStep.run(operationId, async () => {
207
237
  try {
208
238
  return await operationFn();
209
239
  } catch (e) {
210
240
  const errorInstance = getErrorFromUnknown(e, {
211
- serializeStack: false,
241
+ serializeStack: true,
212
242
  fallbackMessage: "Unknown step execution error"
213
243
  });
214
244
  const isNonRetryable = isNonRetryableStepFailure(e);
215
- throw new Error(errorInstance.message, { cause: {
245
+ const wrapped = new ErrorType(errorInstance.message, { cause: {
216
246
  status: "failed",
217
247
  error: errorInstance,
218
248
  endedAt: Date.now(),
219
249
  ...isNonRetryable && { nonRetryable: true }
220
250
  } });
251
+ if (errorInstance.stack) wrapped.stack = errorInstance.stack;
252
+ const builtinErrorType = e instanceof Error ? BUILTIN_ERROR_TYPES.find((BuiltinType) => Object.getPrototypeOf(e) === BuiltinType.prototype) : void 0;
253
+ if (builtinErrorType) Object.setPrototypeOf(wrapped, builtinErrorType.prototype);
254
+ throw wrapped;
221
255
  }
222
256
  });
223
257
  }
@@ -245,6 +279,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
245
279
  async createStepSpan(params) {
246
280
  const { executionContext, operationId, options, parentSpan } = params;
247
281
  const parentSpanId = parentSpan?.id ?? executionContext.tracingIds?.workflowSpanId;
282
+ if (!this.mastra?.observability?.getSelectedInstance({})) return void 0;
248
283
  const exportedSpan = await this.wrapDurableOperation(operationId, async () => {
249
284
  const observability = this.mastra?.observability?.getSelectedInstance({});
250
285
  if (!observability) return void 0;
@@ -284,6 +319,7 @@ var InngestExecutionEngine = class extends DefaultExecutionEngine {
284
319
  async createChildSpan(params) {
285
320
  const { executionContext, operationId, options, parentSpan } = params;
286
321
  const parentSpanId = parentSpan?.id ?? executionContext.tracingIds?.workflowSpanId;
322
+ if (!this.mastra?.observability?.getSelectedInstance({})) return void 0;
287
323
  const exportedSpan = await this.wrapDurableOperation(operationId, async () => {
288
324
  const observability = this.mastra?.observability?.getSelectedInstance({});
289
325
  if (!observability) return void 0;
@@ -1962,18 +1998,947 @@ function toSnapshotResult(output) {
1962
1998
  return output;
1963
1999
  }
1964
2000
  //#endregion
2001
+ //#region src/durable-agent/create-inngest-agentic-workflow.ts
2002
+ /**
2003
+ * Input schema for the durable agentic workflow.
2004
+ * Extends base with observability fields for Inngest.
2005
+ */
2006
+ const durableAgenticInputSchema = z.object({
2007
+ runId: z.string(),
2008
+ agentId: z.string(),
2009
+ agentName: z.string().optional(),
2010
+ messageListState: z.any(),
2011
+ toolsMetadata: z.array(z.any()),
2012
+ modelConfig: modelConfigSchema,
2013
+ options: z.any(),
2014
+ state: z.any(),
2015
+ messageId: z.string(),
2016
+ requestContextEntries: z.record(z.string(), z.any()).optional(),
2017
+ agentSpanData: z.any().optional(),
2018
+ modelSpanData: z.any().optional(),
2019
+ stepIndex: z.number().optional()
2020
+ });
2021
+ /**
2022
+ * Iteration state schema - extends base with observability fields.
2023
+ */
2024
+ const iterationStateSchema = baseIterationStateSchema.extend({
2025
+ agentSpanData: z.any().optional(),
2026
+ modelSpanData: z.any().optional(),
2027
+ stepIndex: z.number()
2028
+ });
2029
+ /**
2030
+ * Create a durable agentic workflow using Inngest.
2031
+ *
2032
+ * This workflow implements the agentic loop pattern in a durable way using
2033
+ * Inngest's execution engine:
2034
+ *
2035
+ * 1. LLM Execution Step - Calls the LLM and gets response/tool calls
2036
+ * 2. Tool Call Steps (foreach) - Executes each tool call individually with suspend support
2037
+ * 3. LLM Mapping Step - Merges tool results back into state
2038
+ * 4. Loop - Continues if more tool calls are needed (dowhile)
2039
+ *
2040
+ * All state flows through workflow input/output, making it durable across
2041
+ * process restarts and execution engine replays.
2042
+ *
2043
+ * @param options - Configuration options
2044
+ * @returns An InngestWorkflow instance that implements the agentic loop
2045
+ */
2046
+ /** Prefix for Inngest engine workflow IDs to avoid collision with other engines */
2047
+ const INNGEST_ENGINE_PREFIX = "inngest";
2048
+ /** Inngest-prefixed workflow IDs */
2049
+ const InngestDurableStepIds = {
2050
+ AGENTIC_EXECUTION: `${INNGEST_ENGINE_PREFIX}:${DurableStepIds.AGENTIC_EXECUTION}`,
2051
+ AGENTIC_LOOP: `${INNGEST_ENGINE_PREFIX}:${DurableStepIds.AGENTIC_LOOP}`
2052
+ };
2053
+ function createInngestDurableAgenticWorkflow(options) {
2054
+ const { inngest, maxSteps = DurableAgentDefaults.MAX_STEPS, retries } = options;
2055
+ const { createWorkflow } = init(inngest);
2056
+ const llmExecutionStep = createDurableLLMExecutionStep();
2057
+ const toolCallStep = createDurableToolCallStep();
2058
+ const llmMappingStep = createDurableLLMMappingStep();
2059
+ const backgroundTaskCheckStep = createDurableBackgroundTaskCheckStep();
2060
+ const singleIterationWorkflow = createWorkflow({
2061
+ id: InngestDurableStepIds.AGENTIC_EXECUTION,
2062
+ retries,
2063
+ inputSchema: iterationStateSchema,
2064
+ outputSchema: iterationStateSchema,
2065
+ options: {
2066
+ tracingPolicy: { internal: InternalSpans.WORKFLOW },
2067
+ shouldPersistSnapshot: ({ workflowStatus }) => workflowStatus === "suspended",
2068
+ evaluatePersistencePredicateBeforeDurableOperation: true,
2069
+ validateInputs: false,
2070
+ emitStepEvents: false
2071
+ },
2072
+ steps: []
2073
+ }).map(async ({ inputData }) => {
2074
+ const state = inputData;
2075
+ return {
2076
+ runId: state.runId,
2077
+ agentId: state.agentId,
2078
+ agentName: state.agentName,
2079
+ messageListState: state.messageListState,
2080
+ toolsMetadata: state.toolsMetadata,
2081
+ modelConfig: state.modelConfig,
2082
+ options: state.options,
2083
+ state: state.state,
2084
+ messageId: state.messageId,
2085
+ requestContextEntries: state.requestContextEntries,
2086
+ agentSpanData: state.agentSpanData,
2087
+ modelSpanData: state.modelSpanData,
2088
+ stepIndex: state.stepIndex
2089
+ };
2090
+ }, { id: "map-to-llm-input" }).then(llmExecutionStep).map(async ({ inputData }) => {
2091
+ const llmOutput = inputData;
2092
+ return (llmOutput.toolCalls ?? []).map((toolCall) => ({
2093
+ ...toolCall,
2094
+ stepSpanData: llmOutput.stepSpanData
2095
+ }));
2096
+ }, { id: "extract-tool-calls" }).foreach(toolCallStep, { concurrency: ({ inputData, getInitData }) => {
2097
+ const state = getInitData();
2098
+ return resolveDurableToolCallConcurrency({
2099
+ options: state?.options,
2100
+ toolsMetadata: state?.toolsMetadata,
2101
+ toolCalls: inputData
2102
+ });
2103
+ } }).map(async ({ inputData, getStepResult, getInitData }) => {
2104
+ const toolResults = inputData;
2105
+ const llmOutput = getStepResult(llmExecutionStep.id);
2106
+ const initData = getInitData();
2107
+ return {
2108
+ llmOutput,
2109
+ toolResults,
2110
+ runId: initData.runId,
2111
+ agentId: initData.agentId,
2112
+ messageId: initData.messageId,
2113
+ state: llmOutput?.state ?? initData.state
2114
+ };
2115
+ }, { id: "collect-tool-results" }).then(llmMappingStep).then(backgroundTaskCheckStep).map(async ({ inputData, getInitData }) => {
2116
+ const executionOutput = inputData;
2117
+ const initData = getInitData();
2118
+ return {
2119
+ ...createBaseIterationStateUpdate({
2120
+ currentState: initData,
2121
+ executionOutput
2122
+ }),
2123
+ agentSpanData: initData.agentSpanData,
2124
+ modelSpanData: initData.modelSpanData,
2125
+ stepIndex: initData.stepIndex + 1
2126
+ };
2127
+ }, { id: "update-iteration-state" }).commit();
2128
+ return createWorkflow({
2129
+ id: InngestDurableStepIds.AGENTIC_LOOP,
2130
+ retries,
2131
+ inputSchema: durableAgenticInputSchema,
2132
+ outputSchema: durableAgenticOutputSchema,
2133
+ options: {
2134
+ tracingPolicy: { internal: InternalSpans.WORKFLOW },
2135
+ shouldPersistSnapshot: ({ workflowStatus }) => workflowStatus === "suspended",
2136
+ evaluatePersistencePredicateBeforeDurableOperation: true,
2137
+ validateInputs: false,
2138
+ emitStepEvents: false
2139
+ },
2140
+ steps: []
2141
+ }).map(async ({ inputData }) => {
2142
+ const input = inputData;
2143
+ const agentSpanData = input.agentSpanData;
2144
+ const modelSpanData = input.modelSpanData;
2145
+ return {
2146
+ ...input,
2147
+ iterationCount: 0,
2148
+ accumulatedSteps: [],
2149
+ accumulatedUsage: {
2150
+ inputTokens: 0,
2151
+ outputTokens: 0,
2152
+ totalTokens: 0
2153
+ },
2154
+ lastStepResult: void 0,
2155
+ agentSpanData,
2156
+ modelSpanData,
2157
+ stepIndex: input.stepIndex ?? 0
2158
+ };
2159
+ }, { id: "init-iteration-state" }).dowhile(singleIterationWorkflow, async ({ inputData }) => {
2160
+ const state = inputData;
2161
+ const shouldContinue = state.lastStepResult?.isContinued === true;
2162
+ const effectiveMaxSteps = state.options?.maxSteps ?? maxSteps;
2163
+ const underMaxSteps = state.iterationCount < effectiveMaxSteps;
2164
+ return shouldContinue && underMaxSteps;
2165
+ }).map(async (params) => {
2166
+ const { inputData, mastra, requestContext, tracingContext } = params;
2167
+ const state = inputData;
2168
+ const initData = params.getInitData();
2169
+ const pubsub = params[PUBSUB_SYMBOL];
2170
+ const lastStep = state.accumulatedSteps[state.accumulatedSteps.length - 1];
2171
+ let finalText = lastStep?.text;
2172
+ const finishResult = await runDurableFinishSideEffects({
2173
+ runId: state.runId,
2174
+ initData,
2175
+ messageListState: state.messageListState,
2176
+ mastra,
2177
+ requestContext,
2178
+ tracingContext,
2179
+ logger: mastra?.getLogger?.(),
2180
+ outputResult: {
2181
+ text: finalText ?? "",
2182
+ usage: state.accumulatedUsage,
2183
+ finishReason: state.lastStepResult?.reason ?? "unknown",
2184
+ steps: state.accumulatedSteps
2185
+ }
2186
+ });
2187
+ if (lastStep && finishResult.outputText && finishResult.outputText !== (finalText ?? "")) {
2188
+ lastStep.text = finishResult.outputText;
2189
+ finalText = finishResult.outputText;
2190
+ }
2191
+ const finalOutput = {
2192
+ messageListState: finishResult.messageListState,
2193
+ messageId: state.messageId,
2194
+ stepResult: state.lastStepResult || {
2195
+ reason: "stop",
2196
+ warnings: [],
2197
+ isContinued: false
2198
+ },
2199
+ output: {
2200
+ text: finalText,
2201
+ usage: state.accumulatedUsage,
2202
+ steps: state.accumulatedSteps
2203
+ },
2204
+ state: state.state
2205
+ };
2206
+ const observability = mastra?.observability?.getSelectedInstance({});
2207
+ if (state.modelSpanData) (observability?.rebuildSpan(state.modelSpanData))?.createTracker()?.endGeneration({
2208
+ output: { text: finalText },
2209
+ attributes: { finishReason: state.lastStepResult?.reason || "stop" },
2210
+ usage: state.accumulatedUsage
2211
+ });
2212
+ if (state.agentSpanData) (observability?.rebuildSpan(state.agentSpanData))?.end({ output: { text: finalText } });
2213
+ if (pubsub) await emitFinishEvent(pubsub, state.runId, {
2214
+ output: finalOutput.output,
2215
+ stepResult: finalOutput.stepResult
2216
+ });
2217
+ return finalOutput;
2218
+ }, { id: "map-final-output" }).map(async ({ inputData, getInitData, mastra, requestContext, tracingContext }) => {
2219
+ executeDurableAgentScorers({
2220
+ initData: getInitData(),
2221
+ finalOutput: inputData,
2222
+ mastra,
2223
+ requestContext,
2224
+ tracingContext
2225
+ });
2226
+ return inputData;
2227
+ }, { id: "execute-scorers" }).commit();
2228
+ }
2229
+ //#endregion
2230
+ //#region src/durable-agent/create-inngest-agent.ts
2231
+ var InngestWorkflowCachingPubSub = class extends CachingPubSub {
2232
+ publish(topic, event, options) {
2233
+ if (topic.startsWith("workflow.events.v2.")) return super.publish(topic, event, {
2234
+ ...options,
2235
+ localOnly: true
2236
+ });
2237
+ return super.publish(topic, event, options);
2238
+ }
2239
+ };
2240
+ /**
2241
+ * Internal sentinel used by {@link InngestAgent.generate} and
2242
+ * {@link InngestAgent.resumeGenerate} to ask the underlying `stream()` /
2243
+ * `resume()` implementation to close the consumer stream on a SUSPENDED
2244
+ * event, so `getFullOutput()` resolves promptly with `finishReason:
2245
+ * 'suspended'` instead of waiting for FINISH/ERROR.
2246
+ *
2247
+ * Modelled on `CLOSE_ON_SUSPEND` in core `DurableAgent`.
2248
+ */
2249
+ const CLOSE_ON_SUSPEND = Symbol("mastra.durable.inngest.closeOnSuspend");
2250
+ /**
2251
+ * Internal symbol used by `generate()` / `resumeGenerate()` to tear down the
2252
+ * pubsub subscription on suspend without removing the run-registry entry.
2253
+ * The public `cleanup()` does both; this lets the generate wrappers keep the
2254
+ * registry alive across `suspend` → `resumeGenerate()` while still releasing
2255
+ * the local stream subscription.
2256
+ */
2257
+ const STREAM_CLEANUP = Symbol("mastra.durable.inngest.streamCleanup");
2258
+ const RESUME_SNAPSHOT_WAIT_MS = 1e4;
2259
+ const RESUME_SNAPSHOT_POLL_MS = 100;
2260
+ /**
2261
+ * Create an Inngest-powered durable agent from a Mastra Agent.
2262
+ *
2263
+ * This factory function wraps a regular Mastra Agent with Inngest's durable
2264
+ * execution capabilities. The returned InngestAgent can be registered with
2265
+ * Mastra, and the required workflow will be automatically registered.
2266
+ *
2267
+ * @param options - Configuration options
2268
+ * @returns An InngestAgent that can be registered with Mastra
2269
+ *
2270
+ * @example
2271
+ * ```typescript
2272
+ * const agent = new Agent({
2273
+ * id: 'my-agent',
2274
+ * instructions: 'You are helpful',
2275
+ * model: openai('gpt-4'),
2276
+ * });
2277
+ *
2278
+ * const durableAgent = createInngestAgent({ agent, inngest });
2279
+ *
2280
+ * const mastra = new Mastra({
2281
+ * agents: { myAgent: durableAgent },
2282
+ * });
2283
+ * ```
2284
+ */
2285
+ function createInngestAgent(options) {
2286
+ const { agent, inngest, id: idOverride, name: nameOverride, pubsub: customPubsub, cache, mastra: mastraOption, shouldPersistSnapshot, retries } = options;
2287
+ if (shouldPersistSnapshot) console.warn(`InngestAgent '${idOverride ?? agent.id}': ignoring the shouldPersistSnapshot option. Inngest's step memoization/replay owns durability, so InngestAgent always persists 'suspended' snapshots only (for human-in-the-loop resume).`);
2288
+ const agentId = idOverride ?? agent.id;
2289
+ const agentName = nameOverride ?? agent.name;
2290
+ let mastra = mastraOption;
2291
+ const activeStreamUntilIdle = /* @__PURE__ */ new Map();
2292
+ let proxyRef;
2293
+ const workflow = createInngestDurableAgenticWorkflow({
2294
+ inngest,
2295
+ retries
2296
+ });
2297
+ let _customCache = cache;
2298
+ let innerPubsub = customPubsub ?? new InngestPubSub(inngest, InngestDurableStepIds.AGENTIC_LOOP);
2299
+ let _cachingPubsub = null;
2300
+ function resolveCache() {
2301
+ const resolved = _customCache ?? mastra?.serverCache ?? new InMemoryServerCache();
2302
+ _customCache = resolved;
2303
+ return resolved;
2304
+ }
2305
+ function getPubsub() {
2306
+ if (!_cachingPubsub) if (innerPubsub instanceof CachingPubSub) {
2307
+ _cachingPubsub = innerPubsub;
2308
+ _customCache = _customCache ?? mastra?.serverCache;
2309
+ } else _cachingPubsub = new CachingPubSub(innerPubsub, resolveCache());
2310
+ return _cachingPubsub;
2311
+ }
2312
+ async function getPubsubOffset(runId) {
2313
+ return (await getPubsub().getHistory(AGENT_STREAM_TOPIC(runId))).length;
2314
+ }
2315
+ workflow.__setPubsubFactory((defaultPubsub) => {
2316
+ if (defaultPubsub instanceof CachingPubSub) return defaultPubsub;
2317
+ getPubsub();
2318
+ return new InngestWorkflowCachingPubSub(defaultPubsub, resolveCache());
2319
+ });
2320
+ function getCache() {
2321
+ getPubsub();
2322
+ return _customCache;
2323
+ }
2324
+ /**
2325
+ * Trigger the workflow via Inngest event
2326
+ */
2327
+ async function triggerWorkflow(runId, workflowInput, tracingOptions, actor) {
2328
+ const eventName = `workflow.${InngestDurableStepIds.AGENTIC_LOOP}`;
2329
+ await inngest.send({
2330
+ name: eventName,
2331
+ data: buildDurableTriggerEventData({
2332
+ inputData: workflowInput,
2333
+ runId,
2334
+ resourceId: workflowInput.state?.resourceId,
2335
+ requestContext: workflowInput.requestContextEntries ?? {},
2336
+ tracingOptions,
2337
+ actor
2338
+ })
2339
+ });
2340
+ }
2341
+ /**
2342
+ * Emit an error event to pubsub.
2343
+ *
2344
+ * Best-effort: callers fire-and-forget this on paths that are already
2345
+ * failing, so an unreachable pubsub must not turn error reporting into an
2346
+ * unhandled rejection.
2347
+ */
2348
+ async function emitError(runId, error) {
2349
+ try {
2350
+ await emitErrorEvent(getPubsub(), runId, error);
2351
+ } catch (publishError) {
2352
+ mastra?.getLogger?.()?.warn?.("Failed to publish Inngest durable agent error event", {
2353
+ agentId,
2354
+ runId,
2355
+ error: publishError instanceof Error ? publishError.message : String(publishError)
2356
+ });
2357
+ }
2358
+ }
2359
+ /**
2360
+ * Stop a run in whichever worker is executing it.
2361
+ *
2362
+ * An Inngest agent's steps run on Inngest's infrastructure, essentially never
2363
+ * in the process that called `stream()`. The local `AbortController` is
2364
+ * therefore invisible to the step worker, and on its own `abort()` cannot
2365
+ * stop anything. Publishing an abort request lets the worker flip its own
2366
+ * controller and unwind the run gracefully, emitting the terminal stream
2367
+ * event consumers wait on — which a hard workflow cancel would skip.
2368
+ *
2369
+ * Best-effort: the local abort has already happened, and a caller asking to
2370
+ * stop a run should not get a rejection because the publish failed.
2371
+ */
2372
+ async function requestRemoteAbort(runId) {
2373
+ try {
2374
+ await publishAbortRequest(getPubsub(), runId);
2375
+ } catch (error) {
2376
+ mastra?.getLogger?.()?.warn?.("Failed to publish Inngest durable agent abort request", {
2377
+ agentId,
2378
+ runId,
2379
+ error: error instanceof Error ? error.message : String(error)
2380
+ });
2381
+ }
2382
+ }
2383
+ const result = new Proxy({
2384
+ get id() {
2385
+ return agentId;
2386
+ },
2387
+ get name() {
2388
+ return agentName;
2389
+ },
2390
+ get agent() {
2391
+ return agent;
2392
+ },
2393
+ get inngest() {
2394
+ return inngest;
2395
+ },
2396
+ get cache() {
2397
+ return getCache();
2398
+ },
2399
+ get pubsub() {
2400
+ return getPubsub();
2401
+ },
2402
+ async stream(messages, streamOptions) {
2403
+ if (streamOptions?.untilIdle) {
2404
+ const { untilIdle, ...rest } = streamOptions;
2405
+ const maxIdleMs = typeof untilIdle === "object" ? untilIdle.maxIdleMs : void 0;
2406
+ return runDurableStreamUntilIdle(proxyRef, messages, {
2407
+ ...rest,
2408
+ maxIdleMs
2409
+ }, {
2410
+ activeStreams: activeStreamUntilIdle,
2411
+ bgManager: mastra?.backgroundTaskManager
2412
+ });
2413
+ }
2414
+ const { runId, messageId, workflowInput, registryEntry, threadId, resourceId } = await prepareForDurableExecution({
2415
+ agent,
2416
+ messages,
2417
+ options: streamOptions,
2418
+ runId: streamOptions?.runId,
2419
+ requestContext: streamOptions?.requestContext,
2420
+ methodType: streamOptions?.__methodType ?? "stream",
2421
+ mastra,
2422
+ durableAgentId: agentId,
2423
+ durableAgentName: agentName
2424
+ });
2425
+ workflowInput.agentId = agentId;
2426
+ workflowInput.agentName = agentName;
2427
+ const abortController = new AbortController();
2428
+ if (streamOptions?.abortSignal) {
2429
+ const external = streamOptions.abortSignal;
2430
+ if (external.aborted) abortController.abort(external.reason);
2431
+ else external.addEventListener("abort", () => abortController.abort(external.reason), { once: true });
2432
+ }
2433
+ registryEntry.abortController = abortController;
2434
+ registryEntry.abortSignal = abortController.signal;
2435
+ globalRunRegistry.set(runId, registryEntry);
2436
+ workflowInput.stepIndex = 0;
2437
+ let cleanedUp = false;
2438
+ const finalizeGlobalRegistry = () => {
2439
+ if (cleanedUp) return;
2440
+ cleanedUp = true;
2441
+ globalRunRegistry.delete(runId);
2442
+ };
2443
+ const { output, cleanup: streamCleanup, ready } = createDurableAgentStream({
2444
+ pubsub: getPubsub(),
2445
+ runId,
2446
+ messageId,
2447
+ model: {
2448
+ modelId: workflowInput.modelConfig.modelId,
2449
+ provider: workflowInput.modelConfig.provider,
2450
+ version: "v3"
2451
+ },
2452
+ threadId,
2453
+ resourceId,
2454
+ onChunk: streamOptions?.onChunk,
2455
+ onStepFinish: streamOptions?.onStepFinish,
2456
+ onFinish: async (result) => {
2457
+ try {
2458
+ await streamOptions?.onFinish?.(result);
2459
+ } finally {
2460
+ finalizeGlobalRegistry();
2461
+ }
2462
+ },
2463
+ onError: async (errorArg) => {
2464
+ try {
2465
+ await streamOptions?.onError?.(errorArg);
2466
+ } finally {
2467
+ finalizeGlobalRegistry();
2468
+ }
2469
+ },
2470
+ onSuspended: streamOptions?.onSuspended,
2471
+ onAbort: async (data) => {
2472
+ try {
2473
+ await (streamOptions?.onAbort)?.(data);
2474
+ } finally {
2475
+ finalizeGlobalRegistry();
2476
+ }
2477
+ },
2478
+ onIterationComplete: streamOptions?.onIterationComplete ? async (data) => {
2479
+ await streamOptions.onIterationComplete?.(data);
2480
+ } : void 0,
2481
+ closeOnSuspend: streamOptions?.[CLOSE_ON_SUSPEND] === true
2482
+ });
2483
+ const agentSpanData = workflowInput.agentSpanData;
2484
+ const tracingOptions = agentSpanData?.traceId && agentSpanData?.id ? {
2485
+ traceId: agentSpanData.traceId,
2486
+ parentSpanId: agentSpanData.id
2487
+ } : void 0;
2488
+ const workflowExecution = ready.then(() => triggerWorkflow(runId, workflowInput, tracingOptions, streamOptions?.actor)).catch((error) => {
2489
+ emitError(runId, error);
2490
+ });
2491
+ const trackedEntry = globalRunRegistry.get(runId);
2492
+ if (trackedEntry) trackedEntry.workflowExecution = workflowExecution;
2493
+ await agentThreadStreamRuntime.registerRun(proxyRef, output, streamOptions ?? {}, agent.getPubSub());
2494
+ const cleanup = () => {
2495
+ streamCleanup();
2496
+ finalizeGlobalRegistry();
2497
+ };
2498
+ const abort = async (reason) => {
2499
+ if (!abortController.signal.aborted) abortController.abort(reason);
2500
+ await requestRemoteAbort(runId);
2501
+ };
2502
+ return {
2503
+ output,
2504
+ runId,
2505
+ threadId,
2506
+ resourceId,
2507
+ cleanup,
2508
+ abort,
2509
+ get fullStream() {
2510
+ return output.fullStream;
2511
+ },
2512
+ [STREAM_CLEANUP]: streamCleanup
2513
+ };
2514
+ },
2515
+ async resume(runId, resumeData, resumeOptions) {
2516
+ if (resumeOptions?.untilIdle) {
2517
+ const { untilIdle, ...rest } = resumeOptions;
2518
+ const maxIdleMs = typeof untilIdle === "object" ? untilIdle.maxIdleMs : void 0;
2519
+ return runResumeDurableStreamUntilIdle(proxyRef, runId, resumeData, {
2520
+ ...rest,
2521
+ maxIdleMs
2522
+ }, {
2523
+ activeStreams: activeStreamUntilIdle,
2524
+ bgManager: mastra?.backgroundTaskManager
2525
+ });
2526
+ }
2527
+ const existingRegistryEntry = globalRunRegistry.get(runId);
2528
+ await (existingRegistryEntry?.workflowExecution)?.catch(() => {});
2529
+ const resumeOffset = await getPubsubOffset(runId);
2530
+ const abortController = new AbortController();
2531
+ if (resumeOptions?.abortSignal) {
2532
+ const external = resumeOptions.abortSignal;
2533
+ if (external.aborted) abortController.abort(external.reason);
2534
+ else external.addEventListener("abort", () => abortController.abort(external.reason), { once: true });
2535
+ }
2536
+ let existingEntry = existingRegistryEntry;
2537
+ if (!existingEntry) {
2538
+ existingEntry = {
2539
+ isPlaceholder: true,
2540
+ tools: {},
2541
+ model: void 0
2542
+ };
2543
+ globalRunRegistry.set(runId, existingEntry);
2544
+ }
2545
+ existingEntry.abortController = abortController;
2546
+ existingEntry.abortSignal = abortController.signal;
2547
+ let resumeCleanedUp = false;
2548
+ const finalizeResumeRegistry = () => {
2549
+ if (resumeCleanedUp) return;
2550
+ resumeCleanedUp = true;
2551
+ globalRunRegistry.delete(runId);
2552
+ };
2553
+ const { output, cleanup: streamCleanup, ready } = createDurableAgentStream({
2554
+ pubsub: getPubsub(),
2555
+ runId,
2556
+ offset: resumeOffset,
2557
+ messageId: crypto.randomUUID(),
2558
+ model: {
2559
+ modelId: void 0,
2560
+ provider: void 0,
2561
+ version: "v3"
2562
+ },
2563
+ threadId: resumeOptions?.threadId,
2564
+ resourceId: resumeOptions?.resourceId,
2565
+ onChunk: resumeOptions?.onChunk,
2566
+ onStepFinish: resumeOptions?.onStepFinish,
2567
+ onFinish: async (result) => {
2568
+ try {
2569
+ await resumeOptions?.onFinish?.(result);
2570
+ } finally {
2571
+ finalizeResumeRegistry();
2572
+ }
2573
+ },
2574
+ onError: async (errorArg) => {
2575
+ try {
2576
+ await resumeOptions?.onError?.(errorArg);
2577
+ } finally {
2578
+ finalizeResumeRegistry();
2579
+ }
2580
+ },
2581
+ onSuspended: resumeOptions?.onSuspended,
2582
+ onAbort: async (data) => {
2583
+ try {
2584
+ await (resumeOptions?.onAbort)?.(data);
2585
+ } finally {
2586
+ finalizeResumeRegistry();
2587
+ }
2588
+ },
2589
+ closeOnSuspend: resumeOptions?.[CLOSE_ON_SUSPEND] === true
2590
+ });
2591
+ const eventName = `workflow.${InngestDurableStepIds.AGENTIC_LOOP}`;
2592
+ let notResumable = false;
2593
+ const dispatch = ready.then(async () => {
2594
+ const workflowsStore = await mastra?.getStorage()?.getStore("workflows");
2595
+ const loadSnapshot = async () => workflowsStore?.loadWorkflowSnapshot({
2596
+ workflowName: InngestDurableStepIds.AGENTIC_LOOP,
2597
+ runId
2598
+ });
2599
+ let snapshot = await loadSnapshot();
2600
+ const deadline = Date.now() + RESUME_SNAPSHOT_WAIT_MS;
2601
+ while (workflowsStore && snapshot?.status !== "suspended" && Date.now() < deadline) {
2602
+ await new Promise((resolve) => setTimeout(resolve, RESUME_SNAPSHOT_POLL_MS));
2603
+ snapshot = await loadSnapshot();
2604
+ }
2605
+ if (workflowsStore && snapshot?.status !== "suspended") {
2606
+ notResumable = true;
2607
+ throw new NonRetriableError(`Cannot resume run ${runId}: it is not suspended` + (snapshot?.status ? ` (status: ${snapshot.status}).` : " (no snapshot found)."));
2608
+ }
2609
+ const suspendedStepIds = snapshot?.suspendedPaths ? Object.keys(snapshot.suspendedPaths) : [];
2610
+ const resumeLabels = snapshot?.resumeLabels ?? {};
2611
+ const toolCallId = resumeOptions?.toolCallId;
2612
+ const expandToLeafPath = (stepId) => {
2613
+ const nestedPath = (snapshot?.context ?? {})[stepId]?.suspendPayload?.__workflow_meta?.path;
2614
+ return Array.isArray(nestedPath) ? [stepId, ...nestedPath] : [stepId];
2615
+ };
2616
+ let steps;
2617
+ if (toolCallId) {
2618
+ const targetStepId = resumeLabels[toolCallId]?.stepId;
2619
+ if (!targetStepId) {
2620
+ const available = Object.keys(resumeLabels);
2621
+ throw new NonRetriableError(`Cannot resume run ${runId}: no suspended tool call with id "${toolCallId}". ` + (available.length > 0 ? `Suspended tool call ids: ${available.join(", ")}.` : `No tool calls are currently suspended.`));
2622
+ }
2623
+ steps = expandToLeafPath(targetStepId);
2624
+ } else {
2625
+ const available = Object.keys(resumeLabels);
2626
+ if (suspendedStepIds.length > 1 || available.length > 1) throw new NonRetriableError(`Cannot resume run ${runId}: more than one suspension is parked. Pass "toolCallId" to choose which suspended tool call to resume.` + (available.length > 0 ? ` Suspended tool call ids: ${available.join(", ")}.` : ""));
2627
+ steps = suspendedStepIds[0] ? expandToLeafPath(suspendedStepIds[0]) : [];
2628
+ }
2629
+ const requestContext = mergeResumeRequestContext(snapshot?.requestContext, resumeOptions?.requestContext);
2630
+ const tracingOptions = snapshot?.tracingContext ? {
2631
+ traceId: snapshot.tracingContext.traceId,
2632
+ parentSpanId: snapshot.tracingContext.spanId
2633
+ } : void 0;
2634
+ await inngest.send({
2635
+ name: eventName,
2636
+ data: buildDurableResumeEventData({
2637
+ inputData: resumeData,
2638
+ runId,
2639
+ resourceId: resumeOptions?.resourceId,
2640
+ requestContext,
2641
+ tracingOptions,
2642
+ actor: resumeOptions?.actor,
2643
+ resume: {
2644
+ steps,
2645
+ resumePayload: resumeData,
2646
+ resumePath: steps[0] ? snapshot?.suspendedPaths?.[steps[0]] : void 0
2647
+ }
2648
+ })
2649
+ });
2650
+ });
2651
+ const workflowExecution = dispatch.catch((error) => {
2652
+ if (!notResumable) emitError(runId, error);
2653
+ });
2654
+ existingEntry.workflowExecution = workflowExecution;
2655
+ try {
2656
+ await dispatch;
2657
+ } catch (error) {
2658
+ streamCleanup();
2659
+ finalizeResumeRegistry();
2660
+ throw error;
2661
+ }
2662
+ const abort = async (reason) => {
2663
+ if (!abortController.signal.aborted) abortController.abort(reason);
2664
+ await requestRemoteAbort(runId);
2665
+ };
2666
+ const cleanup = () => {
2667
+ streamCleanup();
2668
+ finalizeResumeRegistry();
2669
+ };
2670
+ return {
2671
+ output,
2672
+ get fullStream() {
2673
+ return output.fullStream;
2674
+ },
2675
+ runId,
2676
+ threadId: resumeOptions?.threadId,
2677
+ resourceId: resumeOptions?.resourceId,
2678
+ cleanup,
2679
+ abort,
2680
+ [STREAM_CLEANUP]: streamCleanup
2681
+ };
2682
+ },
2683
+ async prepare(messages, prepareOptions) {
2684
+ const preparation = await prepareForDurableExecution({
2685
+ agent,
2686
+ messages,
2687
+ options: prepareOptions,
2688
+ requestContext: prepareOptions?.requestContext,
2689
+ mastra,
2690
+ durableAgentId: agentId,
2691
+ durableAgentName: agentName
2692
+ });
2693
+ preparation.workflowInput.agentId = agentId;
2694
+ preparation.workflowInput.agentName = agentName;
2695
+ return {
2696
+ runId: preparation.runId,
2697
+ messageId: preparation.messageId,
2698
+ workflowInput: preparation.workflowInput,
2699
+ threadId: preparation.threadId,
2700
+ resourceId: preparation.resourceId
2701
+ };
2702
+ },
2703
+ async observe(runId, observeOptions) {
2704
+ const { output, cleanup: streamCleanup, ready } = createDurableAgentStream({
2705
+ pubsub: getPubsub(),
2706
+ runId,
2707
+ messageId: crypto.randomUUID(),
2708
+ model: {
2709
+ modelId: void 0,
2710
+ provider: void 0,
2711
+ version: "v3"
2712
+ },
2713
+ offset: observeOptions?.offset,
2714
+ onChunk: observeOptions?.onChunk,
2715
+ onStepFinish: observeOptions?.onStepFinish,
2716
+ onFinish: observeOptions?.onFinish,
2717
+ onError: observeOptions?.onError,
2718
+ onSuspended: observeOptions?.onSuspended
2719
+ });
2720
+ await ready;
2721
+ const abort = async (_reason) => {
2722
+ streamCleanup();
2723
+ await requestRemoteAbort(runId);
2724
+ };
2725
+ return {
2726
+ output,
2727
+ get fullStream() {
2728
+ return output.fullStream;
2729
+ },
2730
+ runId,
2731
+ cleanup: streamCleanup,
2732
+ abort
2733
+ };
2734
+ },
2735
+ async generate(messages, generateOptions) {
2736
+ const { untilIdle, ...rest } = generateOptions ?? {};
2737
+ const streamOpts = {
2738
+ ...rest,
2739
+ [CLOSE_ON_SUSPEND]: true,
2740
+ __methodType: "generate"
2741
+ };
2742
+ const result = await proxyRef.stream(messages, streamOpts);
2743
+ let suspended = false;
2744
+ try {
2745
+ const fullOutput = await result.output.getFullOutput();
2746
+ if (fullOutput.error) throw fullOutput.error;
2747
+ suspended = fullOutput.finishReason === "suspended";
2748
+ if (suspended) await globalRunRegistry.get(result.runId)?.workflowExecution;
2749
+ if (!fullOutput.runId) fullOutput.runId = result.runId;
2750
+ return fullOutput;
2751
+ } finally {
2752
+ if (suspended) {
2753
+ const streamOnlyCleanup = result[STREAM_CLEANUP];
2754
+ streamOnlyCleanup?.();
2755
+ } else result.cleanup();
2756
+ }
2757
+ },
2758
+ async resumeGenerate(runId, resumeData, resumeOptions) {
2759
+ const { untilIdle, ...rest } = resumeOptions ?? {};
2760
+ const result = await proxyRef.resume(runId, resumeData, {
2761
+ ...rest,
2762
+ [CLOSE_ON_SUSPEND]: true
2763
+ });
2764
+ let suspended = false;
2765
+ try {
2766
+ const fullOutput = await result.output.getFullOutput();
2767
+ if (fullOutput.error) throw fullOutput.error;
2768
+ suspended = fullOutput.finishReason === "suspended";
2769
+ if (suspended) await globalRunRegistry.get(result.runId)?.workflowExecution;
2770
+ if (!fullOutput.runId) fullOutput.runId = result.runId;
2771
+ return fullOutput;
2772
+ } finally {
2773
+ if (suspended) {
2774
+ const streamOnlyCleanup = result[STREAM_CLEANUP];
2775
+ streamOnlyCleanup?.();
2776
+ } else result.cleanup();
2777
+ }
2778
+ },
2779
+ async resumeStream(resumeData, streamOptions) {
2780
+ const runId = streamOptions?.runId;
2781
+ if (!runId) throw new Error("resumeStream() on InngestAgent requires a runId in streamOptions.");
2782
+ const { runId: _runId, ...resumeOptions } = streamOptions;
2783
+ return (await proxyRef.resume(runId, resumeData, {
2784
+ ...resumeOptions,
2785
+ [CLOSE_ON_SUSPEND]: true
2786
+ })).output;
2787
+ },
2788
+ async approveToolCall(options) {
2789
+ return proxyRef.resumeStream({ approved: true }, options);
2790
+ },
2791
+ async declineToolCall(options) {
2792
+ const { reason, ...resumeOptions } = options;
2793
+ return proxyRef.resumeStream({
2794
+ approved: false,
2795
+ ...reason !== void 0 ? { reason } : {}
2796
+ }, resumeOptions);
2797
+ },
2798
+ async approveToolCallGenerate(options) {
2799
+ const { runId, ...resumeOptions } = options;
2800
+ if (!runId) throw new Error("approveToolCallGenerate() on InngestAgent requires a runId.");
2801
+ return proxyRef.resumeGenerate(runId, { approved: true }, resumeOptions);
2802
+ },
2803
+ async declineToolCallGenerate(options) {
2804
+ const { runId, reason, ...resumeOptions } = options;
2805
+ if (!runId) throw new Error("declineToolCallGenerate() on InngestAgent requires a runId.");
2806
+ return proxyRef.resumeGenerate(runId, {
2807
+ approved: false,
2808
+ ...reason !== void 0 ? { reason } : {}
2809
+ }, resumeOptions);
2810
+ },
2811
+ __fork() {
2812
+ const { shouldPersistSnapshot: _ignored, ...forkOptions } = options;
2813
+ return createInngestAgent({
2814
+ ...forkOptions,
2815
+ agent: agent.__fork(),
2816
+ pubsub: innerPubsub,
2817
+ cache: _customCache,
2818
+ mastra
2819
+ });
2820
+ },
2821
+ getDurableWorkflows() {
2822
+ return [workflow];
2823
+ },
2824
+ __setMastra(mastraInstance) {
2825
+ mastra = mastraInstance;
2826
+ }
2827
+ }, {
2828
+ get(target, prop, receiver) {
2829
+ if (prop in target) return Reflect.get(target, prop, receiver);
2830
+ const agentValue = agent[prop];
2831
+ if (typeof agentValue === "function") return agentValue.bind(agent);
2832
+ return agentValue;
2833
+ },
2834
+ has(target, prop) {
2835
+ return prop in target || prop in agent;
2836
+ }
2837
+ });
2838
+ proxyRef = result;
2839
+ agent.__setThreadRuntimeAgent(result);
2840
+ return result;
2841
+ }
2842
+ /**
2843
+ * Check if an object is an InngestAgent
2844
+ */
2845
+ function isInngestAgent(obj) {
2846
+ if (!obj) return false;
2847
+ return typeof obj.id === "string" && typeof obj.name === "string" && "agent" in obj && "inngest" in obj && typeof obj.stream === "function" && typeof obj.getDurableWorkflows === "function";
2848
+ }
2849
+ //#endregion
1965
2850
  //#region src/functions.ts
1966
2851
  function collectInngestFunctions({ mastra, functions: userFunctions = [] }) {
1967
- const workflows = mastra.listWorkflows();
1968
- return [...Array.from(new Set(Object.values(workflows).flatMap((workflow) => {
1969
- if (workflow instanceof InngestWorkflow) {
1970
- workflow.__registerMastra(mastra);
1971
- return workflow.getFunctions();
2852
+ /**
2853
+ * Inngest agents share the same logical durable workflow IDs and resolve the
2854
+ * concrete agent from the workflow input, so only the first registered
2855
+ * agent's workflow needs to be served.
2856
+ */
2857
+ const durableAgent = Object.values(mastra.listAgents()).find((agent) => isInngestAgent(agent));
2858
+ const workflows = [...Object.values(mastra.listWorkflows()), ...durableAgent?.getDurableWorkflows() ?? []];
2859
+ const workflowFunctions = /* @__PURE__ */ new Map();
2860
+ for (const workflow of workflows) {
2861
+ if (!(workflow instanceof InngestWorkflow)) continue;
2862
+ workflow.__registerMastra(mastra);
2863
+ for (const fn of workflow.getFunctions()) {
2864
+ const functionId = fn.id();
2865
+ if (!workflowFunctions.has(functionId)) workflowFunctions.set(functionId, fn);
1972
2866
  }
1973
- return [];
1974
- }))), ...userFunctions];
2867
+ }
2868
+ return [...workflowFunctions.values(), ...userFunctions];
1975
2869
  }
1976
2870
  //#endregion
2871
+ //#region src/serve.ts
2872
+ /**
2873
+ * Collects workflow functions from Mastra and prepares serve options for inngest.
2874
+ */
2875
+ function prepareServeOptions({ mastra, inngest, functions: userFunctions = [], registerOptions }) {
2876
+ return {
2877
+ ...registerOptions,
2878
+ client: inngest,
2879
+ functions: collectInngestFunctions({
2880
+ mastra,
2881
+ functions: userFunctions
2882
+ })
2883
+ };
2884
+ }
2885
+ /**
2886
+ * Factory function to create a serve function with any inngest adapter.
2887
+ * Use this to integrate Mastra workflows with any framework supported by inngest.
2888
+ *
2889
+ * @example Express
2890
+ * ```ts
2891
+ * import { createServe } from '@mastra/inngest';
2892
+ * import { serve } from 'inngest/express';
2893
+ *
2894
+ * const serveExpress = createServe(serve);
2895
+ * app.use('/inngest/api', serveExpress({ mastra, inngest }));
2896
+ * ```
2897
+ *
2898
+ * @example Fastify
2899
+ * ```ts
2900
+ * import { createServe } from '@mastra/inngest';
2901
+ * import { serve } from 'inngest/fastify';
2902
+ *
2903
+ * const serveFastify = createServe(serve);
2904
+ * fastify.route({
2905
+ * method: ['GET', 'POST', 'PUT'],
2906
+ * handler: serveFastify({ mastra, inngest }),
2907
+ * url: '/inngest/api',
2908
+ * });
2909
+ * ```
2910
+ *
2911
+ * @example Next.js
2912
+ * ```ts
2913
+ * // app/inngest/api/route.ts — file path determines the route URL
2914
+ * import { createServe } from '@mastra/inngest';
2915
+ * import { serve } from 'inngest/next';
2916
+ *
2917
+ * const serveNext = createServe(serve);
2918
+ * export const { GET, POST, PUT } = serveNext({ mastra, inngest });
2919
+ * ```
2920
+ */
2921
+ function createServe(adapter) {
2922
+ return (options) => {
2923
+ return adapter(prepareServeOptions(options));
2924
+ };
2925
+ }
2926
+ /**
2927
+ * Serve Mastra workflows with Hono (default).
2928
+ *
2929
+ * For other frameworks, use `createServe` with the appropriate inngest adapter.
2930
+ *
2931
+ * @example
2932
+ * ```ts
2933
+ * import { serve } from '@mastra/inngest';
2934
+ *
2935
+ * app.use('/inngest/api', async (c) => {
2936
+ * return serve({ mastra, inngest })(c);
2937
+ * });
2938
+ * ```
2939
+ */
2940
+ const serve$1 = createServe(serve);
2941
+ //#endregion
1977
2942
  //#region src/connect.ts
1978
2943
  /**
1979
2944
  * Connect Mastra workflows to Inngest using an outbound worker connection.
@@ -2013,6 +2978,514 @@ async function connect(options) {
2013
2978
  });
2014
2979
  }
2015
2980
  //#endregion
2016
- export { buildDurableResumeEventData as a, InngestPubSub as c, InngestRun as i, InngestExecutionEngine as l, collectInngestFunctions as n, buildDurableTriggerEventData as o, InngestWorkflow as r, mergeResumeRequestContext as s, connect as t };
2981
+ //#region src/types.ts
2982
+ const _compatibilityCheck = true;
2983
+ //#endregion
2984
+ //#region src/index.ts
2985
+ function isInngestWorkflow(input) {
2986
+ return input instanceof InngestWorkflow;
2987
+ }
2988
+ /**
2989
+ * copied from @mastra/core/agent/subagent.ts for compatible
2990
+ */
2991
+ function isAgentCompatible(input) {
2992
+ 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";
2993
+ }
2994
+ function isToolStep(input) {
2995
+ return input instanceof Tool;
2996
+ }
2997
+ function isStepParams(input) {
2998
+ return input !== null && typeof input === "object" && "id" in input && "execute" in input && !(input instanceof Agent) && !(input instanceof Tool) && !(input instanceof InngestWorkflow);
2999
+ }
3000
+ /**
3001
+ * Type guard to check if an object is a Processor.
3002
+ * A Processor must have an 'id' property and at least one processor method.
3003
+ */
3004
+ function isProcessor(obj) {
3005
+ 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");
3006
+ }
3007
+ function createStep(params, agentOrToolOptions) {
3008
+ if (isInngestWorkflow(params)) return params;
3009
+ if (isAgentCompatible(params)) return createStepFromAgent$1(params, agentOrToolOptions);
3010
+ if (isToolStep(params)) return createStepFromTool$1(params, agentOrToolOptions);
3011
+ if (isStepParams(params)) return createStepFromParams(params);
3012
+ if (isProcessor(params)) return createStepFromProcessor(params);
3013
+ throw new Error("Invalid input: expected StepParams, Agent, ToolStep, Processor, or InngestWorkflow");
3014
+ }
3015
+ function createStepFromParams(params) {
3016
+ return {
3017
+ id: params.id,
3018
+ description: params.description,
3019
+ inputSchema: toStandardSchema(params.inputSchema),
3020
+ stateSchema: params.stateSchema ? toStandardSchema(params.stateSchema) : void 0,
3021
+ outputSchema: toStandardSchema(params.outputSchema),
3022
+ resumeSchema: params.resumeSchema ? toStandardSchema(params.resumeSchema) : void 0,
3023
+ suspendSchema: params.suspendSchema ? toStandardSchema(params.suspendSchema) : void 0,
3024
+ scorers: params.scorers,
3025
+ retries: params.retries,
3026
+ metadata: params.metadata,
3027
+ execute: params.execute.bind(params)
3028
+ };
3029
+ }
3030
+ function createStepFromAgent$1(params, agentOrToolOptions) {
3031
+ return createStepFromAgent(params, agentOrToolOptions);
3032
+ }
3033
+ function createStepFromTool$1(params, agentOrToolOptions) {
3034
+ return createStepFromTool(params, agentOrToolOptions);
3035
+ }
3036
+ function createStepFromProcessor(processor) {
3037
+ const getProcessorEntityType = (phase) => {
3038
+ switch (phase) {
3039
+ case "input": return EntityType.INPUT_PROCESSOR;
3040
+ case "inputStep": return EntityType.INPUT_STEP_PROCESSOR;
3041
+ case "outputStream":
3042
+ case "outputResult": return EntityType.OUTPUT_PROCESSOR;
3043
+ case "outputStep": return EntityType.OUTPUT_STEP_PROCESSOR;
3044
+ default: return EntityType.OUTPUT_PROCESSOR;
3045
+ }
3046
+ };
3047
+ const getSpanNamePrefix = (phase) => {
3048
+ switch (phase) {
3049
+ case "input": return "input processor";
3050
+ case "inputStep": return "input step processor";
3051
+ case "outputStream": return "output stream processor";
3052
+ case "outputResult": return "output processor";
3053
+ case "outputStep": return "output step processor";
3054
+ default: return "processor";
3055
+ }
3056
+ };
3057
+ const hasPhaseMethod = (phase) => {
3058
+ switch (phase) {
3059
+ case "input": return !!processor.processInput;
3060
+ case "inputStep": return !!processor.processInputStep;
3061
+ case "outputStream": return !!processor.processOutputStream;
3062
+ case "outputResult": return !!processor.processOutputResult;
3063
+ case "outputStep": return !!processor.processOutputStep;
3064
+ default: return false;
3065
+ }
3066
+ };
3067
+ return {
3068
+ id: `processor:${processor.id}`,
3069
+ description: processor.name ?? `Processor ${processor.id}`,
3070
+ inputSchema: ProcessorStepSchema,
3071
+ outputSchema: ProcessorStepOutputSchema,
3072
+ execute: async ({ inputData, requestContext, tracingContext }) => {
3073
+ const input = inputData;
3074
+ const { phase, messages, messageList, stepNumber, systemMessages, part, streamParts, processorStates, result, finishReason, toolCalls, text, retryCount, model, tools, toolChoice, activeTools, providerOptions, modelSettings, structuredOutput, steps, usage } = input;
3075
+ const abort = (reason, options) => {
3076
+ throw new TripWire(reason || `Tripwire triggered by ${processor.id}`, options, processor.id);
3077
+ };
3078
+ if (!hasPhaseMethod(phase)) return input;
3079
+ const currentSpan = tracingContext?.currentSpan;
3080
+ const parentSpan = phase === "inputStep" || phase === "outputStep" ? currentSpan?.findParent(SpanType.MODEL_STEP) || currentSpan : currentSpan?.findParent(SpanType.AGENT_RUN) || currentSpan;
3081
+ const processorSpan = phase !== "outputStream" ? parentSpan?.createChildSpan({
3082
+ type: SpanType.PROCESSOR_RUN,
3083
+ name: `${getSpanNamePrefix(phase)}: ${processor.id}`,
3084
+ entityType: getProcessorEntityType(phase),
3085
+ entityId: processor.id,
3086
+ entityName: processor.name ?? processor.id,
3087
+ input: {
3088
+ phase,
3089
+ messageCount: messages?.length
3090
+ },
3091
+ attributes: {
3092
+ processorExecutor: "workflow",
3093
+ processorIndex: processor.processorIndex
3094
+ }
3095
+ }) : void 0;
3096
+ const processorTracingContext = processorSpan ? { currentSpan: processorSpan } : tracingContext;
3097
+ let processorState = {};
3098
+ if (processorStates) {
3099
+ let ps = processorStates.get(processor.id);
3100
+ if (!ps) {
3101
+ ps = new ProcessorState(processor.id);
3102
+ processorStates.set(processor.id, ps);
3103
+ }
3104
+ processorState = ps.customState;
3105
+ }
3106
+ const baseContext = {
3107
+ abort,
3108
+ retryCount: retryCount ?? 0,
3109
+ requestContext,
3110
+ tracingContext: processorTracingContext
3111
+ };
3112
+ const passThrough = {
3113
+ phase,
3114
+ messageList: messageList ?? (Array.isArray(messages) ? new MessageList().add(messages, "input").addSystem(systemMessages ?? []) : void 0),
3115
+ stepNumber,
3116
+ systemMessages,
3117
+ streamParts,
3118
+ state: processorState,
3119
+ processorStates,
3120
+ result,
3121
+ finishReason,
3122
+ toolCalls,
3123
+ text,
3124
+ retryCount,
3125
+ model,
3126
+ tools,
3127
+ toolChoice,
3128
+ activeTools,
3129
+ providerOptions,
3130
+ modelSettings,
3131
+ structuredOutput,
3132
+ steps,
3133
+ usage
3134
+ };
3135
+ const executePhaseWithSpan = async (fn) => {
3136
+ try {
3137
+ const result = await fn();
3138
+ processorSpan?.end({ output: result });
3139
+ return result;
3140
+ } catch (error) {
3141
+ if (error instanceof TripWire) processorSpan?.end({ output: { tripwire: error.message } });
3142
+ else processorSpan?.error({
3143
+ error,
3144
+ endSpan: true
3145
+ });
3146
+ throw error;
3147
+ }
3148
+ };
3149
+ return executePhaseWithSpan(async () => {
3150
+ switch (phase) {
3151
+ case "input":
3152
+ if (processor.processInput) {
3153
+ if (!passThrough.messageList) throw new MastraError({
3154
+ category: ErrorCategory.USER,
3155
+ domain: ErrorDomain.MASTRA_WORKFLOW,
3156
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
3157
+ text: `Processor ${processor.id} requires messageList or messages for processInput phase`
3158
+ });
3159
+ const idsBeforeProcessing = messages.map((m) => m.id);
3160
+ const check = passThrough.messageList.makeMessageSourceChecker();
3161
+ const result = await processor.processInput({
3162
+ ...baseContext,
3163
+ messages,
3164
+ messageList: passThrough.messageList,
3165
+ systemMessages: systemMessages ?? [],
3166
+ state: processorState
3167
+ });
3168
+ if (result instanceof MessageList) {
3169
+ if (result !== passThrough.messageList) throw new MastraError({
3170
+ category: ErrorCategory.USER,
3171
+ domain: ErrorDomain.MASTRA_WORKFLOW,
3172
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
3173
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
3174
+ });
3175
+ return {
3176
+ ...passThrough,
3177
+ messages: result.get.all.db(),
3178
+ systemMessages: result.getSystemMessages()
3179
+ };
3180
+ } else if (Array.isArray(result)) {
3181
+ ProcessorRunner.applyMessagesToMessageList(result, passThrough.messageList, idsBeforeProcessing, check, "input");
3182
+ return {
3183
+ ...passThrough,
3184
+ messages: result
3185
+ };
3186
+ } else if (result && "messages" in result && "systemMessages" in result) {
3187
+ const typedResult = result;
3188
+ ProcessorRunner.applyMessagesToMessageList(typedResult.messages, passThrough.messageList, idsBeforeProcessing, check, "input");
3189
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
3190
+ return {
3191
+ ...passThrough,
3192
+ messages: typedResult.messages,
3193
+ systemMessages: passThrough.messageList.getSystemMessages()
3194
+ };
3195
+ }
3196
+ return {
3197
+ ...passThrough,
3198
+ messages
3199
+ };
3200
+ }
3201
+ return {
3202
+ ...passThrough,
3203
+ messages
3204
+ };
3205
+ case "inputStep":
3206
+ if (processor.processInputStep) {
3207
+ if (!passThrough.messageList) throw new MastraError({
3208
+ category: ErrorCategory.USER,
3209
+ domain: ErrorDomain.MASTRA_WORKFLOW,
3210
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
3211
+ text: `Processor ${processor.id} requires messageList or messages for processInputStep phase`
3212
+ });
3213
+ const idsBeforeProcessing = messages.map((m) => m.id);
3214
+ const check = passThrough.messageList.makeMessageSourceChecker();
3215
+ const result = await processor.processInputStep({
3216
+ ...baseContext,
3217
+ messages,
3218
+ messageList: passThrough.messageList,
3219
+ stepNumber: stepNumber ?? 0,
3220
+ systemMessages: systemMessages ?? [],
3221
+ model,
3222
+ tools,
3223
+ toolChoice,
3224
+ activeTools,
3225
+ providerOptions,
3226
+ modelSettings,
3227
+ structuredOutput,
3228
+ steps: steps ?? [],
3229
+ state: processorState
3230
+ });
3231
+ const validatedResult = await ProcessorRunner.validateAndFormatProcessInputStepResult(result, {
3232
+ messageList: passThrough.messageList,
3233
+ processor,
3234
+ stepNumber: stepNumber ?? 0
3235
+ });
3236
+ if (validatedResult.messages) ProcessorRunner.applyMessagesToMessageList(validatedResult.messages, passThrough.messageList, idsBeforeProcessing, check);
3237
+ if (validatedResult.systemMessages) passThrough.messageList.replaceAllSystemMessages(validatedResult.systemMessages);
3238
+ return {
3239
+ ...passThrough,
3240
+ messages,
3241
+ ...validatedResult,
3242
+ systemMessages: passThrough.messageList.getSystemMessages()
3243
+ };
3244
+ }
3245
+ return {
3246
+ ...passThrough,
3247
+ messages
3248
+ };
3249
+ case "outputStream":
3250
+ if (processor.processOutputStream) {
3251
+ const spanKey = `__outputStreamSpan_${processor.id}`;
3252
+ const mutableState = processorState;
3253
+ let processorSpan = mutableState[spanKey];
3254
+ if (!processorSpan && parentSpan) {
3255
+ processorSpan = parentSpan.createChildSpan({
3256
+ type: SpanType.PROCESSOR_RUN,
3257
+ name: `output stream processor: ${processor.id}`,
3258
+ entityType: EntityType.OUTPUT_PROCESSOR,
3259
+ entityId: processor.id,
3260
+ entityName: processor.name ?? processor.id,
3261
+ input: {
3262
+ phase,
3263
+ streamParts: []
3264
+ },
3265
+ attributes: {
3266
+ processorExecutor: "workflow",
3267
+ processorIndex: processor.processorIndex
3268
+ }
3269
+ });
3270
+ mutableState[spanKey] = processorSpan;
3271
+ }
3272
+ if (processorSpan) processorSpan.input = {
3273
+ phase,
3274
+ streamParts: streamParts ?? [],
3275
+ totalChunks: (streamParts ?? []).length
3276
+ };
3277
+ const processorTracingContext = processorSpan ? { currentSpan: processorSpan } : baseContext.tracingContext;
3278
+ let result;
3279
+ try {
3280
+ result = await processor.processOutputStream({
3281
+ ...baseContext,
3282
+ tracingContext: processorTracingContext,
3283
+ part,
3284
+ streamParts: streamParts ?? [],
3285
+ state: mutableState,
3286
+ messageList: passThrough.messageList
3287
+ });
3288
+ if (part && part.type === "finish") {
3289
+ processorSpan?.end({ output: result });
3290
+ delete mutableState[spanKey];
3291
+ }
3292
+ } catch (error) {
3293
+ if (error instanceof TripWire) processorSpan?.end({ output: { tripwire: error.message } });
3294
+ else processorSpan?.error({
3295
+ error,
3296
+ endSpan: true
3297
+ });
3298
+ delete mutableState[spanKey];
3299
+ throw error;
3300
+ }
3301
+ return {
3302
+ ...passThrough,
3303
+ state: mutableState,
3304
+ part: result
3305
+ };
3306
+ }
3307
+ return {
3308
+ ...passThrough,
3309
+ part
3310
+ };
3311
+ case "outputResult":
3312
+ if (processor.processOutputResult) {
3313
+ if (!passThrough.messageList) throw new MastraError({
3314
+ category: ErrorCategory.USER,
3315
+ domain: ErrorDomain.MASTRA_WORKFLOW,
3316
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
3317
+ text: `Processor ${processor.id} requires messageList or messages for processOutputResult phase`
3318
+ });
3319
+ const idsBeforeProcessing = messages.map((m) => m.id);
3320
+ const check = passThrough.messageList.makeMessageSourceChecker();
3321
+ const outputResult = passThrough.result ?? {
3322
+ text: "",
3323
+ usage: {
3324
+ inputTokens: 0,
3325
+ outputTokens: 0,
3326
+ totalTokens: 0
3327
+ },
3328
+ finishReason: "unknown",
3329
+ steps: []
3330
+ };
3331
+ const processResult = await processor.processOutputResult({
3332
+ ...baseContext,
3333
+ messages,
3334
+ messageList: passThrough.messageList,
3335
+ state: processorState,
3336
+ result: outputResult
3337
+ });
3338
+ if (processResult instanceof MessageList) {
3339
+ if (processResult !== passThrough.messageList) throw new MastraError({
3340
+ category: ErrorCategory.USER,
3341
+ domain: ErrorDomain.MASTRA_WORKFLOW,
3342
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
3343
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
3344
+ });
3345
+ return {
3346
+ ...passThrough,
3347
+ messages: processResult.get.all.db(),
3348
+ systemMessages: processResult.getSystemMessages()
3349
+ };
3350
+ } else if (Array.isArray(processResult)) {
3351
+ ProcessorRunner.applyMessagesToMessageList(processResult, passThrough.messageList, idsBeforeProcessing, check, "response");
3352
+ return {
3353
+ ...passThrough,
3354
+ messages: processResult
3355
+ };
3356
+ } else if (processResult && "messages" in processResult && "systemMessages" in processResult) {
3357
+ const typedResult = processResult;
3358
+ ProcessorRunner.applyMessagesToMessageList(typedResult.messages, passThrough.messageList, idsBeforeProcessing, check, "response");
3359
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
3360
+ return {
3361
+ ...passThrough,
3362
+ messages: typedResult.messages,
3363
+ systemMessages: passThrough.messageList.getSystemMessages()
3364
+ };
3365
+ }
3366
+ return {
3367
+ ...passThrough,
3368
+ messages
3369
+ };
3370
+ }
3371
+ return {
3372
+ ...passThrough,
3373
+ messages
3374
+ };
3375
+ case "outputStep":
3376
+ if (processor.processOutputStep) {
3377
+ if (!passThrough.messageList) throw new MastraError({
3378
+ category: ErrorCategory.USER,
3379
+ domain: ErrorDomain.MASTRA_WORKFLOW,
3380
+ id: "PROCESSOR_MISSING_MESSAGE_LIST",
3381
+ text: `Processor ${processor.id} requires messageList or messages for processOutputStep phase`
3382
+ });
3383
+ const idsBeforeProcessing = messages.map((m) => m.id);
3384
+ const check = passThrough.messageList.makeMessageSourceChecker();
3385
+ const defaultUsage = {
3386
+ inputTokens: void 0,
3387
+ outputTokens: void 0,
3388
+ totalTokens: void 0
3389
+ };
3390
+ const result = await processor.processOutputStep({
3391
+ ...baseContext,
3392
+ messages,
3393
+ messageList: passThrough.messageList,
3394
+ stepNumber: stepNumber ?? 0,
3395
+ finishReason,
3396
+ toolCalls,
3397
+ text,
3398
+ usage: usage ?? defaultUsage,
3399
+ systemMessages: systemMessages ?? [],
3400
+ steps: steps ?? [],
3401
+ state: processorState
3402
+ });
3403
+ if (result instanceof MessageList) {
3404
+ if (result !== passThrough.messageList) throw new MastraError({
3405
+ category: ErrorCategory.USER,
3406
+ domain: ErrorDomain.MASTRA_WORKFLOW,
3407
+ id: "PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST",
3408
+ text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`
3409
+ });
3410
+ return {
3411
+ ...passThrough,
3412
+ messages: result.get.all.db(),
3413
+ systemMessages: result.getSystemMessages()
3414
+ };
3415
+ } else if (Array.isArray(result)) {
3416
+ ProcessorRunner.applyMessagesToMessageList(result, passThrough.messageList, idsBeforeProcessing, check, "response");
3417
+ return {
3418
+ ...passThrough,
3419
+ messages: result
3420
+ };
3421
+ } else if (result && "messages" in result && "systemMessages" in result) {
3422
+ const typedResult = result;
3423
+ ProcessorRunner.applyMessagesToMessageList(typedResult.messages, passThrough.messageList, idsBeforeProcessing, check, "response");
3424
+ passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);
3425
+ return {
3426
+ ...passThrough,
3427
+ messages: typedResult.messages,
3428
+ systemMessages: passThrough.messageList.getSystemMessages()
3429
+ };
3430
+ }
3431
+ return {
3432
+ ...passThrough,
3433
+ messages
3434
+ };
3435
+ }
3436
+ return {
3437
+ ...passThrough,
3438
+ messages
3439
+ };
3440
+ default: return {
3441
+ ...passThrough,
3442
+ messages
3443
+ };
3444
+ }
3445
+ });
3446
+ },
3447
+ component: "PROCESSOR"
3448
+ };
3449
+ }
3450
+ function init(inngest) {
3451
+ return {
3452
+ createTool,
3453
+ createWorkflow(params) {
3454
+ return new InngestWorkflow(params, inngest);
3455
+ },
3456
+ createStep,
3457
+ cloneStep(step, opts) {
3458
+ return {
3459
+ id: opts.id,
3460
+ description: step.description,
3461
+ inputSchema: step.inputSchema,
3462
+ outputSchema: step.outputSchema,
3463
+ resumeSchema: step.resumeSchema,
3464
+ suspendSchema: step.suspendSchema,
3465
+ stateSchema: step.stateSchema,
3466
+ metadata: step.metadata,
3467
+ execute: step.execute,
3468
+ retries: step.retries,
3469
+ scorers: step.scorers,
3470
+ component: step.component
3471
+ };
3472
+ },
3473
+ cloneWorkflow(workflow, opts) {
3474
+ const wf = new Workflow({
3475
+ id: opts.id,
3476
+ inputSchema: workflow.inputSchema,
3477
+ outputSchema: workflow.outputSchema,
3478
+ steps: workflow.stepDefs,
3479
+ mastra: workflow.mastra,
3480
+ options: workflow.options
3481
+ });
3482
+ wf.setStepFlow(workflow.stepGraph);
3483
+ wf.commit();
3484
+ return wf;
3485
+ }
3486
+ };
3487
+ }
3488
+ //#endregion
3489
+ export { createServe as a, isInngestAgent as c, InngestRun as d, InngestPubSub as f, connect as i, createInngestDurableAgenticWorkflow as l, init as n, serve$1 as o, InngestExecutionEngine as p, _compatibilityCheck as r, createInngestAgent as s, createStep as t, InngestWorkflow as u };
2017
3490
 
2018
- //# sourceMappingURL=connect-DbsoIp0h.js.map
3491
+ //# sourceMappingURL=src-CVg0ITpU.js.map