@mastra/inngest 1.9.1 → 1.9.2-alpha.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src-iZ1vJU4r.js","names":["stepRes","#mastra","#mastra","#pubsubFactory","serve","inngestServeHono","createStepFromAgent","createStepFromTool","coreCreateStepFromAgent","coreCreateStepFromTool"],"sources":["../src/nested-workflow-output.ts","../src/execution-engine.ts","../src/pubsub.ts","../src/durable-event-payload.ts","../src/run.ts","../src/workflow.ts","../src/durable-agent/create-inngest-agentic-workflow.ts","../src/durable-agent/create-inngest-agent.ts","../src/functions.ts","../src/serve.ts","../src/connect.ts","../src/types.ts","../src/index.ts"],"sourcesContent":["import type { WorkflowResult } from '@mastra/core/workflows';\n\nexport const NESTED_WORKFLOW_OUTPUT_MODE = {\n DEFAULT: 'default',\n COMPACT: 'compact',\n} as const;\n\nexport type NestedWorkflowOutputMode = (typeof NESTED_WORKFLOW_OUTPUT_MODE)[keyof typeof NESTED_WORKFLOW_OUTPUT_MODE];\n\ntype AnyWorkflowResult = WorkflowResult<any, any, any, any>;\ntype WorkflowResultWithStatus<TStatus extends AnyWorkflowResult['status']> = Extract<\n AnyWorkflowResult,\n { status: TStatus }\n>;\n\nexport type NestedWorkflowResult =\n | Pick<WorkflowResultWithStatus<'success'>, 'status' | 'state' | 'result'>\n | Pick<WorkflowResultWithStatus<'failed'>, 'status' | 'state' | 'error'>\n | Pick<WorkflowResultWithStatus<'tripwire'>, 'status' | 'state' | 'tripwire'>\n | Pick<WorkflowResultWithStatus<'suspended'>, 'status' | 'state' | 'steps' | 'resumeLabels'>\n | Pick<WorkflowResultWithStatus<'paused'>, 'status' | 'state'>;\n\n/**\n * Normalizes an optional nested workflow output mode to an explicit mode.\n *\n * @param mode - The output mode requested by the invoking workflow.\n * @returns The requested compact mode, or the default mode when compact output was not requested.\n */\nexport function resolveNestedWorkflowOutputMode(\n mode: NestedWorkflowOutputMode | undefined = NESTED_WORKFLOW_OUTPUT_MODE.DEFAULT,\n): NestedWorkflowOutputMode {\n return mode === NESTED_WORKFLOW_OUTPUT_MODE.COMPACT\n ? NESTED_WORKFLOW_OUTPUT_MODE.COMPACT\n : NESTED_WORKFLOW_OUTPUT_MODE.DEFAULT;\n}\n\n/**\n * Keeps only the status-specific fields consumed by a parent workflow after\n * `step.invoke()`. Suspended results retain steps so the parent can construct\n * the nested resume path; completed results do not carry the child input or\n * internal step history into the parent's memoized run state.\n *\n * @param result - The complete result returned by the nested workflow.\n * @returns The status-specific fields required by the invoking parent workflow.\n */\nexport function compactNestedWorkflowResult(result: AnyWorkflowResult): NestedWorkflowResult {\n switch (result.status) {\n case 'success':\n return { status: result.status, result: result.result, state: result.state };\n case 'failed':\n return { status: result.status, error: result.error, state: result.state };\n case 'tripwire':\n return { status: result.status, tripwire: result.tripwire, state: result.state };\n case 'suspended':\n // resumeLabels travels with a suspended result so the parent can re-register\n // the child's labels and stay able to name each parked leaf.\n return { status: result.status, steps: result.steps, state: result.state, resumeLabels: result.resumeLabels };\n case 'paused':\n return { status: result.status, state: result.state };\n }\n}\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport { randomUUID } from 'node:crypto';\nimport type { ActorSignal } from '@mastra/core/auth/ee';\nimport type { RequestContext } from '@mastra/core/di';\nimport { getErrorFromUnknown, MastraNonRetryableError } from '@mastra/core/error';\nimport type { SerializedError } from '@mastra/core/error';\nimport type { PubSub } from '@mastra/core/events';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { EntityType } from '@mastra/core/observability';\nimport { DefaultExecutionEngine, createTimeTravelExecutionParams } from '@mastra/core/workflows';\nimport type {\n ExecutionContext,\n Step,\n StepResult,\n StepFailure,\n ExecutionEngineOptions,\n TimeTravelExecutionParams,\n} from '@mastra/core/workflows';\nimport type { Inngest, BaseContext } from 'inngest';\nimport { NonRetriableError } from 'inngest';\nimport type { NestedWorkflowResult } from './nested-workflow-output';\nimport { NESTED_WORKFLOW_OUTPUT_MODE } from './nested-workflow-output';\nimport { InngestWorkflow } from './workflow';\n\nfunction isNonRetryableStepFailure(error: unknown): boolean {\n if (error instanceof MastraNonRetryableError || error instanceof NonRetriableError) {\n return true;\n }\n\n if (error instanceof Error && error.cause !== undefined && isNonRetryableStepFailure(error.cause)) {\n return true;\n }\n\n if (error && typeof error === 'object') {\n const record = error as {\n nonRetryable?: true;\n error?: unknown;\n name?: string;\n isNonRetryable?: boolean;\n };\n\n if (record.nonRetryable) {\n return true;\n }\n\n if (record.name === 'MastraNonRetryableError' || record.isNonRetryable) {\n return true;\n }\n\n if (record.error !== undefined && isNonRetryableStepFailure(record.error)) {\n return true;\n }\n }\n\n return false;\n}\n\nconst retryCountStorage = new AsyncLocalStorage<number>();\n\nconst BUILTIN_ERROR_TYPES = [TypeError, RangeError, ReferenceError, SyntaxError, EvalError, URIError, AggregateError];\n\nexport class InngestExecutionEngine extends DefaultExecutionEngine {\n private inngestStep: BaseContext<Inngest>['step'];\n private inngestAttempts: number;\n\n constructor(\n mastra: Mastra,\n inngestStep: BaseContext<Inngest>['step'],\n inngestAttempts: number = 0,\n options: ExecutionEngineOptions,\n private parentStream?: { workflowId: string; runId: string },\n ) {\n super({ mastra, options });\n this.inngestStep = inngestStep;\n this.inngestAttempts = inngestAttempts;\n }\n\n override getOrGenerateRetryCount(_stepId: string): number {\n return retryCountStorage.getStore() ?? 0;\n }\n\n // =============================================================================\n // Hook Overrides\n // =============================================================================\n\n /**\n * Format errors while preserving Error instances and their custom properties.\n * Uses getErrorFromUnknown to ensure all error properties are preserved.\n */\n protected formatResultError(\n error: Error | string | undefined,\n lastOutput: StepResult<any, any, any, any>,\n ): SerializedError {\n const outputError = (lastOutput as StepFailure<any, any, any, any>)?.error;\n const errorSource = error || outputError;\n const errorInstance = getErrorFromUnknown(errorSource, {\n serializeStack: true, // Include stack in JSON for better debugging in Inngest\n fallbackMessage: 'Unknown workflow error',\n });\n return errorInstance.toJSON();\n }\n\n /**\n * Detect InngestWorkflow instances for special nested workflow handling\n */\n isNestedWorkflowStep(step: Step<any, any, any>): boolean {\n return step instanceof InngestWorkflow;\n }\n\n /**\n * Inngest requires requestContext serialization for memoization.\n * When steps are replayed, the original function doesn't re-execute,\n * so requestContext modifications must be captured and restored.\n */\n requiresDurableContextSerialization(): boolean {\n return true;\n }\n\n /**\n * Execute a step with retry logic for Inngest.\n * Retries are handled via step-level retry (RetryAfterError thrown INSIDE step.run()).\n * After retries exhausted, error propagates here and we return a failed result.\n */\n async executeStepWithRetry<T>(\n stepId: string,\n runStep: () => Promise<T>,\n params: {\n retries: number;\n delay: number;\n stepSpan?: any;\n workflowId: string;\n runId: string;\n },\n ): Promise<\n | { ok: true; result: T }\n | { ok: false; error: { status: 'failed'; error: Error; endedAt: number; nonRetryable?: true } }\n > {\n for (let i = 0; i < params.retries + 1; i++) {\n if (i > 0 && params.delay) {\n await new Promise(resolve => setTimeout(resolve, params.delay));\n }\n try {\n //removed retry config with RetryAfterError from wrapDurableOperation, since we're manually handling retries here\n const result = await retryCountStorage.run(i, () => this.wrapDurableOperation(stepId, runStep));\n return { ok: true, result };\n } catch (e) {\n const isNonRetryable = isNonRetryableStepFailure(e);\n\n if (isNonRetryable || i === params.retries) {\n // After step-level retries exhausted, extract failure from error cause\n const cause = (e as any)?.cause;\n if (cause?.status === 'failed') {\n params.stepSpan?.error({\n error: e,\n attributes: { status: 'failed' },\n });\n // Ensure cause.error is an Error instance\n if (cause.error && !(cause.error instanceof Error)) {\n cause.error = getErrorFromUnknown(cause.error, { serializeStack: false });\n }\n return {\n ok: false,\n error: {\n ...cause,\n ...(isNonRetryable && { nonRetryable: true as const }),\n },\n };\n }\n\n // Fallback for other errors - preserve the original error instance\n const errorInstance = getErrorFromUnknown(e, {\n serializeStack: false,\n fallbackMessage: 'Unknown step execution error',\n });\n params.stepSpan?.error({\n error: errorInstance,\n attributes: { status: 'failed' },\n });\n return {\n ok: false,\n error: {\n status: 'failed',\n error: errorInstance,\n endedAt: Date.now(),\n ...(isNonRetryable && { nonRetryable: true as const }),\n },\n };\n }\n }\n }\n // Should never reach here, but TypeScript needs it\n return { ok: false, error: { status: 'failed', error: new Error('Unknown error'), endedAt: Date.now() } };\n }\n\n /**\n * Use Inngest's sleep primitive for durability\n */\n async executeSleepDuration(duration: number, sleepId: string, workflowId: string): Promise<void> {\n await this.inngestStep.sleep(`workflow.${workflowId}.sleep.${sleepId}`, duration < 0 ? 0 : duration);\n }\n\n /**\n * Use Inngest's sleepUntil primitive for durability\n */\n async executeSleepUntilDate(date: Date, sleepUntilId: string, workflowId: string): Promise<void> {\n await this.inngestStep.sleepUntil(`workflow.${workflowId}.sleepUntil.${sleepUntilId}`, date);\n }\n\n /**\n * Wrap durable operations in Inngest step.run() for durability.\n *\n * IMPORTANT: Errors are wrapped with a cause structure before throwing.\n * This is necessary because Inngest's error serialization (serialize-error-cjs)\n * only captures standard Error properties (message, name, stack, code, cause).\n * Custom properties like statusCode, responseHeaders from AI SDK errors would\n * be lost. By putting our serialized error (via getErrorFromUnknown with toJSON())\n * in the cause property, we ensure custom properties survive serialization.\n * The cause property is in serialize-error-cjs's allowlist, and when the cause\n * object is finally JSON.stringify'd, our error's toJSON() is called.\n */\n async wrapDurableOperation<T>(operationId: string, operationFn: () => Promise<T>): Promise<T> {\n const result = await this.inngestStep.run(operationId, async () => {\n try {\n const fnResult = await operationFn();\n return fnResult;\n } catch (e) {\n const errorInstance = getErrorFromUnknown(e, {\n serializeStack: true,\n fallbackMessage: 'Unknown step execution error',\n });\n const isNonRetryable = isNonRetryableStepFailure(e);\n const wrapped = new Error(errorInstance.message, {\n cause: {\n status: 'failed',\n error: errorInstance,\n endedAt: Date.now(),\n ...(isNonRetryable && { nonRetryable: true as const }),\n },\n });\n // Report the original failure site to Inngest instead of this wrapper frame.\n if (errorInstance.stack) {\n wrapped.stack = errorInstance.stack;\n }\n // Inngest derives the reported `name` from the prototype, so keep built-in error types (e.g. TypeError).\n const builtinErrorType =\n e instanceof Error\n ? BUILTIN_ERROR_TYPES.find(ErrorType => Object.getPrototypeOf(e) === ErrorType.prototype)\n : undefined;\n if (builtinErrorType) {\n Object.setPrototypeOf(wrapped, builtinErrorType.prototype);\n }\n throw wrapped;\n }\n });\n return result as T;\n }\n\n /**\n * Provide Inngest step primitive in engine context\n */\n getEngineContext(): Record<string, any> {\n return { step: this.inngestStep };\n }\n\n /**\n * For Inngest, lifecycle callbacks are invoked in the workflow's finalize step\n * (wrapped in step.run for durability), not in execute(). Override to skip.\n */\n public async invokeLifecycleCallbacks(_result: {\n status: any;\n result?: any;\n error?: any;\n steps: Record<string, any>;\n tripwire?: any;\n runId: string;\n workflowId: string;\n resourceId?: string;\n input?: any;\n requestContext: RequestContext;\n state: Record<string, any>;\n }): Promise<void> {\n // No-op: Inngest handles callbacks in workflow.ts finalize step\n }\n\n /**\n * Actually invoke the lifecycle callbacks. Called from workflow.ts finalize step.\n */\n public async invokeLifecycleCallbacksInternal(result: {\n status: any;\n result?: any;\n error?: any;\n steps: Record<string, any>;\n tripwire?: any;\n runId: string;\n workflowId: string;\n resourceId?: string;\n input?: any;\n requestContext: RequestContext;\n state: Record<string, any>;\n }): Promise<void> {\n return super.invokeLifecycleCallbacks(result);\n }\n\n // =============================================================================\n // Durable Span Lifecycle Hooks\n // =============================================================================\n\n /**\n * Create a step span durably - on first execution, creates and exports span.\n * On replay, returns cached span data without re-creating.\n */\n async createStepSpan(params: {\n parentSpan: any;\n stepId: string;\n operationId: string;\n options: {\n name: string;\n type: any;\n input?: unknown;\n entityType?: string;\n entityId?: string;\n attributes?: Record<string, unknown>;\n tracingPolicy?: any;\n };\n executionContext: ExecutionContext;\n }): Promise<any> {\n const { executionContext, operationId, options, parentSpan } = params;\n\n // Use the actual parent span's ID if provided (e.g., for steps inside control-flow),\n // otherwise fall back to workflow span\n const parentSpanId = parentSpan?.id ?? executionContext.tracingIds?.workflowSpanId;\n\n // Without observability there is no span to memoize; skip the durable operation.\n if (!this.mastra?.observability?.getSelectedInstance({})) return undefined;\n\n // Use wrapDurableOperation to memoize span creation\n const exportedSpan = await this.wrapDurableOperation(operationId, async () => {\n const observability = this.mastra?.observability?.getSelectedInstance({});\n if (!observability) return undefined;\n\n // Create span using tracingIds for traceId, and actual parent span for parentSpanId\n const span = observability.startSpan({\n ...options,\n entityType: options.entityType as EntityType | undefined,\n traceId: executionContext.tracingIds?.traceId,\n parentSpanId,\n });\n\n // Return serializable form\n return span?.exportSpan();\n });\n\n // Return a rebuilt span that can have .end()/.error() called later\n if (exportedSpan) {\n const observability = this.mastra?.observability?.getSelectedInstance({});\n return observability?.rebuildSpan(exportedSpan);\n }\n\n return undefined;\n }\n\n /**\n * End a step span durably.\n */\n async endStepSpan(params: {\n span: any;\n operationId: string;\n endOptions: {\n output?: unknown;\n attributes?: Record<string, unknown>;\n };\n }): Promise<void> {\n const { span, operationId, endOptions } = params;\n if (!span) return;\n\n await this.wrapDurableOperation(operationId, async () => {\n span.end(endOptions);\n });\n }\n\n /**\n * Record error on step span durably.\n */\n async errorStepSpan(params: {\n span: any;\n operationId: string;\n errorOptions: {\n error: Error;\n attributes?: Record<string, unknown>;\n };\n }): Promise<void> {\n const { span, operationId, errorOptions } = params;\n if (!span) return;\n\n await this.wrapDurableOperation(operationId, async () => {\n span.error(errorOptions);\n });\n }\n\n /**\n * Create a generic child span durably (for control-flow operations).\n * On first execution, creates and exports span. On replay, returns cached span data.\n */\n async createChildSpan(params: {\n parentSpan: any;\n operationId: string;\n options: {\n name: string;\n type: any;\n input?: unknown;\n attributes?: Record<string, unknown>;\n };\n executionContext: ExecutionContext;\n }): Promise<any> {\n const { executionContext, operationId, options, parentSpan } = params;\n\n // Use the actual parent span's ID if provided, otherwise fall back to workflow span\n const parentSpanId = parentSpan?.id ?? executionContext.tracingIds?.workflowSpanId;\n\n // Without observability there is no span to memoize; skip the durable operation.\n if (!this.mastra?.observability?.getSelectedInstance({})) return undefined;\n\n // Use wrapDurableOperation to memoize span creation\n const exportedSpan = await this.wrapDurableOperation(operationId, async () => {\n const observability = this.mastra?.observability?.getSelectedInstance({});\n if (!observability) return undefined;\n\n // Create span using tracingIds for traceId, and actual parent span for parentSpanId\n const span = observability.startSpan({\n ...options,\n traceId: executionContext.tracingIds?.traceId,\n parentSpanId,\n tracingPolicy: this.options?.tracingPolicy,\n });\n\n // Return serializable form\n return span?.exportSpan();\n });\n\n // Return a rebuilt span that can have .end()/.error() called later\n if (exportedSpan) {\n const observability = this.mastra?.observability?.getSelectedInstance({});\n return observability?.rebuildSpan(exportedSpan);\n }\n\n return undefined;\n }\n\n /**\n * End a generic child span durably (for control-flow operations).\n */\n async endChildSpan(params: {\n span: any;\n operationId: string;\n endOptions?: {\n output?: unknown;\n attributes?: Record<string, unknown>;\n };\n }): Promise<void> {\n const { span, operationId, endOptions } = params;\n if (!span) return;\n\n await this.wrapDurableOperation(operationId, async () => {\n span.end(endOptions);\n });\n }\n\n /**\n * Record error on a generic child span durably (for control-flow operations).\n */\n async errorChildSpan(params: {\n span: any;\n operationId: string;\n errorOptions: {\n error: Error;\n attributes?: Record<string, unknown>;\n };\n }): Promise<void> {\n const { span, operationId, errorOptions } = params;\n if (!span) return;\n\n await this.wrapDurableOperation(operationId, async () => {\n span.error(errorOptions);\n });\n }\n\n /**\n * Execute nested InngestWorkflow using inngestStep.invoke() for durability.\n * This MUST be called directly (not inside step.run()) due to Inngest constraints.\n *\n * @param params - The nested workflow step and its current execution state.\n * @returns The nested workflow step result, or null when the step is not an Inngest workflow.\n */\n async executeWorkflowStep(params: {\n step: Step<string, any, any>;\n stepResults: Record<string, StepResult<any, any, any, any>>;\n executionContext: ExecutionContext;\n resume?: {\n steps: string[];\n resumePayload: any;\n runId?: string;\n };\n timeTravel?: TimeTravelExecutionParams;\n prevOutput: any;\n inputData: any;\n pubsub: PubSub;\n startedAt: number;\n perStep?: boolean;\n stepSpan?: any;\n actor?: ActorSignal;\n requestContext?: RequestContext;\n }): Promise<StepResult<any, any, any, any> | null> {\n // Only handle InngestWorkflow instances\n if (!(params.step instanceof InngestWorkflow)) {\n return null;\n }\n\n const {\n step,\n stepResults,\n executionContext,\n resume,\n timeTravel,\n prevOutput,\n inputData,\n pubsub,\n startedAt,\n perStep,\n stepSpan,\n actor,\n requestContext: parentRequestContext,\n } = params;\n const forwardedRequestContext = parentRequestContext\n ? this.serializeRequestContext(parentRequestContext)\n : (inputData?.requestContextEntries ?? {});\n\n // Build trace context to propagate to nested workflow\n const nestedTracingContext = executionContext.tracingIds?.traceId\n ? {\n traceId: executionContext.tracingIds.traceId,\n parentSpanId: stepSpan?.id,\n }\n : undefined;\n\n const parentStream = this.parentStream ?? {\n workflowId: executionContext.workflowId,\n runId: executionContext.runId,\n };\n const isResume = !!resume?.steps?.length;\n // New invocations return compact output; legacy memoized WorkflowResult\n // envelopes are structural supersets of this parent-facing contract.\n let result: NestedWorkflowResult;\n let runId: string;\n\n const isTimeTravel = !!(timeTravel && timeTravel.steps?.length > 1 && timeTravel.steps[0] === step.id);\n\n // The nested run id must be derivable on every replay pass: core strips\n // `suspendPayload` (omitPriorCompletionFields) and persists the stripped step\n // result before this branch runs, so nothing stored on it survives Inngest's\n // re-execution from the snapshot. The default engine runs nested workflows\n // under the parent's run id (Workflow.execute → createRun({ runId })), so\n // derive the same way here; foreach iterations get a per-index suffix so\n // concurrent iterations don't share a snapshot row (executionContext.foreachIndex\n // is set per iteration by the foreach handler and is stable across replays).\n const derivedNestedRunId =\n executionContext.foreachIndex !== undefined\n ? `${executionContext.runId}-foreach-${executionContext.foreachIndex}`\n : executionContext.runId;\n\n try {\n if (isResume) {\n runId = stepResults[resume?.steps?.[0] ?? '']?.suspendPayload?.__workflow_meta?.runId ?? derivedNestedRunId;\n const workflowsStore = await this.mastra?.getStorage()?.getStore('workflows');\n const snapshot: any = await workflowsStore?.loadWorkflowSnapshot({\n workflowName: step.id,\n runId: runId,\n });\n\n const nestedResumeSteps = resume.steps.slice(1);\n let replayOnly = false;\n if (nestedResumeSteps.length === 0) {\n const suspendedStepIds = Object.keys(snapshot?.suspendedPaths ?? {});\n if (suspendedStepIds.length === 0) {\n // The child is no longer suspended: step.invoke parks the parent until the\n // child finishes, so Inngest re-executes this block to deliver the memoized\n // result. Replay the invoke (same durable id) instead of throwing, which\n // would discard a child run that already completed.\n replayOnly = true;\n } else if (suspendedStepIds.length > 1) {\n const pathStrings = suspendedStepIds.map(stepId => `[${stepId}]`);\n throw new Error(\n `Multiple suspended steps found: ${pathStrings.join(', ')}. ` +\n 'Please specify which step to resume using the \"step\" parameter.',\n );\n } else {\n nestedResumeSteps.push(suspendedStepIds[0]!);\n }\n }\n const nestedResumeStepId = nestedResumeSteps[0];\n\n const invokeResp = (await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {\n function: step.getFunction(),\n data: {\n inputData,\n requestContext: forwardedRequestContext,\n parentStream,\n runId: runId,\n ...(replayOnly\n ? { initialState: executionContext.state ?? {} }\n : {\n resume: {\n runId: runId,\n steps: nestedResumeSteps,\n resumePayload: resume.resumePayload,\n resumePath: nestedResumeStepId\n ? (snapshot?.suspendedPaths?.[nestedResumeStepId] as any)\n : undefined,\n },\n }),\n outputOptions: { includeState: true, includeResumeLabels: true },\n nestedWorkflowOutputMode: NESTED_WORKFLOW_OUTPUT_MODE.COMPACT,\n perStep,\n tracingOptions: nestedTracingContext,\n actor,\n },\n })) as any;\n result = invokeResp.result;\n runId = invokeResp.runId;\n executionContext.state = invokeResp.result.state;\n } else if (isTimeTravel) {\n const workflowsStoreForTimeTravel = await this.mastra?.getStorage()?.getStore('workflows');\n const snapshot: any = (await workflowsStoreForTimeTravel?.loadWorkflowSnapshot({\n workflowName: step.id,\n runId: executionContext.runId,\n })) ?? { context: {} };\n const timeTravelParams = createTimeTravelExecutionParams({\n steps: timeTravel.steps.slice(1),\n inputData: timeTravel.inputData,\n resumeData: timeTravel.resumeData,\n context: (timeTravel.nestedStepResults?.[step.id] ?? {}) as any,\n nestedStepsContext: (timeTravel.nestedStepResults ?? {}) as any,\n snapshot,\n graph: step.buildExecutionGraph(),\n });\n const invokeResp = (await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {\n function: step.getFunction(),\n data: {\n timeTravel: timeTravelParams,\n initialState: executionContext.state ?? {},\n requestContext: forwardedRequestContext,\n parentStream,\n runId: executionContext.runId,\n outputOptions: { includeState: true, includeResumeLabels: true },\n nestedWorkflowOutputMode: NESTED_WORKFLOW_OUTPUT_MODE.COMPACT,\n perStep,\n tracingOptions: nestedTracingContext,\n actor,\n },\n })) as any;\n result = invokeResp.result;\n runId = invokeResp.runId;\n executionContext.state = invokeResp.result.state;\n } else {\n // Name the child run on its trigger event. `cancelOn` matches a cancel\n // event against `data.runId` on the trigger, so a nested run invoked\n // without one cannot be cancelled by id — and it would take the\n // unnamed-run branch, warning about advice the caller cannot act on.\n // Derived (not random) so every replay pass addresses the same child\n // snapshot — see `derivedNestedRunId` above.\n const nestedRunId = derivedNestedRunId;\n const invokeResp = (await this.inngestStep.invoke(`workflow.${executionContext.workflowId}.step.${step.id}`, {\n function: step.getFunction(),\n data: {\n inputData,\n initialState: executionContext.state ?? {},\n requestContext: forwardedRequestContext,\n parentStream,\n runId: nestedRunId,\n outputOptions: { includeState: true, includeResumeLabels: true },\n nestedWorkflowOutputMode: NESTED_WORKFLOW_OUTPUT_MODE.COMPACT,\n perStep,\n tracingOptions: nestedTracingContext,\n actor,\n },\n })) as any;\n result = invokeResp.result;\n runId = invokeResp.runId;\n executionContext.state = invokeResp.result.state;\n }\n } catch (e) {\n // Nested workflow threw an error (likely from finalization step).\n // Compact nested failures carry the workflow result and runId in the cause.\n const errorCause = e && typeof e === 'object' && 'cause' in e ? e.cause : undefined;\n\n // Try to extract runId from error cause or generate new one\n if (errorCause && typeof errorCause === 'object' && 'status' in errorCause && errorCause.status === 'failed') {\n result = errorCause as Extract<NestedWorkflowResult, { status: 'failed' }>;\n runId = 'runId' in errorCause && typeof errorCause.runId === 'string' ? errorCause.runId : randomUUID();\n } else {\n // Log before flattening: Error objects don't survive snapshot\n // serialization (JSON.stringify(new Error('x')) is `{}`), so without\n // this the real cause never surfaces past \"Workflow failed\".\n this.logger?.error(\n `Nested workflow step ${step.id} failed: ` + (e instanceof Error ? (e.stack ?? e.message) : String(e)),\n );\n // Fallback: if we can't get the result from error, construct a basic failed result\n runId = randomUUID();\n result = {\n status: 'failed',\n error: e instanceof Error ? e : new Error(String(e)),\n };\n }\n }\n\n const res = await this.inngestStep.run(\n `workflow.${executionContext.workflowId}.step.${step.id}.nestedwf-results`,\n async () => {\n if (result.status === 'failed') {\n await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {\n type: 'watch',\n runId: executionContext.runId,\n data: {\n type: 'workflow-step-result',\n payload: {\n id: step.id,\n status: 'failed',\n error: result?.error,\n payload: prevOutput,\n },\n },\n });\n\n return { executionContext, result: { status: 'failed', error: result?.error, endedAt: Date.now() } };\n } else if (result.status === 'suspended') {\n const suspendedSteps = Object.entries(result.steps).filter(([_stepName, stepResult]) => {\n const stepRes: StepResult<any, any, any, any> = stepResult as StepResult<any, any, any, any>;\n return stepRes?.status === 'suspended';\n });\n\n for (const [stepName, stepResult] of suspendedSteps) {\n const suspendPath: string[] = [stepName, ...(stepResult?.suspendPayload?.__workflow_meta?.path ?? [])];\n executionContext.suspendedPaths[step.id] = executionContext.executionPath;\n\n // Re-register the nested run's resume labels on the parent so the outer snapshot is\n // self-describing about every parked leaf (e.g. `resumeLabels[toolCallId]`). Without\n // this a caller can only target the outer step, and concurrent suspensions inside the\n // nested workflow become impossible to disambiguate. Mirrors `Workflow.execute()` in\n // packages/core/src/workflows/workflow.ts.\n for (const label of Object.keys((result as any)?.resumeLabels ?? {})) {\n executionContext.resumeLabels[label] = { stepId: step.id };\n }\n\n // Keep the nested workflow metadata (foreachIndex, foreachOutput, resumeLabels) when\n // propagating a suspension to the parent — only runId and path change as we move up.\n // Per-iteration `__streamState` blobs are stripped from the propagated copies: they can\n // be large and resume reads them from the nested run's own snapshot, so the parent only\n // needs the identifying fields.\n const nestedMeta = (stepResult as any)?.suspendPayload?.__workflow_meta ?? {};\n const propagatedForeachOutput = Array.isArray(nestedMeta.foreachOutput)\n ? nestedMeta.foreachOutput.map((entry: any) => {\n if (entry?.status !== 'suspended' || !entry.suspendPayload) return entry;\n const { __streamState: _streamState, ...suspendPayload } = entry.suspendPayload;\n return { ...entry, suspendPayload };\n })\n : undefined;\n\n await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {\n type: 'watch',\n runId: executionContext.runId,\n data: {\n type: 'workflow-step-suspended',\n payload: {\n id: step.id,\n status: 'suspended',\n },\n },\n });\n\n return {\n executionContext,\n result: {\n status: 'suspended',\n suspendedAt: Date.now(),\n payload: stepResult.payload,\n suspendPayload: {\n ...(stepResult as any)?.suspendPayload,\n __workflow_meta: {\n ...nestedMeta,\n ...(propagatedForeachOutput ? { foreachOutput: propagatedForeachOutput } : {}),\n runId: runId,\n path: suspendPath,\n },\n },\n },\n };\n }\n\n return {\n executionContext,\n result: {\n status: 'suspended',\n suspendedAt: Date.now(),\n payload: {},\n },\n };\n } else if (result.status === 'tripwire') {\n await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {\n type: 'watch',\n runId: executionContext.runId,\n data: {\n type: 'workflow-step-result',\n payload: {\n id: step.id,\n status: 'tripwire',\n error: result?.tripwire?.reason,\n payload: prevOutput,\n },\n },\n });\n\n return {\n executionContext,\n result: {\n status: 'tripwire',\n tripwire: result?.tripwire,\n endedAt: Date.now(),\n },\n };\n } else if (perStep || result.status === 'paused') {\n await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {\n type: 'watch',\n runId: executionContext.runId,\n data: {\n type: 'workflow-step-result',\n payload: {\n id: step.id,\n status: 'paused',\n },\n },\n });\n\n await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {\n type: 'watch',\n runId: executionContext.runId,\n data: {\n type: 'workflow-step-finish',\n payload: {\n id: step.id,\n metadata: {},\n },\n },\n });\n return { executionContext, result: { status: 'paused' } };\n }\n\n await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {\n type: 'watch',\n runId: executionContext.runId,\n data: {\n type: 'workflow-step-result',\n payload: {\n id: step.id,\n status: 'success',\n output: result?.result,\n },\n },\n });\n\n await pubsub.publish(`workflow.events.v2.${executionContext.runId}`, {\n type: 'watch',\n runId: executionContext.runId,\n data: {\n type: 'workflow-step-finish',\n payload: {\n id: step.id,\n metadata: {},\n },\n },\n });\n\n return { executionContext, result: { status: 'success', output: result?.result, endedAt: Date.now() } };\n },\n );\n\n Object.assign(executionContext, res.executionContext);\n return {\n ...res.result,\n startedAt,\n payload: inputData,\n resumedAt: resume?.steps[0] === step.id ? startedAt : undefined,\n resumePayload: resume?.steps[0] === step.id ? resume?.resumePayload : undefined,\n } as StepResult<any, any, any, any>;\n }\n}\n","import { PubSub } from '@mastra/core/events';\nimport type { Event } from '@mastra/core/events';\nimport type { Inngest } from 'inngest';\nimport { subscribe } from 'inngest/realtime';\n\n/**\n * Build a TopicRef compatible with Inngest SDK v4's `inngest.realtime.publish()`.\n * The runtime only requires `channel` and `topic`; `config.schema` is optional and\n * we leave it absent so no validation runs.\n */\nfunction buildTopicRef(channel: string, topic: string) {\n return { channel, topic, config: {} as any };\n}\n\n/**\n * Parse a topic string and extract the runId and topic type.\n *\n * Supported formats:\n * - \"workflow.events.v2.{runId}\" - workflow events\n * - \"agent.stream.{runId}\" - agent stream events\n * - \"agent.control.{runId}\" - agent control events (cross-process abort)\n *\n * @returns { runId, topicType } or null if not a recognized format\n */\nfunction parseTopic(topic: string): { runId: string; topicType: 'workflow' | 'agent-stream' | 'agent-control' } | null {\n // Try workflow format first\n const workflowMatch = topic.match(/^workflow\\.events\\.v2\\.(.+)$/);\n if (workflowMatch && workflowMatch[1]) {\n return { runId: workflowMatch[1], topicType: 'workflow' };\n }\n\n // Try agent stream format\n const agentStreamMatch = topic.match(/^agent\\.stream\\.(.+)$/);\n if (agentStreamMatch && agentStreamMatch[1]) {\n return { runId: agentStreamMatch[1], topicType: 'agent-stream' };\n }\n\n // Try agent control format\n const agentControlMatch = topic.match(/^agent\\.control\\.(.+)$/);\n if (agentControlMatch && agentControlMatch[1]) {\n return { runId: agentControlMatch[1], topicType: 'agent-control' };\n }\n\n return null;\n}\n\n/**\n * Warn once per unrecognized topic family so a missing topic mapping never fails\n * silently again (dropped `agent.control.*` aborts shipped invisibly — see #22543).\n * Deduped on the topic's leading two segments so run-scoped topics neither spam\n * the logs nor grow the set unboundedly.\n */\nconst warnedUnrecognizedTopics = new Set<string>();\nfunction warnUnrecognizedTopic(topic: string): void {\n const family = topic.split('.').slice(0, 2).join('.');\n if (warnedUnrecognizedTopics.has(family)) return;\n warnedUnrecognizedTopics.add(family);\n console.warn(`InngestPubSub: ignoring unrecognized topic format \"${topic}\"`);\n}\n\n/**\n * PubSub implementation for Inngest workflows.\n *\n * This bridges the PubSub abstract class interface with Inngest's realtime system:\n * - publish() uses `inngest.realtime.publish()` (Inngest SDK v4 client API).\n * This is non-durable: it executes immediately and is not memoized as a step.\n * When called inside an Inngest function it auto-includes the current runId.\n * - subscribe() uses `inngest/realtime` subscribe for real-time streaming.\n *\n * Supported topic formats:\n * - \"workflow.events.v2.{runId}\" - workflow events\n * -> Inngest channel: \"workflow:{workflowId}:{runId}\", topic: \"watch\"\n * - \"agent.stream.{runId}\" - agent stream events (for InngestAgent)\n * -> Inngest channel: \"agent:{runId}\", topic: \"agent-stream\"\n * - \"agent.control.{runId}\" - agent control events (cross-process abort)\n * -> Inngest channel: \"agent:{runId}\", topic: \"agent-control\"\n */\nexport class InngestPubSub extends PubSub {\n private inngest: Inngest;\n private workflowId: string;\n private subscriptions: Map<\n string,\n {\n unsubscribe: () => void;\n callbacks: Set<(event: Event, ack?: () => Promise<void>) => void>;\n }\n > = new Map();\n\n constructor(inngest: Inngest, workflowId: string) {\n super();\n this.inngest = inngest;\n this.workflowId = workflowId;\n }\n\n async publishWorkflowWatchTo(workflowId: string, runId: string, data: unknown): Promise<void> {\n await this.inngest.realtime.publish(buildTopicRef(`workflow:${workflowId}:${runId}`, 'watch'), data);\n }\n\n /**\n * Publish an event to Inngest's realtime system.\n *\n * Supported topic formats:\n * - \"workflow.events.v2.{runId}\" - workflow events\n * -> channel: \"workflow:{workflowId}:{runId}\", topic: \"watch\"\n * - \"agent.stream.{runId}\" - agent stream events\n * -> channel: \"agent:{runId}\", topic: \"agent-stream\"\n * (Note: agent stream uses runId-only channel so nested workflows can publish to same channel)\n * - \"agent.control.{runId}\" - agent control events (cross-process abort)\n * -> channel: \"agent:{runId}\", topic: \"agent-control\"\n */\n async publish(topic: string, event: Omit<Event, 'id' | 'createdAt'>): Promise<void> {\n const parsed = parseTopic(topic);\n if (!parsed) {\n warnUnrecognizedTopic(topic);\n return; // Ignore unrecognized topic formats\n }\n\n const { runId, topicType } = parsed;\n\n // Agent stream/control events share the runId-only channel (so nested workflows\n // publish to the same channel) but use separate Inngest topics so control\n // traffic never reaches stream consumers.\n const isAgentTopic = topicType === 'agent-stream' || topicType === 'agent-control';\n const inngestTopic = isAgentTopic ? topicType : 'watch';\n const channel = isAgentTopic ? `agent:${runId}` : `workflow:${this.workflowId}:${runId}`;\n\n try {\n // For agent stream/control events, send the full event structure so subscribers can access type/runId/data\n // For workflow events, send just the data (existing behavior)\n const dataToSend = isAgentTopic ? event : event.data;\n await this.inngest.realtime.publish(buildTopicRef(channel, inngestTopic), dataToSend);\n } catch (err: any) {\n // Rethrow when losing the event would break the caller:\n // - agent control events: a dropped abort-request means a remote run cannot be\n // stopped; core's requestRemoteAbort() catches and logs with agentId/runId context\n // - agent stream terminal events: losing a finish/error event causes the client\n // stream to hang indefinitely\n if (\n topicType === 'agent-control' ||\n (topicType === 'agent-stream' && (event.type === 'finish' || event.type === 'error'))\n ) {\n throw err;\n }\n // Non-terminal events: log but don't throw\n console.error('InngestPubSub publish error:', err?.message ?? err);\n }\n }\n\n /**\n * Subscribe to events from Inngest's realtime system.\n *\n * Supported topic formats:\n * - \"workflow.events.v2.{runId}\" - workflow events\n * -> channel: \"workflow:{workflowId}:{runId}\", topic: \"watch\"\n * - \"agent.stream.{runId}\" - agent stream events\n * -> channel: \"agent:{runId}\", topic: \"agent-stream\"\n * (Note: agent stream uses runId-only channel so nested workflows can publish to same channel)\n * - \"agent.control.{runId}\" - agent control events (cross-process abort)\n * -> channel: \"agent:{runId}\", topic: \"agent-control\"\n */\n async subscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void> {\n const parsed = parseTopic(topic);\n if (!parsed) {\n warnUnrecognizedTopic(topic);\n return; // Ignore unrecognized topic formats\n }\n\n const { runId, topicType } = parsed;\n\n // Check if we already have a subscription for this topic\n if (this.subscriptions.has(topic)) {\n this.subscriptions.get(topic)!.callbacks.add(cb);\n return;\n }\n\n const callbacks = new Set<(event: Event, ack?: () => Promise<void>) => void>([cb]);\n\n // Agent stream/control events share the runId-only channel (so nested workflows\n // publish to the same channel) but use separate Inngest topics so control\n // traffic never reaches stream consumers.\n const isAgentTopic = topicType === 'agent-stream' || topicType === 'agent-control';\n const inngestTopic = isAgentTopic ? topicType : 'watch';\n const channel = isAgentTopic ? `agent:${runId}` : `workflow:${this.workflowId}:${runId}`;\n\n // Await the subscribe call to ensure the WebSocket connection is established\n // before we consider the subscription \"ready\". This prevents race conditions\n // where the workflow triggers before the subscription can receive events.\n const subscription = await subscribe({\n channel,\n topics: [inngestTopic],\n app: this.inngest,\n onMessage: (message: any) => {\n // For agent stream/control events, message.data is the full event structure (type, runId, data)\n // For workflow events, wrap message.data in a PubSub Event format\n // IMPORTANT: Always generate a unique `id` and `createdAt` for every event.\n // CachingPubSub deduplicates events by `id` — without a unique id, all events\n // after the first would be filtered out (since undefined === undefined in the seen set).\n let event: Event;\n if (isAgentTopic && message.data?.type && message.data?.runId) {\n // Agent stream event - spread the AgentStreamEvent data and add required Event fields\n event = {\n id: crypto.randomUUID(),\n createdAt: new Date(),\n ...message.data,\n } as unknown as Event;\n } else {\n // Workflow event or fallback - wrap in standard Event format\n event = {\n id: crypto.randomUUID(),\n type: inngestTopic,\n runId,\n data: message.data,\n createdAt: new Date(),\n };\n }\n\n for (const callback of callbacks) {\n callback(event);\n }\n },\n });\n\n this.subscriptions.set(topic, {\n unsubscribe: () => {\n try {\n void subscription.close();\n } catch (err) {\n console.error('InngestPubSub unsubscribe error:', err);\n }\n },\n callbacks,\n });\n }\n\n /**\n * Unsubscribe a callback from a topic.\n * If no callbacks remain, the underlying Inngest subscription is cancelled.\n */\n async unsubscribe(topic: string, cb: (event: Event, ack?: () => Promise<void>) => void): Promise<void> {\n const sub = this.subscriptions.get(topic);\n if (!sub) {\n return;\n }\n\n sub.callbacks.delete(cb);\n\n // If no more callbacks, cancel the subscription\n if (sub.callbacks.size === 0) {\n sub.unsubscribe();\n this.subscriptions.delete(topic);\n }\n }\n\n /**\n * Flush any pending operations. No-op for Inngest.\n */\n async flush(): Promise<void> {\n // No-op for Inngest\n }\n\n /**\n * Clean up all subscriptions during graceful shutdown.\n */\n async close(): Promise<void> {\n for (const [, sub] of this.subscriptions) {\n sub.unsubscribe();\n }\n this.subscriptions.clear();\n }\n}\n","import type { ActorSignal } from '@mastra/core/auth/ee';\nimport type { TracingOptions } from '@mastra/core/observability';\nimport { MASTRA_AUTH_TOKEN_KEY } from '@mastra/core/request-context';\nimport type { RequestContext } from '@mastra/core/request-context';\n\n/**\n * Single source of truth for the `data` payload of the `workflow.<id>` events\n * that drive durable execution in `@mastra/inngest`.\n *\n * Two independent public surfaces send these events: `InngestRun`\n * (`start`/`startAsync`/`resume`/`timeTravel`) and the durable-agent wrapper\n * built by `createInngestAgent` (`stream`/`resume`). They used to build the\n * payload separately, and the same class of bug shipped repeatedly as a result:\n * a per-call signal was added to one side and silently dropped on the other\n * (`actor` in #19426, `requestContext` in #19223).\n *\n * The builders below exist to make that failure mode structural rather than a\n * matter of remembering. Their argument types are explicit — adding a new\n * per-call signal means adding a field here, which makes every caller that\n * does not supply it visible. Do not widen these args to a passthrough object.\n *\n * Caller-specific concerns (snapshot persistence and rollback, tracing span\n * construction, pubsub subscription ordering, result polling) legitimately\n * differ between the two surfaces and deliberately stay at the call sites.\n */\n\n/** Per-call signals that every durable event carries, regardless of sender. */\ninterface PerCallSignals {\n /**\n * Actor signal used for FGA checks and tool execution. Always a per-call\n * value: it is supplied fresh on every start and resume and is never read\n * back from a persisted snapshot, so a membership-bypass signal is never\n * written to durable storage. This matches the default engine, which passes\n * `actor: params.actor` on resume (see `packages/core/src/workflows/workflow.ts`\n * `_resume`).\n */\n actor?: ActorSignal;\n /** Whether the run emits per-step output. */\n perStep?: boolean;\n}\n\n/**\n * Flatten a `RequestContext` into the plain JSON object the event carries.\n * Absent context serializes to `{}`, never `undefined`.\n */\nexport function serializeRequestContext(requestContext?: RequestContext<any>): Record<string, any> {\n // `toJSON()` rather than `entries()`: it drops values that cannot survive the\n // JSON round trip through `inngest.send()` (functions, RPC proxies, cyclic\n // references). Passing those through raw makes the send throw.\n const obj = requestContext ? requestContext.toJSON() : {};\n // Never hand the framework-managed bearer token to `inngest.send()`: Inngest\n // durably retains and displays event payloads, so a live token would land in\n // third-party storage on every durable start and resume. A resumed\n // authenticated request supplies its own fresh token. Matches\n // `DefaultExecutionEngine.serializeRequestContext`.\n delete obj[MASTRA_AUTH_TOKEN_KEY];\n return obj;\n}\n\n/**\n * Resume request-context rule: values persisted in the snapshot are the base,\n * and anything the caller supplies on this resume call overrides them.\n */\nexport function mergeResumeRequestContext(\n snapshotRequestContext: Record<string, any> | undefined,\n requestContext?: RequestContext<any>,\n): Record<string, any> {\n return { ...(snapshotRequestContext ?? {}), ...serializeRequestContext(requestContext) };\n}\n\nexport function buildDurableTriggerEventData(\n args: PerCallSignals & {\n inputData: any;\n runId: string;\n resourceId?: string;\n /** Already-serialized request context, or a `RequestContext` to serialize. */\n requestContext?: RequestContext<any> | Record<string, any>;\n initialState?: any;\n outputOptions?: Record<string, any>;\n tracingOptions?: TracingOptions;\n format?: string;\n workflowId?: string;\n },\n): Record<string, any> {\n const { requestContext, ...rest } = args;\n return {\n ...rest,\n requestContext: toRequestContextEntries(requestContext),\n };\n}\n\nexport function buildDurableResumeEventData(\n args: PerCallSignals & {\n inputData: any;\n runId: string;\n resourceId?: string;\n /**\n * Already merged via `mergeResumeRequestContext`, or a `RequestContext`\n * when there is no snapshot context to merge with.\n */\n requestContext?: RequestContext<any> | Record<string, any>;\n resume: {\n steps: string[];\n resumePayload: any;\n resumePath?: any;\n };\n tracingOptions?: TracingOptions;\n workflowId?: string;\n },\n): Record<string, any> {\n const { requestContext, ...rest } = args;\n return {\n ...rest,\n requestContext: toRequestContextEntries(requestContext),\n };\n}\n\nexport function buildDurableTimeTravelEventData(\n args: PerCallSignals & {\n runId: string;\n workflowId: string;\n initialState?: any;\n stepResults?: any;\n timeTravel: any;\n requestContext?: RequestContext<any> | Record<string, any>;\n outputOptions?: Record<string, any>;\n tracingOptions?: TracingOptions;\n },\n): Record<string, any> {\n const { requestContext, ...rest } = args;\n return {\n ...rest,\n requestContext: toRequestContextEntries(requestContext),\n };\n}\n\nfunction toRequestContextEntries(requestContext?: RequestContext<any> | Record<string, any>): Record<string, any> {\n if (!requestContext) return {};\n // Probe `toJSON`, the method `serializeRequestContext` actually calls, so the\n // check stays aligned with the branch it guards.\n return typeof (requestContext as RequestContext<any>).toJSON === 'function'\n ? serializeRequestContext(requestContext as RequestContext<any>)\n : (requestContext as Record<string, any>);\n}\n","import { ReadableStream } from 'node:stream/web';\nimport type { ActorSignal } from '@mastra/core/auth/ee';\nimport { getErrorFromUnknown } from '@mastra/core/error';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { TracingContext, TracingOptions } from '@mastra/core/observability';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport { WorkflowRunOutput, ChunkFrom } from '@mastra/core/stream';\nimport { createTimeTravelExecutionParams, Run, hydrateSerializedStepErrors } from '@mastra/core/workflows';\nimport type {\n ExecutionEngine,\n ExecutionGraph,\n OutputWriter,\n SerializedStepFlowEntry,\n Step,\n StepWithComponent,\n StreamEvent,\n TimeTravelContext,\n WorkflowEngineType,\n WorkflowResult,\n WorkflowStreamEvent,\n} from '@mastra/core/workflows';\nimport { NonRetriableError } from 'inngest';\nimport type { Inngest } from 'inngest';\nimport { subscribe } from 'inngest/realtime';\nimport type { Realtime } from 'inngest/realtime';\nimport {\n buildDurableResumeEventData,\n buildDurableTimeTravelEventData,\n buildDurableTriggerEventData,\n mergeResumeRequestContext,\n} from './durable-event-payload';\nimport type { InngestEngineType } from './types';\n\nexport class InngestRun<\n TEngineType = InngestEngineType,\n TSteps extends Step<string, any, any, any, any, any, TEngineType>[] = Step<\n string,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n TEngineType\n >[],\n TState = unknown,\n TInput = unknown,\n TOutput = unknown,\n TRequestContext = unknown,\n> extends Run<TEngineType, TSteps, TState, TInput, TOutput, TRequestContext> {\n private inngest: Inngest;\n serializedStepGraph: SerializedStepFlowEntry[];\n #mastra: Mastra;\n\n constructor(\n params: {\n workflowId: string;\n runId: string;\n resourceId?: string;\n executionEngine: ExecutionEngine;\n executionGraph: ExecutionGraph;\n serializedStepGraph: SerializedStepFlowEntry[];\n mastra?: Mastra;\n retryConfig?: {\n attempts?: number;\n delay?: number;\n };\n cleanup?: () => void;\n workflowSteps: Record<string, StepWithComponent>;\n workflowEngineType: WorkflowEngineType;\n validateInputs?: boolean;\n },\n inngest: Inngest,\n ) {\n super(params);\n this.inngest = inngest;\n this.serializedStepGraph = params.serializedStepGraph;\n this.#mastra = params.mastra!;\n }\n\n /**\n * Get run output using hybrid approach: realtime subscription + polling fallback.\n * Resolves as soon as either method detects completion.\n */\n async getRunOutput(_eventId: string, maxWaitMs = 300000) {\n const storage = this.#mastra?.getStorage();\n const workflowsStore = await storage?.getStore('workflows');\n if (!workflowsStore) {\n throw new NonRetriableError(`Workflow storage is required to retrieve output for run ${this.runId}`);\n }\n return new Promise<any>((resolve, reject) => {\n let resolved = false;\n let unsubscribe: (() => void) | null = null;\n let pollTimeoutId: NodeJS.Timeout | null = null;\n\n const cleanup = () => {\n if (unsubscribe) {\n try {\n unsubscribe();\n } catch {\n // Ignore unsubscribe errors\n }\n }\n if (pollTimeoutId) {\n clearTimeout(pollTimeoutId);\n }\n };\n\n const handleResult = (result: any, _source: string) => {\n if (!resolved) {\n resolved = true;\n cleanup();\n resolve(result);\n }\n };\n\n const handleError = (error: any, _source: string) => {\n if (!resolved) {\n resolved = true;\n cleanup();\n reject(error);\n }\n };\n\n // Start realtime subscription for workflow-finish event\n let realtimeSubscriptionPromise: Promise<Realtime.Subscribe.CallbackSubscription> | null = null;\n\n const startRealtimeSubscription = async () => {\n try {\n realtimeSubscriptionPromise = subscribe({\n channel: `workflow:${this.workflowId}:${this.runId}`,\n topics: ['watch'],\n app: this.inngest,\n onMessage: async (message: any) => {\n if (resolved) return;\n\n const event = message.data;\n\n if (event?.type === 'workflow-finish') {\n // Got the finish event - load snapshot and resolve\n const snapshot = await workflowsStore?.loadWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n });\n if (snapshot?.context) {\n snapshot.context = hydrateSerializedStepErrors(snapshot.context);\n }\n\n const realtimeResult: Record<string, unknown> = {\n steps: snapshot?.context,\n status: event.payload?.status ?? snapshot?.status,\n input: (snapshot?.context as Record<string, unknown>)?.input,\n };\n const resultValue = event.payload?.result ?? snapshot?.result;\n if (resultValue !== undefined) realtimeResult.result = resultValue;\n const rawError = event.payload?.error ?? snapshot?.error;\n if (rawError) {\n realtimeResult.error = getErrorFromUnknown(rawError, { serializeStack: false });\n }\n if (snapshot?.value !== undefined) realtimeResult.state = snapshot.value;\n const result = { output: { result: realtimeResult } };\n\n handleResult(result, 'realtime');\n }\n },\n });\n\n // Set unsubscribe immediately so cleanup can close the subscription even before setup resolves.\n unsubscribe = () => {\n realtimeSubscriptionPromise?.then(subscription => subscription.close()).catch(() => {});\n };\n\n await realtimeSubscriptionPromise;\n } catch {\n // Realtime subscription failed - polling will still work as fallback\n }\n };\n\n // Start polling by checking our own workflow snapshot store directly.\n // This avoids the Inngest runs API which has a 15-second response cache.\n const startPolling = async () => {\n const startTime = Date.now();\n\n const poll = async () => {\n if (resolved) {\n return;\n }\n if (Date.now() - startTime >= maxWaitMs) {\n handleError(new NonRetriableError(`Workflow did not complete within ${maxWaitMs}ms`), 'polling-timeout');\n return;\n }\n\n try {\n const snapshot = await workflowsStore.loadWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n });\n\n // Still running or in an intermediate state — schedule next poll\n // 'running' = initial state, 'waiting' = sleeping/waiting, 'pending' = not yet started\n if (\n !snapshot ||\n snapshot.status === 'running' ||\n snapshot.status === 'waiting' ||\n snapshot.status === 'pending'\n ) {\n pollTimeoutId = setTimeout(poll, 150 + Math.random() * 100);\n return;\n }\n\n if (snapshot.context) {\n snapshot.context = hydrateSerializedStepErrors(snapshot.context);\n }\n\n const pollingResult: Record<string, unknown> = {\n steps: snapshot.context,\n status: snapshot.status,\n input: (snapshot.context as Record<string, unknown>)?.input,\n };\n if (snapshot.result !== undefined) pollingResult.result = snapshot.result;\n if (snapshot.error !== undefined) {\n pollingResult.error = getErrorFromUnknown(snapshot.error, { serializeStack: false });\n }\n if (snapshot.value !== undefined) pollingResult.state = snapshot.value;\n\n handleResult({ output: { result: pollingResult } }, `polling-${snapshot.status}`);\n } catch (error) {\n if (error instanceof NonRetriableError) {\n handleError(error, 'polling-non-retriable');\n return;\n }\n handleError(\n new NonRetriableError(\n `Failed to poll workflow status: ${error instanceof Error ? error.message : String(error)}`,\n ),\n 'polling-error',\n );\n }\n };\n\n // Start first poll\n void poll();\n };\n\n // Start both in parallel\n void startRealtimeSubscription();\n void startPolling();\n });\n }\n\n async cancel() {\n const storage = this.#mastra?.getStorage();\n\n await this.inngest.send({\n name: `cancel.workflow.${this.workflowId}`,\n data: {\n runId: this.runId,\n },\n });\n\n const workflowsStore = await storage?.getStore('workflows');\n const snapshot = await workflowsStore?.loadWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n });\n if (snapshot) {\n await workflowsStore?.persistWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n resourceId: this.resourceId,\n snapshot: {\n ...snapshot,\n status: 'canceled' as any,\n value: snapshot.value,\n },\n });\n }\n }\n\n async start(\n args: (TInput extends unknown\n ? {\n inputData?: TInput;\n }\n : {\n inputData: TInput;\n }) &\n (TState extends unknown\n ? {\n initialState?: TState;\n }\n : {\n initialState: TState;\n }) & {\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n outputWriter?: OutputWriter;\n tracingContext?: TracingContext;\n tracingOptions?: TracingOptions;\n outputOptions?: {\n includeState?: boolean;\n includeResumeLabels?: boolean;\n };\n perStep?: boolean;\n },\n ): Promise<WorkflowResult<TState, TInput, TOutput, TSteps>> {\n return this._start(args);\n }\n\n /**\n * Starts the workflow execution without waiting for completion (fire-and-forget).\n * Returns immediately with the runId after sending the event to Inngest.\n * The workflow executes independently in Inngest.\n * Use this when you don't need to wait for the result or want to avoid polling failures.\n */\n async startAsync(\n args: (TInput extends unknown\n ? {\n inputData?: TInput;\n }\n : {\n inputData: TInput;\n }) &\n (TState extends unknown\n ? {\n initialState?: TState;\n }\n : {\n initialState: TState;\n }) & {\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n tracingOptions?: TracingOptions;\n outputOptions?: {\n includeState?: boolean;\n includeResumeLabels?: boolean;\n };\n perStep?: boolean;\n },\n ): Promise<{ runId: string }> {\n // Persist initial snapshot\n const workflowsStore = await this.#mastra.getStorage()?.getStore('workflows');\n await workflowsStore?.persistWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n resourceId: this.resourceId,\n snapshot: {\n runId: this.runId,\n serializedStepGraph: this.serializedStepGraph,\n status: 'running',\n value: {},\n context: {} as any,\n activePaths: [],\n suspendedPaths: {},\n activeStepsPath: {},\n resumeLabels: {},\n waitingPaths: {},\n timestamp: Date.now(),\n },\n });\n\n // Validate inputs\n const inputDataToUse = await this._validateInput(args.inputData);\n const initialStateToUse = await this._validateInitialState(args.initialState ?? ({} as TState));\n\n // Send event to Inngest (fire-and-forget)\n const eventOutput = await this.inngest.send({\n name: `workflow.${this.workflowId}`,\n data: buildDurableTriggerEventData({\n inputData: inputDataToUse,\n initialState: initialStateToUse,\n runId: this.runId,\n resourceId: this.resourceId,\n outputOptions: args.outputOptions,\n tracingOptions: args.tracingOptions,\n requestContext: args.requestContext,\n actor: args.actor,\n perStep: args.perStep,\n }),\n });\n\n const eventId = eventOutput.ids[0];\n if (!eventId) {\n throw new Error('Event ID is not set');\n }\n\n // Return immediately - NO POLLING\n return { runId: this.runId };\n }\n\n async _start({\n inputData,\n initialState,\n outputOptions,\n tracingOptions,\n format,\n requestContext,\n actor,\n perStep,\n }: {\n inputData?: TInput;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n initialState?: TState;\n tracingOptions?: TracingOptions;\n outputOptions?: {\n includeState?: boolean;\n includeResumeLabels?: boolean;\n };\n format?: 'legacy' | 'vnext' | undefined;\n perStep?: boolean;\n }): Promise<WorkflowResult<TState, TInput, TOutput, TSteps>> {\n const workflowsStore = await this.#mastra.getStorage()?.getStore('workflows');\n await workflowsStore?.persistWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n resourceId: this.resourceId,\n snapshot: {\n runId: this.runId,\n serializedStepGraph: this.serializedStepGraph,\n status: 'running',\n value: {},\n context: {} as any,\n activePaths: [],\n suspendedPaths: {},\n activeStepsPath: {},\n resumeLabels: {},\n waitingPaths: {},\n timestamp: Date.now(),\n },\n });\n\n const inputDataToUse = await this._validateInput(inputData);\n const initialStateToUse = await this._validateInitialState(initialState ?? ({} as TState));\n\n const eventName = `workflow.${this.workflowId}`;\n\n const eventOutput = await this.inngest.send({\n name: eventName,\n data: buildDurableTriggerEventData({\n inputData: inputDataToUse,\n initialState: initialStateToUse,\n runId: this.runId,\n resourceId: this.resourceId,\n outputOptions,\n tracingOptions,\n format,\n requestContext,\n actor,\n perStep,\n }),\n });\n\n const eventId = eventOutput.ids[0];\n if (!eventId) {\n throw new Error('Event ID is not set');\n }\n\n const runOutput = await this.getRunOutput(eventId);\n const result = runOutput?.output?.result;\n\n this.hydrateFailedResult(result);\n\n // Only include state when explicitly requested, matching core engine behavior\n if (!outputOptions?.includeState) {\n delete result.state;\n }\n\n if (result.status !== 'suspended') {\n this.cleanup?.();\n }\n return result;\n }\n\n async resume<TResume>(params: {\n resumeData?: TResume;\n step?:\n | Step<string, any, any, TResume, any>\n | [...Step<string, any, any, any, any>[], Step<string, any, any, TResume, any>]\n | string\n | string[];\n label?: string;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n perStep?: boolean;\n }): Promise<WorkflowResult<TState, TInput, TOutput, TSteps>> {\n const p = this._resume(params).then(result => {\n if (result.status !== 'suspended') {\n this.closeStreamAction?.().catch(() => {});\n }\n\n return result;\n });\n\n this.executionResults = p;\n return p;\n }\n\n /**\n * Performs all resume preparation and dispatches the resume event to Inngest,\n * but does NOT wait for the workflow result. Shared by `_resume()` (which polls\n * for the result afterwards) and `resumeAsync()` (which returns immediately).\n *\n * Send-time failures (invalid resume data, event send failure) reject synchronously,\n * and the snapshot is rolled back to its prior state on send failure.\n */\n async _resumeAndSendEvent<TResume>(params: {\n resumeData?: TResume;\n step?:\n | Step<string, any, any, TResume, any>\n | [...Step<string, any, any, any, any>[], Step<string, any, any, TResume, any>]\n | string\n | string[];\n label?: string;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n perStep?: boolean;\n }): Promise<{ eventId: string }> {\n const storage = this.#mastra?.getStorage();\n\n const workflowsStore = await storage?.getStore('workflows');\n if (!workflowsStore) {\n throw new NonRetriableError(`Workflow storage is required to resume run ${this.runId}`);\n }\n const snapshot = await workflowsStore.loadWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n });\n if (!snapshot) {\n throw new NonRetriableError(`Cannot resume run ${this.runId}: snapshot not found`);\n }\n\n // Support label-based resume: look up step from resumeLabels\n const snapshotResumeLabel = params.label ? snapshot.resumeLabels?.[params.label] : undefined;\n const stepParam = snapshotResumeLabel?.stepId ?? params.step;\n\n let steps: string[] = [];\n if (stepParam) {\n if (typeof stepParam === 'string') {\n steps = stepParam.split('.');\n } else {\n steps = (Array.isArray(stepParam) ? stepParam : [stepParam]).map(step =>\n typeof step === 'string' ? step : step?.id,\n );\n }\n }\n\n const suspendedStep = this.workflowSteps[steps?.[0] ?? ''];\n\n const resumeDataToUse = await this._validateResumeData(params.resumeData, suspendedStep);\n\n // Merge persisted requestContext from snapshot with any new values from params\n const mergedRequestContext = mergeResumeRequestContext((snapshot as any)?.requestContext, params.requestContext);\n\n // Mark the snapshot as 'running' before sending the event so that\n // snapshot-based polling doesn't return the stale suspended/paused result.\n await workflowsStore.persistWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n resourceId: this.resourceId,\n snapshot: {\n ...snapshot,\n status: 'running',\n result: undefined,\n error: undefined,\n timestamp: Date.now(),\n } as any,\n });\n\n let eventOutput;\n try {\n eventOutput = await this.inngest.send({\n name: `workflow.${this.workflowId}`,\n data: buildDurableResumeEventData({\n inputData: resumeDataToUse,\n runId: this.runId,\n workflowId: this.workflowId,\n resume: {\n steps,\n resumePayload: resumeDataToUse,\n resumePath: steps?.[0] ? (snapshot?.suspendedPaths?.[steps?.[0]] as any) : undefined,\n },\n requestContext: mergedRequestContext,\n actor: params.actor,\n perStep: params.perStep,\n }),\n });\n } catch (err) {\n // Rollback: restore the original snapshot so the run isn't stuck in 'running'.\n // The rollback itself can fail (e.g. transient storage error); log it but\n // always rethrow the original error so the underlying failure isn't masked.\n try {\n await workflowsStore.persistWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n resourceId: this.resourceId,\n snapshot: snapshot as any,\n });\n } catch (rollbackErr) {\n console.error('Failed to rollback snapshot during resume error recovery:', rollbackErr);\n }\n throw err;\n }\n\n const eventId = eventOutput.ids[0];\n if (!eventId) {\n throw new Error('Event ID is not set');\n }\n\n return { eventId };\n }\n\n async _resume<TResume>(params: {\n resumeData?: TResume;\n step?:\n | Step<string, any, any, TResume, any>\n | [...Step<string, any, any, any, any>[], Step<string, any, any, TResume, any>]\n | string\n | string[];\n label?: string;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n perStep?: boolean;\n }): Promise<WorkflowResult<TState, TInput, TOutput, TSteps>> {\n const { eventId } = await this._resumeAndSendEvent(params);\n const runOutput = await this.getRunOutput(eventId);\n const result = runOutput?.output?.result;\n this.hydrateFailedResult(result);\n if (result.status !== 'suspended') {\n this.cleanup?.();\n }\n return result;\n }\n\n /**\n * Resumes a suspended workflow without waiting for completion (fire-and-forget).\n * Returns immediately with the runId after sending the resume event to Inngest.\n * The workflow continues executing independently in Inngest.\n *\n * Mirrors `startAsync()`: send-time failures (invalid resume data, event send\n * failure) still reject synchronously and roll back the snapshot, but the result\n * is never polled via `getRunOutput()`. This avoids the polling-based 404 race when\n * you don't need the resolved result inline.\n *\n * NOTE: this is exposed over HTTP / the client SDK as `resume-no-wait` / `resumeNoWait()`,\n * not `resumeAsync`, because the existing `resumeAsync()` client/server surface awaits the\n * full workflow result. TODO(v2): consolidate so `resumeAsync` consistently means\n * fire-and-forget across core, client SDK and HTTP routes (breaking change deferred to v2).\n */\n async resumeAsync<TResume>(params: {\n resumeData?: TResume;\n step?:\n | Step<string, any, any, TResume, any>\n | [...Step<string, any, any, any, any>[], Step<string, any, any, TResume, any>]\n | string\n | string[];\n label?: string;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n perStep?: boolean;\n }): Promise<{ runId: string }> {\n await this._resumeAndSendEvent(params);\n // Return immediately - NO POLLING\n return { runId: this.runId };\n }\n\n async timeTravel<TInput>(params: {\n inputData?: TInput;\n resumeData?: any;\n initialState?: TState;\n step:\n | Step<string, any, TInput, any, any>\n | [...Step<string, any, any, any, any>[], Step<string, any, TInput, any, any>]\n | string\n | string[];\n context?: TimeTravelContext<any, any, any, any>;\n nestedStepsContext?: Record<string, TimeTravelContext<any, any, any, any>>;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n tracingOptions?: TracingOptions;\n outputOptions?: {\n includeState?: boolean;\n includeResumeLabels?: boolean;\n };\n perStep?: boolean;\n }): Promise<WorkflowResult<TState, TInput, TOutput, TSteps>> {\n const p = this._timeTravel(params).then(result => {\n if (result.status !== 'suspended') {\n this.closeStreamAction?.().catch(() => {});\n }\n\n return result;\n });\n\n this.executionResults = p;\n return p;\n }\n\n async _timeTravel<TInput>(params: {\n inputData?: TInput;\n resumeData?: any;\n initialState?: TState;\n step:\n | Step<string, any, TInput, any, any>\n | [...Step<string, any, any, any, any>[], Step<string, any, TInput, any, any>]\n | string\n | string[];\n context?: TimeTravelContext<any, any, any, any>;\n nestedStepsContext?: Record<string, TimeTravelContext<any, any, any, any>>;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n tracingOptions?: TracingOptions;\n outputOptions?: {\n includeState?: boolean;\n includeResumeLabels?: boolean;\n };\n perStep?: boolean;\n }) {\n if (!params.step || (Array.isArray(params.step) && params.step?.length === 0)) {\n throw new Error('Step is required and must be a valid step or array of steps');\n }\n\n let steps: string[] = [];\n if (typeof params.step === 'string') {\n steps = params.step.split('.');\n } else {\n steps = (Array.isArray(params.step) ? params.step : [params.step]).map(step =>\n typeof step === 'string' ? step : step?.id,\n );\n }\n\n if (steps.length === 0) {\n throw new Error('No steps provided to timeTravel');\n }\n\n const storage = this.#mastra?.getStorage();\n const workflowsStore = await storage?.getStore('workflows');\n if (!workflowsStore) {\n throw new NonRetriableError(`Workflow storage is required to time-travel run ${this.runId}`);\n }\n\n const snapshot = await workflowsStore.loadWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n });\n\n let snapshotForRollback = snapshot;\n if (!snapshot) {\n const pendingSnapshot = {\n runId: this.runId,\n serializedStepGraph: this.serializedStepGraph,\n status: 'pending' as const,\n value: {},\n context: {} as any,\n activePaths: [] as number[],\n suspendedPaths: {},\n activeStepsPath: {},\n resumeLabels: {},\n waitingPaths: {},\n timestamp: Date.now(),\n };\n await workflowsStore.persistWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n resourceId: this.resourceId,\n snapshot: pendingSnapshot,\n });\n snapshotForRollback = pendingSnapshot;\n }\n\n if (snapshot?.status === 'running') {\n throw new Error('This workflow run is still running, cannot time travel');\n }\n\n let inputDataToUse = params.inputData;\n\n if (inputDataToUse && steps.length === 1) {\n inputDataToUse = await this._validateTimetravelInputData(params.inputData, this.workflowSteps[steps[0]!]!);\n }\n\n const timeTravelData = createTimeTravelExecutionParams({\n steps,\n inputData: inputDataToUse,\n resumeData: params.resumeData,\n context: params.context,\n nestedStepsContext: params.nestedStepsContext,\n snapshot: (snapshot ?? { context: {} }) as any,\n graph: this.executionGraph,\n initialState: params.initialState,\n perStep: params.perStep,\n });\n\n // Save previous snapshot for rollback if send fails\n const previousSnapshot = snapshotForRollback;\n\n // Mark the snapshot as 'running' before sending the event so that\n // snapshot-based polling doesn't return the stale result from a previous run.\n await workflowsStore.persistWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n resourceId: this.resourceId,\n snapshot: {\n runId: this.runId,\n serializedStepGraph: this.serializedStepGraph,\n status: 'running',\n value: {},\n context: {} as any,\n activePaths: [],\n suspendedPaths: {},\n activeStepsPath: {},\n resumeLabels: {},\n waitingPaths: {},\n timestamp: Date.now(),\n },\n });\n\n let eventOutput;\n try {\n eventOutput = await this.inngest.send({\n name: `workflow.${this.workflowId}`,\n data: buildDurableTimeTravelEventData({\n initialState: timeTravelData.state,\n runId: this.runId,\n workflowId: this.workflowId,\n stepResults: timeTravelData.stepResults,\n timeTravel: timeTravelData,\n tracingOptions: params.tracingOptions,\n outputOptions: params.outputOptions,\n requestContext: params.requestContext,\n actor: params.actor,\n perStep: params.perStep,\n }),\n });\n } catch (err) {\n // Rollback: restore the previous snapshot so the run isn't stuck in 'running'.\n // The rollback itself can fail (e.g. transient storage error); log it but\n // always rethrow the original error so the underlying failure isn't masked.\n if (previousSnapshot) {\n try {\n await workflowsStore.persistWorkflowSnapshot({\n workflowName: this.workflowId,\n runId: this.runId,\n resourceId: this.resourceId,\n snapshot: previousSnapshot as any,\n });\n } catch (rollbackErr) {\n console.error('Failed to rollback snapshot during time-travel error recovery:', rollbackErr);\n }\n }\n throw err;\n }\n\n const eventId = eventOutput.ids[0];\n if (!eventId) {\n throw new Error('Event ID is not set');\n }\n const runOutput = await this.getRunOutput(eventId);\n const result = runOutput?.output?.result;\n this.hydrateFailedResult(result);\n\n // Only include state when explicitly requested, matching core engine behavior\n if (!params.outputOptions?.includeState) {\n delete result.state;\n }\n\n return result;\n }\n\n watch(cb: (event: WorkflowStreamEvent) => void): () => void {\n let active = true;\n const streamPromise = subscribe(\n {\n channel: `workflow:${this.workflowId}:${this.runId}`,\n topics: ['watch'],\n app: this.inngest,\n },\n (message: any) => {\n if (active) {\n cb(message.data);\n }\n },\n );\n\n return () => {\n active = false;\n streamPromise\n .then(async (stream: Awaited<typeof streamPromise>) => {\n return stream.cancel();\n })\n .catch(err => {\n console.error(err);\n });\n };\n }\n\n streamLegacy({\n inputData,\n requestContext,\n actor,\n }: { inputData?: TInput; requestContext?: RequestContext<TRequestContext>; actor?: ActorSignal } = {}): {\n stream: ReadableStream<StreamEvent>;\n getWorkflowState: () => Promise<WorkflowResult<TState, TInput, TOutput, TSteps>>;\n } {\n const { readable, writable } = new TransformStream<StreamEvent, StreamEvent>();\n\n const writer = writable.getWriter();\n void writer.write({\n // @ts-expect-error - stream event type mismatch\n type: 'start',\n payload: { runId: this.runId },\n });\n\n const unwatch = this.watch(async event => {\n try {\n const e: any = {\n ...event,\n type: event.type.replace('workflow-', ''),\n };\n\n if (e.type === 'step-output') {\n e.type = e.payload.output.type;\n e.payload = e.payload.output.payload;\n }\n // watch events are data stream events, so we need to cast them to the correct type\n await writer.write(e as any);\n } catch {}\n });\n\n this.closeStreamAction = async () => {\n await writer.write({\n type: 'finish',\n // @ts-expect-error - stream event type mismatch\n payload: { runId: this.runId },\n });\n unwatch();\n\n try {\n await writer.close();\n } catch (err) {\n console.error('Error closing stream:', err);\n } finally {\n writer.releaseLock();\n }\n };\n\n this.executionResults = this._start({ inputData, requestContext, actor, format: 'legacy' }).then(result => {\n if (result.status !== 'suspended') {\n this.closeStreamAction?.().catch(() => {});\n }\n\n return result;\n });\n\n return {\n stream: readable as ReadableStream<StreamEvent>,\n getWorkflowState: () => this.executionResults!,\n };\n }\n\n stream({\n inputData,\n requestContext,\n actor,\n tracingOptions,\n closeOnSuspend = true,\n initialState,\n outputOptions,\n perStep,\n }: {\n inputData?: TInput;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n tracingContext?: TracingContext;\n tracingOptions?: TracingOptions;\n closeOnSuspend?: boolean;\n initialState?: TState;\n outputOptions?: {\n includeState?: boolean;\n includeResumeLabels?: boolean;\n };\n perStep?: boolean;\n } = {}): WorkflowRunOutput<WorkflowResult<TState, TInput, TOutput, TSteps>> {\n if (this.closeStreamAction && this.streamOutput) {\n return this.streamOutput;\n }\n\n this.closeStreamAction = async () => {};\n\n const self = this;\n const stream = new ReadableStream<WorkflowStreamEvent>({\n async start(controller) {\n const unwatch = self.watch(async (event: WorkflowStreamEvent) => {\n const { type, from = ChunkFrom.WORKFLOW, payload } = event;\n controller.enqueue({\n type,\n runId: self.runId,\n from,\n payload: {\n stepName: (payload as unknown as { id: string })?.id,\n ...payload,\n },\n } as WorkflowStreamEvent);\n });\n\n self.closeStreamAction = async () => {\n unwatch();\n\n try {\n await controller.close();\n } catch (err) {\n console.error('Error closing stream:', err);\n }\n };\n\n const executionResultsPromise = self._start({\n inputData,\n requestContext,\n actor,\n // tracingContext, // We are not able to pass a reference to a span here, what to do?\n initialState,\n tracingOptions,\n outputOptions,\n format: 'vnext',\n perStep,\n });\n let executionResults;\n try {\n executionResults = await executionResultsPromise;\n\n if (closeOnSuspend) {\n // always close stream, even if the workflow is suspended\n // this will trigger a finish event with workflow status set to suspended\n self.closeStreamAction?.().catch(() => {});\n } else if (executionResults.status !== 'suspended') {\n self.closeStreamAction?.().catch(() => {});\n }\n if (self.streamOutput) {\n self.streamOutput.updateResults(\n executionResults as unknown as WorkflowResult<TState, TInput, TOutput, TSteps>,\n );\n }\n } catch (err) {\n self.streamOutput?.rejectResults(err as unknown as Error);\n self.closeStreamAction?.().catch(() => {});\n }\n },\n });\n\n this.streamOutput = new WorkflowRunOutput<WorkflowResult<TState, TInput, TOutput, TSteps>>({\n runId: this.runId,\n workflowId: this.workflowId,\n stream,\n });\n\n return this.streamOutput;\n }\n\n timeTravelStream<TTravelInput>({\n inputData,\n resumeData,\n initialState,\n step,\n context,\n nestedStepsContext,\n requestContext,\n actor,\n // tracingContext,\n tracingOptions,\n outputOptions,\n perStep,\n }: {\n inputData?: TTravelInput;\n initialState?: TState;\n resumeData?: any;\n step:\n | Step<string, any, any, any, any, any, TEngineType>\n | [...Step<string, any, any, any, any, any, TEngineType>[], Step<string, any, any, any, any, any, TEngineType>]\n | string\n | string[];\n context?: TimeTravelContext<any, any, any, any>;\n nestedStepsContext?: Record<string, TimeTravelContext<any, any, any, any>>;\n requestContext?: RequestContext<TRequestContext>;\n actor?: ActorSignal;\n tracingContext?: TracingContext;\n tracingOptions?: TracingOptions;\n outputOptions?: {\n includeState?: boolean;\n includeResumeLabels?: boolean;\n };\n perStep?: boolean;\n }) {\n this.closeStreamAction = async () => {};\n\n const self = this;\n const stream = new ReadableStream<WorkflowStreamEvent>({\n async start(controller) {\n const unwatch = self.watch(async (event: WorkflowStreamEvent) => {\n const { type, from = ChunkFrom.WORKFLOW, payload } = event;\n controller.enqueue({\n type,\n runId: self.runId,\n from,\n payload: {\n stepName: (payload as unknown as { id: string })?.id,\n ...payload,\n },\n } as WorkflowStreamEvent);\n });\n\n self.closeStreamAction = async () => {\n unwatch();\n\n try {\n controller.close();\n } catch (err) {\n console.error('Error closing stream:', err);\n }\n };\n const executionResultsPromise = self._timeTravel({\n inputData,\n step,\n context,\n nestedStepsContext,\n resumeData,\n initialState,\n requestContext,\n actor,\n tracingOptions,\n outputOptions,\n perStep,\n });\n\n self.executionResults = executionResultsPromise;\n\n let executionResults;\n try {\n executionResults = await executionResultsPromise;\n self.closeStreamAction?.().catch(() => {});\n\n if (self.streamOutput) {\n self.streamOutput.updateResults(executionResults);\n }\n } catch (err) {\n self.streamOutput?.rejectResults(err as unknown as Error);\n self.closeStreamAction?.().catch(() => {});\n }\n },\n });\n\n this.streamOutput = new WorkflowRunOutput<WorkflowResult<TState, TInput, TOutput, TSteps>>({\n runId: this.runId,\n workflowId: this.workflowId,\n stream,\n });\n\n return this.streamOutput;\n }\n\n /**\n * Hydrates errors in a failed workflow result back to proper Error instances.\n * This ensures error.cause chains and custom properties are preserved.\n */\n private hydrateFailedResult(result: WorkflowResult<TState, TInput, TOutput, TSteps>): void {\n if (result.status === 'failed') {\n // Ensure error is a proper Error instance with all properties preserved\n result.error = getErrorFromUnknown(result.error, { serializeStack: false });\n // Re-hydrate serialized errors in step results\n if (result.steps) {\n hydrateSerializedStepErrors(result.steps);\n }\n }\n }\n}\n","import { randomUUID } from 'node:crypto';\nimport { emitErrorEvent } from '@mastra/core/agent/durable';\nimport { RequestContext } from '@mastra/core/di';\nimport type { PubSub } from '@mastra/core/events';\nimport type { Mastra } from '@mastra/core/mastra';\nimport { SpanType, EntityType } from '@mastra/core/observability';\nimport type { WorkflowRuns } from '@mastra/core/storage';\nimport { Workflow, getEntryWorkflow, isSingleStepEntry } from '@mastra/core/workflows';\nimport type {\n Step,\n StepResult,\n WorkflowConfig,\n StepFlowEntry,\n WorkflowResult,\n WorkflowRunState,\n WorkflowStreamEvent,\n Run,\n} from '@mastra/core/workflows';\nimport { NonRetriableError } from 'inngest';\nimport type { Inngest } from 'inngest';\nimport { InngestExecutionEngine } from './execution-engine';\nimport {\n compactNestedWorkflowResult,\n NESTED_WORKFLOW_OUTPUT_MODE,\n resolveNestedWorkflowOutputMode,\n} from './nested-workflow-output';\nimport { InngestPubSub } from './pubsub';\nimport { InngestRun } from './run';\nimport type {\n InngestEngineType,\n InngestFlowControlConfig,\n InngestFlowCronConfig,\n InngestWorkflowConfig,\n} from './types';\n\n/**\n * Resolves the nested `InngestWorkflow` wrapped by a graph entry, if any.\n * Handles both plain single-step entries and `loop` / `foreach` entries whose\n * body is a `SingleStepEntry` wrapper (so `{ type: 'step', step: workflow }`\n * bodies are unwrapped correctly).\n */\nfunction getNestedInngestWorkflow(entry: StepFlowEntry): InngestWorkflow | null {\n let nested: unknown = null;\n if (entry.type === 'loop' || entry.type === 'foreach') {\n nested = getEntryWorkflow(entry.step);\n } else if (isSingleStepEntry(entry)) {\n nested = getEntryWorkflow(entry);\n }\n return nested instanceof InngestWorkflow ? nested : null;\n}\n\nexport class InngestWorkflow<\n TEngineType = InngestEngineType,\n TSteps extends Step<string, any, any, any, any, any, TEngineType, any>[] = Step<\n string,\n unknown,\n unknown,\n unknown,\n unknown,\n unknown,\n TEngineType,\n unknown\n >[],\n TWorkflowId extends string = string,\n TState = unknown,\n TInput = unknown,\n TOutput = unknown,\n TPrevSchema = TInput,\n TRequestContext extends Record<string, any> | unknown = unknown,\n> extends Workflow<TEngineType, TSteps, TWorkflowId, TState, TInput, TOutput, TPrevSchema, TRequestContext> {\n #mastra: Mastra;\n public inngest: Inngest;\n\n private function: ReturnType<Inngest['createFunction']> | undefined;\n private cronFunction: ReturnType<Inngest['createFunction']> | undefined;\n private readonly flowControlConfig?: InngestFlowControlConfig;\n private readonly functionRetries: NonNullable<InngestFlowControlConfig['retries']>;\n private readonly cronConfig?: InngestFlowCronConfig<TInput, TState>;\n /**\n * Optional override that lets a host (e.g. `createInngestAgent`) provide the\n * PubSub instance used by workflow steps for publishing chunk/finish events.\n * When set, the workflow function uses this factory instead of constructing\n * a fresh `InngestPubSub`. This is what lets `DurableAgent.observe()` see\n * cached history when the agent wraps its PubSub in a `CachingPubSub`.\n */\n #pubsubFactory?: (defaultPubsub: PubSub) => PubSub;\n\n constructor(\n params: InngestWorkflowConfig<\n TWorkflowId,\n TState,\n TInput,\n TOutput,\n TSteps & Step<string, any, any, any, any, any, InngestEngineType, any>[],\n TRequestContext\n >,\n inngest: Inngest,\n ) {\n const {\n concurrency,\n rateLimit,\n throttle,\n debounce,\n priority,\n retries,\n cron,\n inputData,\n initialState,\n ...workflowParams\n } = params;\n\n super(workflowParams as WorkflowConfig<TWorkflowId, TState, TInput, TOutput, TSteps, TRequestContext>);\n\n this.engineType = 'inngest';\n\n const flowControlEntries = Object.entries({ concurrency, rateLimit, throttle, debounce, priority }).filter(\n ([_, value]) => value !== undefined,\n );\n\n this.flowControlConfig = flowControlEntries.length > 0 ? Object.fromEntries(flowControlEntries) : undefined;\n this.functionRetries = retries ?? 0;\n\n this.#mastra = params.mastra!;\n this.inngest = inngest;\n\n if (cron) {\n this.cronConfig = { cron, inputData, initialState };\n }\n }\n\n async listWorkflowRuns(args?: {\n fromDate?: Date;\n toDate?: Date;\n perPage?: number | false;\n page?: number;\n resourceId?: string;\n }) {\n const storage = this.#mastra?.getStorage();\n if (!storage) {\n this.logger.debug('Cannot get workflow runs. Mastra engine is not initialized');\n return { runs: [], total: 0 };\n }\n\n const workflowsStore = await storage.getStore('workflows');\n if (!workflowsStore) {\n return { runs: [], total: 0 };\n }\n return workflowsStore.listWorkflowRuns({ workflowName: this.id, ...(args ?? {}) }) as unknown as WorkflowRuns;\n }\n\n /**\n * Override the PubSub used inside the durable workflow function. Callers like\n * `createInngestAgent` use this to route workflow event publishes through the\n * agent's `CachingPubSub`, so `observe()` can replay cached history.\n *\n * The factory receives the workflow's own default `InngestPubSub` (constructed\n * with this workflow's id) as input. Hosts should wrap that instance rather\n * than substitute it, so workflow-event channels (which encode the workflow\n * id) remain workflow-local. Returning a `CachingPubSub` wrapping the default\n * is the canonical pattern.\n *\n * The factory is propagated to every nested `InngestWorkflow` in the step\n * graph. Nested workflows run as their own Inngest functions and resolve\n * their own pubsub at runtime; each invocation passes its own workflow-local\n * default into the same factory, so the host can share cross-workflow state\n * (e.g. a single agent-scoped cache) without collapsing per-workflow channel\n * isolation.\n */\n __setPubsubFactory(factory: (defaultPubsub: PubSub) => PubSub) {\n this.#pubsubFactory = factory;\n const updateNested = (step: StepFlowEntry) => {\n const nested = getNestedInngestWorkflow(step);\n if (nested) {\n nested.__setPubsubFactory(factory);\n } else if (step.type === 'parallel' || step.type === 'conditional') {\n for (const subStep of step.steps) {\n updateNested(subStep);\n }\n }\n };\n for (const step of this.executionGraph.steps) {\n updateNested(step);\n }\n }\n\n /**\n * Test-only accessor for the configured pubsub factory. Lets tests verify that\n * a host (e.g. `createInngestAgent`) wired the workflow to its agent pubsub\n * without having to drive a real Inngest invocation.\n */\n __getPubsubFactory(): ((defaultPubsub: PubSub) => PubSub) | undefined {\n return this.#pubsubFactory;\n }\n\n __registerMastra(mastra: Mastra) {\n super.__registerMastra(mastra);\n this.#mastra = mastra;\n this.executionEngine.__registerMastra(mastra);\n const updateNested = (step: StepFlowEntry) => {\n const nested = getNestedInngestWorkflow(step);\n if (nested) {\n nested.__registerMastra(mastra);\n } else if (step.type === 'parallel' || step.type === 'conditional') {\n for (const subStep of step.steps) {\n updateNested(subStep);\n }\n }\n };\n\n if (this.executionGraph.steps.length) {\n for (const step of this.executionGraph.steps) {\n updateNested(step);\n }\n }\n }\n\n async createRun(options?: {\n runId?: string;\n resourceId?: string;\n disableScorers?: boolean;\n pubsub?: PubSub;\n }): Promise<Run<TEngineType, TSteps, TState, TInput, TOutput, TRequestContext>> {\n const runIdToUse = options?.runId || randomUUID();\n\n // Return a new Run instance with object parameters\n const existingInMemoryRun = this.runs.get(runIdToUse);\n const newRun = new InngestRun<TEngineType, TSteps, TState, TInput, TOutput, TRequestContext>(\n {\n workflowId: this.id,\n runId: runIdToUse,\n resourceId: options?.resourceId,\n executionEngine: this.executionEngine,\n executionGraph: this.executionGraph,\n serializedStepGraph: this.serializedStepGraph,\n mastra: this.#mastra,\n retryConfig: this.retryConfig,\n cleanup: () => this.runs.delete(runIdToUse),\n workflowSteps: this.steps,\n workflowEngineType: this.engineType,\n validateInputs: this.options.validateInputs,\n },\n this.inngest,\n );\n const run = (existingInMemoryRun ?? newRun) as Run<TEngineType, TSteps, TState, TInput, TOutput, TRequestContext>;\n\n this.runs.set(runIdToUse, run);\n\n const shouldPersistSnapshot = this.options.shouldPersistSnapshot({\n workflowStatus: run.workflowRunStatus,\n stepResults: {},\n });\n\n const existingStoredRun = await this.getWorkflowRunById(runIdToUse, {\n withNestedWorkflows: false,\n });\n\n // Check if run exists in persistent storage (not just in-memory)\n const existsInStorage = existingStoredRun && !existingStoredRun.isFromInMemory;\n\n if (!existsInStorage && shouldPersistSnapshot) {\n const workflowsStore = await this.mastra?.getStorage()?.getStore('workflows');\n await workflowsStore?.persistWorkflowSnapshot({\n workflowName: this.id,\n runId: runIdToUse,\n resourceId: options?.resourceId,\n snapshot: {\n runId: runIdToUse,\n status: 'pending',\n value: {},\n context: {},\n activePaths: [],\n activeStepsPath: {},\n waitingPaths: {},\n serializedStepGraph: this.serializedStepGraph,\n suspendedPaths: {},\n resumeLabels: {},\n result: undefined,\n error: undefined,\n timestamp: Date.now(),\n },\n });\n }\n\n return run;\n }\n\n //createCronFunction is only called if cronConfig.cron is defined.\n private createCronFunction() {\n if (this.cronFunction) {\n return this.cronFunction;\n }\n this.cronFunction = this.inngest.createFunction(\n {\n id: `workflow.${this.id}.cron`,\n retries: this.functionRetries,\n // Not scoped by `match` like the event-triggered function above: a cron\n // trigger carries no event data to match a runId against, and the run\n // is created inside the function, so the canceller has no id to name.\n cancelOn: [{ event: `cancel.workflow.${this.id}` }],\n triggers: { cron: this.cronConfig?.cron ?? '' },\n ...this.flowControlConfig,\n },\n async () => {\n const run = await this.createRun();\n // @ts-expect-error - cron inputData type mismatch\n const result = await run.start({\n inputData: this.cronConfig?.inputData,\n initialState: this.cronConfig?.initialState,\n });\n return { result, runId: run.runId };\n },\n );\n return this.cronFunction;\n }\n\n /**\n * Gets the durable Inngest function that executes this workflow.\n *\n * @returns The memoized Inngest function for this workflow.\n */\n getFunction(): ReturnType<Inngest['createFunction']> {\n if (this.function) {\n return this.function;\n }\n\n // Step-code errors are retried at the step level via executeStepWithRetry (step.retries or\n // retryConfig.attempts) and are returned, not rethrown, so function-level retries never re-run\n // failed step code. Function-level retries only re-invoke the function when an SDK request\n // fails (process restart, OOM, 5xx/timeout); they default to 0 and are configurable via `retries`.\n this.function = this.inngest.createFunction(\n {\n id: `workflow.${this.id}`,\n retries: this.functionRetries,\n // `match` scopes the cancellation to the run the cancel event names.\n // Without it Inngest cancels every in-flight run of this function, and\n // since all durable agents share one function, cancelling a single run\n // tore down every other run in the deployment — only the targeted run's\n // snapshot was marked canceled, so the rest simply vanished.\n // Every event that triggers this function carries `data.runId`, and\n // `Run.cancel()` sends the same field.\n cancelOn: [{ event: `cancel.workflow.${this.id}`, match: 'data.runId' }],\n triggers: { event: `workflow.${this.id}` },\n // Spread flow control configuration\n ...this.flowControlConfig,\n },\n /**\n * Executes a workflow invocation from its Inngest trigger event.\n *\n * @param context - The Inngest event, durable step tools, and current attempt.\n * @returns The workflow result and run identifier returned to Inngest.\n */\n async ({ event, step, attempt }) => {\n let {\n inputData,\n initialState,\n runId,\n resourceId,\n resume,\n outputOptions,\n format,\n timeTravel,\n perStep,\n tracingOptions,\n actor,\n parentStream,\n nestedWorkflowOutputMode: requestedNestedWorkflowOutputMode,\n } = event.data;\n const nestedWorkflowOutputMode = resolveNestedWorkflowOutputMode(requestedNestedWorkflowOutputMode);\n const shouldCompactNestedWorkflowOutput = nestedWorkflowOutputMode === NESTED_WORKFLOW_OUTPUT_MODE.COMPACT;\n\n if (!runId) {\n // Reached when a trigger event arrives without a run id — an event sent\n // directly rather than through `createRun()`, which always supplies one.\n // The id generated here never reaches the trigger event that `cancelOn`\n // matches against, so `cancel.workflow.${this.id}` cannot target this\n // run. Warn rather than reject: an unnamed run is still a valid way to\n // start a workflow, it just can't be cancelled by id afterwards.\n runId = await step.run(`workflow.${this.id}.runIdGen`, async () => {\n return randomUUID();\n });\n this.logger.warn?.(\n `Workflow \"${this.id}\" was triggered without a runId, so run \"${runId}\" cannot be cancelled by id. ` +\n `Send \\`data.runId\\` on the trigger event (or start the run with createRun()) to make it cancellable.`,\n );\n }\n\n if (resume && (initialState === undefined || resume.stepResults === undefined)) {\n const workflowsStore = await this.#mastra?.getStorage()?.getStore('workflows');\n const snapshot = await workflowsStore?.loadWorkflowSnapshot({\n workflowName: this.id,\n runId,\n });\n\n initialState ??= snapshot?.value;\n if (resume.stepResults === undefined && snapshot?.context !== undefined) {\n resume = { ...resume, stepResults: snapshot.context };\n }\n }\n\n // Create InngestPubSub instance. Publishes go through `inngest.realtime.publish()`\n // (Inngest SDK v4 client API), which auto-includes the current runId from the\n // function's async context.\n //\n // The default is constructed with `this.id` so workflow-event channels stay\n // workflow-local (InngestPubSub encodes the workflowId in `workflow:<id>:<runId>`).\n // Hosts (e.g. `createInngestAgent`) can override via `__setPubsubFactory` to\n // wrap this default - typically with a `CachingPubSub` so `observe()` can replay\n // cached history - without disturbing per-workflow channel isolation.\n const defaultPubsub = new InngestPubSub(this.inngest, this.id);\n const pubsub: PubSub = this.#pubsubFactory?.(defaultPubsub) ?? defaultPubsub;\n\n // Create requestContext before execute so we can reuse it in finalize\n const requestContext: RequestContext = new RequestContext(Object.entries(event.data.requestContext ?? {}));\n\n // Store mastra reference for use in proxy closure\n const mastra = this.#mastra;\n const tracingPolicy = this.options.tracingPolicy;\n\n // Create the workflow root span durably - exports SPAN_STARTED immediately on first execution\n // On replay, returns memoized ExportedSpan data without re-creating the span\n const workflowSpanData = await step.run(`workflow.${this.id}.span.start`, async () => {\n const observability = mastra?.observability?.getSelectedInstance({ requestContext });\n if (!observability) return undefined;\n\n const span = observability.startSpan({\n type: SpanType.WORKFLOW_RUN,\n name: `workflow run: '${this.id}'`,\n entityType: EntityType.WORKFLOW_RUN,\n entityId: this.id,\n entityName: this.id,\n input: inputData,\n metadata: {\n resourceId,\n runId,\n },\n tracingPolicy,\n tracingOptions,\n requestContext,\n });\n\n return span?.exportSpan();\n });\n\n const engine = new InngestExecutionEngine(this.#mastra, step, attempt, this.options, parentStream);\n\n let result: WorkflowResult<TState, TInput, TOutput, TSteps>;\n try {\n result = await engine.execute<TState, TInput, WorkflowResult<TState, TInput, TOutput, TSteps>>({\n workflowId: this.id,\n runId,\n resourceId,\n graph: this.executionGraph,\n serializedStepGraph: this.serializedStepGraph,\n input: inputData,\n initialState,\n pubsub,\n retryConfig: this.retryConfig,\n requestContext,\n actor,\n resume,\n timeTravel,\n perStep,\n format,\n abortController: new AbortController(),\n // For Inngest, we don't pass workflowSpan - step spans use tracingIds instead\n workflowSpan: undefined,\n // Pass tracing IDs for durable span operations\n tracingIds: workflowSpanData\n ? {\n traceId: workflowSpanData.traceId,\n workflowSpanId: workflowSpanData.id,\n }\n : undefined,\n outputOptions,\n outputWriter: async (chunk: WorkflowStreamEvent) => {\n try {\n await pubsub.publish(`workflow.events.v2.${runId}`, {\n type: 'watch',\n runId,\n data: chunk,\n });\n } catch (err) {\n this.logger.debug?.('Failed to publish watch event:', err);\n }\n // Nested functions have workflow-local channels; send writer chunks\n // directly to the outermost run without forwarding lifecycle events.\n if (parentStream) {\n try {\n await defaultPubsub.publishWorkflowWatchTo(parentStream.workflowId, parentStream.runId, chunk);\n } catch (err) {\n this.logger.debug?.('Failed to publish parent watch event:', err);\n }\n }\n },\n });\n } catch (executionError) {\n // Execution threw an exception (not just returned failed status)\n // Create a failed result to pass to finalize\n result = {\n status: 'failed',\n steps: {},\n state: initialState ?? {},\n error: executionError instanceof Error ? executionError : new Error(String(executionError)),\n } as WorkflowResult<TState, TInput, TOutput, TSteps>;\n }\n\n const returnedResult = shouldCompactNestedWorkflowOutput ? compactNestedWorkflowResult(result) : result;\n\n // Final step to invoke lifecycle callbacks and end workflow span.\n // This step is memoized by step.run.\n let finalizeError: unknown;\n let finalizeErrored = false;\n try {\n /**\n * Finalizes workflow lifecycle reporting in a memoized Inngest step.\n *\n * @returns The workflow result, or only its status for compact nested invocations.\n */\n const finalizeWorkflow = async () => {\n // For durable agent workflows, emit error event on failure so the\n // client's stream can receive the error and close properly.\n if (result.status === 'failed' && inputData?.__workflowKind === 'durable-agent' && inputData?.runId) {\n const error = result.error instanceof Error ? result.error : new Error(String(result.error));\n try {\n await emitErrorEvent(pubsub, inputData.runId, error);\n } catch (e) {\n this.logger.debug?.('Failed to emit error event:', e);\n }\n }\n\n if (result.status !== 'paused') {\n // Invoke lifecycle callbacks (onFinish and onError)\n await engine.invokeLifecycleCallbacksInternal({\n status: result.status,\n result: 'result' in result ? result.result : undefined,\n error: 'error' in result ? result.error : undefined,\n steps: result.steps,\n tripwire: 'tripwire' in result ? result.tripwire : undefined,\n runId,\n workflowId: this.id,\n resourceId,\n input: inputData,\n requestContext,\n state: result.state ?? initialState ?? {},\n });\n }\n\n // End the workflow span with appropriate status\n // The workflow span was already created and SPAN_STARTED was exported in the span.start step\n if (workflowSpanData) {\n const observability = mastra?.observability?.getSelectedInstance({ requestContext });\n if (observability) {\n // Rebuild the span from cached data to call end/error\n const workflowSpan = observability.rebuildSpan(workflowSpanData);\n\n if (result.status === 'failed') {\n workflowSpan.error({\n error: result.error instanceof Error ? result.error : new Error(String(result.error)),\n attributes: { status: 'failed' },\n });\n } else {\n workflowSpan.end({\n output: result.status === 'success' ? result.result : undefined,\n attributes: { status: result.status },\n });\n }\n }\n }\n\n // Ensure final snapshot is persisted BEFORE publishing workflow-finish\n // This fixes a race condition where getRunOutput reads the snapshot before it's fully written\n const shouldPersistFinalSnapshot = this.options.shouldPersistSnapshot({\n workflowStatus: result.status,\n stepResults: result.steps,\n });\n if (shouldPersistFinalSnapshot) {\n const workflowsStore = await mastra?.getStorage()?.getStore('workflows');\n if (workflowsStore) {\n // For suspended workflows, read existing snapshot to preserve suspendedPaths and resumeLabels\n // which were set correctly by the handlers during execution\n let existingSnapshot:\n | { suspendedPaths?: Record<string, number[]>; resumeLabels?: Record<string, any> }\n | undefined;\n if (result.status === 'suspended') {\n existingSnapshot =\n (await workflowsStore.loadWorkflowSnapshot({\n workflowName: this.id,\n runId,\n })) ?? undefined;\n }\n\n await workflowsStore.persistWorkflowSnapshot({\n workflowName: this.id,\n runId,\n resourceId,\n snapshot: {\n runId,\n status: result.status,\n value: result.state ?? initialState ?? {},\n context: toSnapshotContext(result.steps),\n activePaths: [],\n activeStepsPath: {},\n serializedStepGraph: this.serializedStepGraph,\n suspendedPaths: existingSnapshot?.suspendedPaths ?? {},\n waitingPaths: {},\n resumeLabels: existingSnapshot?.resumeLabels ?? result.resumeLabels ?? {},\n result: result.status === 'success' ? toSnapshotResult(result.result) : undefined,\n error: result.status === 'failed' ? result.error : undefined,\n requestContext: requestContext.toJSON(),\n tracingContext: workflowSpanData\n ? {\n traceId: workflowSpanData.traceId,\n spanId: workflowSpanData.id,\n }\n : undefined,\n timestamp: Date.now(),\n },\n });\n }\n }\n\n // Publish workflow-finish event for realtime subscribers (best-effort)\n try {\n await pubsub.publish(`workflow.events.v2.${runId}`, {\n type: 'watch',\n runId,\n data: {\n type: 'workflow-finish',\n payload: {\n status: result.status,\n result: result.status === 'success' ? result.result : undefined,\n error: result.status === 'failed' ? result.error : undefined,\n },\n },\n });\n } catch (publishError) {\n this.logger.debug?.('Failed to publish workflow-finish event:', publishError);\n }\n\n // Throw after span ended for failed workflows\n if (result.status === 'failed') {\n throw new NonRetriableError(`Workflow failed`, {\n cause: shouldCompactNestedWorkflowOutput ? { ...returnedResult, runId } : result,\n });\n }\n\n return shouldCompactNestedWorkflowOutput ? { status: result.status } : result;\n };\n await step.run(`workflow.${this.id}.finalize`, finalizeWorkflow);\n } catch (error) {\n finalizeErrored = true;\n finalizeError = error;\n } finally {\n // Keep this outside step.run memoization, but guaranteed on all paths.\n const observability = mastra?.observability?.getSelectedInstance({ requestContext });\n if (observability) {\n try {\n await observability.flush();\n } catch (flushError) {\n this.logger.debug?.('Failed to flush observability:', flushError);\n }\n }\n }\n\n if (finalizeErrored) {\n throw finalizeError;\n }\n\n return { result: returnedResult, runId };\n },\n );\n return this.function;\n }\n\n getNestedFunctions(steps: StepFlowEntry[]): ReturnType<Inngest['createFunction']>[] {\n return steps.flatMap(step => {\n const nested = getNestedInngestWorkflow(step);\n if (nested) {\n return [nested.getFunction(), ...nested.getNestedFunctions(nested.executionGraph.steps)];\n }\n if (step.type === 'parallel' || step.type === 'conditional') {\n return this.getNestedFunctions(step.steps);\n }\n\n return [];\n });\n }\n\n getFunctions(): ReturnType<Inngest['createFunction']>[] {\n return [\n this.getFunction(),\n ...(this.cronConfig?.cron ? [this.createCronFunction()] : []),\n ...this.getNestedFunctions(this.executionGraph.steps),\n ];\n }\n}\n\n/**\n * Converts runtime step results to the serialized context shape expected by WorkflowRunState.\n * StepResult is a structural subset of SerializedStepResult (widening), so no data\n * transformation is needed — this bridges the generic type mismatch at the persistence boundary.\n */\nfunction toSnapshotContext(steps: Record<string, StepResult<any, any, any, any>>): WorkflowRunState['context'] {\n return steps as unknown as WorkflowRunState['context'];\n}\n\n/**\n * Converts a workflow output value to the record shape expected by WorkflowRunState.result.\n * Workflow outputs are generic (TOutput) but the snapshot schema stores them as Record<string, any>.\n */\nfunction toSnapshotResult(output: unknown): WorkflowRunState['result'] {\n return output as WorkflowRunState['result'];\n}\n","import {\n createDurableBackgroundTaskCheckStep,\n createDurableLLMExecutionStep,\n createDurableLLMMappingStep,\n createDurableToolCallStep,\n DurableAgentDefaults,\n DurableStepIds,\n emitFinishEvent,\n runDurableFinishSideEffects,\n modelConfigSchema,\n durableAgenticOutputSchema,\n baseIterationStateSchema,\n createBaseIterationStateUpdate,\n resolveDurableToolCallConcurrency,\n executeDurableAgentScorers,\n} from '@mastra/core/agent/durable';\nimport type {\n DurableAgenticExecutionOutput,\n DurableAgenticWorkflowInput,\n DurableLLMStepOutput,\n DurableToolCallOutput,\n DurableToolCallInput,\n} from '@mastra/core/agent/durable';\nimport type { PubSub } from '@mastra/core/events';\nimport { SpanType, InternalSpans } from '@mastra/core/observability';\nimport type { AIModelGenerationSpan, ExportedSpan } from '@mastra/core/observability';\nimport { PUBSUB_SYMBOL } from '@mastra/core/workflows/_constants';\nimport type { Inngest } from 'inngest';\nimport { z } from 'zod';\n\nimport { init } from '../index';\nimport type { InngestFlowControlConfig } from '../types';\n\n/**\n * Input schema for the durable agentic workflow.\n * Extends base with observability fields for Inngest.\n */\nconst durableAgenticInputSchema = z.object({\n runId: z.string(),\n agentId: z.string(),\n agentName: z.string().optional(),\n messageListState: z.any(),\n toolsMetadata: z.array(z.any()),\n modelConfig: modelConfigSchema,\n options: z.any(),\n state: z.any(),\n messageId: z.string(),\n // JSON-safe snapshot of the caller's request context. Inngest runs durable\n // steps on a separate worker process, so this snapshot is the only way the\n // rebuild path can recover request-scoped configuration.\n requestContextEntries: z.record(z.string(), z.any()).optional(),\n // Observability fields (Inngest-specific)\n agentSpanData: z.any().optional(),\n modelSpanData: z.any().optional(),\n stepIndex: z.number().optional(),\n});\n\n// Output schema imported from shared (durableAgenticOutputSchema)\n\n/**\n * Options for creating an Inngest durable agentic workflow\n */\nexport interface InngestDurableAgenticWorkflowOptions {\n /** Inngest client instance */\n inngest: Inngest;\n /** Maximum number of agentic loop iterations */\n maxSteps?: number;\n /** Inngest function-level retries for the agentic loop and iteration functions (defaults to 0) */\n retries?: InngestFlowControlConfig['retries'];\n}\n\n/**\n * Iteration state schema - extends base with observability fields.\n */\nconst iterationStateSchema = baseIterationStateSchema.extend({\n // Observability - exported span data for agent run\n agentSpanData: z.any().optional(),\n // Observability - exported span data for model generation (ONE span for entire run)\n modelSpanData: z.any().optional(),\n // Step index for continuation across iterations (maintains step: 0, 1, 2, ...)\n stepIndex: z.number(),\n});\n\ntype IterationState = z.infer<typeof iterationStateSchema> & {\n agentSpanData?: ExportedSpan<SpanType.AGENT_RUN>;\n modelSpanData?: ExportedSpan<SpanType.MODEL_GENERATION>;\n};\n\n/**\n * Create a durable agentic workflow using Inngest.\n *\n * This workflow implements the agentic loop pattern in a durable way using\n * Inngest's execution engine:\n *\n * 1. LLM Execution Step - Calls the LLM and gets response/tool calls\n * 2. Tool Call Steps (foreach) - Executes each tool call individually with suspend support\n * 3. LLM Mapping Step - Merges tool results back into state\n * 4. Loop - Continues if more tool calls are needed (dowhile)\n *\n * All state flows through workflow input/output, making it durable across\n * process restarts and execution engine replays.\n *\n * @param options - Configuration options\n * @returns An InngestWorkflow instance that implements the agentic loop\n */\n/** Prefix for Inngest engine workflow IDs to avoid collision with other engines */\nconst INNGEST_ENGINE_PREFIX = 'inngest';\n\n/** Inngest-prefixed workflow IDs */\nexport const InngestDurableStepIds = {\n AGENTIC_EXECUTION: `${INNGEST_ENGINE_PREFIX}:${DurableStepIds.AGENTIC_EXECUTION}`,\n AGENTIC_LOOP: `${INNGEST_ENGINE_PREFIX}:${DurableStepIds.AGENTIC_LOOP}`,\n} as const;\n\nexport function createInngestDurableAgenticWorkflow(options: InngestDurableAgenticWorkflowOptions) {\n const { inngest, maxSteps = DurableAgentDefaults.MAX_STEPS, retries } = options;\n const { createWorkflow } = init(inngest);\n\n // Create the LLM execution step - tools and model are resolved from Mastra at runtime\n const llmExecutionStep = createDurableLLMExecutionStep();\n\n // Create the tool call step - each tool call runs as its own step with suspend support\n const toolCallStep = createDurableToolCallStep();\n\n // Create the LLM mapping step - reuse from core\n const llmMappingStep = createDurableLLMMappingStep();\n\n // Create the background task check step\n const backgroundTaskCheckStep = createDurableBackgroundTaskCheckStep();\n\n // Create the single iteration workflow (LLM -> Tool Calls -> Mapping)\n const singleIterationWorkflow = createWorkflow({\n id: InngestDurableStepIds.AGENTIC_EXECUTION,\n retries,\n inputSchema: iterationStateSchema,\n outputSchema: iterationStateSchema,\n options: {\n tracingPolicy: {\n // Mark all workflow spans as internal so they're hidden in traces\n // This makes the trace structure match regular agents (agent_run -> model_generation -> tool_call)\n internal: InternalSpans.WORKFLOW,\n },\n shouldPersistSnapshot: ({ workflowStatus }) => workflowStatus === 'suspended',\n evaluatePersistencePredicateBeforeDurableOperation: true,\n validateInputs: false,\n emitStepEvents: false,\n },\n steps: [],\n })\n // Step 0: Convert iteration state to LLM input format\n .map(\n async ({ inputData }) => {\n const state = inputData as IterationState;\n return {\n runId: state.runId,\n agentId: state.agentId,\n agentName: state.agentName,\n messageListState: state.messageListState,\n toolsMetadata: state.toolsMetadata,\n modelConfig: state.modelConfig,\n options: state.options,\n state: state.state,\n messageId: state.messageId,\n // Pass the request context snapshot so dynamic model/tool resolvers\n // see the caller's context on every iteration, not just the first.\n requestContextEntries: state.requestContextEntries,\n // Pass agent span data so model spans can use it as parent\n agentSpanData: state.agentSpanData,\n // Pass model span data (ONE span for entire agent run)\n modelSpanData: state.modelSpanData,\n // Pass step index for continuation (step: 0, 1, 2, ...)\n stepIndex: state.stepIndex,\n };\n },\n { id: 'map-to-llm-input' },\n )\n // Step 1: Execute LLM\n .then(llmExecutionStep)\n // Step 2: Extract tool calls as array for foreach (forward model_step span for nesting)\n .map(\n async ({ inputData }) => {\n const llmOutput = inputData as DurableLLMStepOutput;\n return (llmOutput.toolCalls ?? []).map(toolCall => ({\n ...toolCall,\n stepSpanData: llmOutput.stepSpanData,\n })) as DurableToolCallInput[];\n },\n { id: 'extract-tool-calls' },\n )\n // Step 3: Execute each tool call individually (with suspend support).\n // Tool result/error PubSub emission is handled by createDurableToolCallStep.\n // Concurrency is resolved per run at execution time from the serialized\n // iteration state (never a shared mutable object — the workflow instance is\n // reused across runs and Inngest replays memoized steps): approval/suspend\n // tool sets run sequentially, otherwise the run's `toolCallConcurrency`\n // applies (default 10). Mirrors @mastra/core's behavior after #9704.\n .foreach(toolCallStep, {\n concurrency: ({ inputData, getInitData }) => {\n const state = getInitData() as IterationState | undefined;\n return resolveDurableToolCallConcurrency({\n options: state?.options,\n toolsMetadata: state?.toolsMetadata,\n toolCalls: inputData as DurableToolCallInput[],\n });\n },\n })\n // Step 4: Collect tool results and bundle with LLM output for mapping step.\n // Span bookkeeping happens elsewhere: each tool call creates its own live\n // TOOL_CALL span (createDurableToolCallStep, via the forwarded stepSpanData),\n // and the shared llmMappingStep ends the MODEL_STEP span and emits\n // tool-result MODEL_CHUNK events.\n .map(\n async ({ inputData, getStepResult, getInitData }) => {\n const toolResults = inputData as DurableToolCallOutput[];\n const llmOutput = getStepResult(llmExecutionStep.id) as DurableLLMStepOutput;\n const initData = getInitData() as IterationState;\n\n return {\n llmOutput,\n toolResults,\n runId: initData.runId,\n agentId: initData.agentId,\n messageId: initData.messageId,\n state: llmOutput?.state ?? initData.state,\n };\n },\n { id: 'collect-tool-results' },\n )\n // Step 5: Map tool results back to state\n .then(llmMappingStep)\n // Step 6: Check for pending background tasks\n .then(backgroundTaskCheckStep)\n // Step 7: Map back to iteration state format using shared function\n .map(\n async ({ inputData, getInitData }) => {\n const executionOutput = inputData as DurableAgenticExecutionOutput;\n const initData = getInitData() as IterationState;\n\n // Use shared function for base state update\n const baseUpdate = createBaseIterationStateUpdate({\n currentState: initData,\n executionOutput,\n });\n\n // Extend with Inngest-specific observability fields\n const newIterationState: IterationState = {\n ...baseUpdate,\n // Preserve agent span data for observability\n agentSpanData: initData.agentSpanData,\n // Preserve model span data (ONE span for entire agent run)\n modelSpanData: initData.modelSpanData,\n // Increment step index for next iteration (step: 0 → 1 → 2 → ...)\n stepIndex: initData.stepIndex + 1,\n };\n\n return newIterationState;\n },\n { id: 'update-iteration-state' },\n )\n .commit();\n\n // Create the main agentic loop workflow with dowhile\n return (\n createWorkflow({\n id: InngestDurableStepIds.AGENTIC_LOOP,\n retries,\n inputSchema: durableAgenticInputSchema,\n outputSchema: durableAgenticOutputSchema,\n options: {\n tracingPolicy: {\n // Mark all workflow spans as internal so they're hidden in traces\n // This makes the trace structure match regular agents (agent_run -> model_generation -> tool_call)\n internal: InternalSpans.WORKFLOW,\n },\n shouldPersistSnapshot: ({ workflowStatus }) => workflowStatus === 'suspended',\n evaluatePersistencePredicateBeforeDurableOperation: true,\n validateInputs: false,\n emitStepEvents: false,\n },\n steps: [],\n })\n // Initialize iteration state from input\n // The AGENT_RUN span is created BEFORE the workflow starts (in InngestAgent.stream)\n // and passed via input.agentSpanData so the agent_run is the root of the trace\n .map(\n async ({ inputData }) => {\n const input = inputData as DurableAgenticWorkflowInput;\n\n // Use the agent span data passed from InngestAgent.stream()\n // This span was created before the workflow started, making it the trace root\n const agentSpanData = input.agentSpanData as ExportedSpan<SpanType.AGENT_RUN> | undefined;\n // Use the model span data passed from InngestAgent.stream()\n // This ensures ONE model_generation span contains all steps (like regular agents)\n const modelSpanData = input.modelSpanData as ExportedSpan<SpanType.MODEL_GENERATION> | undefined;\n\n const iterationState: IterationState = {\n ...input,\n iterationCount: 0,\n accumulatedSteps: [],\n accumulatedUsage: {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n },\n lastStepResult: undefined,\n agentSpanData,\n modelSpanData,\n stepIndex: input.stepIndex ?? 0,\n };\n return iterationState;\n },\n { id: 'init-iteration-state' },\n )\n // Run the agentic loop with dowhile\n .dowhile(singleIterationWorkflow, async ({ inputData }) => {\n const state = inputData as IterationState;\n\n // Check if we should continue\n const shouldContinue = state.lastStepResult?.isContinued === true;\n // Use maxSteps from options (per-request), falling back to workflow-level default\n const effectiveMaxSteps = state.options?.maxSteps ?? maxSteps;\n const underMaxSteps = state.iterationCount < effectiveMaxSteps;\n\n return shouldContinue && underMaxSteps;\n })\n // Map final state to output format, close agent span, and emit finish event\n .map(\n async params => {\n const { inputData, mastra, requestContext, tracingContext } = params;\n const state = inputData as IterationState;\n const initData = params.getInitData() as DurableAgenticWorkflowInput;\n\n // Access pubsub via symbol to emit finish event\n const pubsub = (params as any)[PUBSUB_SYMBOL] as PubSub | undefined;\n\n // Extract final text from last step\n const lastStep = state.accumulatedSteps[state.accumulatedSteps.length - 1];\n let finalText = lastStep?.text;\n\n // Run finish side effects directly. This mapping already executes inside the\n // engine's durable boundary (`wrapDurableOperation` -> `inngestStep.run`), so\n // wrapping this call in `params.engine.step.run(...)` would create a nested\n // Inngest step, which the Inngest protocol does not support: the nested step's\n // callback never executes and its promise never settles, hanging the run and\n // silently skipping output processors, memory persistence, and title generation.\n const finishResult = await runDurableFinishSideEffects({\n runId: state.runId,\n initData,\n messageListState: state.messageListState,\n mastra,\n requestContext,\n tracingContext,\n logger: mastra?.getLogger?.(),\n outputResult: {\n text: finalText ?? '',\n usage: state.accumulatedUsage,\n finishReason: state.lastStepResult?.reason ?? 'unknown',\n steps: state.accumulatedSteps,\n },\n });\n if (lastStep && finishResult.outputText && finishResult.outputText !== (finalText ?? '')) {\n lastStep.text = finishResult.outputText;\n finalText = finishResult.outputText;\n }\n\n const finalOutput = {\n messageListState: finishResult.messageListState,\n messageId: state.messageId,\n stepResult: state.lastStepResult || {\n reason: 'stop',\n warnings: [],\n isContinued: false,\n },\n output: {\n text: finalText,\n usage: state.accumulatedUsage,\n steps: state.accumulatedSteps,\n },\n state: state.state,\n };\n\n // End MODEL_GENERATION span with final output (children before parent)\n // This span was created BEFORE the workflow started and stayed open for all iterations.\n // Same shape as the core durable agent: `text` is the output, usage goes to the\n // attributes through the tracker so consumers find it where every other model span puts it.\n const observability = mastra?.observability?.getSelectedInstance({});\n if (state.modelSpanData) {\n const modelSpan = observability?.rebuildSpan(\n state.modelSpanData as ExportedSpan<SpanType.MODEL_GENERATION>,\n ) as AIModelGenerationSpan | undefined;\n modelSpan?.createTracker()?.endGeneration({\n output: { text: finalText },\n attributes: { finishReason: state.lastStepResult?.reason || 'stop' },\n usage: state.accumulatedUsage,\n });\n }\n\n // End AGENT_RUN span with final output\n if (state.agentSpanData) {\n const agentSpan = observability?.rebuildSpan(state.agentSpanData as ExportedSpan<SpanType.AGENT_RUN>);\n agentSpan?.end({ output: { text: finalText } });\n }\n\n // Emit finish event via pubsub\n if (pubsub) {\n await emitFinishEvent(pubsub, state.runId, {\n output: finalOutput.output,\n stepResult: finalOutput.stepResult,\n });\n }\n\n return finalOutput;\n },\n { id: 'map-final-output' },\n )\n // Execute scorers (fire-and-forget, doesn't affect main result)\n .map(\n async ({ inputData, getInitData, mastra, requestContext, tracingContext }) => {\n executeDurableAgentScorers({\n initData: getInitData() as DurableAgenticWorkflowInput,\n finalOutput: inputData,\n mastra,\n requestContext,\n tracingContext,\n });\n\n return inputData;\n },\n { id: 'execute-scorers' },\n )\n .commit()\n );\n}\n","/**\n * Factory function to create an Inngest-powered durable agent.\n *\n * This provides a clean API for wrapping a Mastra Agent with Inngest's\n * durable execution engine. The returned object can be registered with\n * Mastra like any other agent, and the required workflow is automatically\n * registered when added to Mastra.\n *\n * @example\n * ```typescript\n * import { Agent } from '@mastra/core/agent';\n * import { createInngestAgent } from '@mastra/inngest';\n * import { Inngest } from 'inngest';\n *\n * const inngest = new Inngest({\n * id: 'my-app',\n * });\n *\n * const agent = new Agent({\n * id: 'my-agent',\n * name: 'My Agent',\n * instructions: 'You are a helpful assistant',\n * model: openai('gpt-4'),\n * });\n *\n * const durableAgent = createInngestAgent({ agent, inngest });\n *\n * const mastra = new Mastra({\n * agents: { myAgent: durableAgent },\n * });\n *\n * // Use the agent\n * const { output, cleanup } = await durableAgent.stream('Hello!');\n * const text = await output.text;\n * cleanup();\n * ```\n */\n\nimport type { Agent, AgentExecutionOptions } from '@mastra/core/agent';\nimport {\n AGENT_STREAM_TOPIC,\n agentThreadStreamRuntime,\n prepareForDurableExecution,\n createDurableAgentStream,\n emitErrorEvent,\n runDurableStreamUntilIdle,\n runResumeDurableStreamUntilIdle,\n globalRunRegistry,\n publishAbortRequest,\n} from '@mastra/core/agent/durable';\nimport type { AgentStepFinishEventData, AgentSuspendedEventData } from '@mastra/core/agent/durable';\nimport type { MessageListInput } from '@mastra/core/agent/message-list';\nimport type { ActorSignal } from '@mastra/core/auth/ee';\nimport { InMemoryServerCache } from '@mastra/core/cache';\nimport type { MastraServerCache } from '@mastra/core/cache';\nimport { CachingPubSub } from '@mastra/core/events';\nimport type { Event, PubSub } from '@mastra/core/events';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { MastraModelOutput, ChunkType, FullOutput, MastraOnFinishCallback } from '@mastra/core/stream';\nimport type { ShouldPersistSnapshotFn, Workflow } from '@mastra/core/workflows';\nimport { NonRetriableError } from 'inngest';\nimport type { Inngest } from 'inngest';\n\nimport {\n buildDurableResumeEventData,\n buildDurableTriggerEventData,\n mergeResumeRequestContext,\n} from '../durable-event-payload';\nimport { InngestPubSub } from '../pubsub';\nimport type { InngestFlowControlConfig } from '../types';\nimport type { InngestWorkflow } from '../workflow';\nimport { createInngestDurableAgenticWorkflow, InngestDurableStepIds } from './create-inngest-agentic-workflow';\n\nclass InngestWorkflowCachingPubSub extends CachingPubSub {\n override publish(\n topic: string,\n event: Omit<Event, 'id' | 'createdAt' | 'index'>,\n options?: { localOnly?: boolean },\n ): Promise<void> {\n if (topic.startsWith('workflow.events.v2.')) {\n return super.publish(topic, event, { ...options, localOnly: true });\n }\n\n return super.publish(topic, event, options);\n }\n}\n\n/**\n * Internal sentinel used by {@link InngestAgent.generate} and\n * {@link InngestAgent.resumeGenerate} to ask the underlying `stream()` /\n * `resume()` implementation to close the consumer stream on a SUSPENDED\n * event, so `getFullOutput()` resolves promptly with `finishReason:\n * 'suspended'` instead of waiting for FINISH/ERROR.\n *\n * Modelled on `CLOSE_ON_SUSPEND` in core `DurableAgent`.\n */\nconst CLOSE_ON_SUSPEND = Symbol('mastra.durable.inngest.closeOnSuspend');\n\n/**\n * Internal symbol used by `generate()` / `resumeGenerate()` to tear down the\n * pubsub subscription on suspend without removing the run-registry entry.\n * The public `cleanup()` does both; this lets the generate wrappers keep the\n * registry alive across `suspend` → `resumeGenerate()` while still releasing\n * the local stream subscription.\n */\nconst STREAM_CLEANUP = Symbol('mastra.durable.inngest.streamCleanup');\n\nconst RESUME_SNAPSHOT_WAIT_MS = 10_000;\nconst RESUME_SNAPSHOT_POLL_MS = 100;\n\n// =============================================================================\n// Types\n// =============================================================================\n\n/**\n * Options for createInngestAgent factory function.\n */\nexport interface CreateInngestAgentOptions {\n /** The Mastra Agent to wrap with durable execution */\n agent: Agent<any, any, any>;\n /** Inngest client instance */\n inngest: Inngest;\n /** Optional ID override (defaults to agent.id) */\n id?: string;\n /** Optional name override (defaults to agent.name) */\n name?: string;\n /** Optional PubSub override (defaults to InngestPubSub) */\n pubsub?: PubSub;\n /**\n * Cache instance for storing stream events.\n * Enables resumable streams - clients can disconnect and reconnect\n * without missing events.\n *\n * When provided, the pubsub is wrapped with CachingPubSub.\n */\n cache?: MastraServerCache;\n /** Mastra instance for observability (optional, set automatically when registered with Mastra) */\n mastra?: Mastra;\n /**\n * Accepted for API symmetry with `createDurableAgent`, but **ignored** by\n * InngestAgent (a warning is logged if set). Inngest's step memoization and\n * replay own durability, so InngestAgent pins a `suspended`-only snapshot\n * policy — Mastra snapshots exist purely for human-in-the-loop resume.\n */\n shouldPersistSnapshot?: ShouldPersistSnapshotFn;\n /**\n * Inngest function-level retries for the durable agent loop function. Inngest\n * re-invokes the function when an SDK request fails (e.g. the process restarts\n * mid-run), replaying memoized steps. Defaults to 0.\n */\n retries?: InngestFlowControlConfig['retries'];\n}\n\n/**\n * Options for InngestAgent.stream().\n *\n * Mirrors `DurableAgentStreamOptions` from `@mastra/core/agent/durable` so that\n * Inngest-backed durable agents accept the same execution surface as the\n * in-memory `DurableAgent`. Most options flow straight through\n * `prepareForDurableExecution` and onto the shared workflow steps; see\n * `.context/durable-agent-parity.md` for the per-option durability matrix.\n */\nexport interface InngestAgentStreamOptions<OUTPUT = undefined> {\n /** Custom instructions that override the agent's default instructions */\n instructions?: AgentExecutionOptions<OUTPUT>['instructions'];\n /** Additional context messages */\n context?: AgentExecutionOptions<OUTPUT>['context'];\n /** Memory configuration */\n memory?: AgentExecutionOptions<OUTPUT>['memory'];\n /** Unique identifier for this execution run */\n runId?: string;\n /** Request Context */\n requestContext?: AgentExecutionOptions<OUTPUT>['requestContext'];\n /** Maximum number of steps */\n maxSteps?: number;\n /**\n * Stop condition(s) for the agentic loop. Data-shaped conditions are\n * serialized into the workflow snapshot; function-form conditions are stored\n * on the in-process run registry and degrade to \"no extra stop\" on a\n * cross-worker resume (same as core DurableAgent).\n */\n stopWhen?: AgentExecutionOptions<OUTPUT>['stopWhen'];\n /** Additional tool sets */\n toolsets?: AgentExecutionOptions<OUTPUT>['toolsets'];\n /** Client-side tools */\n clientTools?: AgentExecutionOptions<OUTPUT>['clientTools'];\n /** Tool selection strategy */\n toolChoice?: AgentExecutionOptions<OUTPUT>['toolChoice'];\n /** Tool names enabled for this execution */\n activeTools?: AgentExecutionOptions<OUTPUT>['activeTools'];\n /** Model settings */\n modelSettings?: AgentExecutionOptions<OUTPUT>['modelSettings'];\n /** Require approval for tool calls. Boolean (gate all / none) or a per-call function policy. */\n requireToolApproval?: AgentExecutionOptions<OUTPUT>['requireToolApproval'];\n /** Automatically resume suspended tools */\n autoResumeSuspendedTools?: boolean;\n /** Maximum concurrent tool calls */\n toolCallConcurrency?: number;\n /** Include raw chunks in output */\n includeRawChunks?: boolean;\n /** Maximum processor retries */\n maxProcessorRetries?: number;\n /** Structured output configuration */\n structuredOutput?: AgentExecutionOptions<OUTPUT>['structuredOutput'];\n /** Version overrides for sub-agent delegation */\n versions?: AgentExecutionOptions<OUTPUT>['versions'];\n /** Additional system message appended after context but before user messages. */\n system?: AgentExecutionOptions<OUTPUT>['system'];\n /** When true, background tasks are disabled for this run. */\n disableBackgroundTasks?: AgentExecutionOptions<OUTPUT>['disableBackgroundTasks'];\n /** Tracing options forwarded to the agent/model spans. */\n tracingOptions?: AgentExecutionOptions<OUTPUT>['tracingOptions'];\n /** Per-call actor signal forwarded to FGA checks and tool execution. */\n actor?: AgentExecutionOptions<OUTPUT>['actor'];\n /**\n * Tool payload transform policy. `targets` is JSON-safe and persisted in the\n * workflow snapshot; `transformToolPayload` is a closure on the run registry\n * and degrades on cross-worker resume.\n */\n transform?: AgentExecutionOptions<OUTPUT>['transform'];\n /**\n * Per-step preparation hook. Stored on the run registry and applied via a\n * processor in the durable LLM step. Closure — degrades on cross-worker\n * resume.\n */\n prepareStep?: AgentExecutionOptions<OUTPUT>['prepareStep'];\n /**\n * Optional completion config (scorers + onComplete + suppressFeedback).\n * JSON-safe parts are serialized; the `onComplete` callback lives on the run\n * registry and degrades on cross-worker resume.\n */\n isTaskComplete?: AgentExecutionOptions<OUTPUT>['isTaskComplete'];\n /**\n * Sub-agent delegation hooks. Forwarded into `convertTools` at prepare time\n * and baked into the sub-agent tool wrappers stored on the run registry.\n * Cross-worker resume on a fresh worker loses the callbacks and degrades to\n * the agent's default delegation.\n */\n delegation?: AgentExecutionOptions<OUTPUT>['delegation'];\n /** Callback when chunk is received */\n onChunk?: (chunk: ChunkType<OUTPUT>) => void | Promise<void>;\n /** Callback when step finishes */\n onStepFinish?: (result: AgentStepFinishEventData) => void | Promise<void>;\n /** Callback when execution finishes */\n onFinish?: MastraOnFinishCallback<OUTPUT>;\n /** Callback on error */\n onError?: ({ error }: { error: Error | string }) => void | Promise<void>;\n /** Callback when workflow suspends */\n onSuspended?: (data: AgentSuspendedEventData) => void | Promise<void>;\n /** Callback when execution is aborted via abortSignal or `result.abort()` */\n onAbort?: AgentExecutionOptions<OUTPUT>['onAbort'];\n /** Callback fired after each agentic-loop iteration (observation only) */\n onIterationComplete?: AgentExecutionOptions<OUTPUT>['onIterationComplete'];\n /**\n * Optional external abort signal. Forwarded onto an internal AbortController\n * stored on the run registry. Either the external signal or\n * `result.abort()` will cancel the stream and emit an ABORT event over\n * pubsub.\n */\n abortSignal?: AbortSignal;\n /**\n * When set, `stream()` delegates to the idle-loop wrapper that keeps the\n * outer stream open across background-task continuations.\n *\n * Pass `true` for default idle timeout (5 min), or `{ maxIdleMs }` to\n * customise.\n */\n untilIdle?: boolean | { maxIdleMs?: number };\n /** @internal */\n _skipBgTaskWait?: boolean;\n}\n\n/**\n * Result from InngestAgent.stream()\n */\nexport interface InngestAgentStreamResult<OUTPUT = undefined> {\n /** The streaming output */\n output: MastraModelOutput<OUTPUT>;\n /** The full stream - delegates to output.fullStream for server compatibility */\n readonly fullStream: ReadableStream<any>;\n /** The unique run ID */\n runId: string;\n /** Thread ID if using memory */\n threadId?: string;\n /** Resource ID if using memory */\n resourceId?: string;\n /** Cleanup function */\n cleanup: () => void;\n /**\n * Abort this run. Flips the internal AbortController for this stream so the\n * durable LLM step short-circuits (when the step worker shares the same\n * process) and emits an ABORT event over pubsub so the consumer stream\n * closes. Safe to call after the run has already finished.\n *\n * Also publishes an abort request over pubsub, which is what stops work\n * already running on a step worker — a different process from this one.\n * Await the returned promise to know the request has been dispatched;\n * ignoring it keeps the previous fire-and-forget behaviour.\n */\n abort: (reason?: unknown) => Promise<void>;\n}\n\n/**\n * Options for InngestAgent.resume(). Mirrors core DurableAgent.resume().\n */\nexport interface InngestAgentResumeOptions<OUTPUT = undefined> {\n threadId?: string;\n resourceId?: string;\n /**\n * Resume a specific suspended tool call. The agentic loop suspends tool calls\n * with `resumeLabel: toolCallId`, so this targets that exact leaf instead of\n * inferring one from the run's suspended paths. Required when more than one\n * tool call is suspended concurrently.\n */\n toolCallId?: string;\n requestContext?: AgentExecutionOptions<OUTPUT>['requestContext'];\n /**\n * Per-call actor signal forwarded to FGA checks and tool execution. Must be\n * re-supplied on every resume: it is never rehydrated from the workflow\n * snapshot, so a membership-bypass signal is never persisted.\n */\n actor?: AgentExecutionOptions<OUTPUT>['actor'];\n onChunk?: (chunk: ChunkType<OUTPUT>) => void | Promise<void>;\n onStepFinish?: (result: AgentStepFinishEventData) => void | Promise<void>;\n onFinish?: MastraOnFinishCallback<OUTPUT>;\n onError?: ({ error }: { error: Error | string }) => void | Promise<void>;\n onSuspended?: (data: AgentSuspendedEventData) => void | Promise<void>;\n /** Callback when execution is aborted via abortSignal or `result.abort()` */\n onAbort?: AgentExecutionOptions<OUTPUT>['onAbort'];\n /**\n * Optional abort signal scoped to the resumed segment. Forwarded onto a\n * fresh internal controller installed on the run's registry entry, so\n * `result.abort()` and the external signal can both cancel the resumed\n * iterations.\n */\n abortSignal?: AbortSignal;\n /**\n * When set, keep the resumed segment open after the workflow's initial\n * resume turn finishes and continue streaming follow-up turns until the\n * agent goes idle (no in-flight background tasks for the same memory\n * scope). Same semantics as `stream({ untilIdle })`. Pass an object to\n * tune `maxIdleMs`.\n */\n untilIdle?: boolean | { maxIdleMs?: number };\n}\n\n/**\n * An Inngest-powered durable agent.\n *\n * This interface represents an agent that uses Inngest's durable execution engine.\n * It can be registered with Mastra like a regular Agent, and the required workflow\n * is automatically registered.\n *\n * At runtime, a Proxy forwards all Agent method calls (e.g., `generate()`, `listTools()`,\n * `getMemory()`) to the underlying agent. The index signature below reflects this:\n * any property not explicitly declared here is available via the Proxy.\n */\nexport interface InngestAgent<TOutput = undefined> {\n /** Agent ID */\n readonly id: string;\n /** Agent name */\n readonly name: string;\n /** The underlying Mastra Agent (for Mastra registration) */\n readonly agent: Agent<any, any, TOutput>;\n /** The Inngest client */\n readonly inngest: Inngest;\n /** The cache instance if resumable streams are enabled */\n readonly cache?: MastraServerCache;\n\n /**\n * The PubSub instance used for streaming events.\n * Returns the CachingPubSub wrapper if caching is enabled.\n * @internal Used by the server's observe endpoint to subscribe to the correct PubSub instance.\n */\n readonly pubsub: PubSub;\n\n /**\n * Stream a response using Inngest's durable execution.\n */\n stream(\n messages: MessageListInput,\n options?: InngestAgentStreamOptions<TOutput>,\n ): Promise<InngestAgentStreamResult<TOutput>>;\n\n /**\n * Resume a suspended workflow execution.\n */\n resume(\n runId: string,\n resumeData: unknown,\n options?: InngestAgentResumeOptions<TOutput>,\n ): Promise<InngestAgentStreamResult<TOutput>>;\n\n /**\n * Prepare for durable execution without starting it.\n */\n prepare(\n messages: MessageListInput,\n options?: AgentExecutionOptions<TOutput>,\n ): Promise<{\n runId: string;\n messageId: string;\n workflowInput: any;\n threadId?: string;\n resourceId?: string;\n }>;\n\n /**\n * Observe (reconnect to) an existing stream.\n * Use this to resume receiving events after a disconnection.\n *\n * @param runId - The run ID to observe\n * @param options.offset - Resume from this event index (0-based). If omitted, replays all events.\n */\n observe(\n runId: string,\n options?: {\n offset?: number;\n onChunk?: (chunk: ChunkType<TOutput>) => void | Promise<void>;\n onStepFinish?: (result: AgentStepFinishEventData) => void | Promise<void>;\n onFinish?: MastraOnFinishCallback<TOutput>;\n onError?: ({ error }: { error: Error | string }) => void | Promise<void>;\n onSuspended?: (data: AgentSuspendedEventData) => void | Promise<void>;\n },\n ): Promise<Omit<InngestAgentStreamResult<TOutput>, 'threadId' | 'resourceId'> & { runId: string }>;\n\n /**\n * Get the durable workflows required by this agent.\n * Called by Mastra during agent registration.\n * @internal\n */\n getDurableWorkflows(): Workflow<any, any, any, any, any, any, any>[];\n\n /**\n * Set the Mastra instance for observability.\n * Called by Mastra during agent registration.\n * @internal\n */\n __setMastra(mastra: Mastra): void;\n\n /**\n * Drain a durable run to a single {@link FullOutput}. Mirrors\n * {@link DurableAgent.generate}: kicks off the same Inngest durable\n * workflow as {@link InngestAgent.stream}, but threads\n * `methodType: 'generate'` into preparation (so tool/preparation paths\n * that branch on method behave consistently with non-durable\n * `Agent.generate`) and awaits `output.getFullOutput()`.\n *\n * If the run suspends (e.g. tool approval), the returned output's\n * `finishReason` is `'suspended'` — use {@link InngestAgent.resumeGenerate}\n * to continue. The run registry entry is intentionally not cleaned up on\n * suspend so resume can pick it up.\n */\n generate(messages: MessageListInput, options?: InngestAgentStreamOptions<TOutput>): Promise<FullOutput<TOutput>>;\n\n /**\n * Resume a suspended durable run and drain it to a single\n * {@link FullOutput}. Mirrors {@link DurableAgent.resumeGenerate} on top\n * of {@link InngestAgent.resume}.\n */\n resumeGenerate(\n runId: string,\n resumeData: unknown,\n options?: InngestAgentResumeOptions<TOutput>,\n ): Promise<FullOutput<TOutput>>;\n\n // ---------------------------------------------------------------------------\n // Agent methods forwarded via Proxy to the underlying Agent at runtime.\n // Declared here so TypeScript can see them without the Proxy indirection.\n // ---------------------------------------------------------------------------\n\n /** Get the agent's description. Forwarded to the underlying Agent. */\n getDescription(): string;\n /** Get the agent's instructions. Forwarded to the underlying Agent. */\n getInstructions(...args: any[]): any;\n /** List tools available to the agent. Forwarded to the underlying Agent. */\n listTools(...args: any[]): any;\n /** Get the agent's LLM configuration. Forwarded to the underlying Agent. */\n getLLM(...args: any[]): any;\n /** Get the agent's model. Forwarded to the underlying Agent. */\n getModel(...args: any[]): any;\n /** Get the agent's memory instance. Forwarded to the underlying Agent. */\n getMemory(...args: any[]): any;\n /** Check if agent has its own memory. Forwarded to the underlying Agent. */\n hasOwnMemory(): boolean;\n /** Get the agent's workspace. Forwarded to the underlying Agent. */\n getWorkspace(...args: any[]): any;\n /** List sub-agents. Forwarded to the underlying Agent. */\n listAgents(...args: any[]): any;\n /** List workflows. Forwarded to the underlying Agent. */\n listWorkflows(...args: any[]): any;\n /** Get default execution options. Forwarded to the underlying Agent. */\n getDefaultOptions(...args: any[]): any;\n /** Get legacy generate options. Forwarded to the underlying Agent. */\n getDefaultGenerateOptionsLegacy(...args: any[]): any;\n /** Get legacy stream options. Forwarded to the underlying Agent. */\n getDefaultStreamOptionsLegacy(...args: any[]): any;\n /** Get available models. Forwarded to the underlying Agent. */\n getModelList(...args: any[]): any;\n /** Get configured processor workflows. Forwarded to the underlying Agent. */\n getConfiguredProcessorWorkflows(...args: any[]): any;\n /** Get raw agent configuration. Forwarded to the underlying Agent. */\n toRawConfig(...args: any[]): any;\n /**\n * Send a signal to a thread. Forwarded to the underlying Agent; a signal that\n * wakes an idle thread starts the run through this agent's durable `stream()`.\n */\n sendSignal: Agent<any, any, TOutput>['sendSignal'];\n /** Send a state signal to a thread. Forwarded to the underlying Agent. */\n sendStateSignal: Agent<any, any, TOutput>['sendStateSignal'];\n /** Send a notification signal to a thread. Forwarded to the underlying Agent. */\n sendNotificationSignal: Agent<any, any, TOutput>['sendNotificationSignal'];\n /** Subscribe to a thread's runs. Forwarded to the underlying Agent. */\n subscribeToThread: Agent<any, any, TOutput>['subscribeToThread'];\n /** Get the active run id for a thread. Forwarded to the underlying Agent. */\n getActiveThreadRunId: Agent<any, any, TOutput>['getActiveThreadRunId'];\n /**\n * Resume a suspended durable run and return its streaming output. Routes\n * through {@link InngestAgent.resume}; requires `runId` in `streamOptions`.\n */\n resumeStream(resumeData: any, streamOptions?: any): Promise<MastraModelOutput<TOutput>>;\n /** Approve a pending tool call on a suspended durable run (via {@link InngestAgent.resumeStream}). */\n approveToolCall(\n options: { runId: string; toolCallId?: string } & Record<string, any>,\n ): Promise<MastraModelOutput<TOutput>>;\n /** Decline a pending tool call on a suspended durable run (via {@link InngestAgent.resumeStream}). */\n declineToolCall(\n options: { runId: string; toolCallId?: string; reason?: string } & Record<string, any>,\n ): Promise<MastraModelOutput<TOutput>>;\n /** Approve a pending tool call and drain the resumed run (via {@link InngestAgent.resumeGenerate}). */\n approveToolCallGenerate(\n options: { runId: string; toolCallId?: string } & Record<string, any>,\n ): Promise<FullOutput<TOutput>>;\n /** Decline a pending tool call and drain the resumed run (via {@link InngestAgent.resumeGenerate}). */\n declineToolCallGenerate(\n options: { runId: string; toolCallId?: string; reason?: string } & Record<string, any>,\n ): Promise<FullOutput<TOutput>>;\n /**\n * @internal Fork the agent for per-request overrides (used by the editor).\n * Returns a new InngestAgent wrapping a fork of the underlying Agent so the\n * fork keeps durable Inngest execution.\n */\n __fork(): InngestAgent<TOutput>;\n /** @internal Update the agent's model. Forwarded to the underlying Agent. */\n __updateModel(...args: any[]): any;\n /** @internal Reset to original model. Forwarded to the underlying Agent. */\n __resetToOriginalModel(...args: any[]): any;\n /** @internal Set logger. Forwarded to the underlying Agent. */\n __setLogger(...args: any[]): any;\n /** @internal Register primitives. Forwarded to the underlying Agent. */\n __registerPrimitives(...args: any[]): any;\n /** @internal Register Mastra instance. Forwarded to the underlying Agent. */\n __registerMastra(...args: any[]): any;\n}\n\n// =============================================================================\n// Factory Function\n// =============================================================================\n\n/**\n * Create an Inngest-powered durable agent from a Mastra Agent.\n *\n * This factory function wraps a regular Mastra Agent with Inngest's durable\n * execution capabilities. The returned InngestAgent can be registered with\n * Mastra, and the required workflow will be automatically registered.\n *\n * @param options - Configuration options\n * @returns An InngestAgent that can be registered with Mastra\n *\n * @example\n * ```typescript\n * const agent = new Agent({\n * id: 'my-agent',\n * instructions: 'You are helpful',\n * model: openai('gpt-4'),\n * });\n *\n * const durableAgent = createInngestAgent({ agent, inngest });\n *\n * const mastra = new Mastra({\n * agents: { myAgent: durableAgent },\n * });\n * ```\n */\nexport function createInngestAgent<TOutput = undefined>(options: CreateInngestAgentOptions): InngestAgent<TOutput> {\n const {\n agent,\n inngest,\n id: idOverride,\n name: nameOverride,\n pubsub: customPubsub,\n cache,\n mastra: mastraOption,\n shouldPersistSnapshot,\n retries,\n } = options;\n\n if (shouldPersistSnapshot) {\n console.warn(\n `InngestAgent '${idOverride ?? agent.id}': ignoring the shouldPersistSnapshot option. ` +\n `Inngest's step memoization/replay owns durability, so InngestAgent always persists ` +\n `'suspended' snapshots only (for human-in-the-loop resume).`,\n );\n }\n\n // Use provided id/name or fall back to agent.id/agent.name\n const agentId = idOverride ?? agent.id;\n const agentName = nameOverride ?? agent.name;\n\n // Track mastra instance - can be set later when registered with Mastra\n let mastra: Mastra | undefined = mastraOption;\n\n // Active untilIdle wrappers keyed by scope (threadId|resourceId)\n const activeStreamUntilIdle = new Map<string, () => void>();\n\n // Late-bound reference to the proxy so stream() can pass it to runDurableStreamUntilIdle\n let proxyRef: InngestAgent<TOutput> | undefined;\n\n // Create the durable workflow for this agent\n // Mastra's addWorkflow handles deduplication, so creating multiple times is fine\n const workflow = createInngestDurableAgenticWorkflow({ inngest, retries });\n\n // Track whether user provided a custom cache (if not, we'll inherit from mastra)\n let _customCache = cache;\n\n // Set up pubsub with lazy CachingPubSub creation\n // CachingPubSub is an internal implementation detail - users just configure cache and pubsub separately\n let innerPubsub: PubSub = customPubsub ?? new InngestPubSub(inngest, InngestDurableStepIds.AGENTIC_LOOP);\n let _cachingPubsub: CachingPubSub | null = null;\n\n // Resolve the cache that backs CachingPubSub history.\n //\n // Resolution order: user-provided > mastra's serverCache > InMemoryServerCache fallback.\n // The fallback gives single-process observe replay parity with the in-memory durable agent.\n // Cross-process observe still requires a shared cache backend (Redis, etc.) supplied via\n // `cache` or `mastra.serverCache`.\n function resolveCache(): MastraServerCache {\n const resolved = _customCache ?? mastra?.serverCache ?? new InMemoryServerCache();\n _customCache = resolved;\n return resolved;\n }\n\n // Lazily create CachingPubSub for the agent.\n //\n // We always wrap the inner pubsub with CachingPubSub (mirroring the in-memory DurableAgent\n // at packages/core/src/agent/durable/durable-agent.ts#ensurePubsubInitialized). Without it,\n // `observe()` would only see live events: the bare InngestPubSub.subscribe streams from the\n // current point in the realtime channel, with no history replay, so reconnects and late\n // observers miss everything emitted before they attached.\n //\n // If the inner pubsub is already a CachingPubSub (e.g. a user passed `new Mastra({ pubsub })`\n // with their own caching layer), we reuse it instead of double-wrapping (issue #18148).\n function getPubsub(): CachingPubSub {\n if (!_cachingPubsub) {\n if (innerPubsub instanceof CachingPubSub) {\n _cachingPubsub = innerPubsub;\n _customCache = _customCache ?? mastra?.serverCache;\n } else {\n _cachingPubsub = new CachingPubSub(innerPubsub, resolveCache());\n }\n }\n return _cachingPubsub;\n }\n\n async function getPubsubOffset(runId: string): Promise<number> {\n const history = await getPubsub().getHistory(AGENT_STREAM_TOPIC(runId));\n return history.length;\n }\n\n // Route workflow event publishes through a CachingPubSub backed by the same cache\n // as the agent's pubsub. Each InngestWorkflow function (including nested ones)\n // passes its own workflow-local InngestPubSub as `defaultPubsub`, which we wrap.\n // This keeps per-workflow event channels (`workflow:<workflowId>:<runId>`)\n // workflow-local while sharing the cache that `observe()` reads from for\n // agent-stream replay.\n // The chained `.commit()` builder loses the InngestWorkflow subtype, so cast back.\n (workflow as unknown as InngestWorkflow).__setPubsubFactory(defaultPubsub => {\n // If the caller already supplied a CachingPubSub upstream, defer to it.\n if (defaultPubsub instanceof CachingPubSub) return defaultPubsub;\n // Ensure the agent's CachingPubSub (and its cache) is resolved so workflow\n // events and agent.stream events share the same history backend.\n getPubsub();\n return new InngestWorkflowCachingPubSub(defaultPubsub, resolveCache());\n });\n\n // Lazily resolve cache\n function getCache(): MastraServerCache | undefined {\n // Ensure pubsub is initialized (which resolves cache)\n getPubsub();\n return _customCache;\n }\n\n /**\n * Trigger the workflow via Inngest event\n */\n async function triggerWorkflow(\n runId: string,\n workflowInput: any,\n tracingOptions?: { traceId: string; parentSpanId: string },\n actor?: ActorSignal,\n ): Promise<void> {\n const eventName = `workflow.${InngestDurableStepIds.AGENTIC_LOOP}`;\n\n await inngest.send({\n name: eventName,\n data: buildDurableTriggerEventData({\n inputData: workflowInput,\n runId,\n resourceId: workflowInput.state?.resourceId,\n requestContext: workflowInput.requestContextEntries ?? {},\n tracingOptions,\n actor,\n }),\n });\n }\n\n /**\n * Emit an error event to pubsub.\n *\n * Best-effort: callers fire-and-forget this on paths that are already\n * failing, so an unreachable pubsub must not turn error reporting into an\n * unhandled rejection.\n */\n async function emitError(runId: string, error: Error): Promise<void> {\n try {\n await emitErrorEvent(getPubsub(), runId, error);\n } catch (publishError) {\n mastra?.getLogger?.()?.warn?.('Failed to publish Inngest durable agent error event', {\n agentId,\n runId,\n error: publishError instanceof Error ? publishError.message : String(publishError),\n });\n }\n }\n\n /**\n * Stop a run in whichever worker is executing it.\n *\n * An Inngest agent's steps run on Inngest's infrastructure, essentially never\n * in the process that called `stream()`. The local `AbortController` is\n * therefore invisible to the step worker, and on its own `abort()` cannot\n * stop anything. Publishing an abort request lets the worker flip its own\n * controller and unwind the run gracefully, emitting the terminal stream\n * event consumers wait on — which a hard workflow cancel would skip.\n *\n * Best-effort: the local abort has already happened, and a caller asking to\n * stop a run should not get a rejection because the publish failed.\n */\n async function requestRemoteAbort(runId: string): Promise<void> {\n try {\n await publishAbortRequest(getPubsub(), runId);\n } catch (error) {\n mastra?.getLogger?.()?.warn?.('Failed to publish Inngest durable agent abort request', {\n agentId,\n runId,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n // Return the InngestAgent object (Agent methods are added by the Proxy below)\n const inngestAgent: Pick<\n InngestAgent<TOutput>,\n | 'id'\n | 'name'\n | 'agent'\n | 'inngest'\n | 'cache'\n | 'pubsub'\n | 'stream'\n | 'resume'\n | 'prepare'\n | 'observe'\n | 'generate'\n | 'resumeGenerate'\n | 'resumeStream'\n | 'approveToolCall'\n | 'declineToolCall'\n | 'approveToolCallGenerate'\n | 'declineToolCallGenerate'\n | '__fork'\n | 'getDurableWorkflows'\n | '__setMastra'\n > = {\n get id() {\n return agentId;\n },\n\n get name() {\n return agentName;\n },\n\n get agent() {\n return agent as Agent<any, any, TOutput>;\n },\n\n get inngest() {\n return inngest;\n },\n\n get cache() {\n return getCache();\n },\n\n get pubsub() {\n return getPubsub();\n },\n\n async stream(messages, streamOptions): Promise<InngestAgentStreamResult<TOutput>> {\n // Delegate to the idle-loop wrapper when `untilIdle` is set.\n if (streamOptions?.untilIdle) {\n const { untilIdle, ...rest } = streamOptions;\n const maxIdleMs = typeof untilIdle === 'object' ? untilIdle.maxIdleMs : undefined;\n return runDurableStreamUntilIdle<TOutput>(proxyRef as any, messages, { ...rest, maxIdleMs } as any, {\n activeStreams: activeStreamUntilIdle,\n bgManager: mastra?.backgroundTaskManager,\n }) as Promise<InngestAgentStreamResult<TOutput>>;\n }\n\n // 1. Prepare for durable execution\n const preparation = await prepareForDurableExecution<TOutput>({\n agent: agent as Agent<string, any, TOutput>,\n messages,\n options: streamOptions as AgentExecutionOptions<TOutput>,\n runId: streamOptions?.runId,\n requestContext: streamOptions?.requestContext,\n methodType: (streamOptions as any)?.__methodType ?? 'stream',\n mastra,\n durableAgentId: agentId,\n durableAgentName: agentName,\n });\n\n const { runId, messageId, workflowInput, registryEntry, threadId, resourceId } = preparation;\n\n // Override agentId and agentName in workflowInput with the durable agent's values\n workflowInput.agentId = agentId;\n workflowInput.agentName = agentName;\n\n // 1a. Install abort controller for this run. The controller is owned by\n // this InngestAgent instance; `result.abort()` flips it, the durable\n // LLM-execution step reads `abortSignal` off the global run registry\n // (when running in the same process) and the consumer stream closes via\n // an ABORT pubsub event when the inner catch detects the signal. If the\n // caller supplied an external signal, forward it onto the internal\n // controller so either source can cancel the run.\n const abortController = new AbortController();\n if (streamOptions?.abortSignal) {\n const external = streamOptions.abortSignal;\n if (external.aborted) {\n abortController.abort((external as AbortSignal & { reason?: unknown }).reason);\n } else {\n external.addEventListener(\n 'abort',\n () => abortController.abort((external as AbortSignal & { reason?: unknown }).reason),\n { once: true },\n );\n }\n }\n registryEntry.abortController = abortController;\n registryEntry.abortSignal = abortController.signal;\n\n // 1b. Register non-serializable state on the global run registry so\n // workflow steps running in the same process can recover it.\n globalRunRegistry.set(runId, registryEntry);\n\n // 2. The AGENT_RUN and MODEL_GENERATION spans were already opened by the\n // preparation phase and exported onto `workflowInput`. Reusing them (rather\n // than minting new ones here) keeps the whole run on a single trace and\n // keeps the preparation-phase spans — input processors and memory recall —\n // parented under the agent run root.\n workflowInput.stepIndex = 0;\n\n // Track cleanup state and global registry entry lifecycle.\n let cleanedUp = false;\n const finalizeGlobalRegistry = () => {\n if (cleanedUp) return;\n cleanedUp = true;\n globalRunRegistry.delete(runId);\n };\n\n // 2. Create the durable agent stream (subscribes to pubsub)\n const {\n output,\n cleanup: streamCleanup,\n ready,\n } = createDurableAgentStream<TOutput>({\n pubsub: getPubsub(),\n runId,\n messageId,\n model: {\n modelId: workflowInput.modelConfig.modelId,\n provider: workflowInput.modelConfig.provider,\n version: 'v3',\n },\n threadId,\n resourceId,\n onChunk: streamOptions?.onChunk,\n onStepFinish: streamOptions?.onStepFinish,\n onFinish: async result => {\n try {\n await streamOptions?.onFinish?.(result);\n } finally {\n finalizeGlobalRegistry();\n }\n },\n onError: async errorArg => {\n try {\n await streamOptions?.onError?.(errorArg);\n } finally {\n finalizeGlobalRegistry();\n }\n },\n onSuspended: streamOptions?.onSuspended,\n onAbort: async data => {\n try {\n await (streamOptions?.onAbort as ((event: any) => void | Promise<void>) | undefined)?.(data);\n } finally {\n finalizeGlobalRegistry();\n }\n },\n onIterationComplete: streamOptions?.onIterationComplete\n ? async data => {\n await (streamOptions.onIterationComplete as (ctx: any) => void | Promise<void>)?.(data);\n }\n : undefined,\n closeOnSuspend: (streamOptions as any)?.[CLOSE_ON_SUSPEND] === true,\n });\n\n // 3. Wait for subscription to be established, then trigger workflow\n // Pass tracing options so workflow spans are children of the agent span\n const agentSpanData = workflowInput.agentSpanData as { traceId?: string; id?: string } | undefined;\n const tracingOptions =\n agentSpanData?.traceId && agentSpanData?.id\n ? { traceId: agentSpanData.traceId, parentSpanId: agentSpanData.id }\n : undefined;\n\n // Wait for subscription to be ready before triggering workflow\n // This prevents race conditions where events are published before subscription.\n // Track the trigger promise on the registry so generate() can await suspend\n // snapshot persistence before returning.\n const workflowExecution = ready\n .then(() => triggerWorkflow(runId, workflowInput, tracingOptions, streamOptions?.actor))\n .catch(error => {\n void emitError(runId, error);\n });\n const trackedEntry = globalRunRegistry.get(runId);\n if (trackedEntry) {\n trackedEntry.workflowExecution = workflowExecution;\n }\n\n // 3b. Register with the thread-stream runtime under the durable wrapper's\n // identity, mirroring DurableAgent. This lets subscribeToThread /\n // sendSignal find the run, and releases the thread reservation held by a\n // signal-woken run once the durable stream finishes. Uses the Mastra-level\n // pubsub (agent.getPubSub()) — not the CachingPubSub carrying workflow chunks.\n await agentThreadStreamRuntime.registerRun(\n proxyRef as unknown as Agent<any, any, any, any>,\n output,\n (streamOptions ?? {}) as AgentExecutionOptions<TOutput>,\n agent.getPubSub(),\n );\n\n // 4. Return stream result - attach extra properties to output for compatibility\n // This allows both destructuring { output, runId, cleanup } AND direct access to fullStream\n const cleanup = () => {\n streamCleanup();\n finalizeGlobalRegistry();\n };\n const abort = async (reason?: unknown) => {\n if (!abortController.signal.aborted) {\n abortController.abort(reason);\n }\n // The step worker is a different process — see `requestRemoteAbort`.\n await requestRemoteAbort(runId);\n };\n const result = {\n output,\n runId,\n threadId,\n resourceId,\n cleanup,\n abort,\n // Also expose fullStream directly for server compatibility\n get fullStream() {\n return output.fullStream;\n },\n // Internal: stream-only cleanup for generate()/resumeGenerate() to\n // release the subscription on suspend without dropping the registry.\n [STREAM_CLEANUP]: streamCleanup,\n };\n\n return result as InngestAgentStreamResult<TOutput>;\n },\n\n async resume(runId, resumeData, resumeOptions): Promise<InngestAgentStreamResult<TOutput>> {\n // Delegate to the resume idle-loop wrapper when `untilIdle` is set.\n // After the resumed segment completes, the wrapper runs\n // `agent.stream([], ...)` continuations against the same thread until\n // pending background tasks settle.\n if (resumeOptions?.untilIdle) {\n const { untilIdle, ...rest } = resumeOptions;\n const maxIdleMs = typeof untilIdle === 'object' ? untilIdle.maxIdleMs : undefined;\n return runResumeDurableStreamUntilIdle<TOutput>(\n proxyRef as any,\n runId,\n resumeData,\n { ...rest, maxIdleMs } as any,\n {\n activeStreams: activeStreamUntilIdle,\n bgManager: mastra?.backgroundTaskManager,\n },\n ) as Promise<InngestAgentStreamResult<TOutput>>;\n }\n\n const existingRegistryEntry = globalRunRegistry.get(runId);\n const priorExecution = existingRegistryEntry?.workflowExecution;\n\n // Settle the prior segment before taking its event offset. Otherwise a late\n // suspension event can be replayed into the new segment and close it early.\n await priorExecution?.catch(() => {\n /* errors already handled by the prior segment */\n });\n const resumeOffset = await getPubsubOffset(runId);\n\n // Install a fresh abort controller scoped to the resumed segment and\n // attach it to the run-registry entry so the durable LLM step (when\n // co-located) can react. The previous run's controller is no longer\n // relevant.\n const abortController = new AbortController();\n if (resumeOptions?.abortSignal) {\n const external = resumeOptions.abortSignal;\n if (external.aborted) {\n abortController.abort((external as AbortSignal & { reason?: unknown }).reason);\n } else {\n external.addEventListener(\n 'abort',\n () => abortController.abort((external as AbortSignal & { reason?: unknown }).reason),\n { once: true },\n );\n }\n }\n // Ensure a registry entry exists for this resumed segment. On Inngest,\n // a resume frequently runs in a fresh process where no prior stream()\n // entry is in memory — without this, the abort controller would be\n // silently dropped and the durable LLM step (when co-located) would\n // have nothing to react to.\n let existingEntry = existingRegistryEntry;\n if (!existingEntry) {\n existingEntry = {\n // Minimal placeholder fields. The durable LLM step recreates tools\n // and model from the workflow input; this slot exists primarily to\n // carry the abort controller across the resumed segment. The\n // explicit flag tells resolveRuntimeDependencies to rebuild runtime\n // state from the Mastra instance instead of trusting this entry.\n isPlaceholder: true,\n tools: {},\n model: undefined as any,\n };\n globalRunRegistry.set(runId, existingEntry);\n }\n existingEntry.abortController = abortController;\n existingEntry.abortSignal = abortController.signal;\n\n // Track cleanup state for the resumed segment so terminal events\n // (finish/error/abort/cleanup) always tear down the registry entry.\n let resumeCleanedUp = false;\n const finalizeResumeRegistry = () => {\n if (resumeCleanedUp) return;\n resumeCleanedUp = true;\n globalRunRegistry.delete(runId);\n };\n\n // Re-subscribe to the stream\n const {\n output,\n cleanup: streamCleanup,\n ready,\n } = createDurableAgentStream<TOutput>({\n pubsub: getPubsub(),\n runId,\n offset: resumeOffset,\n messageId: crypto.randomUUID(),\n model: {\n modelId: undefined,\n provider: undefined,\n version: 'v3',\n },\n threadId: resumeOptions?.threadId,\n resourceId: resumeOptions?.resourceId,\n onChunk: resumeOptions?.onChunk,\n onStepFinish: resumeOptions?.onStepFinish,\n onFinish: async result => {\n try {\n await resumeOptions?.onFinish?.(result);\n } finally {\n finalizeResumeRegistry();\n }\n },\n onError: async errorArg => {\n try {\n await resumeOptions?.onError?.(errorArg);\n } finally {\n finalizeResumeRegistry();\n }\n },\n onSuspended: resumeOptions?.onSuspended,\n onAbort: async data => {\n try {\n await (resumeOptions?.onAbort as ((event: any) => void | Promise<void>) | undefined)?.(data);\n } finally {\n finalizeResumeRegistry();\n }\n },\n closeOnSuspend: (resumeOptions as any)?.[CLOSE_ON_SUSPEND] === true,\n });\n\n // Load the workflow snapshot to build proper resume data\n // This mirrors InngestRun._resume() which loads the snapshot, finds the suspended step,\n // and sends an event to the same trigger name (not a .resume suffix)\n const eventName = `workflow.${InngestDurableStepIds.AGENTIC_LOOP}`;\n\n // Set when the run is not resumable: that rejection belongs to this caller only\n // and must not be published to the run's shared stream topic, which would close\n // the original run's stream too.\n let notResumable = false;\n\n const dispatch = ready.then(async () => {\n const workflowsStore = await mastra?.getStorage()?.getStore('workflows');\n const loadSnapshot = async (): Promise<any> =>\n workflowsStore?.loadWorkflowSnapshot({ workflowName: InngestDurableStepIds.AGENTIC_LOOP, runId });\n\n // The suspension reaches the caller's stream before the loop's finalize step\n // persists the suspended snapshot. Resuming inside that window used to find no\n // suspended step and dispatch a fresh run whose input was the resume payload,\n // crashing with \"Cannot read properties of undefined (reading 'threadId')\" (#24749).\n let snapshot: any = await loadSnapshot();\n const deadline = Date.now() + RESUME_SNAPSHOT_WAIT_MS;\n while (workflowsStore && snapshot?.status !== 'suspended' && Date.now() < deadline) {\n await new Promise(resolve => setTimeout(resolve, RESUME_SNAPSHOT_POLL_MS));\n snapshot = await loadSnapshot();\n }\n if (workflowsStore && snapshot?.status !== 'suspended') {\n notResumable = true;\n throw new NonRetriableError(\n `Cannot resume run ${runId}: it is not suspended` +\n (snapshot?.status ? ` (status: ${snapshot.status}).` : ' (no snapshot found).'),\n );\n }\n\n // Resolve which suspended leaf to resume. `resume.steps` is a path: the outer\n // step id followed by the nested step ids beneath it, so a nested suspension has\n // to be expanded from the outer step's recorded `__workflow_meta.path` rather\n // than left as a bare step id (see `Workflow._resume` in\n // packages/core/src/workflows/workflow.ts, which builds the same path).\n const suspendedStepIds = snapshot?.suspendedPaths ? Object.keys(snapshot.suspendedPaths) : [];\n const resumeLabels: Record<string, { stepId?: string } | undefined> = snapshot?.resumeLabels ?? {};\n const toolCallId = resumeOptions?.toolCallId;\n\n const expandToLeafPath = (stepId: string): string[] => {\n const stepResult = (snapshot?.context ?? {})[stepId];\n const nestedPath = stepResult?.suspendPayload?.__workflow_meta?.path;\n return Array.isArray(nestedPath) ? [stepId, ...nestedPath] : [stepId];\n };\n\n let steps: string[];\n\n if (toolCallId) {\n // The agentic loop registers each suspended tool call under `resumeLabel:\n // toolCallId`, so a named tool call resolves to exactly one outer step.\n const targetStepId = resumeLabels[toolCallId]?.stepId;\n if (!targetStepId) {\n const available = Object.keys(resumeLabels);\n throw new NonRetriableError(\n `Cannot resume run ${runId}: no suspended tool call with id \"${toolCallId}\". ` +\n (available.length > 0\n ? `Suspended tool call ids: ${available.join(', ')}.`\n : `No tool calls are currently suspended.`),\n );\n }\n steps = expandToLeafPath(targetStepId);\n } else {\n // Without a `toolCallId` there is nothing to disambiguate with, so refuse\n // instead of silently resuming whichever suspension happens to be first.\n const available = Object.keys(resumeLabels);\n if (suspendedStepIds.length > 1 || available.length > 1) {\n throw new NonRetriableError(\n `Cannot resume run ${runId}: more than one suspension is parked. ` +\n `Pass \"toolCallId\" to choose which suspended tool call to resume.` +\n (available.length > 0 ? ` Suspended tool call ids: ${available.join(', ')}.` : ''),\n );\n }\n steps = suspendedStepIds[0] ? expandToLeafPath(suspendedStepIds[0]) : [];\n }\n\n const requestContext = mergeResumeRequestContext(snapshot?.requestContext, resumeOptions?.requestContext);\n const tracingOptions = snapshot?.tracingContext\n ? {\n traceId: snapshot.tracingContext.traceId,\n parentSpanId: snapshot.tracingContext.spanId,\n }\n : undefined;\n\n await inngest.send({\n name: eventName,\n data: buildDurableResumeEventData({\n inputData: resumeData,\n runId,\n resourceId: resumeOptions?.resourceId,\n requestContext,\n tracingOptions,\n actor: resumeOptions?.actor,\n resume: {\n steps,\n resumePayload: resumeData,\n resumePath: steps[0] ? snapshot?.suspendedPaths?.[steps[0]] : undefined,\n },\n }),\n });\n });\n\n // The registry entry still tracks the whole dispatch so watchers keep seeing\n // dispatch failures as a stream error, exactly as before.\n const workflowExecution = dispatch.catch(error => {\n if (!notResumable) void emitError(runId, error);\n });\n existingEntry.workflowExecution = workflowExecution;\n\n // Await the dispatch itself (not workflow completion) so a failure to hand the\n // resume event to Inngest rejects the caller. Previously it was fire-and-forget:\n // resume() resolved successfully while the run stayed parked and resumable, and\n // the only signal was a terminal error on the stream.\n try {\n await dispatch;\n } catch (error) {\n // A run that was never resumed must not keep its registry entry or stream\n // subscription, otherwise a later resume of the same runId is blocked.\n streamCleanup();\n finalizeResumeRegistry();\n throw error;\n }\n\n const abort = async (reason?: unknown) => {\n if (!abortController.signal.aborted) {\n abortController.abort(reason);\n }\n // The step worker is a different process — see `requestRemoteAbort`.\n await requestRemoteAbort(runId);\n };\n\n const cleanup = () => {\n streamCleanup();\n finalizeResumeRegistry();\n };\n\n return {\n output,\n get fullStream() {\n return output.fullStream as ReadableStream<any>;\n },\n runId,\n threadId: resumeOptions?.threadId,\n resourceId: resumeOptions?.resourceId,\n cleanup,\n abort,\n // Internal: stream-only cleanup for resumeGenerate() to release the\n // subscription on suspend without dropping the resumed registry entry.\n [STREAM_CLEANUP]: streamCleanup,\n } as InngestAgentStreamResult<TOutput>;\n },\n\n async prepare(messages, prepareOptions) {\n const preparation = await prepareForDurableExecution<TOutput>({\n agent: agent as Agent<string, any, TOutput>,\n messages,\n options: prepareOptions,\n requestContext: prepareOptions?.requestContext,\n mastra,\n durableAgentId: agentId,\n durableAgentName: agentName,\n });\n\n // Override with durable agent's id/name\n preparation.workflowInput.agentId = agentId;\n preparation.workflowInput.agentName = agentName;\n\n return {\n runId: preparation.runId,\n messageId: preparation.messageId,\n workflowInput: preparation.workflowInput,\n threadId: preparation.threadId,\n resourceId: preparation.resourceId,\n };\n },\n\n async observe(runId, observeOptions) {\n // Create the stream subscription with offset support\n const {\n output,\n cleanup: streamCleanup,\n ready,\n } = createDurableAgentStream<TOutput>({\n pubsub: getPubsub(),\n runId,\n messageId: crypto.randomUUID(),\n model: {\n modelId: undefined,\n provider: undefined,\n version: 'v3',\n },\n offset: observeOptions?.offset,\n onChunk: observeOptions?.onChunk,\n onStepFinish: observeOptions?.onStepFinish,\n onFinish: observeOptions?.onFinish,\n onError: observeOptions?.onError,\n onSuspended: observeOptions?.onSuspended,\n });\n\n await ready;\n\n // `observe()` does not own the run, but it can still stop it: closing the\n // local subscription and publishing an abort request, which reaches the\n // worker actually executing it.\n const abort = async (_reason?: unknown) => {\n streamCleanup();\n await requestRemoteAbort(runId);\n };\n\n return {\n output,\n get fullStream() {\n return output.fullStream as ReadableStream<any>;\n },\n runId,\n cleanup: streamCleanup,\n abort,\n };\n },\n\n async generate(messages, generateOptions): Promise<FullOutput<TOutput>> {\n // Delegate to stream() with `methodType: 'generate'` and `closeOnSuspend`\n // so that getFullOutput() resolves promptly on suspend (mirroring\n // DurableAgent.generate). We do NOT pass `untilIdle` through — generate\n // is a one-shot drain, not an idle loop.\n const { untilIdle, ...rest } = generateOptions ?? {};\n void untilIdle;\n const streamOpts = {\n ...rest,\n [CLOSE_ON_SUSPEND]: true,\n __methodType: 'generate',\n } as InngestAgentStreamOptions<TOutput>;\n const result = await proxyRef!.stream(messages, streamOpts);\n\n let suspended = false;\n try {\n const fullOutput = (await result.output.getFullOutput()) as FullOutput<TOutput>;\n if (fullOutput.error) {\n throw fullOutput.error;\n }\n suspended = fullOutput.finishReason === 'suspended';\n // On suspend, wait for the workflow trigger promise so the suspend\n // snapshot has landed before returning — otherwise a follow-up\n // resumeGenerate() may race the storage write.\n if (suspended) {\n await globalRunRegistry.get(result.runId)?.workflowExecution;\n }\n if (!fullOutput.runId) {\n (fullOutput as { runId?: string }).runId = result.runId;\n }\n return fullOutput;\n } finally {\n // Always release the local stream subscription. On suspend, keep the\n // registry entry alive so resumeGenerate() can pick it up; other\n // outcomes run the full public cleanup (which also finalizes the\n // registry).\n if (suspended) {\n const streamOnlyCleanup = (result as unknown as { [STREAM_CLEANUP]?: () => void })[STREAM_CLEANUP];\n streamOnlyCleanup?.();\n } else {\n result.cleanup();\n }\n }\n },\n\n async resumeGenerate(runId, resumeData, resumeOptions): Promise<FullOutput<TOutput>> {\n // `resumeGenerate` is a one-shot drain; strip `untilIdle` so the\n // underlying resume() never delegates to the idle-loop wrapper.\n const { untilIdle, ...rest } = resumeOptions ?? {};\n void untilIdle;\n const result = await proxyRef!.resume(runId, resumeData, {\n ...rest,\n [CLOSE_ON_SUSPEND]: true,\n } as InngestAgentResumeOptions<TOutput>);\n\n let suspended = false;\n try {\n const fullOutput = (await result.output.getFullOutput()) as FullOutput<TOutput>;\n if (fullOutput.error) {\n throw fullOutput.error;\n }\n suspended = fullOutput.finishReason === 'suspended';\n if (suspended) {\n await globalRunRegistry.get(result.runId)?.workflowExecution;\n }\n if (!fullOutput.runId) {\n (fullOutput as { runId?: string }).runId = result.runId;\n }\n return fullOutput;\n } finally {\n if (suspended) {\n const streamOnlyCleanup = (result as unknown as { [STREAM_CLEANUP]?: () => void })[STREAM_CLEANUP];\n streamOnlyCleanup?.();\n } else {\n result.cleanup();\n }\n }\n },\n\n async resumeStream(resumeData, streamOptions) {\n const runId = streamOptions?.runId;\n if (!runId) {\n throw new Error('resumeStream() on InngestAgent requires a runId in streamOptions.');\n }\n const { runId: _runId, ...resumeOptions } = streamOptions;\n const result = await proxyRef!.resume(runId, resumeData, {\n ...resumeOptions,\n // Close the stream when the run re-suspends so callers' loops terminate.\n [CLOSE_ON_SUSPEND]: true,\n } as InngestAgentResumeOptions<TOutput>);\n return result.output;\n },\n\n async approveToolCall(options) {\n return proxyRef!.resumeStream({ approved: true }, options);\n },\n\n async declineToolCall(options) {\n const { reason, ...resumeOptions } = options;\n return proxyRef!.resumeStream({ approved: false, ...(reason !== undefined ? { reason } : {}) }, resumeOptions);\n },\n\n async approveToolCallGenerate(options) {\n const { runId, ...resumeOptions } = options;\n if (!runId) {\n throw new Error('approveToolCallGenerate() on InngestAgent requires a runId.');\n }\n return proxyRef!.resumeGenerate(runId, { approved: true }, resumeOptions as InngestAgentResumeOptions<TOutput>);\n },\n\n async declineToolCallGenerate(options) {\n const { runId, reason, ...resumeOptions } = options;\n if (!runId) {\n throw new Error('declineToolCallGenerate() on InngestAgent requires a runId.');\n }\n return proxyRef!.resumeGenerate(\n runId,\n { approved: false, ...(reason !== undefined ? { reason } : {}) },\n resumeOptions as InngestAgentResumeOptions<TOutput>,\n );\n },\n\n __fork() {\n // Re-wrap a fork of the underlying agent so editor overrides keep\n // durable execution (mirrors DurableAgent.__fork, see #18106).\n // shouldPersistSnapshot is dropped: it is ignored and would only re-warn.\n const { shouldPersistSnapshot: _ignored, ...forkOptions } = options;\n return createInngestAgent<TOutput>({\n ...forkOptions,\n agent: agent.__fork(),\n pubsub: innerPubsub,\n cache: _customCache,\n mastra,\n });\n },\n\n getDurableWorkflows() {\n return [workflow];\n },\n\n __setMastra(mastraInstance: Mastra) {\n mastra = mastraInstance;\n\n // NOTE: Unlike core DurableAgent, we do NOT replace innerPubsub with mastra.pubsub.\n // InngestAgent uses InngestPubSub which handles both publishing (via\n // `inngest.realtime.publish()` in SDK v4) and subscribing (via @inngest/realtime).\n // Replacing it with mastra's EventEmitterPubSub would break streaming because\n // the subscriber would be on a different transport than the publisher.\n },\n };\n\n // Use a Proxy to forward any unknown property/method calls to the underlying agent\n // This ensures the InngestAgent has all Agent methods (getMemory, etc.) while\n // overriding stream() to use durable execution\n const result = new Proxy(inngestAgent, {\n get(target, prop, receiver) {\n // First check if the property exists on our InngestAgent object\n if (prop in target) {\n return Reflect.get(target, prop, receiver);\n }\n // Otherwise, forward to the underlying agent\n const agentValue = (agent as any)[prop];\n if (typeof agentValue === 'function') {\n return agentValue.bind(agent);\n }\n return agentValue;\n },\n has(target, prop) {\n return prop in target || prop in agent;\n },\n }) as InngestAgent<TOutput>;\n\n // Assign the late-bound reference so stream()'s untilIdle path can use it\n proxyRef = result;\n // Signal, message, and subscription APIs are forwarded to the wrapped agent\n // by the Proxy above, and the thread-stream runtime wakes idle threads with\n // `agent.stream()`. Point the runtime at the proxy so those wakes take the\n // durable path instead of the wrapped agent's in-process stream().\n agent.__setThreadRuntimeAgent(result as unknown as Agent<any, any, any, any>);\n return result;\n}\n\n// =============================================================================\n// Type Guard\n// =============================================================================\n\n/**\n * Check if an object is an InngestAgent\n */\nexport function isInngestAgent(obj: any): obj is InngestAgent {\n if (!obj) return false;\n return (\n typeof obj.id === 'string' &&\n typeof obj.name === 'string' &&\n 'agent' in obj &&\n 'inngest' in obj &&\n typeof obj.stream === 'function' &&\n typeof obj.getDurableWorkflows === 'function'\n );\n}\n","import type { Mastra } from '@mastra/core/mastra';\nimport type { InngestFunction } from 'inngest';\nimport { isInngestAgent } from './durable-agent';\nimport { InngestWorkflow } from './workflow';\n\nexport function collectInngestFunctions({\n mastra,\n functions: userFunctions = [],\n}: {\n mastra: Mastra;\n functions?: InngestFunction.Like[];\n}) {\n /**\n * Inngest agents share the same logical durable workflow IDs and resolve the\n * concrete agent from the workflow input, so only the first registered\n * agent's workflow needs to be served.\n */\n const durableAgent = Object.values(mastra.listAgents()).find(agent => isInngestAgent(agent));\n const workflows = [...Object.values(mastra.listWorkflows()), ...(durableAgent?.getDurableWorkflows() ?? [])];\n const workflowFunctions = new Map<string, InngestFunction.Like>();\n\n for (const workflow of workflows) {\n if (!(workflow instanceof InngestWorkflow)) continue;\n\n workflow.__registerMastra(mastra);\n for (const fn of workflow.getFunctions()) {\n const functionId = fn.id();\n if (!workflowFunctions.has(functionId)) {\n workflowFunctions.set(functionId, fn);\n }\n }\n }\n\n return [...workflowFunctions.values(), ...userFunctions];\n}\n","import type { Mastra } from '@mastra/core/mastra';\nimport type { Inngest, InngestFunction, RegisterOptions } from 'inngest';\nimport { serve as inngestServeHono } from 'inngest/hono';\nimport { collectInngestFunctions } from './functions';\n\n/**\n * Options for serve functions\n */\nexport interface MastraServeOptions {\n mastra: Mastra;\n inngest: Inngest;\n /**\n * Optional array of additional functions to serve and register with Inngest.\n */\n functions?: InngestFunction.Like[];\n registerOptions?: RegisterOptions;\n}\n\n/**\n * Type for inngest serve adapters (e.g., from inngest/hono, inngest/express, etc.)\n * Inferred from the inngest serve function signatures.\n */\nexport type InngestServeAdapter<THandler> = (options: {\n client: Inngest;\n functions: InngestFunction.Like[];\n [key: string]: unknown;\n}) => THandler;\n\n/**\n * Collects workflow functions from Mastra and prepares serve options for inngest.\n */\nfunction prepareServeOptions({ mastra, inngest, functions: userFunctions = [], registerOptions }: MastraServeOptions) {\n return {\n ...registerOptions,\n client: inngest,\n functions: collectInngestFunctions({ mastra, functions: userFunctions }),\n };\n}\n\n/**\n * Factory function to create a serve function with any inngest adapter.\n * Use this to integrate Mastra workflows with any framework supported by inngest.\n *\n * @example Express\n * ```ts\n * import { createServe } from '@mastra/inngest';\n * import { serve } from 'inngest/express';\n *\n * const serveExpress = createServe(serve);\n * app.use('/inngest/api', serveExpress({ mastra, inngest }));\n * ```\n *\n * @example Fastify\n * ```ts\n * import { createServe } from '@mastra/inngest';\n * import { serve } from 'inngest/fastify';\n *\n * const serveFastify = createServe(serve);\n * fastify.route({\n * method: ['GET', 'POST', 'PUT'],\n * handler: serveFastify({ mastra, inngest }),\n * url: '/inngest/api',\n * });\n * ```\n *\n * @example Next.js\n * ```ts\n * // app/inngest/api/route.ts — file path determines the route URL\n * import { createServe } from '@mastra/inngest';\n * import { serve } from 'inngest/next';\n *\n * const serveNext = createServe(serve);\n * export const { GET, POST, PUT } = serveNext({ mastra, inngest });\n * ```\n */\nexport function createServe<THandler>(\n adapter: InngestServeAdapter<THandler>,\n): (options: MastraServeOptions) => THandler {\n return (options: MastraServeOptions): THandler => {\n const serveOptions = prepareServeOptions(options);\n return adapter(serveOptions);\n };\n}\n\n/**\n * Serve Mastra workflows with Hono (default).\n *\n * For other frameworks, use `createServe` with the appropriate inngest adapter.\n *\n * @example\n * ```ts\n * import { serve } from '@mastra/inngest';\n *\n * app.use('/inngest/api', async (c) => {\n * return serve({ mastra, inngest })(c);\n * });\n * ```\n */\nexport const serve: (options: MastraServeOptions) => ReturnType<typeof inngestServeHono> =\n createServe(inngestServeHono);\n","import type { Mastra } from '@mastra/core/mastra';\nimport type { Inngest, InngestFunction, RegisterOptions } from 'inngest';\nimport type { connect as inngestConnect } from 'inngest/connect';\nimport { collectInngestFunctions } from './functions';\n\ntype InngestConnectOptions = Parameters<typeof inngestConnect>[0];\n\nexport interface MastraConnectOptions extends Omit<InngestConnectOptions, 'apps'> {\n mastra: Mastra;\n inngest: Inngest;\n /**\n * Optional array of additional Inngest functions to expose through the same Connect worker.\n */\n functions?: InngestFunction.Like[];\n /**\n * Forwarded to Inngest as part of the app registration (timeout, signing key overrides, etc.).\n *\n * When a field is present in both `registerOptions` and the top-level Connect options\n * (e.g. `signingKey`), `registerOptions` wins. This matches the override behavior of\n * `serve()` so the two surfaces stay consistent.\n */\n registerOptions?: RegisterOptions;\n}\n\n/**\n * Connect Mastra workflows to Inngest using an outbound worker connection.\n *\n * Use this instead of `serve()` when the worker process should not expose an inbound HTTP\n * endpoint. The same workflow functions collected by `serve()` are forwarded to\n * `inngest/connect`, alongside any additional user functions.\n *\n * If the Mastra instance has no `InngestWorkflow` and no additional `functions` are\n * provided, a warning is emitted because the worker would otherwise idle forever with\n * nothing to execute.\n *\n * @example Worker process\n * ```ts\n * import { connect } from '@mastra/inngest/connect';\n * import { mastra } from './mastra';\n * import { inngest } from './mastra/inngest';\n *\n * await connect({ mastra, inngest });\n * ```\n */\nexport async function connect(options: MastraConnectOptions) {\n const { mastra, inngest, functions, registerOptions, ...connectOptions } = options;\n const appFunctions = collectInngestFunctions({ mastra, functions });\n\n if (appFunctions.length === 0) {\n console.warn(\n '[@mastra/inngest] connect() was called with no Inngest workflows and no additional functions. ' +\n 'The worker will connect to Inngest but has nothing to execute. ' +\n 'Register at least one InngestWorkflow on the Mastra instance or pass `functions: [...]`.',\n );\n }\n\n const { connect: connectWorker } = await import('inngest/connect');\n\n return connectWorker({\n // Top-level Connect options first, then registerOptions so they take precedence\n // for any overlapping keys (e.g. `signingKey`). This matches serve()'s behavior.\n ...connectOptions,\n ...registerOptions,\n apps: [{ client: inngest, functions: appFunctions }],\n });\n}\n","import type { Step, WorkflowConfig } from '@mastra/core/workflows';\nimport type { Inngest } from 'inngest';\n\n// Extract Inngest's native flow control configuration types from createFunction first argument\nexport type InngestCreateFunctionConfig = Parameters<Inngest['createFunction']>[0];\n\n// Extract specific flow control properties (excluding batching).\n// `retries` is function-level: Inngest re-invokes the function when an SDK request fails\n// (process restart, OOM, 5xx/timeout). Step-code errors are retried separately by\n// executeStepWithRetry and never rethrown to Inngest.\nexport type InngestFlowControlConfig = Pick<\n InngestCreateFunctionConfig,\n 'concurrency' | 'rateLimit' | 'throttle' | 'debounce' | 'priority' | 'retries'\n>;\n\n// Cron config for scheduled workflows\nexport type InngestFlowCronConfig<TInputData, TInitialState> = {\n cron?: string;\n inputData?: TInputData;\n initialState?: TInitialState;\n};\n\n// Union type for Inngest workflows with flow control\nexport type InngestWorkflowConfig<\n TWorkflowId extends string,\n TState,\n TInput,\n TOutput,\n TSteps extends Step<string, any, any, any, any, any, InngestEngineType, any>[],\n TRequestContext extends Record<string, any> | unknown = unknown,\n> = WorkflowConfig<TWorkflowId, TState, TInput, TOutput, TSteps, TRequestContext> &\n InngestFlowControlConfig &\n InngestFlowCronConfig<TInput, TState>;\n\n// Compile-time compatibility assertion\nexport type _AssertInngestCompatibility =\n InngestFlowControlConfig extends Pick<Parameters<Inngest['createFunction']>[0], keyof InngestFlowControlConfig>\n ? true\n : never;\nexport const _compatibilityCheck: _AssertInngestCompatibility = true;\n\nexport type InngestEngineType = {\n step: any;\n};\n","import type { ReadableStream } from 'node:stream/web';\nimport { Agent, MessageList, TripWire } from '@mastra/core/agent';\nimport type { MastraDBMessage } from '@mastra/core/agent';\nimport { ErrorCategory, ErrorDomain, MastraError } from '@mastra/core/error';\nimport type { MastraScorers } from '@mastra/core/evals';\nimport type { CoreMessage } from '@mastra/core/llm';\nimport type { TracingContext } from '@mastra/core/observability';\nimport { EntityType, SpanType } from '@mastra/core/observability';\nimport type { Processor, ProcessorStepOutput, ProcessorStepInputSchema, OutputResult } from '@mastra/core/processors';\nimport {\n ProcessorRunner,\n ProcessorState,\n ProcessorStepOutputSchema,\n ProcessorStepSchema,\n} from '@mastra/core/processors';\nimport type { InferPublicSchema, PublicSchema, StandardSchemaWithJSON } from '@mastra/core/schema';\nimport { toStandardSchema } from '@mastra/core/schema';\nimport type { ChunkType, LanguageModelUsage } from '@mastra/core/stream';\nimport type { ToolExecutionContext } from '@mastra/core/tools';\nimport { Tool, createTool } from '@mastra/core/tools';\nimport type { DynamicArgument } from '@mastra/core/types';\nimport type { Step, AgentStepOptions, StepParams, ToolStep, StepMetadata } from '@mastra/core/workflows';\nimport {\n Workflow,\n createStepFromAgent as coreCreateStepFromAgent,\n createStepFromTool as coreCreateStepFromTool,\n} from '@mastra/core/workflows';\nimport type { Inngest } from 'inngest';\nimport type { InngestEngineType, InngestWorkflowConfig } from './types';\nimport { InngestWorkflow } from './workflow';\n\nexport * from './workflow';\nexport * from './execution-engine';\nexport * from './pubsub';\nexport * from './run';\nexport * from './serve';\nexport * from './connect';\nexport * from './types';\nexport * from './durable-agent';\n\ntype InngestSubAgent<TId extends string = string> = {\n id: TId;\n name?: string;\n getDescription: () => string;\n getModel: () => Promise<{ specificationVersion: string }> | { specificationVersion: string };\n generate: (...args: any[]) => Promise<any>;\n stream: (...args: any[]) => Promise<{ fullStream: ReadableStream<any> }>;\n streamLegacy?: (...args: any[]) => Promise<{ fullStream: ReadableStream<any> }>;\n};\n\n// ============================================\n// Type Guards\n// ============================================\n\nfunction isInngestWorkflow(input: unknown): input is InngestWorkflow<any, any, any, any, any, any, any> {\n return input instanceof InngestWorkflow;\n}\n\n/**\n * copied from @mastra/core/agent/subagent.ts for compatible\n */\nfunction isAgentCompatible<TId extends string>(input: unknown): input is InngestSubAgent<TId> {\n return (\n typeof input === 'object' &&\n input !== null &&\n 'generate' in input &&\n typeof input.generate === 'function' &&\n 'stream' in input &&\n typeof input.stream === 'function' &&\n 'getDescription' in input &&\n typeof input.getDescription === 'function' &&\n 'getModel' in input &&\n typeof input.getModel === 'function'\n );\n}\n\nfunction isToolStep(input: unknown): input is ToolStep<any, any, any, any, any> {\n return input instanceof Tool;\n}\n\nfunction isStepParams(input: unknown): input is StepParams<any, any, any, any, any, any> {\n return (\n input !== null &&\n typeof input === 'object' &&\n 'id' in input &&\n 'execute' in input &&\n !(input instanceof Agent) &&\n !(input instanceof Tool) &&\n !(input instanceof InngestWorkflow)\n );\n}\n\n/**\n * Type guard to check if an object is a Processor.\n * A Processor must have an 'id' property and at least one processor method.\n */\nfunction isProcessor(obj: unknown): obj is Processor {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n 'id' in obj &&\n typeof (obj as any).id === 'string' &&\n !(obj instanceof Agent) &&\n !(obj instanceof Tool) &&\n !(obj instanceof InngestWorkflow) &&\n (typeof (obj as any).processInput === 'function' ||\n typeof (obj as any).processInputStep === 'function' ||\n typeof (obj as any).processOutputStream === 'function' ||\n typeof (obj as any).processOutputResult === 'function' ||\n typeof (obj as any).processOutputStep === 'function')\n );\n}\n\n// ============================================\n// Overloads (Public API - clean types for consumers)\n// ============================================\n\n/**\n * Creates a step from explicit params (IMPORTANT: FIRST overload for best error messages when using .then in workflows)\n * @param params Configuration parameters for the step\n * @param params.id Unique identifier for the step\n * @param params.description Optional description of what the step does\n * @param params.inputSchema Zod schema defining the input structure\n * @param params.outputSchema Zod schema defining the output structure\n * @param params.execute Function that performs the step's operations\n * @returns A Step object that can be added to the workflow\n */\nexport function createStep<\n TStepId extends string,\n TStateSchema extends PublicSchema | undefined,\n TInputSchema extends PublicSchema,\n TOutputSchema extends PublicSchema,\n TResumeSchema extends PublicSchema | undefined = undefined,\n TSuspendSchema extends PublicSchema | undefined = undefined,\n>(\n params: StepParams<TStepId, TStateSchema, TInputSchema, TOutputSchema, TResumeSchema, TSuspendSchema>,\n): Step<\n TStepId,\n TStateSchema extends PublicSchema ? InferPublicSchema<TStateSchema> : unknown,\n InferPublicSchema<TInputSchema>,\n InferPublicSchema<TOutputSchema>,\n TResumeSchema extends PublicSchema ? InferPublicSchema<TResumeSchema> : unknown,\n TSuspendSchema extends PublicSchema ? InferPublicSchema<TSuspendSchema> : unknown,\n InngestEngineType\n>;\n\n/**\n * Creates a step from an agent with structured output\n */\nexport function createStep<TStepId extends string, TStepOutput>(\n agent: InngestSubAgent<TStepId> | Agent<TStepId, any>,\n agentOptions: AgentStepOptions<TStepOutput> & {\n structuredOutput: { schema: StandardSchemaWithJSON<TStepOutput> };\n retries?: number;\n scorers?: DynamicArgument<MastraScorers>;\n metadata?: StepMetadata;\n },\n): Step<TStepId, unknown, { prompt: string }, TStepOutput, unknown, unknown, InngestEngineType>;\n\n/**\n * Creates a step from an agent (defaults to { text: string } output)\n */\nexport function createStep<\n TStepId extends string,\n TStepInput extends { prompt: string },\n TStepOutput extends { text: string },\n TResume,\n TSuspend,\n>(\n agent: InngestSubAgent<TStepId> | Agent<TStepId, any>,\n agentOptions?: AgentStepOptions<TStepOutput> & {\n retries?: number;\n scorers?: DynamicArgument<MastraScorers>;\n },\n): Step<TStepId, unknown, TStepInput, TStepOutput, TResume, TSuspend, InngestEngineType>;\n\n/**\n * Creates a step from a tool\n */\nexport function createStep<\n TSchemaIn,\n TSchemaOut,\n TSuspend,\n TResume,\n TContext extends ToolExecutionContext<TSuspend, TResume, any> = ToolExecutionContext<TSuspend, TResume>,\n TId extends string = string,\n TRequestContext extends Record<string, any> | unknown = unknown,\n>(\n tool: Tool<TSchemaIn, TSchemaOut, TSuspend, TResume, TContext, TId, TRequestContext>,\n toolOptions?: { retries?: number; scorers?: DynamicArgument<MastraScorers>; metadata?: StepMetadata },\n): Step<TId, unknown, TSchemaIn, TSchemaOut, TSuspend, TResume, InngestEngineType>;\n\n/**\n * Creates a step from a Processor - wraps a Processor as a workflow step\n * Note: We require at least one processor method to distinguish from StepParams\n */\nexport function createStep<TProcessorId extends string>(\n processor:\n | (Processor<TProcessorId> & { processInput: Function })\n | (Processor<TProcessorId> & { processInputStream: Function })\n | (Processor<TProcessorId> & { processInputStep: Function })\n | (Processor<TProcessorId> & { processOutputStream: Function })\n | (Processor<TProcessorId> & { processOutputResult: Function })\n | (Processor<TProcessorId> & { processOutputStep: Function }),\n): Step<\n `processor:${TProcessorId}`,\n unknown,\n InferPublicSchema<typeof ProcessorStepInputSchema>,\n InferPublicSchema<typeof ProcessorStepOutputSchema>,\n unknown,\n unknown,\n InngestEngineType\n>;\n\n/**\n * IMPORTANT: Fallback overload - provides better error messages when StepParams doesn't match\n * This should be LAST and will show clearer errors about what's wrong\n * This is a copy of first one, KEEP THIS IN SYNC!\n */\nexport function createStep<\n TStepId extends string,\n TStateSchema extends PublicSchema | undefined,\n TInputSchema extends PublicSchema,\n TOutputSchema extends PublicSchema,\n TResumeSchema extends PublicSchema | undefined = undefined,\n TSuspendSchema extends PublicSchema | undefined = undefined,\n>(\n params: StepParams<TStepId, TStateSchema, TInputSchema, TOutputSchema, TResumeSchema, TSuspendSchema>,\n): Step<\n TStepId,\n TStateSchema extends PublicSchema ? InferPublicSchema<TStateSchema> : unknown,\n InferPublicSchema<TInputSchema>,\n InferPublicSchema<TOutputSchema>,\n TResumeSchema extends PublicSchema ? InferPublicSchema<TResumeSchema> : unknown,\n TSuspendSchema extends PublicSchema ? InferPublicSchema<TSuspendSchema> : unknown,\n InngestEngineType\n>;\n\n// ============================================\n// Implementation (uses type guards for clean logic)\n// ============================================\n\nexport function createStep(params: any, agentOrToolOptions?: any): Step<any, any, any, any, any, any, any> {\n // Type assertions are needed because each branch returns a different Step type,\n // but the overloads ensure type safety for consumers\n\n // Issue #9965: Preserve InngestWorkflow identity when passed to createStep\n // This ensures nested workflows in foreach are properly detected by isNestedWorkflowStep()\n if (isInngestWorkflow(params)) {\n return params;\n }\n\n if (isAgentCompatible(params)) {\n return createStepFromAgent(params, agentOrToolOptions);\n }\n\n if (isToolStep(params)) {\n return createStepFromTool(params, agentOrToolOptions);\n }\n\n // StepParams check must come before isProcessor since both have 'id'\n // StepParams always has 'execute', while Processor has processor methods\n if (isStepParams(params)) {\n return createStepFromParams(params);\n }\n\n if (isProcessor(params)) {\n return createStepFromProcessor(params);\n }\n\n throw new Error('Invalid input: expected StepParams, Agent, ToolStep, Processor, or InngestWorkflow');\n}\n\n// ============================================\n// Internal Implementations\n// ============================================\n\nfunction createStepFromParams<\n TStepId extends string,\n TStateSchema extends PublicSchema<any> | undefined,\n TInputSchema extends PublicSchema<any>,\n TOutputSchema extends PublicSchema<any>,\n TResumeSchema extends PublicSchema<any> | undefined = undefined,\n TSuspendSchema extends PublicSchema<any> | undefined = undefined,\n>(\n params: StepParams<TStepId, TStateSchema, TInputSchema, TOutputSchema, TResumeSchema, TSuspendSchema>,\n): Step<\n TStepId,\n TStateSchema extends PublicSchema<any> ? InferPublicSchema<TStateSchema> : unknown,\n InferPublicSchema<TInputSchema>,\n InferPublicSchema<TOutputSchema>,\n TResumeSchema extends PublicSchema<any> ? InferPublicSchema<TResumeSchema> : unknown,\n TSuspendSchema extends PublicSchema<any> ? InferPublicSchema<TSuspendSchema> : unknown,\n InngestEngineType\n> {\n // Type assertion needed because toStandardSchema returns StandardSchemaWithJSON<unknown>\n // but we need it to match the inferred generic types. The public overloads ensure\n // type safety for consumers.\n return {\n id: params.id,\n description: params.description,\n inputSchema: toStandardSchema(params.inputSchema),\n stateSchema: params.stateSchema ? toStandardSchema(params.stateSchema) : undefined,\n outputSchema: toStandardSchema(params.outputSchema),\n resumeSchema: params.resumeSchema ? toStandardSchema(params.resumeSchema) : undefined,\n suspendSchema: params.suspendSchema ? toStandardSchema(params.suspendSchema) : undefined,\n scorers: params.scorers,\n retries: params.retries,\n metadata: params.metadata,\n execute: params.execute.bind(params) as Step<\n TStepId,\n TStateSchema extends PublicSchema<any> ? InferPublicSchema<TStateSchema> : unknown,\n InferPublicSchema<TInputSchema>,\n InferPublicSchema<TOutputSchema>,\n TResumeSchema extends PublicSchema<any> ? InferPublicSchema<TResumeSchema> : unknown,\n TSuspendSchema extends PublicSchema<any> ? InferPublicSchema<TSuspendSchema> : unknown,\n InngestEngineType\n >['execute'],\n };\n}\n\nfunction createStepFromAgent<TStepId extends string, TStepOutput>(\n params: InngestSubAgent<TStepId> | Agent<TStepId, any>,\n agentOrToolOptions?: Record<string, unknown>,\n): Step<TStepId, any, any, TStepOutput, unknown, unknown, InngestEngineType> {\n // Delegates to core's factory: the run logic lives in the shared entry\n // executors (`runAgentEntry`), which is also what the inherited\n // `DefaultExecutionEngine.executeAgent` runs for declarative graph entries.\n // The engine generic is phantom (executors never read `ctx.engine`), so the\n // cast only re-brands the step for Inngest consumers.\n return coreCreateStepFromAgent(params as any, agentOrToolOptions as any) as unknown as Step<\n TStepId,\n any,\n any,\n TStepOutput,\n unknown,\n unknown,\n InngestEngineType\n >;\n}\n\nfunction createStepFromTool<TStepInput, TSuspend, TResume, TStepOutput>(\n params: ToolStep<TStepInput, TSuspend, TResume, TStepOutput, any>,\n agentOrToolOptions?: Record<string, unknown>,\n): Step<string, any, TStepInput, TStepOutput, TResume, TSuspend, InngestEngineType> {\n // Delegates to core's factory (shared `runToolEntry` executor); see\n // `createStepFromAgent` above for why the engine re-brand cast is safe.\n return coreCreateStepFromTool(params as any, agentOrToolOptions as any) as unknown as Step<\n string,\n any,\n TStepInput,\n TStepOutput,\n TResume,\n TSuspend,\n InngestEngineType\n >;\n}\n\nfunction createStepFromProcessor<TProcessorId extends string>(\n processor: Processor<TProcessorId>,\n): Step<`processor:${TProcessorId}`, unknown, any, any, unknown, unknown, InngestEngineType> {\n // Helper to map phase to entity type\n const getProcessorEntityType = (phase: string): EntityType => {\n switch (phase) {\n case 'input':\n return EntityType.INPUT_PROCESSOR;\n case 'inputStep':\n return EntityType.INPUT_STEP_PROCESSOR;\n case 'outputStream':\n case 'outputResult':\n return EntityType.OUTPUT_PROCESSOR;\n case 'outputStep':\n return EntityType.OUTPUT_STEP_PROCESSOR;\n default:\n return EntityType.OUTPUT_PROCESSOR;\n }\n };\n\n // Helper to get span name prefix\n const getSpanNamePrefix = (phase: string): string => {\n switch (phase) {\n case 'input':\n return 'input processor';\n case 'inputStep':\n return 'input step processor';\n case 'outputStream':\n return 'output stream processor';\n case 'outputResult':\n return 'output processor';\n case 'outputStep':\n return 'output step processor';\n default:\n return 'processor';\n }\n };\n\n // Helper to check if processor implements a phase\n const hasPhaseMethod = (phase: string): boolean => {\n switch (phase) {\n case 'input':\n return !!processor.processInput;\n case 'inputStep':\n return !!processor.processInputStep;\n case 'outputStream':\n return !!processor.processOutputStream;\n case 'outputResult':\n return !!processor.processOutputResult;\n case 'outputStep':\n return !!processor.processOutputStep;\n default:\n return false;\n }\n };\n\n return {\n id: `processor:${processor.id}`,\n description: processor.name ?? `Processor ${processor.id}`,\n inputSchema: ProcessorStepSchema,\n outputSchema: ProcessorStepOutputSchema,\n execute: async ({ inputData, requestContext, tracingContext }) => {\n // Cast to output type for easier property access - the discriminated union\n // ensures type safety at the schema level, but inside the execute function\n // we need access to all possible properties\n const input = inputData as ProcessorStepOutput & { processorStates?: Map<string, ProcessorState> };\n const {\n phase,\n messages,\n messageList,\n stepNumber,\n systemMessages,\n part,\n streamParts,\n processorStates,\n result,\n finishReason,\n toolCalls,\n text,\n retryCount,\n // inputStep phase fields for model/tools configuration\n model,\n tools,\n toolChoice,\n activeTools,\n providerOptions,\n modelSettings,\n structuredOutput,\n steps,\n usage,\n } = input;\n\n // Create a minimal abort function that throws TripWire\n const abort = (reason?: string, options?: { retry?: boolean; metadata?: unknown }): never => {\n throw new TripWire(reason || `Tripwire triggered by ${processor.id}`, options, processor.id);\n };\n\n // Early return if processor doesn't implement this phase - no span created\n // This prevents empty spans for phases the processor doesn't handle\n if (!hasPhaseMethod(phase)) {\n return input;\n }\n\n // Create processor span for non-stream phases\n // outputStream phase doesn't need its own span (stream chunks are already tracked)\n const currentSpan = tracingContext?.currentSpan;\n\n // Find appropriate parent span:\n // - For input/outputResult: find AGENT_RUN (processor runs once at start/end)\n // - For inputStep/outputStep: find MODEL_STEP (processor runs per LLM call)\n // When workflow is executed, currentSpan is WORKFLOW_STEP, so we walk up the parent chain\n const parentSpan =\n phase === 'inputStep' || phase === 'outputStep'\n ? currentSpan?.findParent(SpanType.MODEL_STEP) || currentSpan\n : currentSpan?.findParent(SpanType.AGENT_RUN) || currentSpan;\n\n const processorSpan =\n phase !== 'outputStream'\n ? parentSpan?.createChildSpan({\n type: SpanType.PROCESSOR_RUN,\n name: `${getSpanNamePrefix(phase)}: ${processor.id}`,\n entityType: getProcessorEntityType(phase),\n entityId: processor.id,\n entityName: processor.name ?? processor.id,\n input: { phase, messageCount: messages?.length },\n attributes: {\n processorExecutor: 'workflow',\n // Read processorIndex from processor (set in combineProcessorsIntoWorkflow)\n processorIndex: processor.processorIndex,\n },\n })\n : undefined;\n\n // Create tracing context with processor span so internal agent calls nest correctly\n const processorTracingContext: TracingContext | undefined = processorSpan\n ? { currentSpan: processorSpan }\n : tracingContext;\n\n // Resolve this processor's persistent state from the shared processorStates map.\n // Each processor's state lives in the map keyed by processor id, so mutations\n // persist across phases and across chained processor steps.\n let processorState: Record<string, unknown> = {};\n if (processorStates) {\n let ps = processorStates.get(processor.id);\n if (!ps) {\n ps = new ProcessorState(processor.id);\n processorStates.set(processor.id, ps);\n }\n processorState = ps.customState;\n }\n\n // Base context for all processor methods - includes requestContext for memory processors\n // and tracingContext for proper span nesting when processors call internal agents\n const baseContext = {\n abort,\n retryCount: retryCount ?? 0,\n requestContext,\n tracingContext: processorTracingContext,\n };\n\n // Pass-through data that should flow to the next processor in a chain\n // This enables processor workflows to use .then(), .parallel(), .branch(), etc.\n const passThrough = {\n phase,\n // Auto-create MessageList from messages if not provided\n // This enables running processor workflows from the UI where messageList can't be serialized\n messageList:\n messageList ??\n (Array.isArray(messages)\n ? new MessageList()\n .add(messages as MastraDBMessage[], 'input')\n .addSystem((systemMessages ?? []) as CoreMessage[])\n : undefined),\n stepNumber,\n systemMessages,\n streamParts,\n state: processorState,\n processorStates,\n result,\n finishReason,\n toolCalls,\n text,\n retryCount,\n // inputStep phase fields for model/tools configuration\n model,\n tools,\n toolChoice,\n activeTools,\n providerOptions,\n modelSettings,\n structuredOutput,\n steps,\n usage,\n };\n\n // Helper to execute phase with proper span lifecycle management\n const executePhaseWithSpan = async <T>(fn: () => Promise<T>): Promise<T> => {\n try {\n const result = await fn();\n processorSpan?.end({ output: result });\n return result;\n } catch (error) {\n // TripWire errors should end span but bubble up to halt the workflow\n if (error instanceof TripWire) {\n processorSpan?.end({ output: { tripwire: error.message } });\n } else {\n processorSpan?.error({ error: error as Error, endSpan: true });\n }\n throw error;\n }\n };\n\n // Execute the phase with span lifecycle management\n return executePhaseWithSpan(async () => {\n switch (phase) {\n case 'input': {\n if (processor.processInput) {\n if (!passThrough.messageList) {\n throw new MastraError({\n category: ErrorCategory.USER,\n domain: ErrorDomain.MASTRA_WORKFLOW,\n id: 'PROCESSOR_MISSING_MESSAGE_LIST',\n text: `Processor ${processor.id} requires messageList or messages for processInput phase`,\n });\n }\n\n // Create source checker before processing to preserve message sources\n const idsBeforeProcessing = (messages as MastraDBMessage[]).map(m => m.id);\n const check = passThrough.messageList.makeMessageSourceChecker();\n\n const result = await processor.processInput({\n ...baseContext,\n messages: messages as MastraDBMessage[],\n messageList: passThrough.messageList,\n systemMessages: (systemMessages ?? []) as CoreMessage[],\n state: processorState,\n });\n\n if (result instanceof MessageList) {\n // Validate same instance\n if (result !== passThrough.messageList) {\n throw new MastraError({\n category: ErrorCategory.USER,\n domain: ErrorDomain.MASTRA_WORKFLOW,\n id: 'PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST',\n text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`,\n });\n }\n return {\n ...passThrough,\n messages: result.get.all.db(),\n systemMessages: result.getSystemMessages(),\n };\n } else if (Array.isArray(result)) {\n // Processor returned an array of messages\n ProcessorRunner.applyMessagesToMessageList(\n result as MastraDBMessage[],\n passThrough.messageList,\n idsBeforeProcessing,\n check,\n 'input',\n );\n return { ...passThrough, messages: result };\n } else if (result && 'messages' in result && 'systemMessages' in result) {\n // Processor returned { messages, systemMessages }\n const typedResult = result as { messages: MastraDBMessage[]; systemMessages: CoreMessage[] };\n ProcessorRunner.applyMessagesToMessageList(\n typedResult.messages,\n passThrough.messageList,\n idsBeforeProcessing,\n check,\n 'input',\n );\n passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);\n return {\n ...passThrough,\n messages: typedResult.messages,\n systemMessages: passThrough.messageList.getSystemMessages(),\n };\n }\n return { ...passThrough, messages };\n }\n return { ...passThrough, messages };\n }\n\n case 'inputStep': {\n if (processor.processInputStep) {\n if (!passThrough.messageList) {\n throw new MastraError({\n category: ErrorCategory.USER,\n domain: ErrorDomain.MASTRA_WORKFLOW,\n id: 'PROCESSOR_MISSING_MESSAGE_LIST',\n text: `Processor ${processor.id} requires messageList or messages for processInputStep phase`,\n });\n }\n\n // Create source checker before processing to preserve message sources\n const idsBeforeProcessing = (messages as MastraDBMessage[]).map(m => m.id);\n const check = passThrough.messageList.makeMessageSourceChecker();\n\n const result = await processor.processInputStep({\n ...baseContext,\n messages: messages as MastraDBMessage[],\n messageList: passThrough.messageList,\n stepNumber: stepNumber ?? 0,\n systemMessages: (systemMessages ?? []) as CoreMessage[],\n // Pass model/tools configuration fields - types match ProcessInputStepArgs\n model: model!,\n tools,\n toolChoice,\n activeTools,\n providerOptions,\n modelSettings,\n structuredOutput,\n steps: steps ?? [],\n state: processorState,\n });\n\n const validatedResult = await ProcessorRunner.validateAndFormatProcessInputStepResult(result, {\n messageList: passThrough.messageList,\n processor,\n stepNumber: stepNumber ?? 0,\n });\n\n if (validatedResult.messages) {\n ProcessorRunner.applyMessagesToMessageList(\n validatedResult.messages,\n passThrough.messageList,\n idsBeforeProcessing,\n check,\n );\n }\n\n if (validatedResult.systemMessages) {\n passThrough.messageList!.replaceAllSystemMessages(validatedResult.systemMessages as CoreMessage[]);\n }\n\n // Preserve messages in return - passThrough doesn't include messages,\n // so we must explicitly include it to avoid losing it for subsequent steps\n return {\n ...passThrough,\n messages,\n ...validatedResult,\n systemMessages: passThrough.messageList!.getSystemMessages(),\n };\n }\n return { ...passThrough, messages };\n }\n\n case 'outputStream': {\n if (processor.processOutputStream) {\n // Manage per-processor span lifecycle across stream chunks\n // Use unique key to store span on shared state object\n const spanKey = `__outputStreamSpan_${processor.id}`;\n const mutableState = processorState;\n let processorSpan = mutableState[spanKey] as\n | ReturnType<NonNullable<typeof parentSpan>['createChildSpan']>\n | undefined;\n\n if (!processorSpan && parentSpan) {\n // First chunk - create span for this processor\n processorSpan = parentSpan.createChildSpan({\n type: SpanType.PROCESSOR_RUN,\n name: `output stream processor: ${processor.id}`,\n entityType: EntityType.OUTPUT_PROCESSOR,\n entityId: processor.id,\n entityName: processor.name ?? processor.id,\n input: { phase, streamParts: [] },\n attributes: {\n processorExecutor: 'workflow',\n processorIndex: processor.processorIndex,\n },\n });\n mutableState[spanKey] = processorSpan;\n }\n\n // Update span with current chunk data\n if (processorSpan) {\n processorSpan.input = {\n phase,\n streamParts: streamParts ?? [],\n totalChunks: (streamParts ?? []).length,\n };\n }\n\n // Create tracing context with processor span for internal agent calls\n const processorTracingContext = processorSpan\n ? { currentSpan: processorSpan }\n : baseContext.tracingContext;\n\n // Handle outputStream span lifecycle explicitly (not via executePhaseWithSpan)\n // because outputStream uses a per-processor span stored in mutableState\n let result: ChunkType | null | undefined;\n try {\n result = await processor.processOutputStream({\n ...baseContext,\n tracingContext: processorTracingContext,\n part: part as ChunkType,\n streamParts: (streamParts ?? []) as ChunkType[],\n state: mutableState,\n messageList: passThrough.messageList, // Optional for stream processing\n });\n\n // End span on finish chunk\n if (part && (part as ChunkType).type === 'finish') {\n processorSpan?.end({ output: result });\n delete mutableState[spanKey];\n }\n } catch (error) {\n // End span with error and clean up state\n if (error instanceof TripWire) {\n processorSpan?.end({ output: { tripwire: error.message } });\n } else {\n processorSpan?.error({ error: error as Error, endSpan: true });\n }\n delete mutableState[spanKey];\n throw error;\n }\n\n return { ...passThrough, state: mutableState, part: result };\n }\n return { ...passThrough, part };\n }\n\n case 'outputResult': {\n if (processor.processOutputResult) {\n if (!passThrough.messageList) {\n throw new MastraError({\n category: ErrorCategory.USER,\n domain: ErrorDomain.MASTRA_WORKFLOW,\n id: 'PROCESSOR_MISSING_MESSAGE_LIST',\n text: `Processor ${processor.id} requires messageList or messages for processOutputResult phase`,\n });\n }\n\n // Create source checker before processing to preserve message sources\n const idsBeforeProcessing = (messages as MastraDBMessage[]).map(m => m.id);\n const check = passThrough.messageList.makeMessageSourceChecker();\n\n const outputResult = (passThrough.result as OutputResult | undefined) ?? {\n text: '',\n usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n finishReason: 'unknown',\n steps: [],\n };\n\n const processResult = await processor.processOutputResult({\n ...baseContext,\n messages: messages as MastraDBMessage[],\n messageList: passThrough.messageList,\n state: processorState,\n result: outputResult,\n });\n\n if (processResult instanceof MessageList) {\n // Validate same instance\n if (processResult !== passThrough.messageList) {\n throw new MastraError({\n category: ErrorCategory.USER,\n domain: ErrorDomain.MASTRA_WORKFLOW,\n id: 'PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST',\n text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`,\n });\n }\n return {\n ...passThrough,\n messages: processResult.get.all.db(),\n systemMessages: processResult.getSystemMessages(),\n };\n } else if (Array.isArray(processResult)) {\n // Processor returned an array of messages\n ProcessorRunner.applyMessagesToMessageList(\n processResult as MastraDBMessage[],\n passThrough.messageList,\n idsBeforeProcessing,\n check,\n 'response',\n );\n return { ...passThrough, messages: processResult };\n } else if (processResult && 'messages' in processResult && 'systemMessages' in processResult) {\n // Processor returned { messages, systemMessages }\n const typedResult = processResult as { messages: MastraDBMessage[]; systemMessages: CoreMessage[] };\n ProcessorRunner.applyMessagesToMessageList(\n typedResult.messages,\n passThrough.messageList,\n idsBeforeProcessing,\n check,\n 'response',\n );\n passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);\n return {\n ...passThrough,\n messages: typedResult.messages,\n systemMessages: passThrough.messageList.getSystemMessages(),\n };\n }\n return { ...passThrough, messages };\n }\n return { ...passThrough, messages };\n }\n\n case 'outputStep': {\n if (processor.processOutputStep) {\n if (!passThrough.messageList) {\n throw new MastraError({\n category: ErrorCategory.USER,\n domain: ErrorDomain.MASTRA_WORKFLOW,\n id: 'PROCESSOR_MISSING_MESSAGE_LIST',\n text: `Processor ${processor.id} requires messageList or messages for processOutputStep phase`,\n });\n }\n\n // Create source checker before processing to preserve message sources\n const idsBeforeProcessing = (messages as MastraDBMessage[]).map(m => m.id);\n const check = passThrough.messageList.makeMessageSourceChecker();\n\n const defaultUsage: LanguageModelUsage = {\n inputTokens: undefined,\n outputTokens: undefined,\n totalTokens: undefined,\n };\n const result = await processor.processOutputStep({\n ...baseContext,\n messages: messages as MastraDBMessage[],\n messageList: passThrough.messageList,\n stepNumber: stepNumber ?? 0,\n finishReason,\n toolCalls: toolCalls as any,\n text,\n usage: (usage as LanguageModelUsage) ?? defaultUsage,\n systemMessages: (systemMessages ?? []) as CoreMessage[],\n steps: steps ?? [],\n state: processorState,\n });\n\n if (result instanceof MessageList) {\n // Validate same instance\n if (result !== passThrough.messageList) {\n throw new MastraError({\n category: ErrorCategory.USER,\n domain: ErrorDomain.MASTRA_WORKFLOW,\n id: 'PROCESSOR_RETURNED_EXTERNAL_MESSAGE_LIST',\n text: `Processor ${processor.id} returned a MessageList instance other than the one passed in. Use the messageList argument instead.`,\n });\n }\n return {\n ...passThrough,\n messages: result.get.all.db(),\n systemMessages: result.getSystemMessages(),\n };\n } else if (Array.isArray(result)) {\n // Processor returned an array of messages\n ProcessorRunner.applyMessagesToMessageList(\n result as MastraDBMessage[],\n passThrough.messageList,\n idsBeforeProcessing,\n check,\n 'response',\n );\n return { ...passThrough, messages: result };\n } else if (result && 'messages' in result && 'systemMessages' in result) {\n // Processor returned { messages, systemMessages }\n const typedResult = result as { messages: MastraDBMessage[]; systemMessages: CoreMessage[] };\n ProcessorRunner.applyMessagesToMessageList(\n typedResult.messages,\n passThrough.messageList,\n idsBeforeProcessing,\n check,\n 'response',\n );\n passThrough.messageList.replaceAllSystemMessages(typedResult.systemMessages);\n return {\n ...passThrough,\n messages: typedResult.messages,\n systemMessages: passThrough.messageList.getSystemMessages(),\n };\n }\n return { ...passThrough, messages };\n }\n return { ...passThrough, messages };\n }\n\n default:\n return { ...passThrough, messages };\n }\n });\n },\n component: 'PROCESSOR',\n };\n}\n\nexport function init<TRequestContext = unknown>(inngest: Inngest) {\n return {\n createTool,\n createWorkflow<\n TWorkflowId extends string = string,\n TState = any,\n TInput = any,\n TOutput = any,\n TSteps extends Step<string, any, any, any, any, any, InngestEngineType>[] = Step<\n string,\n any,\n any,\n any,\n any,\n any,\n InngestEngineType\n >[],\n >(params: InngestWorkflowConfig<TWorkflowId, TState, TInput, TOutput, TSteps, TRequestContext>) {\n return new InngestWorkflow<\n InngestEngineType,\n TSteps,\n TWorkflowId,\n TState,\n TInput,\n TOutput,\n TInput,\n TRequestContext\n >(params, inngest);\n },\n createStep,\n cloneStep<TStepId extends string>(\n step: Step<TStepId, any, any, any, any, any, InngestEngineType>,\n opts: { id: TStepId },\n ): Step<TStepId, any, any, any, any, any, InngestEngineType> {\n return {\n id: opts.id,\n description: step.description,\n inputSchema: step.inputSchema,\n outputSchema: step.outputSchema,\n resumeSchema: step.resumeSchema,\n suspendSchema: step.suspendSchema,\n stateSchema: step.stateSchema,\n metadata: step.metadata,\n execute: step.execute,\n retries: step.retries,\n scorers: step.scorers,\n component: step.component,\n };\n },\n cloneWorkflow<\n TWorkflowId extends string = string,\n TState = unknown,\n TInput = unknown,\n TOutput = unknown,\n TSteps extends Step<string, any, any, any, any, any, InngestEngineType>[] = Step<\n string,\n any,\n any,\n any,\n any,\n any,\n InngestEngineType\n >[],\n TPrev = TInput,\n >(\n workflow: Workflow<InngestEngineType, TSteps, string, TState, TInput, TOutput, TPrev>,\n opts: { id: TWorkflowId },\n ): Workflow<InngestEngineType, TSteps, TWorkflowId, TState, TInput, TOutput, TPrev> {\n const wf: Workflow<InngestEngineType, TSteps, TWorkflowId, TState, TInput, TOutput, TPrev> = new Workflow({\n id: opts.id,\n inputSchema: workflow.inputSchema,\n outputSchema: workflow.outputSchema,\n steps: workflow.stepDefs,\n mastra: workflow.mastra,\n options: workflow.options,\n });\n\n wf.setStepFlow(workflow.stepGraph);\n wf.commit();\n return wf;\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAEA,MAAa,8BAA8B;CACzC,SAAS;CACT,SAAS;AACX;;;;;;;AAuBA,SAAgB,gCACd,OAA6C,4BAA4B,SAC/C;CAC1B,OAAO,SAAS,4BAA4B,UACxC,4BAA4B,UAC5B,4BAA4B;AAClC;;;;;;;;;;AAWA,SAAgB,4BAA4B,QAAiD;CAC3F,QAAQ,OAAO,QAAf;EACE,KAAK,WACH,OAAO;GAAE,QAAQ,OAAO;GAAQ,QAAQ,OAAO;GAAQ,OAAO,OAAO;EAAM;EAC7E,KAAK,UACH,OAAO;GAAE,QAAQ,OAAO;GAAQ,OAAO,OAAO;GAAO,OAAO,OAAO;EAAM;EAC3E,KAAK,YACH,OAAO;GAAE,QAAQ,OAAO;GAAQ,UAAU,OAAO;GAAU,OAAO,OAAO;EAAM;EACjF,KAAK,aAGH,OAAO;GAAE,QAAQ,OAAO;GAAQ,OAAO,OAAO;GAAO,OAAO,OAAO;GAAO,cAAc,OAAO;EAAa;EAC9G,KAAK,UACH,OAAO;GAAE,QAAQ,OAAO;GAAQ,OAAO,OAAO;EAAM;CACxD;AACF;;;ACpCA,SAAS,0BAA0B,OAAyB;CAC1D,IAAI,iBAAiB,2BAA2B,iBAAiB,mBAC/D,OAAO;CAGT,IAAI,iBAAiB,SAAS,MAAM,UAAU,KAAA,KAAa,0BAA0B,MAAM,KAAK,GAC9F,OAAO;CAGT,IAAI,SAAS,OAAO,UAAU,UAAU;EACtC,MAAM,SAAS;EAOf,IAAI,OAAO,cACT,OAAO;EAGT,IAAI,OAAO,SAAS,6BAA6B,OAAO,gBACtD,OAAO;EAGT,IAAI,OAAO,UAAU,KAAA,KAAa,0BAA0B,OAAO,KAAK,GACtE,OAAO;CAEX;CAEA,OAAO;AACT;AAEA,MAAM,oBAAoB,IAAI,kBAA0B;AAExD,MAAM,sBAAsB;CAAC;CAAW;CAAY;CAAgB;CAAa;CAAW;CAAU;AAAc;AAEpH,IAAa,yBAAb,cAA4C,uBAAuB;CASvD;CARV;CACA;CAEA,YACE,QACA,aACA,kBAA0B,GAC1B,SACA,cACA;EACA,MAAM;GAAE;GAAQ;EAAQ,CAAC;EAFjB,KAAA,eAAA;EAGR,KAAK,cAAc;EACnB,KAAK,kBAAkB;CACzB;CAEA,wBAAiC,SAAyB;EACxD,OAAO,kBAAkB,SAAS,KAAK;CACzC;;;;;CAUA,kBACE,OACA,YACiB;EACjB,MAAM,cAAe,YAAgD;EAMrE,OAJsB,oBADF,SAAS,aAC0B;GACrD,gBAAgB;GAChB,iBAAiB;EACnB,CACmB,CAAC,CAAC,OAAO;CAC9B;;;;CAKA,qBAAqB,MAAoC;EACvD,OAAO,gBAAgB;CACzB;;;;;;CAOA,sCAA+C;EAC7C,OAAO;CACT;;;;;;CAOA,MAAM,qBACJ,QACA,SACA,QAUA;EACA,KAAK,IAAI,IAAI,GAAG,IAAI,OAAO,UAAU,GAAG,KAAK;GAC3C,IAAI,IAAI,KAAK,OAAO,OAClB,MAAM,IAAI,SAAQ,YAAW,WAAW,SAAS,OAAO,KAAK,CAAC;GAEhE,IAAI;IAGF,OAAO;KAAE,IAAI;KAAM,QAAA,MADE,kBAAkB,IAAI,SAAS,KAAK,qBAAqB,QAAQ,OAAO,CAAC;IACpE;GAC5B,SAAS,GAAG;IACV,MAAM,iBAAiB,0BAA0B,CAAC;IAElD,IAAI,kBAAkB,MAAM,OAAO,SAAS;KAE1C,MAAM,QAAS,GAAW;KAC1B,IAAI,OAAO,WAAW,UAAU;MAC9B,OAAO,UAAU,MAAM;OACrB,OAAO;OACP,YAAY,EAAE,QAAQ,SAAS;MACjC,CAAC;MAED,IAAI,MAAM,SAAS,EAAE,MAAM,iBAAiB,QAC1C,MAAM,QAAQ,oBAAoB,MAAM,OAAO,EAAE,gBAAgB,MAAM,CAAC;MAE1E,OAAO;OACL,IAAI;OACJ,OAAO;QACL,GAAG;QACH,GAAI,kBAAkB,EAAE,cAAc,KAAc;OACtD;MACF;KACF;KAGA,MAAM,gBAAgB,oBAAoB,GAAG;MAC3C,gBAAgB;MAChB,iBAAiB;KACnB,CAAC;KACD,OAAO,UAAU,MAAM;MACrB,OAAO;MACP,YAAY,EAAE,QAAQ,SAAS;KACjC,CAAC;KACD,OAAO;MACL,IAAI;MACJ,OAAO;OACL,QAAQ;OACR,OAAO;OACP,SAAS,KAAK,IAAI;OAClB,GAAI,kBAAkB,EAAE,cAAc,KAAc;MACtD;KACF;IACF;GACF;EACF;EAEA,OAAO;GAAE,IAAI;GAAO,OAAO;IAAE,QAAQ;IAAU,uBAAO,IAAI,MAAM,eAAe;IAAG,SAAS,KAAK,IAAI;GAAE;EAAE;CAC1G;;;;CAKA,MAAM,qBAAqB,UAAkB,SAAiB,YAAmC;EAC/F,MAAM,KAAK,YAAY,MAAM,YAAY,WAAW,SAAS,WAAW,WAAW,IAAI,IAAI,QAAQ;CACrG;;;;CAKA,MAAM,sBAAsB,MAAY,cAAsB,YAAmC;EAC/F,MAAM,KAAK,YAAY,WAAW,YAAY,WAAW,cAAc,gBAAgB,IAAI;CAC7F;;;;;;;;;;;;;CAcA,MAAM,qBAAwB,aAAqB,aAA2C;EAkC5F,OAAO,MAjCc,KAAK,YAAY,IAAI,aAAa,YAAY;GACjE,IAAI;IAEF,OAAO,MADgB,YAAY;GAErC,SAAS,GAAG;IACV,MAAM,gBAAgB,oBAAoB,GAAG;KAC3C,gBAAgB;KAChB,iBAAiB;IACnB,CAAC;IACD,MAAM,iBAAiB,0BAA0B,CAAC;IAClD,MAAM,UAAU,IAAI,MAAM,cAAc,SAAS,EAC/C,OAAO;KACL,QAAQ;KACR,OAAO;KACP,SAAS,KAAK,IAAI;KAClB,GAAI,kBAAkB,EAAE,cAAc,KAAc;IACtD,EACF,CAAC;IAED,IAAI,cAAc,OAChB,QAAQ,QAAQ,cAAc;IAGhC,MAAM,mBACJ,aAAa,QACT,oBAAoB,MAAK,cAAa,OAAO,eAAe,CAAC,MAAM,UAAU,SAAS,IACtF,KAAA;IACN,IAAI,kBACF,OAAO,eAAe,SAAS,iBAAiB,SAAS;IAE3D,MAAM;GACR;EACF,CAAC;CAEH;;;;CAKA,mBAAwC;EACtC,OAAO,EAAE,MAAM,KAAK,YAAY;CAClC;;;;;CAMA,MAAa,yBAAyB,SAYpB,CAElB;;;;CAKA,MAAa,iCAAiC,QAY5B;EAChB,OAAO,MAAM,yBAAyB,MAAM;CAC9C;;;;;CAUA,MAAM,eAAe,QAcJ;EACf,MAAM,EAAE,kBAAkB,aAAa,SAAS,eAAe;EAI/D,MAAM,eAAe,YAAY,MAAM,iBAAiB,YAAY;EAGpE,IAAI,CAAC,KAAK,QAAQ,eAAe,oBAAoB,CAAC,CAAC,GAAG,OAAO,KAAA;EAGjE,MAAM,eAAe,MAAM,KAAK,qBAAqB,aAAa,YAAY;GAC5E,MAAM,gBAAgB,KAAK,QAAQ,eAAe,oBAAoB,CAAC,CAAC;GACxE,IAAI,CAAC,eAAe,OAAO,KAAA;GAW3B,OARa,cAAc,UAAU;IACnC,GAAG;IACH,YAAY,QAAQ;IACpB,SAAS,iBAAiB,YAAY;IACtC;GACF,CAGU,CAAC,EAAE,WAAW;EAC1B,CAAC;EAGD,IAAI,cAEF,QADsB,KAAK,QAAQ,eAAe,oBAAoB,CAAC,CAAC,EAAA,EAClD,YAAY,YAAY;CAIlD;;;;CAKA,MAAM,YAAY,QAOA;EAChB,MAAM,EAAE,MAAM,aAAa,eAAe;EAC1C,IAAI,CAAC,MAAM;EAEX,MAAM,KAAK,qBAAqB,aAAa,YAAY;GACvD,KAAK,IAAI,UAAU;EACrB,CAAC;CACH;;;;CAKA,MAAM,cAAc,QAOF;EAChB,MAAM,EAAE,MAAM,aAAa,iBAAiB;EAC5C,IAAI,CAAC,MAAM;EAEX,MAAM,KAAK,qBAAqB,aAAa,YAAY;GACvD,KAAK,MAAM,YAAY;EACzB,CAAC;CACH;;;;;CAMA,MAAM,gBAAgB,QAUL;EACf,MAAM,EAAE,kBAAkB,aAAa,SAAS,eAAe;EAG/D,MAAM,eAAe,YAAY,MAAM,iBAAiB,YAAY;EAGpE,IAAI,CAAC,KAAK,QAAQ,eAAe,oBAAoB,CAAC,CAAC,GAAG,OAAO,KAAA;EAGjE,MAAM,eAAe,MAAM,KAAK,qBAAqB,aAAa,YAAY;GAC5E,MAAM,gBAAgB,KAAK,QAAQ,eAAe,oBAAoB,CAAC,CAAC;GACxE,IAAI,CAAC,eAAe,OAAO,KAAA;GAW3B,OARa,cAAc,UAAU;IACnC,GAAG;IACH,SAAS,iBAAiB,YAAY;IACtC;IACA,eAAe,KAAK,SAAS;GAC/B,CAGU,CAAC,EAAE,WAAW;EAC1B,CAAC;EAGD,IAAI,cAEF,QADsB,KAAK,QAAQ,eAAe,oBAAoB,CAAC,CAAC,EAAA,EAClD,YAAY,YAAY;CAIlD;;;;CAKA,MAAM,aAAa,QAOD;EAChB,MAAM,EAAE,MAAM,aAAa,eAAe;EAC1C,IAAI,CAAC,MAAM;EAEX,MAAM,KAAK,qBAAqB,aAAa,YAAY;GACvD,KAAK,IAAI,UAAU;EACrB,CAAC;CACH;;;;CAKA,MAAM,eAAe,QAOH;EAChB,MAAM,EAAE,MAAM,aAAa,iBAAiB;EAC5C,IAAI,CAAC,MAAM;EAEX,MAAM,KAAK,qBAAqB,aAAa,YAAY;GACvD,KAAK,MAAM,YAAY;EACzB,CAAC;CACH;;;;;;;;CASA,MAAM,oBAAoB,QAkByB;EAEjD,IAAI,EAAE,OAAO,gBAAgB,kBAC3B,OAAO;EAGT,MAAM,EACJ,MACA,aACA,kBACA,QACA,YACA,YACA,WACA,QACA,WACA,SACA,UACA,OACA,gBAAgB,yBACd;EACJ,MAAM,0BAA0B,uBAC5B,KAAK,wBAAwB,oBAAoB,IAChD,WAAW,yBAAyB,CAAC;EAG1C,MAAM,uBAAuB,iBAAiB,YAAY,UACtD;GACE,SAAS,iBAAiB,WAAW;GACrC,cAAc,UAAU;EAC1B,IACA,KAAA;EAEJ,MAAM,eAAe,KAAK,gBAAgB;GACxC,YAAY,iBAAiB;GAC7B,OAAO,iBAAiB;EAC1B;EACA,MAAM,WAAW,CAAC,CAAC,QAAQ,OAAO;EAGlC,IAAI;EACJ,IAAI;EAEJ,MAAM,eAAe,CAAC,EAAE,cAAc,WAAW,OAAO,SAAS,KAAK,WAAW,MAAM,OAAO,KAAK;EAUnG,MAAM,qBACJ,iBAAiB,iBAAiB,KAAA,IAC9B,GAAG,iBAAiB,MAAM,WAAW,iBAAiB,iBACtD,iBAAiB;EAEvB,IAAI;GACF,IAAI,UAAU;IACZ,QAAQ,YAAY,QAAQ,QAAQ,MAAM,GAAG,EAAE,gBAAgB,iBAAiB,SAAS;IAEzF,MAAM,WAAgB,OAAM,MADC,KAAK,QAAQ,WAAW,CAAC,EAAE,SAAS,WAAW,EAAA,EAChC,qBAAqB;KAC/D,cAAc,KAAK;KACZ;IACT,CAAC;IAED,MAAM,oBAAoB,OAAO,MAAM,MAAM,CAAC;IAC9C,IAAI,aAAa;IACjB,IAAI,kBAAkB,WAAW,GAAG;KAClC,MAAM,mBAAmB,OAAO,KAAK,UAAU,kBAAkB,CAAC,CAAC;KACnE,IAAI,iBAAiB,WAAW,GAK9B,aAAa;UACR,IAAI,iBAAiB,SAAS,GAAG;MACtC,MAAM,cAAc,iBAAiB,KAAI,WAAU,IAAI,OAAO,EAAE;MAChE,MAAM,IAAI,MACR,mCAAmC,YAAY,KAAK,IAAI,EAAE,kEAE5D;KACF,OACE,kBAAkB,KAAK,iBAAiB,EAAG;IAE/C;IACA,MAAM,qBAAqB,kBAAkB;IAE7C,MAAM,aAAc,MAAM,KAAK,YAAY,OAAO,YAAY,iBAAiB,WAAW,QAAQ,KAAK,MAAM;KAC3G,UAAU,KAAK,YAAY;KAC3B,MAAM;MACJ;MACA,gBAAgB;MAChB;MACO;MACP,GAAI,aACA,EAAE,cAAc,iBAAiB,SAAS,CAAC,EAAE,IAC7C,EACE,QAAQ;OACC;OACP,OAAO;OACP,eAAe,OAAO;OACtB,YAAY,qBACP,UAAU,iBAAiB,sBAC5B,KAAA;MACN,EACF;MACJ,eAAe;OAAE,cAAc;OAAM,qBAAqB;MAAK;MAC/D,0BAA0B,4BAA4B;MACtD;MACA,gBAAgB;MAChB;KACF;IACF,CAAC;IACD,SAAS,WAAW;IACpB,QAAQ,WAAW;IACnB,iBAAiB,QAAQ,WAAW,OAAO;GAC7C,OAAO,IAAI,cAAc;IAEvB,MAAM,WAAiB,OAAM,MADa,KAAK,QAAQ,WAAW,CAAC,EAAE,SAAS,WAAW,EAAA,EAC/B,qBAAqB;KAC7E,cAAc,KAAK;KACnB,OAAO,iBAAiB;IAC1B,CAAC,KAAM,EAAE,SAAS,CAAC,EAAE;IACrB,MAAM,mBAAmB,gCAAgC;KACvD,OAAO,WAAW,MAAM,MAAM,CAAC;KAC/B,WAAW,WAAW;KACtB,YAAY,WAAW;KACvB,SAAU,WAAW,oBAAoB,KAAK,OAAO,CAAC;KACtD,oBAAqB,WAAW,qBAAqB,CAAC;KACtD;KACA,OAAO,KAAK,oBAAoB;IAClC,CAAC;IACD,MAAM,aAAc,MAAM,KAAK,YAAY,OAAO,YAAY,iBAAiB,WAAW,QAAQ,KAAK,MAAM;KAC3G,UAAU,KAAK,YAAY;KAC3B,MAAM;MACJ,YAAY;MACZ,cAAc,iBAAiB,SAAS,CAAC;MACzC,gBAAgB;MAChB;MACA,OAAO,iBAAiB;MACxB,eAAe;OAAE,cAAc;OAAM,qBAAqB;MAAK;MAC/D,0BAA0B,4BAA4B;MACtD;MACA,gBAAgB;MAChB;KACF;IACF,CAAC;IACD,SAAS,WAAW;IACpB,QAAQ,WAAW;IACnB,iBAAiB,QAAQ,WAAW,OAAO;GAC7C,OAAO;IAOL,MAAM,cAAc;IACpB,MAAM,aAAc,MAAM,KAAK,YAAY,OAAO,YAAY,iBAAiB,WAAW,QAAQ,KAAK,MAAM;KAC3G,UAAU,KAAK,YAAY;KAC3B,MAAM;MACJ;MACA,cAAc,iBAAiB,SAAS,CAAC;MACzC,gBAAgB;MAChB;MACA,OAAO;MACP,eAAe;OAAE,cAAc;OAAM,qBAAqB;MAAK;MAC/D,0BAA0B,4BAA4B;MACtD;MACA,gBAAgB;MAChB;KACF;IACF,CAAC;IACD,SAAS,WAAW;IACpB,QAAQ,WAAW;IACnB,iBAAiB,QAAQ,WAAW,OAAO;GAC7C;EACF,SAAS,GAAG;GAGV,MAAM,aAAa,KAAK,OAAO,MAAM,YAAY,WAAW,IAAI,EAAE,QAAQ,KAAA;GAG1E,IAAI,cAAc,OAAO,eAAe,YAAY,YAAY,cAAc,WAAW,WAAW,UAAU;IAC5G,SAAS;IACT,QAAQ,WAAW,cAAc,OAAO,WAAW,UAAU,WAAW,WAAW,QAAQ,WAAW;GACxG,OAAO;IAIL,KAAK,QAAQ,MACX,wBAAwB,KAAK,GAAG,cAAc,aAAa,QAAS,EAAE,SAAS,EAAE,UAAW,OAAO,CAAC,EACtG;IAEA,QAAQ,WAAW;IACnB,SAAS;KACP,QAAQ;KACR,OAAO,aAAa,QAAQ,IAAI,IAAI,MAAM,OAAO,CAAC,CAAC;IACrD;GACF;EACF;EAEA,MAAM,MAAM,MAAM,KAAK,YAAY,IACjC,YAAY,iBAAiB,WAAW,QAAQ,KAAK,GAAG,oBACxD,YAAY;GACV,IAAI,OAAO,WAAW,UAAU;IAC9B,MAAM,OAAO,QAAQ,sBAAsB,iBAAiB,SAAS;KACnE,MAAM;KACN,OAAO,iBAAiB;KACxB,MAAM;MACJ,MAAM;MACN,SAAS;OACP,IAAI,KAAK;OACT,QAAQ;OACR,OAAO,QAAQ;OACf,SAAS;MACX;KACF;IACF,CAAC;IAED,OAAO;KAAE;KAAkB,QAAQ;MAAE,QAAQ;MAAU,OAAO,QAAQ;MAAO,SAAS,KAAK,IAAI;KAAE;IAAE;GACrG,OAAO,IAAI,OAAO,WAAW,aAAa;IACxC,MAAM,iBAAiB,OAAO,QAAQ,OAAO,KAAK,CAAC,CAAC,QAAQ,CAAC,WAAW,gBAAgB;KAEtF,OAAOA,YAAS,WAAW;IAC7B,CAAC;IAED,KAAK,MAAM,CAAC,UAAU,eAAe,gBAAgB;KACnD,MAAM,cAAwB,CAAC,UAAU,GAAI,YAAY,gBAAgB,iBAAiB,QAAQ,CAAC,CAAE;KACrG,iBAAiB,eAAe,KAAK,MAAM,iBAAiB;KAO5D,KAAK,MAAM,SAAS,OAAO,KAAM,QAAgB,gBAAgB,CAAC,CAAC,GACjE,iBAAiB,aAAa,SAAS,EAAE,QAAQ,KAAK,GAAG;KAQ3D,MAAM,aAAc,YAAoB,gBAAgB,mBAAmB,CAAC;KAC5E,MAAM,0BAA0B,MAAM,QAAQ,WAAW,aAAa,IAClE,WAAW,cAAc,KAAK,UAAe;MAC3C,IAAI,OAAO,WAAW,eAAe,CAAC,MAAM,gBAAgB,OAAO;MACnE,MAAM,EAAE,eAAe,cAAc,GAAG,mBAAmB,MAAM;MACjE,OAAO;OAAE,GAAG;OAAO;MAAe;KACpC,CAAC,IACD,KAAA;KAEJ,MAAM,OAAO,QAAQ,sBAAsB,iBAAiB,SAAS;MACnE,MAAM;MACN,OAAO,iBAAiB;MACxB,MAAM;OACJ,MAAM;OACN,SAAS;QACP,IAAI,KAAK;QACT,QAAQ;OACV;MACF;KACF,CAAC;KAED,OAAO;MACL;MACA,QAAQ;OACN,QAAQ;OACR,aAAa,KAAK,IAAI;OACtB,SAAS,WAAW;OACpB,gBAAgB;QACd,GAAI,YAAoB;QACxB,iBAAiB;SACf,GAAG;SACH,GAAI,0BAA0B,EAAE,eAAe,wBAAwB,IAAI,CAAC;SACrE;SACP,MAAM;QACR;OACF;MACF;KACF;IACF;IAEA,OAAO;KACL;KACA,QAAQ;MACN,QAAQ;MACR,aAAa,KAAK,IAAI;MACtB,SAAS,CAAC;KACZ;IACF;GACF,OAAO,IAAI,OAAO,WAAW,YAAY;IACvC,MAAM,OAAO,QAAQ,sBAAsB,iBAAiB,SAAS;KACnE,MAAM;KACN,OAAO,iBAAiB;KACxB,MAAM;MACJ,MAAM;MACN,SAAS;OACP,IAAI,KAAK;OACT,QAAQ;OACR,OAAO,QAAQ,UAAU;OACzB,SAAS;MACX;KACF;IACF,CAAC;IAED,OAAO;KACL;KACA,QAAQ;MACN,QAAQ;MACR,UAAU,QAAQ;MAClB,SAAS,KAAK,IAAI;KACpB;IACF;GACF,OAAO,IAAI,WAAW,OAAO,WAAW,UAAU;IAChD,MAAM,OAAO,QAAQ,sBAAsB,iBAAiB,SAAS;KACnE,MAAM;KACN,OAAO,iBAAiB;KACxB,MAAM;MACJ,MAAM;MACN,SAAS;OACP,IAAI,KAAK;OACT,QAAQ;MACV;KACF;IACF,CAAC;IAED,MAAM,OAAO,QAAQ,sBAAsB,iBAAiB,SAAS;KACnE,MAAM;KACN,OAAO,iBAAiB;KACxB,MAAM;MACJ,MAAM;MACN,SAAS;OACP,IAAI,KAAK;OACT,UAAU,CAAC;MACb;KACF;IACF,CAAC;IACD,OAAO;KAAE;KAAkB,QAAQ,EAAE,QAAQ,SAAS;IAAE;GAC1D;GAEA,MAAM,OAAO,QAAQ,sBAAsB,iBAAiB,SAAS;IACnE,MAAM;IACN,OAAO,iBAAiB;IACxB,MAAM;KACJ,MAAM;KACN,SAAS;MACP,IAAI,KAAK;MACT,QAAQ;MACR,QAAQ,QAAQ;KAClB;IACF;GACF,CAAC;GAED,MAAM,OAAO,QAAQ,sBAAsB,iBAAiB,SAAS;IACnE,MAAM;IACN,OAAO,iBAAiB;IACxB,MAAM;KACJ,MAAM;KACN,SAAS;MACP,IAAI,KAAK;MACT,UAAU,CAAC;KACb;IACF;GACF,CAAC;GAED,OAAO;IAAE;IAAkB,QAAQ;KAAE,QAAQ;KAAW,QAAQ,QAAQ;KAAQ,SAAS,KAAK,IAAI;IAAE;GAAE;EACxG,CACF;EAEA,OAAO,OAAO,kBAAkB,IAAI,gBAAgB;EACpD,OAAO;GACL,GAAG,IAAI;GACP;GACA,SAAS;GACT,WAAW,QAAQ,MAAM,OAAO,KAAK,KAAK,YAAY,KAAA;GACtD,eAAe,QAAQ,MAAM,OAAO,KAAK,KAAK,QAAQ,gBAAgB,KAAA;EACxE;CACF;AACF;;;;;;;;ACn3BA,SAAS,cAAc,SAAiB,OAAe;CACrD,OAAO;EAAE;EAAS;EAAO,QAAQ,CAAC;CAAS;AAC7C;;;;;;;;;;;AAYA,SAAS,WAAW,OAAmG;CAErH,MAAM,gBAAgB,MAAM,MAAM,8BAA8B;CAChE,IAAI,iBAAiB,cAAc,IACjC,OAAO;EAAE,OAAO,cAAc;EAAI,WAAW;CAAW;CAI1D,MAAM,mBAAmB,MAAM,MAAM,uBAAuB;CAC5D,IAAI,oBAAoB,iBAAiB,IACvC,OAAO;EAAE,OAAO,iBAAiB;EAAI,WAAW;CAAe;CAIjE,MAAM,oBAAoB,MAAM,MAAM,wBAAwB;CAC9D,IAAI,qBAAqB,kBAAkB,IACzC,OAAO;EAAE,OAAO,kBAAkB;EAAI,WAAW;CAAgB;CAGnE,OAAO;AACT;;;;;;;AAQA,MAAM,2CAA2B,IAAI,IAAY;AACjD,SAAS,sBAAsB,OAAqB;CAClD,MAAM,SAAS,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG;CACpD,IAAI,yBAAyB,IAAI,MAAM,GAAG;CAC1C,yBAAyB,IAAI,MAAM;CACnC,QAAQ,KAAK,sDAAsD,MAAM,EAAE;AAC7E;;;;;;;;;;;;;;;;;;AAmBA,IAAa,gBAAb,cAAmC,OAAO;CACxC;CACA;CACA,gCAMI,IAAI,IAAI;CAEZ,YAAY,SAAkB,YAAoB;EAChD,MAAM;EACN,KAAK,UAAU;EACf,KAAK,aAAa;CACpB;CAEA,MAAM,uBAAuB,YAAoB,OAAe,MAA8B;EAC5F,MAAM,KAAK,QAAQ,SAAS,QAAQ,cAAc,YAAY,WAAW,GAAG,SAAS,OAAO,GAAG,IAAI;CACrG;;;;;;;;;;;;;CAcA,MAAM,QAAQ,OAAe,OAAuD;EAClF,MAAM,SAAS,WAAW,KAAK;EAC/B,IAAI,CAAC,QAAQ;GACX,sBAAsB,KAAK;GAC3B;EACF;EAEA,MAAM,EAAE,OAAO,cAAc;EAK7B,MAAM,eAAe,cAAc,kBAAkB,cAAc;EACnE,MAAM,eAAe,eAAe,YAAY;EAChD,MAAM,UAAU,eAAe,SAAS,UAAU,YAAY,KAAK,WAAW,GAAG;EAEjF,IAAI;GAGF,MAAM,aAAa,eAAe,QAAQ,MAAM;GAChD,MAAM,KAAK,QAAQ,SAAS,QAAQ,cAAc,SAAS,YAAY,GAAG,UAAU;EACtF,SAAS,KAAU;GAMjB,IACE,cAAc,mBACb,cAAc,mBAAmB,MAAM,SAAS,YAAY,MAAM,SAAS,UAE5E,MAAM;GAGR,QAAQ,MAAM,gCAAgC,KAAK,WAAW,GAAG;EACnE;CACF;;;;;;;;;;;;;CAcA,MAAM,UAAU,OAAe,IAAsE;EACnG,MAAM,SAAS,WAAW,KAAK;EAC/B,IAAI,CAAC,QAAQ;GACX,sBAAsB,KAAK;GAC3B;EACF;EAEA,MAAM,EAAE,OAAO,cAAc;EAG7B,IAAI,KAAK,cAAc,IAAI,KAAK,GAAG;GACjC,KAAK,cAAc,IAAI,KAAK,CAAC,CAAE,UAAU,IAAI,EAAE;GAC/C;EACF;EAEA,MAAM,4BAAY,IAAI,IAAuD,CAAC,EAAE,CAAC;EAKjF,MAAM,eAAe,cAAc,kBAAkB,cAAc;EACnE,MAAM,eAAe,eAAe,YAAY;EAMhD,MAAM,eAAe,MAAM,UAAU;GACnC,SANc,eAAe,SAAS,UAAU,YAAY,KAAK,WAAW,GAAG;GAO/E,QAAQ,CAAC,YAAY;GACrB,KAAK,KAAK;GACV,YAAY,YAAiB;IAM3B,IAAI;IACJ,IAAI,gBAAgB,QAAQ,MAAM,QAAQ,QAAQ,MAAM,OAEtD,QAAQ;KACN,IAAI,OAAO,WAAW;KACtB,2BAAW,IAAI,KAAK;KACpB,GAAG,QAAQ;IACb;SAGA,QAAQ;KACN,IAAI,OAAO,WAAW;KACtB,MAAM;KACN;KACA,MAAM,QAAQ;KACd,2BAAW,IAAI,KAAK;IACtB;IAGF,KAAK,MAAM,YAAY,WACrB,SAAS,KAAK;GAElB;EACF,CAAC;EAED,KAAK,cAAc,IAAI,OAAO;GAC5B,mBAAmB;IACjB,IAAI;KACF,aAAkB,MAAM;IAC1B,SAAS,KAAK;KACZ,QAAQ,MAAM,oCAAoC,GAAG;IACvD;GACF;GACA;EACF,CAAC;CACH;;;;;CAMA,MAAM,YAAY,OAAe,IAAsE;EACrG,MAAM,MAAM,KAAK,cAAc,IAAI,KAAK;EACxC,IAAI,CAAC,KACH;EAGF,IAAI,UAAU,OAAO,EAAE;EAGvB,IAAI,IAAI,UAAU,SAAS,GAAG;GAC5B,IAAI,YAAY;GAChB,KAAK,cAAc,OAAO,KAAK;EACjC;CACF;;;;CAKA,MAAM,QAAuB,CAE7B;;;;CAKA,MAAM,QAAuB;EAC3B,KAAK,MAAM,GAAG,QAAQ,KAAK,eACzB,IAAI,YAAY;EAElB,KAAK,cAAc,MAAM;CAC3B;AACF;;;;;;;AChOA,SAAgB,wBAAwB,gBAA2D;CAIjG,MAAM,MAAM,iBAAiB,eAAe,OAAO,IAAI,CAAC;CAMxD,OAAO,IAAI;CACX,OAAO;AACT;;;;;AAMA,SAAgB,0BACd,wBACA,gBACqB;CACrB,OAAO;EAAE,GAAI,0BAA0B,CAAC;EAAI,GAAG,wBAAwB,cAAc;CAAE;AACzF;AAEA,SAAgB,6BACd,MAYqB;CACrB,MAAM,EAAE,gBAAgB,GAAG,SAAS;CACpC,OAAO;EACL,GAAG;EACH,gBAAgB,wBAAwB,cAAc;CACxD;AACF;AAEA,SAAgB,4BACd,MAiBqB;CACrB,MAAM,EAAE,gBAAgB,GAAG,SAAS;CACpC,OAAO;EACL,GAAG;EACH,gBAAgB,wBAAwB,cAAc;CACxD;AACF;AAEA,SAAgB,gCACd,MAUqB;CACrB,MAAM,EAAE,gBAAgB,GAAG,SAAS;CACpC,OAAO;EACL,GAAG;EACH,gBAAgB,wBAAwB,cAAc;CACxD;AACF;AAEA,SAAS,wBAAwB,gBAAiF;CAChH,IAAI,CAAC,gBAAgB,OAAO,CAAC;CAG7B,OAAO,OAAQ,eAAuC,WAAW,aAC7D,wBAAwB,cAAqC,IAC5D;AACP;;;AC9GA,IAAa,aAAb,cAeU,IAAmE;CAC3E;CACA;CACA;CAEA,YACE,QAiBA,SACA;EACA,MAAM,MAAM;EACZ,KAAK,UAAU;EACf,KAAK,sBAAsB,OAAO;EAClC,KAAKC,UAAU,OAAO;CACxB;;;;;CAMA,MAAM,aAAa,UAAkB,YAAY,KAAQ;EAEvD,MAAM,iBAAiB,OADP,KAAKA,SAAS,WAAW,EAAA,EACH,SAAS,WAAW;EAC1D,IAAI,CAAC,gBACH,MAAM,IAAI,kBAAkB,2DAA2D,KAAK,OAAO;EAErG,OAAO,IAAI,SAAc,SAAS,WAAW;GAC3C,IAAI,WAAW;GACf,IAAI,cAAmC;GACvC,IAAI,gBAAuC;GAE3C,MAAM,gBAAgB;IACpB,IAAI,aACF,IAAI;KACF,YAAY;IACd,QAAQ,CAER;IAEF,IAAI,eACF,aAAa,aAAa;GAE9B;GAEA,MAAM,gBAAgB,QAAa,YAAoB;IACrD,IAAI,CAAC,UAAU;KACb,WAAW;KACX,QAAQ;KACR,QAAQ,MAAM;IAChB;GACF;GAEA,MAAM,eAAe,OAAY,YAAoB;IACnD,IAAI,CAAC,UAAU;KACb,WAAW;KACX,QAAQ;KACR,OAAO,KAAK;IACd;GACF;GAGA,IAAI,8BAAuF;GAE3F,MAAM,4BAA4B,YAAY;IAC5C,IAAI;KACF,8BAA8B,UAAU;MACtC,SAAS,YAAY,KAAK,WAAW,GAAG,KAAK;MAC7C,QAAQ,CAAC,OAAO;MAChB,KAAK,KAAK;MACV,WAAW,OAAO,YAAiB;OACjC,IAAI,UAAU;OAEd,MAAM,QAAQ,QAAQ;OAEtB,IAAI,OAAO,SAAS,mBAAmB;QAErC,MAAM,WAAW,MAAM,gBAAgB,qBAAqB;SAC1D,cAAc,KAAK;SACnB,OAAO,KAAK;QACd,CAAC;QACD,IAAI,UAAU,SACZ,SAAS,UAAU,4BAA4B,SAAS,OAAO;QAGjE,MAAM,iBAA0C;SAC9C,OAAO,UAAU;SACjB,QAAQ,MAAM,SAAS,UAAU,UAAU;SAC3C,QAAQ,UAAU,QAAA,EAAqC;QACzD;QACA,MAAM,cAAc,MAAM,SAAS,UAAU,UAAU;QACvD,IAAI,gBAAgB,KAAA,GAAW,eAAe,SAAS;QACvD,MAAM,WAAW,MAAM,SAAS,SAAS,UAAU;QACnD,IAAI,UACF,eAAe,QAAQ,oBAAoB,UAAU,EAAE,gBAAgB,MAAM,CAAC;QAEhF,IAAI,UAAU,UAAU,KAAA,GAAW,eAAe,QAAQ,SAAS;QAGnE,aAAa,EAFI,QAAQ,EAAE,QAAQ,eAAe,EAEhC,GAAG,UAAU;OACjC;MACF;KACF,CAAC;KAGD,oBAAoB;MAClB,6BAA6B,MAAK,iBAAgB,aAAa,MAAM,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;KACxF;KAEA,MAAM;IACR,QAAQ,CAER;GACF;GAIA,MAAM,eAAe,YAAY;IAC/B,MAAM,YAAY,KAAK,IAAI;IAE3B,MAAM,OAAO,YAAY;KACvB,IAAI,UACF;KAEF,IAAI,KAAK,IAAI,IAAI,aAAa,WAAW;MACvC,YAAY,IAAI,kBAAkB,oCAAoC,UAAU,GAAG,GAAG,iBAAiB;MACvG;KACF;KAEA,IAAI;MACF,MAAM,WAAW,MAAM,eAAe,qBAAqB;OACzD,cAAc,KAAK;OACnB,OAAO,KAAK;MACd,CAAC;MAID,IACE,CAAC,YACD,SAAS,WAAW,aACpB,SAAS,WAAW,aACpB,SAAS,WAAW,WACpB;OACA,gBAAgB,WAAW,MAAM,MAAM,KAAK,OAAO,IAAI,GAAG;OAC1D;MACF;MAEA,IAAI,SAAS,SACX,SAAS,UAAU,4BAA4B,SAAS,OAAO;MAGjE,MAAM,gBAAyC;OAC7C,OAAO,SAAS;OAChB,QAAQ,SAAS;OACjB,OAAQ,SAAS,SAAqC;MACxD;MACA,IAAI,SAAS,WAAW,KAAA,GAAW,cAAc,SAAS,SAAS;MACnE,IAAI,SAAS,UAAU,KAAA,GACrB,cAAc,QAAQ,oBAAoB,SAAS,OAAO,EAAE,gBAAgB,MAAM,CAAC;MAErF,IAAI,SAAS,UAAU,KAAA,GAAW,cAAc,QAAQ,SAAS;MAEjE,aAAa,EAAE,QAAQ,EAAE,QAAQ,cAAc,EAAE,GAAG,WAAW,SAAS,QAAQ;KAClF,SAAS,OAAO;MACd,IAAI,iBAAiB,mBAAmB;OACtC,YAAY,OAAO,uBAAuB;OAC1C;MACF;MACA,YACE,IAAI,kBACF,mCAAmC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAC1F,GACA,eACF;KACF;IACF;IAGA,KAAU;GACZ;GAGA,0BAA+B;GAC/B,aAAkB;EACpB,CAAC;CACH;CAEA,MAAM,SAAS;EACb,MAAM,UAAU,KAAKA,SAAS,WAAW;EAEzC,MAAM,KAAK,QAAQ,KAAK;GACtB,MAAM,mBAAmB,KAAK;GAC9B,MAAM,EACJ,OAAO,KAAK,MACd;EACF,CAAC;EAED,MAAM,iBAAiB,MAAM,SAAS,SAAS,WAAW;EAC1D,MAAM,WAAW,MAAM,gBAAgB,qBAAqB;GAC1D,cAAc,KAAK;GACnB,OAAO,KAAK;EACd,CAAC;EACD,IAAI,UACF,MAAM,gBAAgB,wBAAwB;GAC5C,cAAc,KAAK;GACnB,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB,UAAU;IACR,GAAG;IACH,QAAQ;IACR,OAAO,SAAS;GAClB;EACF,CAAC;CAEL;CAEA,MAAM,MACJ,MAyB0D;EAC1D,OAAO,KAAK,OAAO,IAAI;CACzB;;;;;;;CAQA,MAAM,WACJ,MAuB4B;EAG5B,OAAM,MADuB,KAAKA,QAAQ,WAAW,CAAC,EAAE,SAAS,WAAW,EAAA,EACtD,wBAAwB;GAC5C,cAAc,KAAK;GACnB,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB,UAAU;IACR,OAAO,KAAK;IACZ,qBAAqB,KAAK;IAC1B,QAAQ;IACR,OAAO,CAAC;IACR,SAAS,CAAC;IACV,aAAa,CAAC;IACd,gBAAgB,CAAC;IACjB,iBAAiB,CAAC;IAClB,cAAc,CAAC;IACf,cAAc,CAAC;IACf,WAAW,KAAK,IAAI;GACtB;EACF,CAAC;EAGD,MAAM,iBAAiB,MAAM,KAAK,eAAe,KAAK,SAAS;EAC/D,MAAM,oBAAoB,MAAM,KAAK,sBAAsB,KAAK,gBAAiB,CAAC,CAAY;EAmB9F,IAAI,EADY,MAfU,KAAK,QAAQ,KAAK;GAC1C,MAAM,YAAY,KAAK;GACvB,MAAM,6BAA6B;IACjC,WAAW;IACX,cAAc;IACd,OAAO,KAAK;IACZ,YAAY,KAAK;IACjB,eAAe,KAAK;IACpB,gBAAgB,KAAK;IACrB,gBAAgB,KAAK;IACrB,OAAO,KAAK;IACZ,SAAS,KAAK;GAChB,CAAC;EACH,CAAC,EAAA,CAE2B,IAAI,IAE9B,MAAM,IAAI,MAAM,qBAAqB;EAIvC,OAAO,EAAE,OAAO,KAAK,MAAM;CAC7B;CAEA,MAAM,OAAO,EACX,WACA,cACA,eACA,gBACA,QACA,gBACA,OACA,WAa2D;EAE3D,OAAM,MADuB,KAAKA,QAAQ,WAAW,CAAC,EAAE,SAAS,WAAW,EAAA,EACtD,wBAAwB;GAC5C,cAAc,KAAK;GACnB,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB,UAAU;IACR,OAAO,KAAK;IACZ,qBAAqB,KAAK;IAC1B,QAAQ;IACR,OAAO,CAAC;IACR,SAAS,CAAC;IACV,aAAa,CAAC;IACd,gBAAgB,CAAC;IACjB,iBAAiB,CAAC;IAClB,cAAc,CAAC;IACf,cAAc,CAAC;IACf,WAAW,KAAK,IAAI;GACtB;EACF,CAAC;EAED,MAAM,iBAAiB,MAAM,KAAK,eAAe,SAAS;EAC1D,MAAM,oBAAoB,MAAM,KAAK,sBAAsB,gBAAiB,CAAC,CAAY;EAEzF,MAAM,YAAY,YAAY,KAAK;EAkBnC,MAAM,WAAU,MAhBU,KAAK,QAAQ,KAAK;GAC1C,MAAM;GACN,MAAM,6BAA6B;IACjC,WAAW;IACX,cAAc;IACd,OAAO,KAAK;IACZ,YAAY,KAAK;IACjB;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;EACH,CAAC,EAAA,CAE2B,IAAI;EAChC,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,qBAAqB;EAIvC,MAAM,UAAS,MADS,KAAK,aAAa,OAAO,EAAA,EACvB,QAAQ;EAElC,KAAK,oBAAoB,MAAM;EAG/B,IAAI,CAAC,eAAe,cAClB,OAAO,OAAO;EAGhB,IAAI,OAAO,WAAW,aACpB,KAAK,UAAU;EAEjB,OAAO;CACT;CAEA,MAAM,OAAgB,QAWuC;EAC3D,MAAM,IAAI,KAAK,QAAQ,MAAM,CAAC,CAAC,MAAK,WAAU;GAC5C,IAAI,OAAO,WAAW,aACpB,KAAK,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;GAG3C,OAAO;EACT,CAAC;EAED,KAAK,mBAAmB;EACxB,OAAO;CACT;;;;;;;;;CAUA,MAAM,oBAA6B,QAWF;EAG/B,MAAM,iBAAiB,OAFP,KAAKA,SAAS,WAAW,EAAA,EAEH,SAAS,WAAW;EAC1D,IAAI,CAAC,gBACH,MAAM,IAAI,kBAAkB,8CAA8C,KAAK,OAAO;EAExF,MAAM,WAAW,MAAM,eAAe,qBAAqB;GACzD,cAAc,KAAK;GACnB,OAAO,KAAK;EACd,CAAC;EACD,IAAI,CAAC,UACH,MAAM,IAAI,kBAAkB,qBAAqB,KAAK,MAAM,qBAAqB;EAKnF,MAAM,aADsB,OAAO,QAAQ,SAAS,eAAe,OAAO,SAAS,KAAA,EAAA,EAC5C,UAAU,OAAO;EAExD,IAAI,QAAkB,CAAC;EACvB,IAAI,WACF,IAAI,OAAO,cAAc,UACvB,QAAQ,UAAU,MAAM,GAAG;OAE3B,SAAS,MAAM,QAAQ,SAAS,IAAI,YAAY,CAAC,SAAS,EAAA,CAAG,KAAI,SAC/D,OAAO,SAAS,WAAW,OAAO,MAAM,EAC1C;EAIJ,MAAM,gBAAgB,KAAK,cAAc,QAAQ,MAAM;EAEvD,MAAM,kBAAkB,MAAM,KAAK,oBAAoB,OAAO,YAAY,aAAa;EAGvF,MAAM,uBAAuB,0BAA2B,UAAkB,gBAAgB,OAAO,cAAc;EAI/G,MAAM,eAAe,wBAAwB;GAC3C,cAAc,KAAK;GACnB,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB,UAAU;IACR,GAAG;IACH,QAAQ;IACR,QAAQ,KAAA;IACR,OAAO,KAAA;IACP,WAAW,KAAK,IAAI;GACtB;EACF,CAAC;EAED,IAAI;EACJ,IAAI;GACF,cAAc,MAAM,KAAK,QAAQ,KAAK;IACpC,MAAM,YAAY,KAAK;IACvB,MAAM,4BAA4B;KAChC,WAAW;KACX,OAAO,KAAK;KACZ,YAAY,KAAK;KACjB,QAAQ;MACN;MACA,eAAe;MACf,YAAY,QAAQ,KAAM,UAAU,iBAAiB,QAAQ,MAAc,KAAA;KAC7E;KACA,gBAAgB;KAChB,OAAO,OAAO;KACd,SAAS,OAAO;IAClB,CAAC;GACH,CAAC;EACH,SAAS,KAAK;GAIZ,IAAI;IACF,MAAM,eAAe,wBAAwB;KAC3C,cAAc,KAAK;KACnB,OAAO,KAAK;KACZ,YAAY,KAAK;KACP;IACZ,CAAC;GACH,SAAS,aAAa;IACpB,QAAQ,MAAM,6DAA6D,WAAW;GACxF;GACA,MAAM;EACR;EAEA,MAAM,UAAU,YAAY,IAAI;EAChC,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,qBAAqB;EAGvC,OAAO,EAAE,QAAQ;CACnB;CAEA,MAAM,QAAiB,QAWsC;EAC3D,MAAM,EAAE,YAAY,MAAM,KAAK,oBAAoB,MAAM;EAEzD,MAAM,UAAS,MADS,KAAK,aAAa,OAAO,EAAA,EACvB,QAAQ;EAClC,KAAK,oBAAoB,MAAM;EAC/B,IAAI,OAAO,WAAW,aACpB,KAAK,UAAU;EAEjB,OAAO;CACT;;;;;;;;;;;;;;;;CAiBA,MAAM,YAAqB,QAWI;EAC7B,MAAM,KAAK,oBAAoB,MAAM;EAErC,OAAO,EAAE,OAAO,KAAK,MAAM;CAC7B;CAEA,MAAM,WAAmB,QAmBoC;EAC3D,MAAM,IAAI,KAAK,YAAY,MAAM,CAAC,CAAC,MAAK,WAAU;GAChD,IAAI,OAAO,WAAW,aACpB,KAAK,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;GAG3C,OAAO;EACT,CAAC;EAED,KAAK,mBAAmB;EACxB,OAAO;CACT;CAEA,MAAM,YAAoB,QAmBvB;EACD,IAAI,CAAC,OAAO,QAAS,MAAM,QAAQ,OAAO,IAAI,KAAK,OAAO,MAAM,WAAW,GACzE,MAAM,IAAI,MAAM,6DAA6D;EAG/E,IAAI,QAAkB,CAAC;EACvB,IAAI,OAAO,OAAO,SAAS,UACzB,QAAQ,OAAO,KAAK,MAAM,GAAG;OAE7B,SAAS,MAAM,QAAQ,OAAO,IAAI,IAAI,OAAO,OAAO,CAAC,OAAO,IAAI,EAAA,CAAG,KAAI,SACrE,OAAO,SAAS,WAAW,OAAO,MAAM,EAC1C;EAGF,IAAI,MAAM,WAAW,GACnB,MAAM,IAAI,MAAM,iCAAiC;EAInD,MAAM,iBAAiB,OADP,KAAKA,SAAS,WAAW,EAAA,EACH,SAAS,WAAW;EAC1D,IAAI,CAAC,gBACH,MAAM,IAAI,kBAAkB,mDAAmD,KAAK,OAAO;EAG7F,MAAM,WAAW,MAAM,eAAe,qBAAqB;GACzD,cAAc,KAAK;GACnB,OAAO,KAAK;EACd,CAAC;EAED,IAAI,sBAAsB;EAC1B,IAAI,CAAC,UAAU;GACb,MAAM,kBAAkB;IACtB,OAAO,KAAK;IACZ,qBAAqB,KAAK;IAC1B,QAAQ;IACR,OAAO,CAAC;IACR,SAAS,CAAC;IACV,aAAa,CAAC;IACd,gBAAgB,CAAC;IACjB,iBAAiB,CAAC;IAClB,cAAc,CAAC;IACf,cAAc,CAAC;IACf,WAAW,KAAK,IAAI;GACtB;GACA,MAAM,eAAe,wBAAwB;IAC3C,cAAc,KAAK;IACnB,OAAO,KAAK;IACZ,YAAY,KAAK;IACjB,UAAU;GACZ,CAAC;GACD,sBAAsB;EACxB;EAEA,IAAI,UAAU,WAAW,WACvB,MAAM,IAAI,MAAM,wDAAwD;EAG1E,IAAI,iBAAiB,OAAO;EAE5B,IAAI,kBAAkB,MAAM,WAAW,GACrC,iBAAiB,MAAM,KAAK,6BAA6B,OAAO,WAAW,KAAK,cAAc,MAAM,GAAK;EAG3G,MAAM,iBAAiB,gCAAgC;GACrD;GACA,WAAW;GACX,YAAY,OAAO;GACnB,SAAS,OAAO;GAChB,oBAAoB,OAAO;GAC3B,UAAW,YAAY,EAAE,SAAS,CAAC,EAAE;GACrC,OAAO,KAAK;GACZ,cAAc,OAAO;GACrB,SAAS,OAAO;EAClB,CAAC;EAGD,MAAM,mBAAmB;EAIzB,MAAM,eAAe,wBAAwB;GAC3C,cAAc,KAAK;GACnB,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB,UAAU;IACR,OAAO,KAAK;IACZ,qBAAqB,KAAK;IAC1B,QAAQ;IACR,OAAO,CAAC;IACR,SAAS,CAAC;IACV,aAAa,CAAC;IACd,gBAAgB,CAAC;IACjB,iBAAiB,CAAC;IAClB,cAAc,CAAC;IACf,cAAc,CAAC;IACf,WAAW,KAAK,IAAI;GACtB;EACF,CAAC;EAED,IAAI;EACJ,IAAI;GACF,cAAc,MAAM,KAAK,QAAQ,KAAK;IACpC,MAAM,YAAY,KAAK;IACvB,MAAM,gCAAgC;KACpC,cAAc,eAAe;KAC7B,OAAO,KAAK;KACZ,YAAY,KAAK;KACjB,aAAa,eAAe;KAC5B,YAAY;KACZ,gBAAgB,OAAO;KACvB,eAAe,OAAO;KACtB,gBAAgB,OAAO;KACvB,OAAO,OAAO;KACd,SAAS,OAAO;IAClB,CAAC;GACH,CAAC;EACH,SAAS,KAAK;GAIZ,IAAI,kBACF,IAAI;IACF,MAAM,eAAe,wBAAwB;KAC3C,cAAc,KAAK;KACnB,OAAO,KAAK;KACZ,YAAY,KAAK;KACjB,UAAU;IACZ,CAAC;GACH,SAAS,aAAa;IACpB,QAAQ,MAAM,kEAAkE,WAAW;GAC7F;GAEF,MAAM;EACR;EAEA,MAAM,UAAU,YAAY,IAAI;EAChC,IAAI,CAAC,SACH,MAAM,IAAI,MAAM,qBAAqB;EAGvC,MAAM,UAAS,MADS,KAAK,aAAa,OAAO,EAAA,EACvB,QAAQ;EAClC,KAAK,oBAAoB,MAAM;EAG/B,IAAI,CAAC,OAAO,eAAe,cACzB,OAAO,OAAO;EAGhB,OAAO;CACT;CAEA,MAAM,IAAsD;EAC1D,IAAI,SAAS;EACb,MAAM,gBAAgB,UACpB;GACE,SAAS,YAAY,KAAK,WAAW,GAAG,KAAK;GAC7C,QAAQ,CAAC,OAAO;GAChB,KAAK,KAAK;EACZ,IACC,YAAiB;GAChB,IAAI,QACF,GAAG,QAAQ,IAAI;EAEnB,CACF;EAEA,aAAa;GACX,SAAS;GACT,cACG,KAAK,OAAO,WAA0C;IACrD,OAAO,OAAO,OAAO;GACvB,CAAC,CAAC,CACD,OAAM,QAAO;IACZ,QAAQ,MAAM,GAAG;GACnB,CAAC;EACL;CACF;CAEA,aAAa,EACX,WACA,gBACA,UACiG,CAAC,GAGlG;EACA,MAAM,EAAE,UAAU,aAAa,IAAI,gBAA0C;EAE7E,MAAM,SAAS,SAAS,UAAU;EAClC,OAAY,MAAM;GAEhB,MAAM;GACN,SAAS,EAAE,OAAO,KAAK,MAAM;EAC/B,CAAC;EAED,MAAM,UAAU,KAAK,MAAM,OAAM,UAAS;GACxC,IAAI;IACF,MAAM,IAAS;KACb,GAAG;KACH,MAAM,MAAM,KAAK,QAAQ,aAAa,EAAE;IAC1C;IAEA,IAAI,EAAE,SAAS,eAAe;KAC5B,EAAE,OAAO,EAAE,QAAQ,OAAO;KAC1B,EAAE,UAAU,EAAE,QAAQ,OAAO;IAC/B;IAEA,MAAM,OAAO,MAAM,CAAQ;GAC7B,QAAQ,CAAC;EACX,CAAC;EAED,KAAK,oBAAoB,YAAY;GACnC,MAAM,OAAO,MAAM;IACjB,MAAM;IAEN,SAAS,EAAE,OAAO,KAAK,MAAM;GAC/B,CAAC;GACD,QAAQ;GAER,IAAI;IACF,MAAM,OAAO,MAAM;GACrB,SAAS,KAAK;IACZ,QAAQ,MAAM,yBAAyB,GAAG;GAC5C,UAAU;IACR,OAAO,YAAY;GACrB;EACF;EAEA,KAAK,mBAAmB,KAAK,OAAO;GAAE;GAAW;GAAgB;GAAO,QAAQ;EAAS,CAAC,CAAC,CAAC,MAAK,WAAU;GACzG,IAAI,OAAO,WAAW,aACpB,KAAK,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;GAG3C,OAAO;EACT,CAAC;EAED,OAAO;GACL,QAAQ;GACR,wBAAwB,KAAK;EAC/B;CACF;CAEA,OAAO,EACL,WACA,gBACA,OACA,gBACA,iBAAiB,MACjB,cACA,eACA,YAcE,CAAC,GAAuE;EAC1E,IAAI,KAAK,qBAAqB,KAAK,cACjC,OAAO,KAAK;EAGd,KAAK,oBAAoB,YAAY,CAAC;EAEtC,MAAM,OAAO;EACb,MAAM,SAAS,IAAI,eAAoC,EACrD,MAAM,MAAM,YAAY;GACtB,MAAM,UAAU,KAAK,MAAM,OAAO,UAA+B;IAC/D,MAAM,EAAE,MAAM,OAAO,UAAU,UAAU,YAAY;IACrD,WAAW,QAAQ;KACjB;KACA,OAAO,KAAK;KACZ;KACA,SAAS;MACP,UAAW,SAAuC;MAClD,GAAG;KACL;IACF,CAAwB;GAC1B,CAAC;GAED,KAAK,oBAAoB,YAAY;IACnC,QAAQ;IAER,IAAI;KACF,MAAM,WAAW,MAAM;IACzB,SAAS,KAAK;KACZ,QAAQ,MAAM,yBAAyB,GAAG;IAC5C;GACF;GAEA,MAAM,0BAA0B,KAAK,OAAO;IAC1C;IACA;IACA;IAEA;IACA;IACA;IACA,QAAQ;IACR;GACF,CAAC;GACD,IAAI;GACJ,IAAI;IACF,mBAAmB,MAAM;IAEzB,IAAI,gBAGF,KAAK,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;SACpC,IAAI,iBAAiB,WAAW,aACrC,KAAK,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;IAE3C,IAAI,KAAK,cACP,KAAK,aAAa,cAChB,gBACF;GAEJ,SAAS,KAAK;IACZ,KAAK,cAAc,cAAc,GAAuB;IACxD,KAAK,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;GAC3C;EACF,EACF,CAAC;EAED,KAAK,eAAe,IAAI,kBAAmE;GACzF,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB;EACF,CAAC;EAED,OAAO,KAAK;CACd;CAEA,iBAA+B,EAC7B,WACA,YACA,cACA,MACA,SACA,oBACA,gBACA,OAEA,gBACA,eACA,WAqBC;EACD,KAAK,oBAAoB,YAAY,CAAC;EAEtC,MAAM,OAAO;EACb,MAAM,SAAS,IAAI,eAAoC,EACrD,MAAM,MAAM,YAAY;GACtB,MAAM,UAAU,KAAK,MAAM,OAAO,UAA+B;IAC/D,MAAM,EAAE,MAAM,OAAO,UAAU,UAAU,YAAY;IACrD,WAAW,QAAQ;KACjB;KACA,OAAO,KAAK;KACZ;KACA,SAAS;MACP,UAAW,SAAuC;MAClD,GAAG;KACL;IACF,CAAwB;GAC1B,CAAC;GAED,KAAK,oBAAoB,YAAY;IACnC,QAAQ;IAER,IAAI;KACF,WAAW,MAAM;IACnB,SAAS,KAAK;KACZ,QAAQ,MAAM,yBAAyB,GAAG;IAC5C;GACF;GACA,MAAM,0BAA0B,KAAK,YAAY;IAC/C;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF,CAAC;GAED,KAAK,mBAAmB;GAExB,IAAI;GACJ,IAAI;IACF,mBAAmB,MAAM;IACzB,KAAK,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;IAEzC,IAAI,KAAK,cACP,KAAK,aAAa,cAAc,gBAAgB;GAEpD,SAAS,KAAK;IACZ,KAAK,cAAc,cAAc,GAAuB;IACxD,KAAK,oBAAoB,CAAC,CAAC,YAAY,CAAC,CAAC;GAC3C;EACF,EACF,CAAC;EAED,KAAK,eAAe,IAAI,kBAAmE;GACzF,OAAO,KAAK;GACZ,YAAY,KAAK;GACjB;EACF,CAAC;EAED,OAAO,KAAK;CACd;;;;;CAMA,oBAA4B,QAA+D;EACzF,IAAI,OAAO,WAAW,UAAU;GAE9B,OAAO,QAAQ,oBAAoB,OAAO,OAAO,EAAE,gBAAgB,MAAM,CAAC;GAE1E,IAAI,OAAO,OACT,4BAA4B,OAAO,KAAK;EAE5C;CACF;AACF;;;;;;;;;AC1mCA,SAAS,yBAAyB,OAA8C;CAC9E,IAAI,SAAkB;CACtB,IAAI,MAAM,SAAS,UAAU,MAAM,SAAS,WAC1C,SAAS,iBAAiB,MAAM,IAAI;MAC/B,IAAI,kBAAkB,KAAK,GAChC,SAAS,iBAAiB,KAAK;CAEjC,OAAO,kBAAkB,kBAAkB,SAAS;AACtD;AAEA,IAAa,kBAAb,cAkBU,SAAkG;CAC1G;CACA;CAEA;CACA;CACA;CACA;CACA;;;;;;;;CAQA;CAEA,YACE,QAQA,SACA;EACA,MAAM,EACJ,aACA,WACA,UACA,UACA,UACA,SACA,MACA,WACA,cACA,GAAG,mBACD;EAEJ,MAAM,cAA+F;EAErG,KAAK,aAAa;EAElB,MAAM,qBAAqB,OAAO,QAAQ;GAAE;GAAa;GAAW;GAAU;GAAU;EAAS,CAAC,CAAC,CAAC,QACjG,CAAC,GAAG,WAAW,UAAU,KAAA,CAC5B;EAEA,KAAK,oBAAoB,mBAAmB,SAAS,IAAI,OAAO,YAAY,kBAAkB,IAAI,KAAA;EAClG,KAAK,kBAAkB,WAAW;EAElC,KAAKC,UAAU,OAAO;EACtB,KAAK,UAAU;EAEf,IAAI,MACF,KAAK,aAAa;GAAE;GAAM;GAAW;EAAa;CAEtD;CAEA,MAAM,iBAAiB,MAMpB;EACD,MAAM,UAAU,KAAKA,SAAS,WAAW;EACzC,IAAI,CAAC,SAAS;GACZ,KAAK,OAAO,MAAM,4DAA4D;GAC9E,OAAO;IAAE,MAAM,CAAC;IAAG,OAAO;GAAE;EAC9B;EAEA,MAAM,iBAAiB,MAAM,QAAQ,SAAS,WAAW;EACzD,IAAI,CAAC,gBACH,OAAO;GAAE,MAAM,CAAC;GAAG,OAAO;EAAE;EAE9B,OAAO,eAAe,iBAAiB;GAAE,cAAc,KAAK;GAAI,GAAI,QAAQ,CAAC;EAAG,CAAC;CACnF;;;;;;;;;;;;;;;;;;;CAoBA,mBAAmB,SAA4C;EAC7D,KAAKC,iBAAiB;EACtB,MAAM,gBAAgB,SAAwB;GAC5C,MAAM,SAAS,yBAAyB,IAAI;GAC5C,IAAI,QACF,OAAO,mBAAmB,OAAO;QAC5B,IAAI,KAAK,SAAS,cAAc,KAAK,SAAS,eACnD,KAAK,MAAM,WAAW,KAAK,OACzB,aAAa,OAAO;EAG1B;EACA,KAAK,MAAM,QAAQ,KAAK,eAAe,OACrC,aAAa,IAAI;CAErB;;;;;;CAOA,qBAAsE;EACpE,OAAO,KAAKA;CACd;CAEA,iBAAiB,QAAgB;EAC/B,MAAM,iBAAiB,MAAM;EAC7B,KAAKD,UAAU;EACf,KAAK,gBAAgB,iBAAiB,MAAM;EAC5C,MAAM,gBAAgB,SAAwB;GAC5C,MAAM,SAAS,yBAAyB,IAAI;GAC5C,IAAI,QACF,OAAO,iBAAiB,MAAM;QACzB,IAAI,KAAK,SAAS,cAAc,KAAK,SAAS,eACnD,KAAK,MAAM,WAAW,KAAK,OACzB,aAAa,OAAO;EAG1B;EAEA,IAAI,KAAK,eAAe,MAAM,QAC5B,KAAK,MAAM,QAAQ,KAAK,eAAe,OACrC,aAAa,IAAI;CAGvB;CAEA,MAAM,UAAU,SAKgE;EAC9E,MAAM,aAAa,SAAS,SAAS,WAAW;EAGhD,MAAM,sBAAsB,KAAK,KAAK,IAAI,UAAU;EACpD,MAAM,SAAS,IAAI,WACjB;GACE,YAAY,KAAK;GACjB,OAAO;GACP,YAAY,SAAS;GACrB,iBAAiB,KAAK;GACtB,gBAAgB,KAAK;GACrB,qBAAqB,KAAK;GAC1B,QAAQ,KAAKA;GACb,aAAa,KAAK;GAClB,eAAe,KAAK,KAAK,OAAO,UAAU;GAC1C,eAAe,KAAK;GACpB,oBAAoB,KAAK;GACzB,gBAAgB,KAAK,QAAQ;EAC/B,GACA,KAAK,OACP;EACA,MAAM,MAAO,uBAAuB;EAEpC,KAAK,KAAK,IAAI,YAAY,GAAG;EAE7B,MAAM,wBAAwB,KAAK,QAAQ,sBAAsB;GAC/D,gBAAgB,IAAI;GACpB,aAAa,CAAC;EAChB,CAAC;EAED,MAAM,oBAAoB,MAAM,KAAK,mBAAmB,YAAY,EAClE,qBAAqB,MACvB,CAAC;EAKD,IAAI,EAFoB,qBAAqB,CAAC,kBAAkB,mBAExC,uBAEtB,OAAM,MADuB,KAAK,QAAQ,WAAW,CAAC,EAAE,SAAS,WAAW,EAAA,EACtD,wBAAwB;GAC5C,cAAc,KAAK;GACnB,OAAO;GACP,YAAY,SAAS;GACrB,UAAU;IACR,OAAO;IACP,QAAQ;IACR,OAAO,CAAC;IACR,SAAS,CAAC;IACV,aAAa,CAAC;IACd,iBAAiB,CAAC;IAClB,cAAc,CAAC;IACf,qBAAqB,KAAK;IAC1B,gBAAgB,CAAC;IACjB,cAAc,CAAC;IACf,QAAQ,KAAA;IACR,OAAO,KAAA;IACP,WAAW,KAAK,IAAI;GACtB;EACF,CAAC;EAGH,OAAO;CACT;CAGA,qBAA6B;EAC3B,IAAI,KAAK,cACP,OAAO,KAAK;EAEd,KAAK,eAAe,KAAK,QAAQ,eAC/B;GACE,IAAI,YAAY,KAAK,GAAG;GACxB,SAAS,KAAK;GAId,UAAU,CAAC,EAAE,OAAO,mBAAmB,KAAK,KAAK,CAAC;GAClD,UAAU,EAAE,MAAM,KAAK,YAAY,QAAQ,GAAG;GAC9C,GAAG,KAAK;EACV,GACA,YAAY;GACV,MAAM,MAAM,MAAM,KAAK,UAAU;GAMjC,OAAO;IAAE,QAAA,MAJY,IAAI,MAAM;KAC7B,WAAW,KAAK,YAAY;KAC5B,cAAc,KAAK,YAAY;IACjC,CAAC;IACgB,OAAO,IAAI;GAAM;EACpC,CACF;EACA,OAAO,KAAK;CACd;;;;;;CAOA,cAAqD;EACnD,IAAI,KAAK,UACP,OAAO,KAAK;EAOd,KAAK,WAAW,KAAK,QAAQ;GAC3B;IACE,IAAI,YAAY,KAAK;IACrB,SAAS,KAAK;IAQd,UAAU,CAAC;KAAE,OAAO,mBAAmB,KAAK;KAAM,OAAO;IAAa,CAAC;IACvE,UAAU,EAAE,OAAO,YAAY,KAAK,KAAK;IAEzC,GAAG,KAAK;GACV;;;;;;;GAOA,OAAO,EAAE,OAAO,MAAM,cAAc;IAClC,IAAI,EACF,WACA,cACA,OACA,YACA,QACA,eACA,QACA,YACA,SACA,gBACA,OACA,cACA,0BAA0B,sCACxB,MAAM;IAEV,MAAM,oCAD2B,gCAAgC,iCACA,MAAM,4BAA4B;IAEnG,IAAI,CAAC,OAAO;KAOV,QAAQ,MAAM,KAAK,IAAI,YAAY,KAAK,GAAG,YAAY,YAAY;MACjE,OAAO,WAAW;KACpB,CAAC;KACD,KAAK,OAAO,OACV,aAAa,KAAK,GAAG,2CAA2C,MAAM,kIAExE;IACF;IAEA,IAAI,WAAW,iBAAiB,KAAA,KAAa,OAAO,gBAAgB,KAAA,IAAY;KAE9E,MAAM,WAAW,OAAM,MADM,KAAKA,SAAS,WAAW,CAAC,EAAE,SAAS,WAAW,EAAA,EACtC,qBAAqB;MAC1D,cAAc,KAAK;MACnB;KACF,CAAC;KAED,iBAAiB,UAAU;KAC3B,IAAI,OAAO,gBAAgB,KAAA,KAAa,UAAU,YAAY,KAAA,GAC5D,SAAS;MAAE,GAAG;MAAQ,aAAa,SAAS;KAAQ;IAExD;IAWA,MAAM,gBAAgB,IAAI,cAAc,KAAK,SAAS,KAAK,EAAE;IAC7D,MAAM,SAAiB,KAAKC,iBAAiB,aAAa,KAAK;IAG/D,MAAM,iBAAiC,IAAI,eAAe,OAAO,QAAQ,MAAM,KAAK,kBAAkB,CAAC,CAAC,CAAC;IAGzG,MAAM,SAAS,KAAKD;IACpB,MAAM,gBAAgB,KAAK,QAAQ;IAInC,MAAM,mBAAmB,MAAM,KAAK,IAAI,YAAY,KAAK,GAAG,cAAc,YAAY;KACpF,MAAM,gBAAgB,QAAQ,eAAe,oBAAoB,EAAE,eAAe,CAAC;KACnF,IAAI,CAAC,eAAe,OAAO,KAAA;KAkB3B,OAhBa,cAAc,UAAU;MACnC,MAAM,SAAS;MACf,MAAM,kBAAkB,KAAK,GAAG;MAChC,YAAY,WAAW;MACvB,UAAU,KAAK;MACf,YAAY,KAAK;MACjB,OAAO;MACP,UAAU;OACR;OACA;MACF;MACA;MACA;MACA;KACF,CAEU,CAAC,EAAE,WAAW;IAC1B,CAAC;IAED,MAAM,SAAS,IAAI,uBAAuB,KAAKA,SAAS,MAAM,SAAS,KAAK,SAAS,YAAY;IAEjG,IAAI;IACJ,IAAI;KACF,SAAS,MAAM,OAAO,QAAyE;MAC7F,YAAY,KAAK;MACjB;MACA;MACA,OAAO,KAAK;MACZ,qBAAqB,KAAK;MAC1B,OAAO;MACP;MACA;MACA,aAAa,KAAK;MAClB;MACA;MACA;MACA;MACA;MACA;MACA,iBAAiB,IAAI,gBAAgB;MAErC,cAAc,KAAA;MAEd,YAAY,mBACR;OACE,SAAS,iBAAiB;OAC1B,gBAAgB,iBAAiB;MACnC,IACA,KAAA;MACJ;MACA,cAAc,OAAO,UAA+B;OAClD,IAAI;QACF,MAAM,OAAO,QAAQ,sBAAsB,SAAS;SAClD,MAAM;SACN;SACA,MAAM;QACR,CAAC;OACH,SAAS,KAAK;QACZ,KAAK,OAAO,QAAQ,kCAAkC,GAAG;OAC3D;OAGA,IAAI,cACF,IAAI;QACF,MAAM,cAAc,uBAAuB,aAAa,YAAY,aAAa,OAAO,KAAK;OAC/F,SAAS,KAAK;QACZ,KAAK,OAAO,QAAQ,yCAAyC,GAAG;OAClE;MAEJ;KACF,CAAC;IACH,SAAS,gBAAgB;KAGvB,SAAS;MACP,QAAQ;MACR,OAAO,CAAC;MACR,OAAO,gBAAgB,CAAC;MACxB,OAAO,0BAA0B,QAAQ,iBAAiB,IAAI,MAAM,OAAO,cAAc,CAAC;KAC5F;IACF;IAEA,MAAM,iBAAiB,oCAAoC,4BAA4B,MAAM,IAAI;IAIjG,IAAI;IACJ,IAAI,kBAAkB;IACtB,IAAI;;;;;;KAMF,MAAM,mBAAmB,YAAY;MAGnC,IAAI,OAAO,WAAW,YAAY,WAAW,mBAAmB,mBAAmB,WAAW,OAAO;OACnG,MAAM,QAAQ,OAAO,iBAAiB,QAAQ,OAAO,QAAQ,IAAI,MAAM,OAAO,OAAO,KAAK,CAAC;OAC3F,IAAI;QACF,MAAM,eAAe,QAAQ,UAAU,OAAO,KAAK;OACrD,SAAS,GAAG;QACV,KAAK,OAAO,QAAQ,+BAA+B,CAAC;OACtD;MACF;MAEA,IAAI,OAAO,WAAW,UAEpB,MAAM,OAAO,iCAAiC;OAC5C,QAAQ,OAAO;OACf,QAAQ,YAAY,SAAS,OAAO,SAAS,KAAA;OAC7C,OAAO,WAAW,SAAS,OAAO,QAAQ,KAAA;OAC1C,OAAO,OAAO;OACd,UAAU,cAAc,SAAS,OAAO,WAAW,KAAA;OACnD;OACA,YAAY,KAAK;OACjB;OACA,OAAO;OACP;OACA,OAAO,OAAO,SAAS,gBAAgB,CAAC;MAC1C,CAAC;MAKH,IAAI,kBAAkB;OACpB,MAAM,gBAAgB,QAAQ,eAAe,oBAAoB,EAAE,eAAe,CAAC;OACnF,IAAI,eAAe;QAEjB,MAAM,eAAe,cAAc,YAAY,gBAAgB;QAE/D,IAAI,OAAO,WAAW,UACpB,aAAa,MAAM;SACjB,OAAO,OAAO,iBAAiB,QAAQ,OAAO,QAAQ,IAAI,MAAM,OAAO,OAAO,KAAK,CAAC;SACpF,YAAY,EAAE,QAAQ,SAAS;QACjC,CAAC;aAED,aAAa,IAAI;SACf,QAAQ,OAAO,WAAW,YAAY,OAAO,SAAS,KAAA;SACtD,YAAY,EAAE,QAAQ,OAAO,OAAO;QACtC,CAAC;OAEL;MACF;MAQA,IAJmC,KAAK,QAAQ,sBAAsB;OACpE,gBAAgB,OAAO;OACvB,aAAa,OAAO;MACtB,CAC6B,GAAG;OAC9B,MAAM,iBAAiB,MAAM,QAAQ,WAAW,CAAC,EAAE,SAAS,WAAW;OACvE,IAAI,gBAAgB;QAGlB,IAAI;QAGJ,IAAI,OAAO,WAAW,aACpB,mBACG,MAAM,eAAe,qBAAqB;SACzC,cAAc,KAAK;SACnB;QACF,CAAC,KAAM,KAAA;QAGX,MAAM,eAAe,wBAAwB;SAC3C,cAAc,KAAK;SACnB;SACA;SACA,UAAU;UACR;UACA,QAAQ,OAAO;UACf,OAAO,OAAO,SAAS,gBAAgB,CAAC;UACxC,SAAS,kBAAkB,OAAO,KAAK;UACvC,aAAa,CAAC;UACd,iBAAiB,CAAC;UAClB,qBAAqB,KAAK;UAC1B,gBAAgB,kBAAkB,kBAAkB,CAAC;UACrD,cAAc,CAAC;UACf,cAAc,kBAAkB,gBAAgB,OAAO,gBAAgB,CAAC;UACxE,QAAQ,OAAO,WAAW,YAAY,iBAAiB,OAAO,MAAM,IAAI,KAAA;UACxE,OAAO,OAAO,WAAW,WAAW,OAAO,QAAQ,KAAA;UACnD,gBAAgB,eAAe,OAAO;UACtC,gBAAgB,mBACZ;WACE,SAAS,iBAAiB;WAC1B,QAAQ,iBAAiB;UAC3B,IACA,KAAA;UACJ,WAAW,KAAK,IAAI;SACtB;QACF,CAAC;OACH;MACF;MAGA,IAAI;OACF,MAAM,OAAO,QAAQ,sBAAsB,SAAS;QAClD,MAAM;QACN;QACA,MAAM;SACJ,MAAM;SACN,SAAS;UACP,QAAQ,OAAO;UACf,QAAQ,OAAO,WAAW,YAAY,OAAO,SAAS,KAAA;UACtD,OAAO,OAAO,WAAW,WAAW,OAAO,QAAQ,KAAA;SACrD;QACF;OACF,CAAC;MACH,SAAS,cAAc;OACrB,KAAK,OAAO,QAAQ,4CAA4C,YAAY;MAC9E;MAGA,IAAI,OAAO,WAAW,UACpB,MAAM,IAAI,kBAAkB,mBAAmB,EAC7C,OAAO,oCAAoC;OAAE,GAAG;OAAgB;MAAM,IAAI,OAC5E,CAAC;MAGH,OAAO,oCAAoC,EAAE,QAAQ,OAAO,OAAO,IAAI;KACzE;KACA,MAAM,KAAK,IAAI,YAAY,KAAK,GAAG,YAAY,gBAAgB;IACjE,SAAS,OAAO;KACd,kBAAkB;KAClB,gBAAgB;IAClB,UAAU;KAER,MAAM,gBAAgB,QAAQ,eAAe,oBAAoB,EAAE,eAAe,CAAC;KACnF,IAAI,eACF,IAAI;MACF,MAAM,cAAc,MAAM;KAC5B,SAAS,YAAY;MACnB,KAAK,OAAO,QAAQ,kCAAkC,UAAU;KAClE;IAEJ;IAEA,IAAI,iBACF,MAAM;IAGR,OAAO;KAAE,QAAQ;KAAgB;IAAM;GACzC;EACF;EACA,OAAO,KAAK;CACd;CAEA,mBAAmB,OAAiE;EAClF,OAAO,MAAM,SAAQ,SAAQ;GAC3B,MAAM,SAAS,yBAAyB,IAAI;GAC5C,IAAI,QACF,OAAO,CAAC,OAAO,YAAY,GAAG,GAAG,OAAO,mBAAmB,OAAO,eAAe,KAAK,CAAC;GAEzF,IAAI,KAAK,SAAS,cAAc,KAAK,SAAS,eAC5C,OAAO,KAAK,mBAAmB,KAAK,KAAK;GAG3C,OAAO,CAAC;EACV,CAAC;CACH;CAEA,eAAwD;EACtD,OAAO;GACL,KAAK,YAAY;GACjB,GAAI,KAAK,YAAY,OAAO,CAAC,KAAK,mBAAmB,CAAC,IAAI,CAAC;GAC3D,GAAG,KAAK,mBAAmB,KAAK,eAAe,KAAK;EACtD;CACF;AACF;;;;;;AAOA,SAAS,kBAAkB,OAAoF;CAC7G,OAAO;AACT;;;;;AAMA,SAAS,iBAAiB,QAA6C;CACrE,OAAO;AACT;;;;;;;ACnqBA,MAAM,4BAA4B,EAAE,OAAO;CACzC,OAAO,EAAE,OAAO;CAChB,SAAS,EAAE,OAAO;CAClB,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;CAC/B,kBAAkB,EAAE,IAAI;CACxB,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC;CAC9B,aAAa;CACb,SAAS,EAAE,IAAI;CACf,OAAO,EAAE,IAAI;CACb,WAAW,EAAE,OAAO;CAIpB,uBAAuB,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS;CAE9D,eAAe,EAAE,IAAI,CAAC,CAAC,SAAS;CAChC,eAAe,EAAE,IAAI,CAAC,CAAC,SAAS;CAChC,WAAW,EAAE,OAAO,CAAC,CAAC,SAAS;AACjC,CAAC;;;;AAmBD,MAAM,uBAAuB,yBAAyB,OAAO;CAE3D,eAAe,EAAE,IAAI,CAAC,CAAC,SAAS;CAEhC,eAAe,EAAE,IAAI,CAAC,CAAC,SAAS;CAEhC,WAAW,EAAE,OAAO;AACtB,CAAC;;;;;;;;;;;;;;;;;;;AAyBD,MAAM,wBAAwB;;AAG9B,MAAa,wBAAwB;CACnC,mBAAmB,GAAG,sBAAsB,GAAG,eAAe;CAC9D,cAAc,GAAG,sBAAsB,GAAG,eAAe;AAC3D;AAEA,SAAgB,oCAAoC,SAA+C;CACjG,MAAM,EAAE,SAAS,WAAW,qBAAqB,WAAW,YAAY;CACxE,MAAM,EAAE,mBAAmB,KAAK,OAAO;CAGvC,MAAM,mBAAmB,8BAA8B;CAGvD,MAAM,eAAe,0BAA0B;CAG/C,MAAM,iBAAiB,4BAA4B;CAGnD,MAAM,0BAA0B,qCAAqC;CAGrE,MAAM,0BAA0B,eAAe;EAC7C,IAAI,sBAAsB;EAC1B;EACA,aAAa;EACb,cAAc;EACd,SAAS;GACP,eAAe,EAGb,UAAU,cAAc,SAC1B;GACA,wBAAwB,EAAE,qBAAqB,mBAAmB;GAClE,oDAAoD;GACpD,gBAAgB;GAChB,gBAAgB;EAClB;EACA,OAAO,CAAC;CACV,CAAC,CAAC,CAEC,IACC,OAAO,EAAE,gBAAgB;EACvB,MAAM,QAAQ;EACd,OAAO;GACL,OAAO,MAAM;GACb,SAAS,MAAM;GACf,WAAW,MAAM;GACjB,kBAAkB,MAAM;GACxB,eAAe,MAAM;GACrB,aAAa,MAAM;GACnB,SAAS,MAAM;GACf,OAAO,MAAM;GACb,WAAW,MAAM;GAGjB,uBAAuB,MAAM;GAE7B,eAAe,MAAM;GAErB,eAAe,MAAM;GAErB,WAAW,MAAM;EACnB;CACF,GACA,EAAE,IAAI,mBAAmB,CAC3B,CAAC,CAEA,KAAK,gBAAgB,CAAC,CAEtB,IACC,OAAO,EAAE,gBAAgB;EACvB,MAAM,YAAY;EAClB,QAAQ,UAAU,aAAa,CAAC,EAAA,CAAG,KAAI,cAAa;GAClD,GAAG;GACH,cAAc,UAAU;EAC1B,EAAE;CACJ,GACA,EAAE,IAAI,qBAAqB,CAC7B,CAAC,CAQA,QAAQ,cAAc,EACrB,cAAc,EAAE,WAAW,kBAAkB;EAC3C,MAAM,QAAQ,YAAY;EAC1B,OAAO,kCAAkC;GACvC,SAAS,OAAO;GAChB,eAAe,OAAO;GACtB,WAAW;EACb,CAAC;CACH,EACF,CAAC,CAAC,CAMD,IACC,OAAO,EAAE,WAAW,eAAe,kBAAkB;EACnD,MAAM,cAAc;EACpB,MAAM,YAAY,cAAc,iBAAiB,EAAE;EACnD,MAAM,WAAW,YAAY;EAE7B,OAAO;GACL;GACA;GACA,OAAO,SAAS;GAChB,SAAS,SAAS;GAClB,WAAW,SAAS;GACpB,OAAO,WAAW,SAAS,SAAS;EACtC;CACF,GACA,EAAE,IAAI,uBAAuB,CAC/B,CAAC,CAEA,KAAK,cAAc,CAAC,CAEpB,KAAK,uBAAuB,CAAC,CAE7B,IACC,OAAO,EAAE,WAAW,kBAAkB;EACpC,MAAM,kBAAkB;EACxB,MAAM,WAAW,YAAY;EAmB7B,OAAO;GATL,GAPiB,+BAA+B;IAChD,cAAc;IACd;GACF,CAIc;GAEZ,eAAe,SAAS;GAExB,eAAe,SAAS;GAExB,WAAW,SAAS,YAAY;EAGX;CACzB,GACA,EAAE,IAAI,yBAAyB,CACjC,CAAC,CACA,OAAO;CAGV,OACE,eAAe;EACb,IAAI,sBAAsB;EAC1B;EACA,aAAa;EACb,cAAc;EACd,SAAS;GACP,eAAe,EAGb,UAAU,cAAc,SAC1B;GACA,wBAAwB,EAAE,qBAAqB,mBAAmB;GAClE,oDAAoD;GACpD,gBAAgB;GAChB,gBAAgB;EAClB;EACA,OAAO,CAAC;CACV,CAAC,CAAC,CAIC,IACC,OAAO,EAAE,gBAAgB;EACvB,MAAM,QAAQ;EAId,MAAM,gBAAgB,MAAM;EAG5B,MAAM,gBAAgB,MAAM;EAgB5B,OAAO;GAbL,GAAG;GACH,gBAAgB;GAChB,kBAAkB,CAAC;GACnB,kBAAkB;IAChB,aAAa;IACb,cAAc;IACd,aAAa;GACf;GACA,gBAAgB,KAAA;GAChB;GACA;GACA,WAAW,MAAM,aAAa;EAEZ;CACtB,GACA,EAAE,IAAI,uBAAuB,CAC/B,CAAC,CAEA,QAAQ,yBAAyB,OAAO,EAAE,gBAAgB;EACzD,MAAM,QAAQ;EAGd,MAAM,iBAAiB,MAAM,gBAAgB,gBAAgB;EAE7D,MAAM,oBAAoB,MAAM,SAAS,YAAY;EACrD,MAAM,gBAAgB,MAAM,iBAAiB;EAE7C,OAAO,kBAAkB;CAC3B,CAAC,CAAC,CAED,IACC,OAAM,WAAU;EACd,MAAM,EAAE,WAAW,QAAQ,gBAAgB,mBAAmB;EAC9D,MAAM,QAAQ;EACd,MAAM,WAAW,OAAO,YAAY;EAGpC,MAAM,SAAU,OAAe;EAG/B,MAAM,WAAW,MAAM,iBAAiB,MAAM,iBAAiB,SAAS;EACxE,IAAI,YAAY,UAAU;EAQ1B,MAAM,eAAe,MAAM,4BAA4B;GACrD,OAAO,MAAM;GACb;GACA,kBAAkB,MAAM;GACxB;GACA;GACA;GACA,QAAQ,QAAQ,YAAY;GAC5B,cAAc;IACZ,MAAM,aAAa;IACnB,OAAO,MAAM;IACb,cAAc,MAAM,gBAAgB,UAAU;IAC9C,OAAO,MAAM;GACf;EACF,CAAC;EACD,IAAI,YAAY,aAAa,cAAc,aAAa,gBAAgB,aAAa,KAAK;GACxF,SAAS,OAAO,aAAa;GAC7B,YAAY,aAAa;EAC3B;EAEA,MAAM,cAAc;GAClB,kBAAkB,aAAa;GAC/B,WAAW,MAAM;GACjB,YAAY,MAAM,kBAAkB;IAClC,QAAQ;IACR,UAAU,CAAC;IACX,aAAa;GACf;GACA,QAAQ;IACN,MAAM;IACN,OAAO,MAAM;IACb,OAAO,MAAM;GACf;GACA,OAAO,MAAM;EACf;EAMA,MAAM,gBAAgB,QAAQ,eAAe,oBAAoB,CAAC,CAAC;EACnE,IAAI,MAAM,eAIR,CAHkB,eAAe,YAC/B,MAAM,aACR,EAAA,EACW,cAAc,CAAC,EAAE,cAAc;GACxC,QAAQ,EAAE,MAAM,UAAU;GAC1B,YAAY,EAAE,cAAc,MAAM,gBAAgB,UAAU,OAAO;GACnE,OAAO,MAAM;EACf,CAAC;EAIH,IAAI,MAAM,eAER,CADkB,eAAe,YAAY,MAAM,aAAiD,EAAA,EACzF,IAAI,EAAE,QAAQ,EAAE,MAAM,UAAU,EAAE,CAAC;EAIhD,IAAI,QACF,MAAM,gBAAgB,QAAQ,MAAM,OAAO;GACzC,QAAQ,YAAY;GACpB,YAAY,YAAY;EAC1B,CAAC;EAGH,OAAO;CACT,GACA,EAAE,IAAI,mBAAmB,CAC3B,CAAC,CAEA,IACC,OAAO,EAAE,WAAW,aAAa,QAAQ,gBAAgB,qBAAqB;EAC5E,2BAA2B;GACzB,UAAU,YAAY;GACtB,aAAa;GACb;GACA;GACA;EACF,CAAC;EAED,OAAO;CACT,GACA,EAAE,IAAI,kBAAkB,CAC1B,CAAC,CACA,OAAO;AAEd;;;ACvWA,IAAM,+BAAN,cAA2C,cAAc;CACvD,QACE,OACA,OACA,SACe;EACf,IAAI,MAAM,WAAW,qBAAqB,GACxC,OAAO,MAAM,QAAQ,OAAO,OAAO;GAAE,GAAG;GAAS,WAAW;EAAK,CAAC;EAGpE,OAAO,MAAM,QAAQ,OAAO,OAAO,OAAO;CAC5C;AACF;;;;;;;;;;AAWA,MAAM,mBAAmB,OAAO,uCAAuC;;;;;;;;AASvE,MAAM,iBAAiB,OAAO,sCAAsC;AAEpE,MAAM,0BAA0B;AAChC,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;AA4dhC,SAAgB,mBAAwC,SAA2D;CACjH,MAAM,EACJ,OACA,SACA,IAAI,YACJ,MAAM,cACN,QAAQ,cACR,OACA,QAAQ,cACR,uBACA,YACE;CAEJ,IAAI,uBACF,QAAQ,KACN,iBAAiB,cAAc,MAAM,GAAG,4LAG1C;CAIF,MAAM,UAAU,cAAc,MAAM;CACpC,MAAM,YAAY,gBAAgB,MAAM;CAGxC,IAAI,SAA6B;CAGjC,MAAM,wCAAwB,IAAI,IAAwB;CAG1D,IAAI;CAIJ,MAAM,WAAW,oCAAoC;EAAE;EAAS;CAAQ,CAAC;CAGzE,IAAI,eAAe;CAInB,IAAI,cAAsB,gBAAgB,IAAI,cAAc,SAAS,sBAAsB,YAAY;CACvG,IAAI,iBAAuC;CAQ3C,SAAS,eAAkC;EACzC,MAAM,WAAW,gBAAgB,QAAQ,eAAe,IAAI,oBAAoB;EAChF,eAAe;EACf,OAAO;CACT;CAYA,SAAS,YAA2B;EAClC,IAAI,CAAC,gBACH,IAAI,uBAAuB,eAAe;GACxC,iBAAiB;GACjB,eAAe,gBAAgB,QAAQ;EACzC,OACE,iBAAiB,IAAI,cAAc,aAAa,aAAa,CAAC;EAGlE,OAAO;CACT;CAEA,eAAe,gBAAgB,OAAgC;EAE7D,QAAO,MADe,UAAU,CAAC,CAAC,WAAW,mBAAmB,KAAK,CAAC,EAAA,CACvD;CACjB;CASA,SAAyC,oBAAmB,kBAAiB;EAE3E,IAAI,yBAAyB,eAAe,OAAO;EAGnD,UAAU;EACV,OAAO,IAAI,6BAA6B,eAAe,aAAa,CAAC;CACvE,CAAC;CAGD,SAAS,WAA0C;EAEjD,UAAU;EACV,OAAO;CACT;;;;CAKA,eAAe,gBACb,OACA,eACA,gBACA,OACe;EACf,MAAM,YAAY,YAAY,sBAAsB;EAEpD,MAAM,QAAQ,KAAK;GACjB,MAAM;GACN,MAAM,6BAA6B;IACjC,WAAW;IACX;IACA,YAAY,cAAc,OAAO;IACjC,gBAAgB,cAAc,yBAAyB,CAAC;IACxD;IACA;GACF,CAAC;EACH,CAAC;CACH;;;;;;;;CASA,eAAe,UAAU,OAAe,OAA6B;EACnE,IAAI;GACF,MAAM,eAAe,UAAU,GAAG,OAAO,KAAK;EAChD,SAAS,cAAc;GACrB,QAAQ,YAAY,CAAC,EAAE,OAAO,uDAAuD;IACnF;IACA;IACA,OAAO,wBAAwB,QAAQ,aAAa,UAAU,OAAO,YAAY;GACnF,CAAC;EACH;CACF;;;;;;;;;;;;;;CAeA,eAAe,mBAAmB,OAA8B;EAC9D,IAAI;GACF,MAAM,oBAAoB,UAAU,GAAG,KAAK;EAC9C,SAAS,OAAO;GACd,QAAQ,YAAY,CAAC,EAAE,OAAO,yDAAyD;IACrF;IACA;IACA,OAAO,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;GAC9D,CAAC;EACH;CACF;CA8tBA,MAAM,SAAS,IAAI,MAAM;EApsBvB,IAAI,KAAK;GACP,OAAO;EACT;EAEA,IAAI,OAAO;GACT,OAAO;EACT;EAEA,IAAI,QAAQ;GACV,OAAO;EACT;EAEA,IAAI,UAAU;GACZ,OAAO;EACT;EAEA,IAAI,QAAQ;GACV,OAAO,SAAS;EAClB;EAEA,IAAI,SAAS;GACX,OAAO,UAAU;EACnB;EAEA,MAAM,OAAO,UAAU,eAA2D;GAEhF,IAAI,eAAe,WAAW;IAC5B,MAAM,EAAE,WAAW,GAAG,SAAS;IAC/B,MAAM,YAAY,OAAO,cAAc,WAAW,UAAU,YAAY,KAAA;IACxE,OAAO,0BAAmC,UAAiB,UAAU;KAAE,GAAG;KAAM;IAAU,GAAU;KAClG,eAAe;KACf,WAAW,QAAQ;IACrB,CAAC;GACH;GAeA,MAAM,EAAE,OAAO,WAAW,eAAe,eAAe,UAAU,eAAe,MAZvD,2BAAoC;IACrD;IACP;IACA,SAAS;IACT,OAAO,eAAe;IACtB,gBAAgB,eAAe;IAC/B,YAAa,eAAuB,gBAAgB;IACpD;IACA,gBAAgB;IAChB,kBAAkB;GACpB,CAAC;GAKD,cAAc,UAAU;GACxB,cAAc,YAAY;GAS1B,MAAM,kBAAkB,IAAI,gBAAgB;GAC5C,IAAI,eAAe,aAAa;IAC9B,MAAM,WAAW,cAAc;IAC/B,IAAI,SAAS,SACX,gBAAgB,MAAO,SAAgD,MAAM;SAE7E,SAAS,iBACP,eACM,gBAAgB,MAAO,SAAgD,MAAM,GACnF,EAAE,MAAM,KAAK,CACf;GAEJ;GACA,cAAc,kBAAkB;GAChC,cAAc,cAAc,gBAAgB;GAI5C,kBAAkB,IAAI,OAAO,aAAa;GAO1C,cAAc,YAAY;GAG1B,IAAI,YAAY;GAChB,MAAM,+BAA+B;IACnC,IAAI,WAAW;IACf,YAAY;IACZ,kBAAkB,OAAO,KAAK;GAChC;GAGA,MAAM,EACJ,QACA,SAAS,eACT,UACE,yBAAkC;IACpC,QAAQ,UAAU;IAClB;IACA;IACA,OAAO;KACL,SAAS,cAAc,YAAY;KACnC,UAAU,cAAc,YAAY;KACpC,SAAS;IACX;IACA;IACA;IACA,SAAS,eAAe;IACxB,cAAc,eAAe;IAC7B,UAAU,OAAM,WAAU;KACxB,IAAI;MACF,MAAM,eAAe,WAAW,MAAM;KACxC,UAAU;MACR,uBAAuB;KACzB;IACF;IACA,SAAS,OAAM,aAAY;KACzB,IAAI;MACF,MAAM,eAAe,UAAU,QAAQ;KACzC,UAAU;MACR,uBAAuB;KACzB;IACF;IACA,aAAa,eAAe;IAC5B,SAAS,OAAM,SAAQ;KACrB,IAAI;MACF,OAAO,eAAe,QAAA,GAAiE,IAAI;KAC7F,UAAU;MACR,uBAAuB;KACzB;IACF;IACA,qBAAqB,eAAe,sBAChC,OAAM,SAAQ;KACZ,MAAO,cAAc,sBAA6D,IAAI;IACxF,IACA,KAAA;IACJ,gBAAiB,gBAAwB,sBAAsB;GACjE,CAAC;GAID,MAAM,gBAAgB,cAAc;GACpC,MAAM,iBACJ,eAAe,WAAW,eAAe,KACrC;IAAE,SAAS,cAAc;IAAS,cAAc,cAAc;GAAG,IACjE,KAAA;GAMN,MAAM,oBAAoB,MACvB,WAAW,gBAAgB,OAAO,eAAe,gBAAgB,eAAe,KAAK,CAAC,CAAC,CACvF,OAAM,UAAS;IACd,UAAe,OAAO,KAAK;GAC7B,CAAC;GACH,MAAM,eAAe,kBAAkB,IAAI,KAAK;GAChD,IAAI,cACF,aAAa,oBAAoB;GAQnC,MAAM,yBAAyB,YAC7B,UACA,QACC,iBAAiB,CAAC,GACnB,MAAM,UAAU,CAClB;GAIA,MAAM,gBAAgB;IACpB,cAAc;IACd,uBAAuB;GACzB;GACA,MAAM,QAAQ,OAAO,WAAqB;IACxC,IAAI,CAAC,gBAAgB,OAAO,SAC1B,gBAAgB,MAAM,MAAM;IAG9B,MAAM,mBAAmB,KAAK;GAChC;GAiBA,OAAO;IAfL;IACA;IACA;IACA;IACA;IACA;IAEA,IAAI,aAAa;KACf,OAAO,OAAO;IAChB;KAGC,iBAAiB;GAGR;EACd;EAEA,MAAM,OAAO,OAAO,YAAY,eAA2D;GAKzF,IAAI,eAAe,WAAW;IAC5B,MAAM,EAAE,WAAW,GAAG,SAAS;IAC/B,MAAM,YAAY,OAAO,cAAc,WAAW,UAAU,YAAY,KAAA;IACxE,OAAO,gCACL,UACA,OACA,YACA;KAAE,GAAG;KAAM;IAAU,GACrB;KACE,eAAe;KACf,WAAW,QAAQ;IACrB,CACF;GACF;GAEA,MAAM,wBAAwB,kBAAkB,IAAI,KAAK;GAKzD,OAJuB,uBAAuB,kBAAA,EAIxB,YAAY,CAElC,CAAC;GACD,MAAM,eAAe,MAAM,gBAAgB,KAAK;GAMhD,MAAM,kBAAkB,IAAI,gBAAgB;GAC5C,IAAI,eAAe,aAAa;IAC9B,MAAM,WAAW,cAAc;IAC/B,IAAI,SAAS,SACX,gBAAgB,MAAO,SAAgD,MAAM;SAE7E,SAAS,iBACP,eACM,gBAAgB,MAAO,SAAgD,MAAM,GACnF,EAAE,MAAM,KAAK,CACf;GAEJ;GAMA,IAAI,gBAAgB;GACpB,IAAI,CAAC,eAAe;IAClB,gBAAgB;KAMd,eAAe;KACf,OAAO,CAAC;KACR,OAAO,KAAA;IACT;IACA,kBAAkB,IAAI,OAAO,aAAa;GAC5C;GACA,cAAc,kBAAkB;GAChC,cAAc,cAAc,gBAAgB;GAI5C,IAAI,kBAAkB;GACtB,MAAM,+BAA+B;IACnC,IAAI,iBAAiB;IACrB,kBAAkB;IAClB,kBAAkB,OAAO,KAAK;GAChC;GAGA,MAAM,EACJ,QACA,SAAS,eACT,UACE,yBAAkC;IACpC,QAAQ,UAAU;IAClB;IACA,QAAQ;IACR,WAAW,OAAO,WAAW;IAC7B,OAAO;KACL,SAAS,KAAA;KACT,UAAU,KAAA;KACV,SAAS;IACX;IACA,UAAU,eAAe;IACzB,YAAY,eAAe;IAC3B,SAAS,eAAe;IACxB,cAAc,eAAe;IAC7B,UAAU,OAAM,WAAU;KACxB,IAAI;MACF,MAAM,eAAe,WAAW,MAAM;KACxC,UAAU;MACR,uBAAuB;KACzB;IACF;IACA,SAAS,OAAM,aAAY;KACzB,IAAI;MACF,MAAM,eAAe,UAAU,QAAQ;KACzC,UAAU;MACR,uBAAuB;KACzB;IACF;IACA,aAAa,eAAe;IAC5B,SAAS,OAAM,SAAQ;KACrB,IAAI;MACF,OAAO,eAAe,QAAA,GAAiE,IAAI;KAC7F,UAAU;MACR,uBAAuB;KACzB;IACF;IACA,gBAAiB,gBAAwB,sBAAsB;GACjE,CAAC;GAKD,MAAM,YAAY,YAAY,sBAAsB;GAKpD,IAAI,eAAe;GAEnB,MAAM,WAAW,MAAM,KAAK,YAAY;IACtC,MAAM,iBAAiB,MAAM,QAAQ,WAAW,CAAC,EAAE,SAAS,WAAW;IACvE,MAAM,eAAe,YACnB,gBAAgB,qBAAqB;KAAE,cAAc,sBAAsB;KAAc;IAAM,CAAC;IAMlG,IAAI,WAAgB,MAAM,aAAa;IACvC,MAAM,WAAW,KAAK,IAAI,IAAI;IAC9B,OAAO,kBAAkB,UAAU,WAAW,eAAe,KAAK,IAAI,IAAI,UAAU;KAClF,MAAM,IAAI,SAAQ,YAAW,WAAW,SAAS,uBAAuB,CAAC;KACzE,WAAW,MAAM,aAAa;IAChC;IACA,IAAI,kBAAkB,UAAU,WAAW,aAAa;KACtD,eAAe;KACf,MAAM,IAAI,kBACR,qBAAqB,MAAM,0BACxB,UAAU,SAAS,aAAa,SAAS,OAAO,MAAM,wBAC3D;IACF;IAOA,MAAM,mBAAmB,UAAU,iBAAiB,OAAO,KAAK,SAAS,cAAc,IAAI,CAAC;IAC5F,MAAM,eAAgE,UAAU,gBAAgB,CAAC;IACjG,MAAM,aAAa,eAAe;IAElC,MAAM,oBAAoB,WAA6B;KAErD,MAAM,cADc,UAAU,WAAW,CAAC,EAAA,CAAG,OAChB,EAAE,gBAAgB,iBAAiB;KAChE,OAAO,MAAM,QAAQ,UAAU,IAAI,CAAC,QAAQ,GAAG,UAAU,IAAI,CAAC,MAAM;IACtE;IAEA,IAAI;IAEJ,IAAI,YAAY;KAGd,MAAM,eAAe,aAAa,WAAW,EAAE;KAC/C,IAAI,CAAC,cAAc;MACjB,MAAM,YAAY,OAAO,KAAK,YAAY;MAC1C,MAAM,IAAI,kBACR,qBAAqB,MAAM,oCAAoC,WAAW,QACvE,UAAU,SAAS,IAChB,4BAA4B,UAAU,KAAK,IAAI,EAAE,KACjD,yCACR;KACF;KACA,QAAQ,iBAAiB,YAAY;IACvC,OAAO;KAGL,MAAM,YAAY,OAAO,KAAK,YAAY;KAC1C,IAAI,iBAAiB,SAAS,KAAK,UAAU,SAAS,GACpD,MAAM,IAAI,kBACR,qBAAqB,MAAM,2GAExB,UAAU,SAAS,IAAI,6BAA6B,UAAU,KAAK,IAAI,EAAE,KAAK,GACnF;KAEF,QAAQ,iBAAiB,KAAK,iBAAiB,iBAAiB,EAAE,IAAI,CAAC;IACzE;IAEA,MAAM,iBAAiB,0BAA0B,UAAU,gBAAgB,eAAe,cAAc;IACxG,MAAM,iBAAiB,UAAU,iBAC7B;KACE,SAAS,SAAS,eAAe;KACjC,cAAc,SAAS,eAAe;IACxC,IACA,KAAA;IAEJ,MAAM,QAAQ,KAAK;KACjB,MAAM;KACN,MAAM,4BAA4B;MAChC,WAAW;MACX;MACA,YAAY,eAAe;MAC3B;MACA;MACA,OAAO,eAAe;MACtB,QAAQ;OACN;OACA,eAAe;OACf,YAAY,MAAM,KAAK,UAAU,iBAAiB,MAAM,MAAM,KAAA;MAChE;KACF,CAAC;IACH,CAAC;GACH,CAAC;GAID,MAAM,oBAAoB,SAAS,OAAM,UAAS;IAChD,IAAI,CAAC,cAAc,UAAe,OAAO,KAAK;GAChD,CAAC;GACD,cAAc,oBAAoB;GAMlC,IAAI;IACF,MAAM;GACR,SAAS,OAAO;IAGd,cAAc;IACd,uBAAuB;IACvB,MAAM;GACR;GAEA,MAAM,QAAQ,OAAO,WAAqB;IACxC,IAAI,CAAC,gBAAgB,OAAO,SAC1B,gBAAgB,MAAM,MAAM;IAG9B,MAAM,mBAAmB,KAAK;GAChC;GAEA,MAAM,gBAAgB;IACpB,cAAc;IACd,uBAAuB;GACzB;GAEA,OAAO;IACL;IACA,IAAI,aAAa;KACf,OAAO,OAAO;IAChB;IACA;IACA,UAAU,eAAe;IACzB,YAAY,eAAe;IAC3B;IACA;KAGC,iBAAiB;GACpB;EACF;EAEA,MAAM,QAAQ,UAAU,gBAAgB;GACtC,MAAM,cAAc,MAAM,2BAAoC;IACrD;IACP;IACA,SAAS;IACT,gBAAgB,gBAAgB;IAChC;IACA,gBAAgB;IAChB,kBAAkB;GACpB,CAAC;GAGD,YAAY,cAAc,UAAU;GACpC,YAAY,cAAc,YAAY;GAEtC,OAAO;IACL,OAAO,YAAY;IACnB,WAAW,YAAY;IACvB,eAAe,YAAY;IAC3B,UAAU,YAAY;IACtB,YAAY,YAAY;GAC1B;EACF;EAEA,MAAM,QAAQ,OAAO,gBAAgB;GAEnC,MAAM,EACJ,QACA,SAAS,eACT,UACE,yBAAkC;IACpC,QAAQ,UAAU;IAClB;IACA,WAAW,OAAO,WAAW;IAC7B,OAAO;KACL,SAAS,KAAA;KACT,UAAU,KAAA;KACV,SAAS;IACX;IACA,QAAQ,gBAAgB;IACxB,SAAS,gBAAgB;IACzB,cAAc,gBAAgB;IAC9B,UAAU,gBAAgB;IAC1B,SAAS,gBAAgB;IACzB,aAAa,gBAAgB;GAC/B,CAAC;GAED,MAAM;GAKN,MAAM,QAAQ,OAAO,YAAsB;IACzC,cAAc;IACd,MAAM,mBAAmB,KAAK;GAChC;GAEA,OAAO;IACL;IACA,IAAI,aAAa;KACf,OAAO,OAAO;IAChB;IACA;IACA,SAAS;IACT;GACF;EACF;EAEA,MAAM,SAAS,UAAU,iBAA+C;GAKtE,MAAM,EAAE,WAAW,GAAG,SAAS,mBAAmB,CAAC;GAEnD,MAAM,aAAa;IACjB,GAAG;KACF,mBAAmB;IACpB,cAAc;GAChB;GACA,MAAM,SAAS,MAAM,SAAU,OAAO,UAAU,UAAU;GAE1D,IAAI,YAAY;GAChB,IAAI;IACF,MAAM,aAAc,MAAM,OAAO,OAAO,cAAc;IACtD,IAAI,WAAW,OACb,MAAM,WAAW;IAEnB,YAAY,WAAW,iBAAiB;IAIxC,IAAI,WACF,MAAM,kBAAkB,IAAI,OAAO,KAAK,CAAC,EAAE;IAE7C,IAAI,CAAC,WAAW,OACd,WAAmC,QAAQ,OAAO;IAEpD,OAAO;GACT,UAAU;IAKR,IAAI,WAAW;KACb,MAAM,oBAAqB,OAAwD;KACnF,oBAAoB;IACtB,OACE,OAAO,QAAQ;GAEnB;EACF;EAEA,MAAM,eAAe,OAAO,YAAY,eAA6C;GAGnF,MAAM,EAAE,WAAW,GAAG,SAAS,iBAAiB,CAAC;GAEjD,MAAM,SAAS,MAAM,SAAU,OAAO,OAAO,YAAY;IACvD,GAAG;KACF,mBAAmB;GACtB,CAAuC;GAEvC,IAAI,YAAY;GAChB,IAAI;IACF,MAAM,aAAc,MAAM,OAAO,OAAO,cAAc;IACtD,IAAI,WAAW,OACb,MAAM,WAAW;IAEnB,YAAY,WAAW,iBAAiB;IACxC,IAAI,WACF,MAAM,kBAAkB,IAAI,OAAO,KAAK,CAAC,EAAE;IAE7C,IAAI,CAAC,WAAW,OACd,WAAmC,QAAQ,OAAO;IAEpD,OAAO;GACT,UAAU;IACR,IAAI,WAAW;KACb,MAAM,oBAAqB,OAAwD;KACnF,oBAAoB;IACtB,OACE,OAAO,QAAQ;GAEnB;EACF;EAEA,MAAM,aAAa,YAAY,eAAe;GAC5C,MAAM,QAAQ,eAAe;GAC7B,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,mEAAmE;GAErF,MAAM,EAAE,OAAO,QAAQ,GAAG,kBAAkB;GAM5C,QAAO,MALc,SAAU,OAAO,OAAO,YAAY;IACvD,GAAG;KAEF,mBAAmB;GACtB,CAAuC,EAAA,CACzB;EAChB;EAEA,MAAM,gBAAgB,SAAS;GAC7B,OAAO,SAAU,aAAa,EAAE,UAAU,KAAK,GAAG,OAAO;EAC3D;EAEA,MAAM,gBAAgB,SAAS;GAC7B,MAAM,EAAE,QAAQ,GAAG,kBAAkB;GACrC,OAAO,SAAU,aAAa;IAAE,UAAU;IAAO,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;GAAG,GAAG,aAAa;EAC/G;EAEA,MAAM,wBAAwB,SAAS;GACrC,MAAM,EAAE,OAAO,GAAG,kBAAkB;GACpC,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,6DAA6D;GAE/E,OAAO,SAAU,eAAe,OAAO,EAAE,UAAU,KAAK,GAAG,aAAmD;EAChH;EAEA,MAAM,wBAAwB,SAAS;GACrC,MAAM,EAAE,OAAO,QAAQ,GAAG,kBAAkB;GAC5C,IAAI,CAAC,OACH,MAAM,IAAI,MAAM,6DAA6D;GAE/E,OAAO,SAAU,eACf,OACA;IAAE,UAAU;IAAO,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,CAAC;GAAG,GAC/D,aACF;EACF;EAEA,SAAS;GAIP,MAAM,EAAE,uBAAuB,UAAU,GAAG,gBAAgB;GAC5D,OAAO,mBAA4B;IACjC,GAAG;IACH,OAAO,MAAM,OAAO;IACpB,QAAQ;IACR,OAAO;IACP;GACF,CAAC;EACH;EAEA,sBAAsB;GACpB,OAAO,CAAC,QAAQ;EAClB;EAEA,YAAY,gBAAwB;GAClC,SAAS;EAOX;CAMkC,GAAG;EACrC,IAAI,QAAQ,MAAM,UAAU;GAE1B,IAAI,QAAQ,QACV,OAAO,QAAQ,IAAI,QAAQ,MAAM,QAAQ;GAG3C,MAAM,aAAc,MAAc;GAClC,IAAI,OAAO,eAAe,YACxB,OAAO,WAAW,KAAK,KAAK;GAE9B,OAAO;EACT;EACA,IAAI,QAAQ,MAAM;GAChB,OAAO,QAAQ,UAAU,QAAQ;EACnC;CACF,CAAC;CAGD,WAAW;CAKX,MAAM,wBAAwB,MAA8C;CAC5E,OAAO;AACT;;;;AASA,SAAgB,eAAe,KAA+B;CAC5D,IAAI,CAAC,KAAK,OAAO;CACjB,OACE,OAAO,IAAI,OAAO,YAClB,OAAO,IAAI,SAAS,YACpB,WAAW,OACX,aAAa,OACb,OAAO,IAAI,WAAW,cACtB,OAAO,IAAI,wBAAwB;AAEvC;;;AC5/CA,SAAgB,wBAAwB,EACtC,QACA,WAAW,gBAAgB,CAAC,KAI3B;;;;;;CAMD,MAAM,eAAe,OAAO,OAAO,OAAO,WAAW,CAAC,CAAC,CAAC,MAAK,UAAS,eAAe,KAAK,CAAC;CAC3F,MAAM,YAAY,CAAC,GAAG,OAAO,OAAO,OAAO,cAAc,CAAC,GAAG,GAAI,cAAc,oBAAoB,KAAK,CAAC,CAAE;CAC3G,MAAM,oCAAoB,IAAI,IAAkC;CAEhE,KAAK,MAAM,YAAY,WAAW;EAChC,IAAI,EAAE,oBAAoB,kBAAkB;EAE5C,SAAS,iBAAiB,MAAM;EAChC,KAAK,MAAM,MAAM,SAAS,aAAa,GAAG;GACxC,MAAM,aAAa,GAAG,GAAG;GACzB,IAAI,CAAC,kBAAkB,IAAI,UAAU,GACnC,kBAAkB,IAAI,YAAY,EAAE;EAExC;CACF;CAEA,OAAO,CAAC,GAAG,kBAAkB,OAAO,GAAG,GAAG,aAAa;AACzD;;;;;;ACHA,SAAS,oBAAoB,EAAE,QAAQ,SAAS,WAAW,gBAAgB,CAAC,GAAG,mBAAuC;CACpH,OAAO;EACL,GAAG;EACH,QAAQ;EACR,WAAW,wBAAwB;GAAE;GAAQ,WAAW;EAAc,CAAC;CACzE;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,SAAgB,YACd,SAC2C;CAC3C,QAAQ,YAA0C;EAEhD,OAAO,QADc,oBAAoB,OACf,CAAC;CAC7B;AACF;;;;;;;;;;;;;;;AAgBA,MAAaE,UACX,YAAYC,KAAgB;;;;;;;;;;;;;;;;;;;;;;;ACvD9B,eAAsB,QAAQ,SAA+B;CAC3D,MAAM,EAAE,QAAQ,SAAS,WAAW,iBAAiB,GAAG,mBAAmB;CAC3E,MAAM,eAAe,wBAAwB;EAAE;EAAQ;CAAU,CAAC;CAElE,IAAI,aAAa,WAAW,GAC1B,QAAQ,KACN,uPAGF;CAGF,MAAM,EAAE,SAAS,kBAAkB,MAAM,OAAO;CAEhD,OAAO,cAAc;EAGnB,GAAG;EACH,GAAG;EACH,MAAM,CAAC;GAAE,QAAQ;GAAS,WAAW;EAAa,CAAC;CACrD,CAAC;AACH;;;AC1BA,MAAa,sBAAmD;;;ACehE,SAAS,kBAAkB,OAA6E;CACtG,OAAO,iBAAiB;AAC1B;;;;AAKA,SAAS,kBAAsC,OAA+C;CAC5F,OACE,OAAO,UAAU,YACjB,UAAU,QACV,cAAc,SACd,OAAO,MAAM,aAAa,cAC1B,YAAY,SACZ,OAAO,MAAM,WAAW,cACxB,oBAAoB,SACpB,OAAO,MAAM,mBAAmB,cAChC,cAAc,SACd,OAAO,MAAM,aAAa;AAE9B;AAEA,SAAS,WAAW,OAA4D;CAC9E,OAAO,iBAAiB;AAC1B;AAEA,SAAS,aAAa,OAAmE;CACvF,OACE,UAAU,QACV,OAAO,UAAU,YACjB,QAAQ,SACR,aAAa,SACb,EAAE,iBAAiB,UACnB,EAAE,iBAAiB,SACnB,EAAE,iBAAiB;AAEvB;;;;;AAMA,SAAS,YAAY,KAAgC;CACnD,OACE,QAAQ,QACR,OAAO,QAAQ,YACf,QAAQ,OACR,OAAQ,IAAY,OAAO,YAC3B,EAAE,eAAe,UACjB,EAAE,eAAe,SACjB,EAAE,eAAe,qBAChB,OAAQ,IAAY,iBAAiB,cACpC,OAAQ,IAAY,qBAAqB,cACzC,OAAQ,IAAY,wBAAwB,cAC5C,OAAQ,IAAY,wBAAwB,cAC5C,OAAQ,IAAY,sBAAsB;AAEhD;AAmIA,SAAgB,WAAW,QAAa,oBAAmE;CAMzG,IAAI,kBAAkB,MAAM,GAC1B,OAAO;CAGT,IAAI,kBAAkB,MAAM,GAC1B,OAAOC,sBAAoB,QAAQ,kBAAkB;CAGvD,IAAI,WAAW,MAAM,GACnB,OAAOC,qBAAmB,QAAQ,kBAAkB;CAKtD,IAAI,aAAa,MAAM,GACrB,OAAO,qBAAqB,MAAM;CAGpC,IAAI,YAAY,MAAM,GACpB,OAAO,wBAAwB,MAAM;CAGvC,MAAM,IAAI,MAAM,oFAAoF;AACtG;AAMA,SAAS,qBAQP,QASA;CAIA,OAAO;EACL,IAAI,OAAO;EACX,aAAa,OAAO;EACpB,aAAa,iBAAiB,OAAO,WAAW;EAChD,aAAa,OAAO,cAAc,iBAAiB,OAAO,WAAW,IAAI,KAAA;EACzE,cAAc,iBAAiB,OAAO,YAAY;EAClD,cAAc,OAAO,eAAe,iBAAiB,OAAO,YAAY,IAAI,KAAA;EAC5E,eAAe,OAAO,gBAAgB,iBAAiB,OAAO,aAAa,IAAI,KAAA;EAC/E,SAAS,OAAO;EAChB,SAAS,OAAO;EAChB,UAAU,OAAO;EACjB,SAAS,OAAO,QAAQ,KAAK,MAAM;CASrC;AACF;AAEA,SAASD,sBACP,QACA,oBAC2E;CAM3E,OAAOE,oBAAwB,QAAe,kBAAyB;AASzE;AAEA,SAASD,qBACP,QACA,oBACkF;CAGlF,OAAOE,mBAAuB,QAAe,kBAAyB;AASxE;AAEA,SAAS,wBACP,WAC2F;CAE3F,MAAM,0BAA0B,UAA8B;EAC5D,QAAQ,OAAR;GACE,KAAK,SACH,OAAO,WAAW;GACpB,KAAK,aACH,OAAO,WAAW;GACpB,KAAK;GACL,KAAK,gBACH,OAAO,WAAW;GACpB,KAAK,cACH,OAAO,WAAW;GACpB,SACE,OAAO,WAAW;EACtB;CACF;CAGA,MAAM,qBAAqB,UAA0B;EACnD,QAAQ,OAAR;GACE,KAAK,SACH,OAAO;GACT,KAAK,aACH,OAAO;GACT,KAAK,gBACH,OAAO;GACT,KAAK,gBACH,OAAO;GACT,KAAK,cACH,OAAO;GACT,SACE,OAAO;EACX;CACF;CAGA,MAAM,kBAAkB,UAA2B;EACjD,QAAQ,OAAR;GACE,KAAK,SACH,OAAO,CAAC,CAAC,UAAU;GACrB,KAAK,aACH,OAAO,CAAC,CAAC,UAAU;GACrB,KAAK,gBACH,OAAO,CAAC,CAAC,UAAU;GACrB,KAAK,gBACH,OAAO,CAAC,CAAC,UAAU;GACrB,KAAK,cACH,OAAO,CAAC,CAAC,UAAU;GACrB,SACE,OAAO;EACX;CACF;CAEA,OAAO;EACL,IAAI,aAAa,UAAU;EAC3B,aAAa,UAAU,QAAQ,aAAa,UAAU;EACtD,aAAa;EACb,cAAc;EACd,SAAS,OAAO,EAAE,WAAW,gBAAgB,qBAAqB;GAIhE,MAAM,QAAQ;GACd,MAAM,EACJ,OACA,UACA,aACA,YACA,gBACA,MACA,aACA,iBACA,QACA,cACA,WACA,MACA,YAEA,OACA,OACA,YACA,aACA,iBACA,eACA,kBACA,OACA,UACE;GAGJ,MAAM,SAAS,QAAiB,YAA6D;IAC3F,MAAM,IAAI,SAAS,UAAU,yBAAyB,UAAU,MAAM,SAAS,UAAU,EAAE;GAC7F;GAIA,IAAI,CAAC,eAAe,KAAK,GACvB,OAAO;GAKT,MAAM,cAAc,gBAAgB;GAMpC,MAAM,aACJ,UAAU,eAAe,UAAU,eAC/B,aAAa,WAAW,SAAS,UAAU,KAAK,cAChD,aAAa,WAAW,SAAS,SAAS,KAAK;GAErD,MAAM,gBACJ,UAAU,iBACN,YAAY,gBAAgB;IAC1B,MAAM,SAAS;IACf,MAAM,GAAG,kBAAkB,KAAK,EAAE,IAAI,UAAU;IAChD,YAAY,uBAAuB,KAAK;IACxC,UAAU,UAAU;IACpB,YAAY,UAAU,QAAQ,UAAU;IACxC,OAAO;KAAE;KAAO,cAAc,UAAU;IAAO;IAC/C,YAAY;KACV,mBAAmB;KAEnB,gBAAgB,UAAU;IAC5B;GACF,CAAC,IACD,KAAA;GAGN,MAAM,0BAAsD,gBACxD,EAAE,aAAa,cAAc,IAC7B;GAKJ,IAAI,iBAA0C,CAAC;GAC/C,IAAI,iBAAiB;IACnB,IAAI,KAAK,gBAAgB,IAAI,UAAU,EAAE;IACzC,IAAI,CAAC,IAAI;KACP,KAAK,IAAI,eAAe,UAAU,EAAE;KACpC,gBAAgB,IAAI,UAAU,IAAI,EAAE;IACtC;IACA,iBAAiB,GAAG;GACtB;GAIA,MAAM,cAAc;IAClB;IACA,YAAY,cAAc;IAC1B;IACA,gBAAgB;GAClB;GAIA,MAAM,cAAc;IAClB;IAGA,aACE,gBACC,MAAM,QAAQ,QAAQ,IACnB,IAAI,YAAY,CAAC,CACd,IAAI,UAA+B,OAAO,CAAC,CAC3C,UAAW,kBAAkB,CAAC,CAAmB,IACpD,KAAA;IACN;IACA;IACA;IACA,OAAO;IACP;IACA;IACA;IACA;IACA;IACA;IAEA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;GACF;GAGA,MAAM,uBAAuB,OAAU,OAAqC;IAC1E,IAAI;KACF,MAAM,SAAS,MAAM,GAAG;KACxB,eAAe,IAAI,EAAE,QAAQ,OAAO,CAAC;KACrC,OAAO;IACT,SAAS,OAAO;KAEd,IAAI,iBAAiB,UACnB,eAAe,IAAI,EAAE,QAAQ,EAAE,UAAU,MAAM,QAAQ,EAAE,CAAC;UAE1D,eAAe,MAAM;MAAS;MAAgB,SAAS;KAAK,CAAC;KAE/D,MAAM;IACR;GACF;GAGA,OAAO,qBAAqB,YAAY;IACtC,QAAQ,OAAR;KACE,KAAK;MACH,IAAI,UAAU,cAAc;OAC1B,IAAI,CAAC,YAAY,aACf,MAAM,IAAI,YAAY;QACpB,UAAU,cAAc;QACxB,QAAQ,YAAY;QACpB,IAAI;QACJ,MAAM,aAAa,UAAU,GAAG;OAClC,CAAC;OAIH,MAAM,sBAAuB,SAA+B,KAAI,MAAK,EAAE,EAAE;OACzE,MAAM,QAAQ,YAAY,YAAY,yBAAyB;OAE/D,MAAM,SAAS,MAAM,UAAU,aAAa;QAC1C,GAAG;QACO;QACV,aAAa,YAAY;QACzB,gBAAiB,kBAAkB,CAAC;QACpC,OAAO;OACT,CAAC;OAED,IAAI,kBAAkB,aAAa;QAEjC,IAAI,WAAW,YAAY,aACzB,MAAM,IAAI,YAAY;SACpB,UAAU,cAAc;SACxB,QAAQ,YAAY;SACpB,IAAI;SACJ,MAAM,aAAa,UAAU,GAAG;QAClC,CAAC;QAEH,OAAO;SACL,GAAG;SACH,UAAU,OAAO,IAAI,IAAI,GAAG;SAC5B,gBAAgB,OAAO,kBAAkB;QAC3C;OACF,OAAO,IAAI,MAAM,QAAQ,MAAM,GAAG;QAEhC,gBAAgB,2BACd,QACA,YAAY,aACZ,qBACA,OACA,OACF;QACA,OAAO;SAAE,GAAG;SAAa,UAAU;QAAO;OAC5C,OAAO,IAAI,UAAU,cAAc,UAAU,oBAAoB,QAAQ;QAEvE,MAAM,cAAc;QACpB,gBAAgB,2BACd,YAAY,UACZ,YAAY,aACZ,qBACA,OACA,OACF;QACA,YAAY,YAAY,yBAAyB,YAAY,cAAc;QAC3E,OAAO;SACL,GAAG;SACH,UAAU,YAAY;SACtB,gBAAgB,YAAY,YAAY,kBAAkB;QAC5D;OACF;OACA,OAAO;QAAE,GAAG;QAAa;OAAS;MACpC;MACA,OAAO;OAAE,GAAG;OAAa;MAAS;KAGpC,KAAK;MACH,IAAI,UAAU,kBAAkB;OAC9B,IAAI,CAAC,YAAY,aACf,MAAM,IAAI,YAAY;QACpB,UAAU,cAAc;QACxB,QAAQ,YAAY;QACpB,IAAI;QACJ,MAAM,aAAa,UAAU,GAAG;OAClC,CAAC;OAIH,MAAM,sBAAuB,SAA+B,KAAI,MAAK,EAAE,EAAE;OACzE,MAAM,QAAQ,YAAY,YAAY,yBAAyB;OAE/D,MAAM,SAAS,MAAM,UAAU,iBAAiB;QAC9C,GAAG;QACO;QACV,aAAa,YAAY;QACzB,YAAY,cAAc;QAC1B,gBAAiB,kBAAkB,CAAC;QAE7B;QACP;QACA;QACA;QACA;QACA;QACA;QACA,OAAO,SAAS,CAAC;QACjB,OAAO;OACT,CAAC;OAED,MAAM,kBAAkB,MAAM,gBAAgB,wCAAwC,QAAQ;QAC5F,aAAa,YAAY;QACzB;QACA,YAAY,cAAc;OAC5B,CAAC;OAED,IAAI,gBAAgB,UAClB,gBAAgB,2BACd,gBAAgB,UAChB,YAAY,aACZ,qBACA,KACF;OAGF,IAAI,gBAAgB,gBAClB,YAAY,YAAa,yBAAyB,gBAAgB,cAA+B;OAKnG,OAAO;QACL,GAAG;QACH;QACA,GAAG;QACH,gBAAgB,YAAY,YAAa,kBAAkB;OAC7D;MACF;MACA,OAAO;OAAE,GAAG;OAAa;MAAS;KAGpC,KAAK;MACH,IAAI,UAAU,qBAAqB;OAGjC,MAAM,UAAU,sBAAsB,UAAU;OAChD,MAAM,eAAe;OACrB,IAAI,gBAAgB,aAAa;OAIjC,IAAI,CAAC,iBAAiB,YAAY;QAEhC,gBAAgB,WAAW,gBAAgB;SACzC,MAAM,SAAS;SACf,MAAM,4BAA4B,UAAU;SAC5C,YAAY,WAAW;SACvB,UAAU,UAAU;SACpB,YAAY,UAAU,QAAQ,UAAU;SACxC,OAAO;UAAE;UAAO,aAAa,CAAC;SAAE;SAChC,YAAY;UACV,mBAAmB;UACnB,gBAAgB,UAAU;SAC5B;QACF,CAAC;QACD,aAAa,WAAW;OAC1B;OAGA,IAAI,eACF,cAAc,QAAQ;QACpB;QACA,aAAa,eAAe,CAAC;QAC7B,cAAc,eAAe,CAAC,EAAA,CAAG;OACnC;OAIF,MAAM,0BAA0B,gBAC5B,EAAE,aAAa,cAAc,IAC7B,YAAY;OAIhB,IAAI;OACJ,IAAI;QACF,SAAS,MAAM,UAAU,oBAAoB;SAC3C,GAAG;SACH,gBAAgB;SACV;SACN,aAAc,eAAe,CAAC;SAC9B,OAAO;SACP,aAAa,YAAY;QAC3B,CAAC;QAGD,IAAI,QAAS,KAAmB,SAAS,UAAU;SACjD,eAAe,IAAI,EAAE,QAAQ,OAAO,CAAC;SACrC,OAAO,aAAa;QACtB;OACF,SAAS,OAAO;QAEd,IAAI,iBAAiB,UACnB,eAAe,IAAI,EAAE,QAAQ,EAAE,UAAU,MAAM,QAAQ,EAAE,CAAC;aAE1D,eAAe,MAAM;SAAS;SAAgB,SAAS;QAAK,CAAC;QAE/D,OAAO,aAAa;QACpB,MAAM;OACR;OAEA,OAAO;QAAE,GAAG;QAAa,OAAO;QAAc,MAAM;OAAO;MAC7D;MACA,OAAO;OAAE,GAAG;OAAa;MAAK;KAGhC,KAAK;MACH,IAAI,UAAU,qBAAqB;OACjC,IAAI,CAAC,YAAY,aACf,MAAM,IAAI,YAAY;QACpB,UAAU,cAAc;QACxB,QAAQ,YAAY;QACpB,IAAI;QACJ,MAAM,aAAa,UAAU,GAAG;OAClC,CAAC;OAIH,MAAM,sBAAuB,SAA+B,KAAI,MAAK,EAAE,EAAE;OACzE,MAAM,QAAQ,YAAY,YAAY,yBAAyB;OAE/D,MAAM,eAAgB,YAAY,UAAuC;QACvE,MAAM;QACN,OAAO;SAAE,aAAa;SAAG,cAAc;SAAG,aAAa;QAAE;QACzD,cAAc;QACd,OAAO,CAAC;OACV;OAEA,MAAM,gBAAgB,MAAM,UAAU,oBAAoB;QACxD,GAAG;QACO;QACV,aAAa,YAAY;QACzB,OAAO;QACP,QAAQ;OACV,CAAC;OAED,IAAI,yBAAyB,aAAa;QAExC,IAAI,kBAAkB,YAAY,aAChC,MAAM,IAAI,YAAY;SACpB,UAAU,cAAc;SACxB,QAAQ,YAAY;SACpB,IAAI;SACJ,MAAM,aAAa,UAAU,GAAG;QAClC,CAAC;QAEH,OAAO;SACL,GAAG;SACH,UAAU,cAAc,IAAI,IAAI,GAAG;SACnC,gBAAgB,cAAc,kBAAkB;QAClD;OACF,OAAO,IAAI,MAAM,QAAQ,aAAa,GAAG;QAEvC,gBAAgB,2BACd,eACA,YAAY,aACZ,qBACA,OACA,UACF;QACA,OAAO;SAAE,GAAG;SAAa,UAAU;QAAc;OACnD,OAAO,IAAI,iBAAiB,cAAc,iBAAiB,oBAAoB,eAAe;QAE5F,MAAM,cAAc;QACpB,gBAAgB,2BACd,YAAY,UACZ,YAAY,aACZ,qBACA,OACA,UACF;QACA,YAAY,YAAY,yBAAyB,YAAY,cAAc;QAC3E,OAAO;SACL,GAAG;SACH,UAAU,YAAY;SACtB,gBAAgB,YAAY,YAAY,kBAAkB;QAC5D;OACF;OACA,OAAO;QAAE,GAAG;QAAa;OAAS;MACpC;MACA,OAAO;OAAE,GAAG;OAAa;MAAS;KAGpC,KAAK;MACH,IAAI,UAAU,mBAAmB;OAC/B,IAAI,CAAC,YAAY,aACf,MAAM,IAAI,YAAY;QACpB,UAAU,cAAc;QACxB,QAAQ,YAAY;QACpB,IAAI;QACJ,MAAM,aAAa,UAAU,GAAG;OAClC,CAAC;OAIH,MAAM,sBAAuB,SAA+B,KAAI,MAAK,EAAE,EAAE;OACzE,MAAM,QAAQ,YAAY,YAAY,yBAAyB;OAE/D,MAAM,eAAmC;QACvC,aAAa,KAAA;QACb,cAAc,KAAA;QACd,aAAa,KAAA;OACf;OACA,MAAM,SAAS,MAAM,UAAU,kBAAkB;QAC/C,GAAG;QACO;QACV,aAAa,YAAY;QACzB,YAAY,cAAc;QAC1B;QACW;QACX;QACA,OAAQ,SAAgC;QACxC,gBAAiB,kBAAkB,CAAC;QACpC,OAAO,SAAS,CAAC;QACjB,OAAO;OACT,CAAC;OAED,IAAI,kBAAkB,aAAa;QAEjC,IAAI,WAAW,YAAY,aACzB,MAAM,IAAI,YAAY;SACpB,UAAU,cAAc;SACxB,QAAQ,YAAY;SACpB,IAAI;SACJ,MAAM,aAAa,UAAU,GAAG;QAClC,CAAC;QAEH,OAAO;SACL,GAAG;SACH,UAAU,OAAO,IAAI,IAAI,GAAG;SAC5B,gBAAgB,OAAO,kBAAkB;QAC3C;OACF,OAAO,IAAI,MAAM,QAAQ,MAAM,GAAG;QAEhC,gBAAgB,2BACd,QACA,YAAY,aACZ,qBACA,OACA,UACF;QACA,OAAO;SAAE,GAAG;SAAa,UAAU;QAAO;OAC5C,OAAO,IAAI,UAAU,cAAc,UAAU,oBAAoB,QAAQ;QAEvE,MAAM,cAAc;QACpB,gBAAgB,2BACd,YAAY,UACZ,YAAY,aACZ,qBACA,OACA,UACF;QACA,YAAY,YAAY,yBAAyB,YAAY,cAAc;QAC3E,OAAO;SACL,GAAG;SACH,UAAU,YAAY;SACtB,gBAAgB,YAAY,YAAY,kBAAkB;QAC5D;OACF;OACA,OAAO;QAAE,GAAG;QAAa;OAAS;MACpC;MACA,OAAO;OAAE,GAAG;OAAa;MAAS;KAGpC,SACE,OAAO;MAAE,GAAG;MAAa;KAAS;IACtC;GACF,CAAC;EACH;EACA,WAAW;CACb;AACF;AAEA,SAAgB,KAAgC,SAAkB;CAChE,OAAO;EACL;EACA,eAcE,QAA8F;GAC9F,OAAO,IAAI,gBAST,QAAQ,OAAO;EACnB;EACA;EACA,UACE,MACA,MAC2D;GAC3D,OAAO;IACL,IAAI,KAAK;IACT,aAAa,KAAK;IAClB,aAAa,KAAK;IAClB,cAAc,KAAK;IACnB,cAAc,KAAK;IACnB,eAAe,KAAK;IACpB,aAAa,KAAK;IAClB,UAAU,KAAK;IACf,SAAS,KAAK;IACd,SAAS,KAAK;IACd,SAAS,KAAK;IACd,WAAW,KAAK;GAClB;EACF;EACA,cAgBE,UACA,MACkF;GAClF,MAAM,KAAuF,IAAI,SAAS;IACxG,IAAI,KAAK;IACT,aAAa,SAAS;IACtB,cAAc,SAAS;IACvB,OAAO,SAAS;IAChB,QAAQ,SAAS;IACjB,SAAS,SAAS;GACpB,CAAC;GAED,GAAG,YAAY,SAAS,SAAS;GACjC,GAAG,OAAO;GACV,OAAO;EACT;CACF;AACF"}