@tanstack/ai 0.53.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -13
- package/dist/esm/activities/chat/index.js +22 -4
- package/dist/esm/activities/chat/index.js.map +1 -1
- package/dist/esm/activities/chat/messages.d.ts +21 -1
- package/dist/esm/activities/chat/messages.js +50 -1
- package/dist/esm/activities/chat/messages.js.map +1 -1
- package/dist/esm/activities/chat/stream/processor.d.ts +17 -0
- package/dist/esm/activities/chat/stream/processor.js +27 -0
- package/dist/esm/activities/chat/stream/processor.js.map +1 -1
- package/dist/esm/activities/generateLiveVideo/adapter.d.ts +69 -0
- package/dist/esm/activities/generateLiveVideo/adapter.js +23 -0
- package/dist/esm/activities/generateLiveVideo/adapter.js.map +1 -0
- package/dist/esm/activities/generateLiveVideo/index.d.ts +99 -0
- package/dist/esm/activities/generateLiveVideo/index.js +162 -0
- package/dist/esm/activities/generateLiveVideo/index.js.map +1 -0
- package/dist/esm/activities/generateVideo/index.js +3 -1
- package/dist/esm/activities/generateVideo/index.js.map +1 -1
- package/dist/esm/activities/generateWorld/adapter.d.ts +69 -0
- package/dist/esm/activities/generateWorld/adapter.js +23 -0
- package/dist/esm/activities/generateWorld/adapter.js.map +1 -0
- package/dist/esm/activities/generateWorld/index.d.ts +99 -0
- package/dist/esm/activities/generateWorld/index.js +162 -0
- package/dist/esm/activities/generateWorld/index.js.map +1 -0
- package/dist/esm/activities/index.d.ts +8 -2
- package/dist/esm/activities/index.js +11 -7
- package/dist/esm/activities/middleware/types.d.ts +1 -1
- package/dist/esm/client.d.ts +4 -2
- package/dist/esm/client.js +3 -1
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.d.ts +4 -2
- package/dist/esm/index.js +3 -1
- package/dist/esm/middlewares/otel.js +3 -1
- package/dist/esm/middlewares/otel.js.map +1 -1
- package/dist/esm/types.d.ts +112 -0
- package/package.json +3 -3
- package/skills/ai-core/adapter-configuration/SKILL.md +91 -43
- package/skills/ai-core/adapter-configuration/references/anthropic-adapter.md +39 -21
- package/skills/ai-core/adapter-configuration/references/byteplus-adapter.md +5 -0
- package/skills/ai-core/adapter-configuration/references/gemini-adapter.md +14 -6
- package/skills/ai-core/adapter-configuration/references/grok-adapter.md +33 -25
- package/skills/ai-core/adapter-configuration/references/groq-adapter.md +7 -2
- package/skills/ai-core/adapter-configuration/references/ollama-adapter.md +25 -12
- package/skills/ai-core/adapter-configuration/references/openai-adapter.md +19 -9
- package/skills/ai-core/adapter-configuration/references/openrouter-adapter.md +34 -21
- package/skills/ai-core/ag-ui-protocol/SKILL.md +16 -10
- package/skills/ai-core/chat-experience/SKILL.md +228 -108
- package/skills/ai-core/client-persistence/SKILL.md +21 -9
- package/skills/ai-core/custom-backend-integration/SKILL.md +86 -52
- package/skills/ai-core/debug-logging/SKILL.md +100 -18
- package/skills/ai-core/locks/SKILL.md +35 -7
- package/skills/ai-core/media-generation/SKILL.md +136 -61
- package/skills/ai-core/middleware/SKILL.md +174 -69
- package/skills/ai-core/structured-outputs/SKILL.md +98 -49
- package/skills/ai-core/tool-calling/SKILL.md +245 -158
- package/src/activities/chat/index.ts +29 -7
- package/src/activities/chat/messages.ts +60 -0
- package/src/activities/chat/stream/processor.ts +31 -0
- package/src/activities/generateLiveVideo/adapter.ts +99 -0
- package/src/activities/generateLiveVideo/index.ts +339 -0
- package/src/activities/generateVideo/index.ts +3 -4
- package/src/activities/generateWorld/adapter.ts +96 -0
- package/src/activities/generateWorld/index.ts +339 -0
- package/src/activities/index.ts +44 -0
- package/src/activities/middleware/types.ts +2 -0
- package/src/client.ts +8 -0
- package/src/index.ts +8 -0
- package/src/middlewares/otel.ts +2 -0
- package/src/types.ts +128 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/activities/chat/index.ts"],"sourcesContent":["/**\n * Text Activity\n *\n * Handles agentic text generation, one-shot text generation, and agentic structured output.\n * This is a self-contained module with implementation, types, and JSDoc.\n */\n\nimport { devtoolsMiddleware } from '@tanstack/ai-event-client'\nimport { undoNullWidening } from '@tanstack/ai-utils'\nimport { streamToText } from '../../stream-to-response.js'\nimport { resolveDebugOption } from '../../logger/resolve'\nimport { EventType } from '../../types'\nimport {\n INTERRUPT_BINDING_METADATA_KEY,\n InterruptResumeValidationError,\n readInterruptBinding,\n readUnopenedInterruptBinding,\n validateInterruptResumeBatch,\n} from '../../interrupt-resume'\nimport { INTERRUPT_BINDING_VERSION } from '../../interrupts'\nimport {\n INTERRUPT_PAYLOAD_METADATA_KEY,\n createInterruptBinding,\n rehydrateInterruptRequest,\n} from '../../interrupt-definition'\nimport { readGenericInterruptContinuation } from '../../generic-interrupt-continuation'\nimport type {\n GenericInterruptRequest,\n InterruptDefinition,\n} from '../../interrupt-definition'\nimport {\n canonicalInterruptJson,\n digestInterruptJson,\n} from '../../interrupt-serialization'\nimport { rebuildTokenUsage } from '../../utilities/ag-ui-usage'\nimport { uiMessagesToWire } from '../../utilities/ag-ui-wire'\nimport {\n tanstackMetadata,\n withTanstackMetadata,\n} from '../../utilities/merge-metadata'\nimport { normalizeStreamChunk } from '../../utilities/normalize-stream-chunk'\nimport { restorePublicUsage } from '../../utilities/restore-inbound-chunk'\nimport type { AdapterYieldChunk } from '../../utilities/adapter-yield-chunk'\nimport { normalizeToolResult } from '../../utilities/tool-result'\nimport { isProviderExecutedToolCall } from '../../utilities/provider-executed'\nimport { LazyToolManager } from './tools/lazy-tool-manager'\nimport { assertUniqueToolNames } from './tools/unique-tool-names'\nimport {\n MiddlewareAbortError,\n ToolCallManager,\n executeToolCalls,\n} from './tools/tool-calls'\nimport {\n convertSchemaForStructuredOutput,\n convertSchemaToJsonSchema,\n isStandardSchema,\n parseWithStandardSchema,\n} from './tools/schema-converter'\nimport {\n hashSchemaInput,\n normalizeApprovalSchema,\n} from './tools/approval-schema'\nimport { maxIterations as maxIterationsStrategy } from './agent-loop-strategies'\nimport { isCancelRequestedReason } from './cancel'\nimport {\n convertMessagesToModelMessages,\n generateMessageId,\n modelMessagesToUIMessages,\n safeJsonStringify,\n} from './messages'\nimport { MiddlewareRunner } from './middleware/compose'\nimport { getRunDetached } from './middleware/run-store'\nimport { publishRunDetachedSignal } from '../../delivery-detach'\nimport { publishRunDisconnectHandler } from '../../delivery-disconnect'\nimport { provideSandboxRuntime } from './middleware/sandbox-runtime'\nimport { provideRunDisconnect } from './middleware/run-disconnect'\nimport { CapabilityRegistry } from './middleware/capabilities'\nimport { validateCapabilities } from './middleware/validate'\nimport { MCPManager } from './mcp/manager'\nimport type {\n InterruptBinding,\n InterruptSubmissionError,\n ToolApprovalResolution,\n} from '../../interrupts'\nimport type {\n ApprovalRequest,\n ClientToolRequest,\n ToolResult,\n} from './tools/tool-calls'\nimport type { ApprovalSchemaConfig } from './tools/tool-definition'\nimport type {\n AnyTextAdapter,\n StructuredOutputOptions,\n StructuredOutputResult,\n} from './adapter'\nimport type {\n AgentLoopStrategy,\n AnyTool,\n ChatStream,\n ConstrainedModelMessage,\n CustomEvent,\n InferSchemaType,\n Interrupt,\n JSONSchema,\n LazyToolsConfig,\n ModelMessage,\n ProviderTool,\n RunFinishedEvent,\n SchemaInput,\n StreamChunk,\n StructuredOutputCompleteEvent,\n StructuredOutputPart,\n StructuredOutputStream,\n TextMessageContentEvent,\n TextOptions,\n ToolCall,\n ToolCallArgsEvent,\n ReasoningEncryptedValueEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n ToolCallStartEvent,\n UIMessage,\n} from '../../types'\nimport type {\n AnyChatMiddleware,\n ChatMiddleware,\n ChatMiddlewareConfig,\n ChatMiddlewareContext,\n ChatResumeGenericResolution,\n ChatResumeToolState,\n InterruptResolutionCollection,\n SandboxFileHookEvent,\n StructuredOutputMiddlewareConfig,\n} from './middleware/types'\nimport { provideGenericInterruptDefinitionRegistry } from './middleware/generic-interrupts'\nimport type { CheckCoverage } from './middleware/builder'\nimport type { SystemPrompt } from '../../system-prompts'\nimport type { InternalLogger } from '../../logger/internal-logger'\nimport type { DebugOption } from '../../logger/types'\nimport type {\n ContextFromMiddleware,\n ContextFromTool,\n DefinedContext,\n MergeContext,\n UnionToIntersection,\n} from './runtime-context-types'\nimport type { ChatMCPOptions } from './mcp/types'\n\n// ===========================\n// Activity Kind\n// ===========================\n\n/** The adapter kind this activity handles */\nexport const kind = 'text' as const\n\ntype AnyRuntimeTool = AnyTool\ntype RuntimeToolWithApproval = AnyRuntimeTool & {\n approvalSchema?: ApprovalSchemaConfig\n}\nconst interruptBindingMetadataKey = INTERRUPT_BINDING_METADATA_KEY\n\ninterface StructuralInterruptFailure {\n error: Error\n errors: ReadonlyArray<InterruptSubmissionError>\n}\n\nfunction isInterruptSubmissionError(\n value: unknown,\n): value is InterruptSubmissionError {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n if (\n !('scope' in value) ||\n !('code' in value) ||\n !('message' in value) ||\n !('source' in value) ||\n !('retryable' in value) ||\n !('threadId' in value) ||\n !('interruptedRunId' in value) ||\n !('generation' in value) ||\n typeof value.code !== 'string' ||\n typeof value.message !== 'string' ||\n typeof value.retryable !== 'boolean' ||\n typeof value.threadId !== 'string' ||\n typeof value.interruptedRunId !== 'string' ||\n typeof value.generation !== 'number'\n ) {\n return false\n }\n if (value.scope === 'item') {\n return (\n 'interruptId' in value &&\n typeof value.interruptId === 'string' &&\n (value.source === 'client' || value.source === 'server')\n )\n }\n return (\n value.scope === 'batch' &&\n 'interruptIds' in value &&\n Array.isArray(value.interruptIds) &&\n value.interruptIds.every((id) => typeof id === 'string') &&\n (value.source === 'client' ||\n value.source === 'server' ||\n value.source === 'transport')\n )\n}\n\nfunction structuralInterruptFailure(\n error: unknown,\n): StructuralInterruptFailure | undefined {\n if (\n !(error instanceof Error) ||\n error.name !== 'InterruptResumeValidationError' ||\n !('errors' in error) ||\n !Array.isArray(error.errors) ||\n error.errors.length === 0 ||\n !error.errors.every(isInterruptSubmissionError)\n ) {\n return undefined\n }\n return {\n error,\n errors: error.errors,\n }\n}\n\nfunction normalizePublicInterruptBinding(\n value: unknown,\n expectedInterruptId: string,\n): InterruptBinding | undefined {\n return readInterruptBinding({\n id: expectedInterruptId,\n reason: '',\n metadata: { [INTERRUPT_BINDING_METADATA_KEY]: value },\n })\n}\n\n// The leaf context-inference primitives (KnownContext, MergeContext,\n// UnionToIntersection, DefinedContext, ContextFromTool, ContextFromMiddleware)\n// are shared with the tool execution layer — see ./runtime-context-types.\ntype ContextFromConsumer<T> = ContextFromTool<T> | ContextFromMiddleware<T>\n\ntype RequiredContextFromConsumerUnion<T> = T extends unknown\n ? undefined extends ContextFromConsumer<T>\n ? never\n : ContextFromConsumer<T>\n : never\n\ntype ContextFromConsumerUnion<T> = [\n UnionToIntersection<DefinedContext<ContextFromConsumer<T>>>,\n] extends [never]\n ? never\n : [RequiredContextFromConsumerUnion<T>] extends [never]\n ? UnionToIntersection<DefinedContext<ContextFromConsumer<T>>> | undefined\n : UnionToIntersection<DefinedContext<ContextFromConsumer<T>>>\n\ntype ContextFromArray<T> = T extends readonly [infer THead, ...infer TTail]\n ? MergeContext<ContextFromConsumer<THead>, ContextFromArray<TTail>>\n : T extends ReadonlyArray<infer TItem>\n ? ContextFromConsumerUnion<TItem>\n : never\n\ntype ContextFromInputs<TTools, TMiddleware> = MergeContext<\n ContextFromArray<NonNullable<TTools>>,\n ContextFromArray<NonNullable<TMiddleware>>\n>\n\ntype InferredContext<TTools, TMiddleware> = [\n ContextFromInputs<TTools, TMiddleware>,\n] extends [never]\n ? unknown\n : ContextFromInputs<TTools, TMiddleware>\n\ntype RegistryInterrupt<\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n> = [TInterrupts[number]] extends [never] ? never : TInterrupts[number]\n\ntype DuplicateInterruptDefinitionId<\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TSeenIds extends string = never,\n> = TInterrupts extends readonly [infer THead, ...infer TTail]\n ? THead extends InterruptDefinition<infer TId, any, any, any>\n ? string extends TId\n ? TTail extends ReadonlyArray<InterruptDefinition<any, any, any, any>>\n ? DuplicateInterruptDefinitionId<TTail, TSeenIds>\n : never\n : TId extends TSeenIds\n ? TId\n : TTail extends ReadonlyArray<InterruptDefinition<any, any, any, any>>\n ? DuplicateInterruptDefinitionId<TTail, TSeenIds | TId>\n : never\n : never\n : never\n\ntype CheckUniqueInterruptDefinitions<\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n> = [DuplicateInterruptDefinitionId<TInterrupts>] extends [never]\n ? unknown\n : {\n readonly '✖ Duplicate interrupt definition id in chat({ interrupts }).': never\n }\n\ntype InlineChatContext<TTools, TContext> = MergeContext<\n ContextFromArray<NonNullable<TTools>>,\n TContext\n>\n\ntype RegistryChatMiddleware<\n TContext,\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n> = ChatMiddleware<TContext, RegistryInterrupt<TInterrupts>>\n\ntype MiddlewareInterruptDefinitions<TMiddleware> =\n TMiddleware extends ReadonlyArray<infer TMiddlewareItem>\n ? TMiddlewareItem extends ChatMiddleware<any, infer TDefinitions>\n ? TDefinitions\n : never\n : never\n\ntype IsAny<TValue> = 0 extends 1 & TValue ? true : false\n\ntype CheckInterruptRegistry<\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TMiddleware,\n> =\n IsAny<MiddlewareInterruptDefinitions<TMiddleware>> extends true\n ? unknown\n : [MiddlewareInterruptDefinitions<TMiddleware>] extends [never]\n ? unknown\n : [\n Exclude<\n MiddlewareInterruptDefinitions<TMiddleware>,\n RegistryInterrupt<TInterrupts>\n >,\n ] extends [never]\n ? unknown\n : {\n readonly '✖ Middleware emits an interrupt definition that is not registered in chat({ interrupts }).': never\n }\n\ntype RuntimeContextOption<TTools, TMiddleware, TContext> = [\n MergeContext<ContextFromInputs<TTools, TMiddleware>, TContext>,\n] extends [never]\n ? { context?: TContext }\n : undefined extends MergeContext<\n ContextFromInputs<TTools, TMiddleware>,\n TContext\n >\n ? {\n context?: MergeContext<ContextFromInputs<TTools, TMiddleware>, TContext>\n }\n : {\n context: MergeContext<ContextFromInputs<TTools, TMiddleware>, TContext>\n }\n\ntype ExactMiddlewareOption<\n TTools,\n TContext,\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TMiddleware extends Array<unknown> | undefined,\n> = [TMiddleware] extends [undefined]\n ? Array<\n RegistryChatMiddleware<\n InlineChatContext<TTools, TContext>,\n NoInfer<TInterrupts>\n >\n >\n : TMiddleware &\n (TMiddleware extends Array<\n RegistryChatMiddleware<\n InlineChatContext<TTools, NoInfer<TContext>>,\n NoInfer<TInterrupts>\n >\n >\n ? Array<\n RegistryChatMiddleware<\n InlineChatContext<TTools, TContext>,\n NoInfer<TInterrupts>\n >\n >\n : CheckInterruptRegistry<TInterrupts, TMiddleware>) &\n CheckCoverage<Extract<TMiddleware, ReadonlyArray<AnyChatMiddleware>>>\n\ntype TextActivityOptionsWithContext<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined,\n TStream extends boolean,\n TTools extends TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'],\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =\n [],\n TContext = unknown,\n TMiddleware extends Array<unknown> | undefined = undefined,\n> = Omit<\n TextActivityOptions<TAdapter, TSchema, TStream, any>,\n 'tools' | 'middleware' | 'context' | 'interrupts'\n> & {\n tools?: TTools\n interrupts?: TInterrupts & CheckUniqueInterruptDefinitions<TInterrupts>\n middleware?: ExactMiddlewareOption<TTools, TContext, TInterrupts, TMiddleware>\n} & RuntimeContextOption<TTools, TMiddleware, TContext>\n\n// ===========================\n// Activity Options Type\n// ===========================\n\n/**\n * Options for the text activity.\n * Types are extracted directly from the adapter (which has pre-resolved generics).\n *\n * @template TAdapter - The text adapter type (created by a provider function)\n * @template TSchema - Optional Standard Schema for structured output\n * @template TStream - Whether to stream the output (default: true)\n * @template TContext - Runtime context value threaded to middleware hooks and server tools\n */\nexport interface TextActivityOptions<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined,\n TStream extends boolean,\n TContext = unknown,\n> {\n /** The text adapter to use (created by a provider function like openaiText('gpt-5.5')) */\n adapter: TAdapter\n /**\n * Conversation messages. Accepts:\n * - `ConstrainedModelMessage` — content types constrained by the adapter's input modalities.\n * - `ModelMessage` — unconstrained model message (e.g., forwarded from an AG-UI wire payload).\n * - `UIMessage` — parts-based UI representation; converted internally via `convertMessagesToModelMessages`.\n *\n * The three shapes can be mixed in a single array (e.g., when forwarding a wire payload that includes both anchor UIMessages and AG-UI fan-out ModelMessages).\n */\n messages?:\n | Array<\n | UIMessage\n | ModelMessage\n | ConstrainedModelMessage<{\n inputModalities: TAdapter['~types']['inputModalities']\n messageMetadataByModality: TAdapter['~types']['messageMetadataByModality']\n }>\n >\n | undefined\n /**\n * System prompts to prepend to the conversation.\n *\n * Accepts plain strings or `{ content, metadata }` objects. The `metadata`\n * field is typed by the adapter — Anthropic narrows it to\n * `AnthropicSystemPromptMetadata` (with `cache_control` for prompt\n * caching), providers without per-prompt metadata reject the field\n * entirely.\n */\n systemPrompts?:\n | Array<SystemPrompt<TAdapter['~types']['systemPromptMetadata']>>\n | undefined\n /**\n * Tools for function calling (auto-executed when called).\n *\n * Accepts two shapes:\n * - User-defined tools via `toolDefinition()` — plain `Tool`, always assignable.\n * - Provider tools from `@tanstack/ai-<provider>/tools` (e.g. `webSearchTool`)\n * — branded and type-checked against the selected model's\n * `supports.tools` list. Passing an unsupported tool produces a\n * compile-time error on the array element.\n */\n tools?:\n | ReadonlyArray<\n | (AnyRuntimeTool & { readonly '~toolKind'?: never })\n | ProviderTool<string, TAdapter['~types']['toolCapabilities'][number]>\n >\n | undefined\n /**\n * Hand MCP clients/pools to chat(): their tools are discovered at run start\n * and merged into the run; `connection` controls whether chat() closes them\n * when the run ends. See docs/tools/mcp.md \"Managing MCP clients with chat()\".\n */\n mcp?: ChatMCPOptions\n /** Additional metadata to attach to the request. */\n metadata?: TextOptions['metadata']\n /** Model-specific provider options (type comes from adapter) */\n modelOptions?: TAdapter['~types']['providerOptions']\n /** AbortController for cancellation */\n abortController?: TextOptions['abortController']\n /** Strategy for controlling the agent loop */\n agentLoopStrategy?: TextOptions['agentLoopStrategy']\n /**\n * Optional configuration for lazy-tool discovery (tools marked `lazy: true`).\n * Tunes how much of each lazy tool's description appears in the discovery\n * catalog. Optional — defaults to `{ includeDescription: 'none' }`.\n */\n lazyToolsConfig?: LazyToolsConfig\n /** Unique conversation identifier for tracking */\n conversationId?: TextOptions['conversationId']\n /** Thread/conversation ID for AG-UI protocol. Auto-generated if not provided. */\n threadId?: TextOptions['threadId']\n /** Run ID override for AG-UI protocol. Auto-generated by adapter if not provided. */\n runId?: TextOptions['runId']\n /** Parent run ID for AG-UI protocol nested run correlation. */\n parentRunId?: TextOptions['parentRunId']\n /** Application state mirrored in a STATE_SNAPSHOT before an interrupt terminal. */\n state?: TextOptions['state']\n /**\n * AG-UI interrupt resume responses. Persistence middleware validates these\n * before accepting new input on a thread with pending interrupts.\n */\n resume?: TextOptions['resume']\n /**\n * Optional Standard Schema for structured output.\n * When provided, the activity will:\n * 1. Run the full agentic loop (executing tools as needed)\n * 2. Once complete, return a Promise with the parsed output matching the schema\n *\n * Supports any Standard Schema compliant library (Zod v4+, ArkType, Valibot, etc.)\n *\n * @example\n * ```ts\n * const result = await chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Generate a person' }],\n * outputSchema: z.object({ name: z.string(), age: z.number() })\n * })\n * // result is { name: string, age: number }\n * ```\n */\n outputSchema?: TSchema\n /**\n * Whether to stream the text result.\n * When true (default), returns a ChatStream for streaming output.\n * When false, returns a Promise<string> with the collected text content.\n *\n * Note: If outputSchema is provided, this option is ignored and the result\n * is always a Promise<InferSchemaType<TSchema>>.\n *\n * @default true\n *\n * @example Non-streaming text\n * ```ts\n * const text = await chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Hello!' }],\n * stream: false\n * })\n * // text is a string with the full response\n * ```\n */\n stream?: TStream\n /**\n * Optional middleware array for observing/transforming chat behavior.\n * Middleware hooks are called in array order. See {@link ChatMiddleware} for available hooks.\n *\n * @example\n * ```ts\n * const stream = chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [...],\n * middleware: [loggingMiddleware, redactionMiddleware],\n * })\n * ```\n */\n middleware?: Array<ChatMiddleware<TContext>>\n /**\n * First-party generic interrupt definitions for this chat call.\n * Register the same definitions on the client to type payloads and answers.\n */\n interrupts?: ReadonlyArray<InterruptDefinition<any, any, any, any>>\n /**\n * Runtime context value passed to middleware hooks and server tools.\n */\n context?: TContext\n /**\n * Enable debug logging. Pass `true` to enable all categories with the default\n * console logger, `false` to silence everything, or a `DebugConfig` object for\n * granular control and/or a custom `Logger`. Defaults to `undefined`, which\n * means only the `errors` category is active.\n */\n debug?: DebugOption\n}\n\n// ===========================\n// Chat Options Helper\n// ===========================\n\n/**\n * Create typed options for the chat() function without executing.\n * This is useful for pre-defining configurations with full type inference.\n *\n * @example\n * ```ts\n * const chatOptions = createChatOptions({\n * adapter: anthropicText('claude-sonnet-4-5'),\n * })\n *\n * const stream = chat({ ...chatOptions, messages })\n * ```\n */\nexport function createChatOptions<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined = undefined,\n TStream extends boolean = true,\n const TTools extends TextActivityOptions<\n TAdapter,\n TSchema,\n TStream,\n any\n >['tools'] = TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'],\n const TInterrupts extends ReadonlyArray<\n InterruptDefinition<any, any, any, any>\n > = [],\n TContext = unknown,\n const TMiddleware extends Array<unknown> | undefined = undefined,\n>(\n options: TextActivityOptionsWithContext<\n TAdapter,\n TSchema,\n TStream,\n TTools,\n TInterrupts,\n TContext,\n TMiddleware\n >,\n): Omit<\n TextActivityOptions<\n TAdapter,\n TSchema,\n TStream,\n InferredContext<TTools, TMiddleware>\n >,\n 'tools' | 'middleware' | 'interrupts' | 'context'\n> & {\n tools?: TTools\n interrupts?: TInterrupts\n middleware?: ExactMiddlewareOption<TTools, TContext, TInterrupts, TMiddleware>\n} & RuntimeContextOption<TTools, TMiddleware, TContext> {\n return options\n}\n\n// ===========================\n// Activity Result Type\n// ===========================\n\n/**\n * Result type for the text activity.\n * - If outputSchema is provided AND stream is explicitly true:\n * StructuredOutputStream<InferSchemaType<TSchema>> — yields raw JSON deltas\n * via TEXT_MESSAGE_CONTENT plus a terminal StructuredOutputCompleteEvent\n * carrying the validated object.\n * - If outputSchema is provided without explicit stream:true:\n * Promise<InferSchemaType<TSchema>>.\n * - If stream is explicitly false (no schema): Promise<string>.\n * - Otherwise (default): ChatStream.\n *\n * `[TStream] extends [true]` is used (not `TStream extends true`) so that the\n * default `boolean` value of `TStream` does *not* match the streaming branch.\n * Without this, plain `chat({ outputSchema })` would type as a stream while\n * the runtime returns a Promise — see issue #526.\n */\nexport type TextActivityResult<\n TSchema extends SchemaInput | undefined,\n TStream extends boolean = boolean,\n // Unconstrained so `chat()` can forward its inferred `options['tools']` type\n // (which may be `undefined` or the broad `AnyRuntimeTool | ProviderTool`\n // array) directly; non-tool-array inputs normalize to the default below.\n TTools = ReadonlyArray<AnyTool>,\n> = TSchema extends SchemaInput\n ? [TStream] extends [true]\n ? StructuredOutputStream<InferSchemaType<TSchema>>\n : Promise<InferSchemaType<TSchema>>\n : [TStream] extends [false]\n ? Promise<string>\n : TTools extends infer _TTools\n ? ChatStream\n : ChatStream\n\n// ===========================\n// ChatEngine Implementation\n// ===========================\n\ninterface TextEngineConfig<\n TAdapter extends AnyTextAdapter,\n TContext = unknown,\n TParams extends TextOptions<any, any, TContext> = TextOptions<\n any,\n any,\n TContext\n >,\n> {\n adapter: TAdapter\n systemPrompts?: Array<SystemPrompt>\n params: TParams\n middleware?: Array<AnyChatMiddleware>\n context?: TContext\n /**\n * If set, after the agent loop finishes the engine runs a\n * structured-output finalization step through the same middleware\n * pipeline. See `runStructuredFinalization` for the flow.\n *\n * - jsonSchema: the JSON Schema to send to the provider\n * - yieldChunks: when true, finalization chunks are yielded to the caller\n * (used by runStreamingStructuredOutput). When false, chunks are\n * consumed internally for middleware visibility but not yielded\n * (used by runAgenticStructuredOutput).\n * - normalize: optional schema-aware transform applied to the captured\n * structured-output object the moment it enters the engine — BEFORE it is\n * stored, validated, or yielded. Used to undo strict-mode null-widening\n * (`undoNullWidening`): strict schemas widen optional fields to\n * `required` + nullable so the provider returns `null` for an absent\n * optional, and this strips exactly those synthesized nulls while keeping\n * the ones a `.nullable()` field genuinely allows. Applied here (not in\n * the adapter) because the engine is the only layer holding the original\n * schema's null-widening map, and applying it at capture fixes BOTH the\n * streaming chunk and the Promise<T> result with one transform.\n * - validate: optional callback invoked AFTER `normalize` and AFTER the\n * structured-output result is captured, but BEFORE the terminal hook\n * fires. If it throws, the engine records a `finalizationError` and fires\n * `onError` instead of `onFinish` (per spec §7.3). On success, the\n * returned value is stored as the validated result and retrievable via\n * `getValidatedStructuredOutput()`. Used by `runAgenticStructuredOutput`\n * to perform Standard Schema validation inside the engine.\n * - nativeCombined: when true, the adapter declared\n * `supportsCombinedToolsAndSchema()` and the engine wires `jsonSchema`\n * into the regular `chatStream` call instead of running a separate\n * finalization round-trip. The `'structuredOutput'` middleware phase\n * does NOT fire on this path — middleware sees the run through\n * `beforeModel` / `modelStream` as usual.\n * - source: how to take the combined object. `'text'` (default) parses\n * accumulated assistant text. `'event'` reads an adapter-emitted\n * `structured-output.complete` and does not parse prose.\n */\n finalStructuredOutput?: {\n jsonSchema: JSONSchema\n yieldChunks: boolean\n normalize?: (data: unknown) => unknown\n validate?: (data: unknown) => unknown\n nativeCombined?: boolean\n source?: 'text' | 'event'\n }\n}\n\ntype ToolPhaseResult = 'continue' | 'stop' | 'wait'\ntype CyclePhase = 'processText' | 'executeToolCalls'\n\n/**\n * Combine two optional AbortSignals into one that aborts when either does.\n * Returns the other signal directly when one is absent or already aborted.\n * (Manual implementation — `AbortSignal.any` requires Node >= 20.3.)\n */\nfunction combineAbortSignals(\n a: AbortSignal | undefined,\n b: AbortSignal | undefined,\n): AbortSignal | undefined {\n if (!a) return b\n if (!b) return a\n if (a.aborted) return a\n if (b.aborted) return b\n const controller = new AbortController()\n const onAbort = (source: AbortSignal) => () => {\n controller.abort(source.reason)\n }\n a.addEventListener('abort', onAbort(a), { once: true })\n b.addEventListener('abort', onAbort(b), { once: true })\n return controller.signal\n}\n\nclass TextEngine<\n TAdapter extends AnyTextAdapter,\n TContext = unknown,\n TParams extends TextOptions<any, any, TContext> = TextOptions<\n any,\n any,\n TContext\n >,\n> {\n private readonly adapter: TAdapter\n private readonly interruptDefinitions: ReadonlyMap<\n string,\n InterruptDefinition<any, any, any, any>\n >\n private params: TParams\n private systemPrompts: Array<SystemPrompt>\n private tools: Array<AnyRuntimeTool>\n private readonly loopStrategy: AgentLoopStrategy\n private toolCallManager: ToolCallManager<ReadonlyArray<AnyTool>, TContext>\n private readonly lazyToolManager: LazyToolManager\n /** A public interruption terminal must always have this run's start event. */\n private hasPublicRunStarted = false\n private readonly initialMessageCount: number\n private readonly requestId: string\n private readonly streamId: string\n private readonly effectiveRequest?: Request | RequestInit\n private readonly effectiveSignal?: AbortSignal\n\n private messages: Array<ModelMessage>\n private providerMessages: Array<ModelMessage>\n private iterationCount = 0\n /** Cumulative tool calls counted in this run (emitted + pending resume). */\n private toolCallCount = 0\n /** Tool calls in the most recent budgeted batch (0 when none). */\n private lastTurnToolCallCount = 0\n /** Tool call IDs already counted toward `toolCallCount` (avoids double-count on resume). */\n private readonly countedToolCallIds = new Set<string>()\n private lastFinishReason: string | null = null\n private streamStartTime = 0\n private totalChunkCount = 0\n private currentMessageId: string | null = null\n private currentMessageCreatedAt: Date | null = null\n private streamIdentityCaptured = false\n private accumulatedContent = ''\n private accumulatedThinking: Array<{ content: string; signature?: string }> =\n []\n private currentThinkingContent = ''\n private currentThinkingSignature = ''\n private eventOptions?: Record<string, unknown> | undefined\n private eventToolNames?: Array<string>\n private finishedEvent: RunFinishedEvent | null = null\n private readonly streamedToolErrorResults = new Map<string, ToolResult>()\n private deferredToolCallRunFinishedChunks: Array<StreamChunk> = []\n /** The model terminal is held until afterModel can choose an interrupt. */\n private deferredModelRunFinishedChunks: Array<StreamChunk> = []\n\n private earlyTermination = false\n private toolPhase: ToolPhaseResult = 'continue'\n private cyclePhase: CyclePhase = 'processText'\n // Client state extracted from initial messages (before conversion to ModelMessage)\n private readonly initialApprovals: Map<string, ToolApprovalResolution>\n private readonly initialClientToolResults: Map<string, any>\n private readonly resumeApprovals = new Map<string, ToolApprovalResolution>()\n private readonly resumeClientToolResults = new Map<string, any>()\n private readonly resumeDeniedToolResults = new Map<string, unknown>()\n private readonly resumeCancelledToolCallIds = new Set<string>()\n private readonly resumeGenericInterrupts = new Map<\n string,\n ChatResumeGenericResolution\n >()\n private readonly resumeGenericInterruptRequests = new Map<\n string,\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n >()\n\n // AG-UI protocol IDs\n private readonly threadId: string\n private readonly runIdOverride?: string\n private readonly parentRunIdOverride?: string\n\n // Middleware support\n private readonly middlewareRunner: MiddlewareRunner<\n TContext,\n InterruptDefinition<any, any, any, any>\n >\n private readonly middlewareCtx: ChatMiddlewareContext<TContext>\n private readonly sandboxFileQueue: Array<StreamChunk> = []\n private readonly middlewareCustomQueue: Array<StreamChunk> = []\n private middlewareCustomWaiters: Array<() => void> = []\n private drainingMiddlewareCustom = false\n private readonly deferredPromises: Array<Promise<unknown>> = []\n private abortReason?: string\n private readonly middlewareAbortController?: AbortController\n // Combines the caller's signal with middleware abort() so running tools\n // observe both cancellation sources via ctx.abortSignal.\n private readonly toolAbortSignal?: AbortSignal\n private terminalHookCalled = false\n /**\n * Latched the first time the delivery socket closes; see `notifyDisconnected`.\n * Also read by `subscribe` so a listener registered AFTER the disconnect (a\n * middleware whose `setup` was still running at the time — the common case) is\n * called immediately rather than never.\n */\n private disconnected = false\n private readonly disconnectListeners: Array<() => void | Promise<void>> = []\n\n private readonly logger: InternalLogger\n\n // Structured-output finalization state (populated by runStructuredFinalization)\n private structuredOutputResult: {\n data: unknown\n rawText: string\n reasoning?: string\n } | null = null\n private structuredOutputMessageId: string | null = null\n private structuredOutputMessageCreatedAt: Date | null = null\n // Native combined mode: tracks whether we've already emitted the synthetic\n // `structured-output.start` event before the schema-constrained final-turn\n // text begins streaming. The event must precede the first\n // TEXT_MESSAGE_START so the client-side StreamProcessor routes the JSON\n // deltas into a StructuredOutputPart instead of a plain TextPart.\n private combinedStartEmitted = false\n // Native combined mode: messageId we want the synthetic\n // `structured-output.start` (and any error emitted before deltas arrive)\n // to carry, so the client matches it to the streaming text deltas.\n private combinedStructuredMessageId: string | null = null\n // Holds the validated value when `finalStructuredOutput.validate` is provided\n // and succeeds. Distinct from `structuredOutputResult.data` (the normalized\n // but unvalidated payload from the structured-output.complete chunk).\n private validatedStructuredOutput: unknown = undefined\n private hasValidatedStructuredOutput = false\n private finalizationError: {\n message: string\n code?: string\n cause?: unknown\n } | null = null\n private combinedCompleteEmitted = false\n private readonly finalStructuredOutput?: {\n jsonSchema: JSONSchema\n yieldChunks: boolean\n normalize?: (data: unknown) => unknown\n validate?: (data: unknown) => unknown\n nativeCombined?: boolean\n source?: 'text' | 'event'\n }\n\n constructor(\n config: TextEngineConfig<TAdapter, TContext, TParams>,\n logger: InternalLogger,\n ) {\n this.logger = logger\n this.adapter = config.adapter\n this.interruptDefinitions = new Map(\n (\n (\n config.params as TParams & {\n interrupts?: ReadonlyArray<InterruptDefinition<any, any, any, any>>\n }\n ).interrupts ?? []\n ).map((definition) => [definition.id, definition]),\n )\n this.finalStructuredOutput = config.finalStructuredOutput\n this.params = config.params\n this.systemPrompts = config.params.systemPrompts || []\n this.loopStrategy =\n config.params.agentLoopStrategy || maxIterationsStrategy(5)\n this.initialMessageCount = config.params.messages.length\n\n // Extract client state (approvals, client tool results) from original messages BEFORE conversion\n // This preserves UIMessage parts data that would be lost during conversion to ModelMessage\n const { approvals, clientToolResults } =\n this.extractClientStateFromOriginalMessages(\n config.params.messages as Array<any>,\n )\n this.initialApprovals = approvals\n this.initialClientToolResults = clientToolResults\n\n // Convert messages to ModelMessage format (handles both UIMessage and ModelMessage input)\n // This ensures consistent internal format regardless of what the client sends\n this.messages = convertMessagesToModelMessages(config.params.messages)\n this.providerMessages = this.messages\n\n // Initialize lazy tool manager after messages are converted (needs message history for scanning)\n assertUniqueToolNames(config.params.tools || [])\n this.lazyToolManager = new LazyToolManager(\n config.params.tools || [],\n this.messages,\n config.params.lazyToolsConfig,\n )\n this.tools = this.lazyToolManager.getActiveTools()\n this.toolCallManager = new ToolCallManager<\n ReadonlyArray<AnyTool>,\n TContext\n >(this.tools)\n this.requestId = this.createId('chat')\n this.streamId = this.createId('stream')\n this.effectiveRequest = config.params.abortController\n ? { signal: config.params.abortController.signal }\n : undefined\n this.effectiveSignal = config.params.abortController?.signal\n // `conversationId` is the legacy alias of `threadId` — accept it\n // as a fallback so `chat({ conversationId })` keeps working, with\n // explicit `threadId` winning when both are set.\n this.threadId =\n config.params.threadId ||\n config.params.conversationId ||\n this.createId('thread')\n this.runIdOverride = config.params.runId\n this.parentRunIdOverride = config.params.parentRunId\n\n // Initialize middleware — devtools first. Spec stripping for the AG-UI\n // wire happens in toServerSentEventsStream, so in-process chat()\n // consumers still see TokenUsage and tool aliases.\n const allMiddleware: Array<\n ChatMiddleware<TContext, InterruptDefinition<any, any, any, any>>\n > = [devtoolsMiddleware(), ...(config.middleware || [])]\n this.middlewareRunner = new MiddlewareRunner(allMiddleware, logger)\n this.middlewareAbortController = new AbortController()\n this.toolAbortSignal = combineAbortSignals(\n this.effectiveSignal,\n this.middlewareAbortController.signal,\n )\n this.middlewareCtx = {\n requestId: this.requestId,\n streamId: this.streamId,\n runId: this.runIdOverride ?? this.requestId,\n parentRunId: this.parentRunIdOverride,\n threadId: this.threadId,\n // Legacy alias kept on the ctx so middleware that reads\n // `ctx.conversationId` keeps working. Always equals `threadId`.\n conversationId: this.threadId,\n phase: 'init',\n iteration: 0,\n chunkIndex: 0,\n signal: this.effectiveSignal,\n abort: (reason?: string) => {\n this.abortReason = reason\n this.middlewareAbortController?.abort(reason)\n },\n emitCustomEvent: (name, value) => {\n this.middlewareCustomQueue.push(\n this.createCustomEventChunk(name, value),\n )\n const waiters = this.middlewareCustomWaiters\n this.middlewareCustomWaiters = []\n for (const waiter of waiters) waiter()\n },\n context: config.context as TContext,\n defer: (promise: Promise<unknown>) => {\n this.deferredPromises.push(promise)\n },\n // Provider / adapter info\n activity: 'chat',\n provider: config.adapter.name,\n model: config.params.model,\n source: 'server',\n streaming: true,\n // Config-derived (updated in beforeRun and applyMiddlewareConfig)\n systemPrompts: this.systemPrompts,\n toolNames: undefined,\n options: undefined,\n modelOptions: config.params.modelOptions,\n // Computed\n messageCount: this.initialMessageCount,\n hasTools: this.tools.length > 0,\n // Mutable per-iteration\n currentMessageId: null,\n accumulatedContent: '',\n // References\n messages: this.messages,\n createId: (prefix: string) => this.createId(prefix),\n // Capability bookkeeping for this request (populated by middleware setup)\n capabilities: new CapabilityRegistry(),\n // Convenience accessors that delegate to a capability handle's own\n // tuple getter/provider, keyed by this context. `getX(ctx)` and\n // `ctx.get(X)` are interchangeable.\n get: (capability) => capability[0](this.middlewareCtx),\n getOptional: (capability) =>\n capability[0](this.middlewareCtx, { optional: true }),\n provide: (capability, value) => capability[1](this.middlewareCtx, value),\n }\n\n // Provide the internal RunDisconnect capability BEFORE `setup` runs, so a\n // middleware can subscribe from inside its own `setup` — which is where the\n // subscription has to happen, because `setup` is the long await the common\n // disconnect lands in.\n //\n // `subscribe` calls back IMMEDIATELY when the socket has already closed. That\n // ordering is load-bearing rather than defensive: a middleware whose `setup`\n // was still running during the disconnect would otherwise register a listener\n // for an event that has already been and gone, and silently never detach.\n provideRunDisconnect(this.middlewareCtx, {\n subscribe: (listener) => {\n this.disconnectListeners.push(listener)\n if (this.disconnected) this.runDisconnectListener(listener)\n },\n })\n\n provideGenericInterruptDefinitionRegistry(this.middlewareCtx, {\n definitions: this.interruptDefinitions,\n })\n\n // Provide the internal SandboxRuntime capability so harness adapters and\n // sandbox middleware can emit file events. The sink logs, fans the event\n // out through the middleware `onFile*` hooks (fire-and-forget), and queues\n // a `sandbox.file` custom chunk to be drained into the public stream.\n provideSandboxRuntime(this.middlewareCtx, {\n logger: this.logger,\n emit: (event: SandboxFileHookEvent) => {\n this.logger.sandbox(`file ${event.type} ${event.path}`, {\n event: {\n type: event.type,\n path: event.path,\n timestamp: event.timestamp,\n },\n })\n void this.middlewareRunner\n .runSandboxFile(this.middlewareCtx, event)\n .catch((err: unknown) => {\n this.logger.errors('sandbox file hook failed', { error: err })\n })\n this.sandboxFileQueue.push(\n this.createCustomEventChunk('sandbox.file', {\n type: event.type,\n path: event.path,\n timestamp: event.timestamp,\n }),\n )\n },\n emitFileDiff: (value: { path: string; diff: string }) => {\n this.sandboxFileQueue.push(\n this.createCustomEventChunk('sandbox.file.diff', value),\n )\n },\n })\n }\n\n /** Get the accumulated content after the chat loop completes */\n getAccumulatedContent(): string {\n return this.accumulatedContent\n }\n\n /** Get the final messages array after the chat loop completes */\n getMessages(): Array<ModelMessage> {\n return this.messages\n }\n\n /** Returns the structured-output result if finalization ran successfully. */\n getStructuredOutputResult(): { data: unknown; rawText: string } | null {\n return this.structuredOutputResult\n }\n\n /**\n * Returns the validated structured-output value (the result of running\n * `finalStructuredOutput.validate` against the raw structured-output data)\n * wrapped in a `{ value }` object so callers can distinguish \"no validation\n * happened\" from \"validation produced undefined\". Returns `null` when no\n * validator was configured or validation hasn't been performed yet.\n */\n getValidatedStructuredOutput(): { value: unknown } | null {\n return this.hasValidatedStructuredOutput\n ? { value: this.validatedStructuredOutput }\n : null\n }\n\n /** Returns the recorded finalization error, if any. */\n getFinalizationError(): {\n message: string\n code?: string\n cause?: unknown\n } | null {\n return this.finalizationError\n }\n\n async *run(): AsyncGenerator<StreamChunk> {\n this.beforeRun()\n this.logger.agentLoop('run started', {\n threadId: this.middlewareCtx.threadId,\n })\n\n try {\n // Provision capabilities before any consumer (onConfig onward) can read them\n yield* this.runWhileYielding(\n this.middlewareRunner.runSetup(this.middlewareCtx),\n )\n\n // Run initial onConfig (phase = init)\n this.middlewareCtx.phase = 'init'\n const initialConfig = this.buildMiddlewareConfig()\n const transformedConfig = yield* this.runWhileYielding(\n this.middlewareRunner.runOnConfig(this.middlewareCtx, initialConfig),\n )\n this.applyMiddlewareConfig(transformedConfig)\n await this.applyEphemeralInterruptResume(transformedConfig)\n await this.applyDurableGenericInterruptResolution()\n\n // Run onStart (devtools middleware emits text:request:started and initial messages here)\n yield* this.runWhileYielding(\n this.middlewareRunner.runOnStart(this.middlewareCtx),\n )\n\n if (this.earlyTermination) {\n yield* this.emitSuccessfulEarlyTermination()\n if (!this.terminalHookCalled) {\n this.terminalHookCalled = true\n await this.middlewareRunner.runOnFinish(this.middlewareCtx, {\n finishReason: this.lastFinishReason,\n duration: Date.now() - this.streamStartTime,\n content: this.accumulatedContent,\n usage: rebuildTokenUsage(\n this.finishedEvent?.usage,\n tanstackMetadata(this.finishedEvent ?? undefined)?.usage,\n ),\n })\n }\n return\n }\n\n const pendingPhase = yield* this.checkForPendingToolCalls()\n if (pendingPhase === 'wait') {\n return\n }\n\n // Skip the agent loop entirely when there are no tools AND a separate\n // structured-output finalization will run. Without tools the model has\n // nothing to do in the loop, so executing one iteration would burn an\n // extra provider call before the finalization request.\n //\n // Native combined mode does NOT skip — the agent loop itself produces\n // the schema-constrained final answer in one pass (model emits the\n // schema-constrained text on its natural final turn). Even with zero\n // tools, the single chatStream call IS the structured-output call.\n const skipAgentLoop =\n !!this.finalStructuredOutput &&\n this.tools.length === 0 &&\n this.finalStructuredOutput.nativeCombined !== true\n\n if (!skipAgentLoop) {\n do {\n if (this.earlyTermination) break\n if (this.isCancelled()) return\n\n this.logger.agentLoop(`iteration=${this.middlewareCtx.iteration}`, {\n iteration: this.middlewareCtx.iteration,\n })\n\n yield* this.runWhileYielding(this.beginCycle())\n\n if (this.cyclePhase === 'processText') {\n // Run onConfig before each model call (phase = beforeModel)\n this.middlewareCtx.phase = 'beforeModel'\n this.middlewareCtx.iteration = this.iterationCount\n const iterConfig = this.buildMiddlewareConfig()\n const iterTransformedConfig = yield* this.runWhileYielding(\n this.middlewareRunner.runOnConfig(this.middlewareCtx, iterConfig),\n )\n this.applyMiddlewareConfig(iterTransformedConfig)\n\n if (\n yield* this.emitBoundaryInterrupts(\n 'beforeModel',\n this.createSyntheticFinishedEvent(),\n )\n ) {\n this.setToolPhase('wait')\n return\n }\n\n yield* this.streamModelResponse()\n\n if (this.earlyTermination) break\n\n if (\n yield* this.emitBoundaryInterrupts(\n 'afterModel',\n this.finishedEvent ?? this.createSyntheticFinishedEvent(),\n )\n ) {\n this.setToolPhase('wait')\n return\n }\n if (this.shouldExecuteToolPhase()) {\n this.deferredToolCallRunFinishedChunks.push(\n ...this.deferredModelRunFinishedChunks,\n )\n this.deferredModelRunFinishedChunks = []\n } else {\n yield* this.flushDeferredModelRunFinishedChunks()\n }\n } else {\n yield* this.processToolCalls()\n }\n\n this.endCycle()\n } while (yield* this.runWhileYielding(this.shouldContinue()))\n }\n\n this.logger.agentLoop('run finished', {\n finishReason: this.lastFinishReason,\n })\n\n // After the agent loop ends, if a structured-output finalization was\n // requested AND the run hasn't already errored/aborted, run it through\n // the middleware pipeline. The terminal hook fires once at the very\n // end (after finalization), not after the agent loop.\n // Actionable waits already emitted a RUN_FINISHED interrupt terminal, so\n // do not run finalization after `processToolCalls()` pauses the stream.\n //\n // Native combined mode takes a different path: the agent loop's final-\n // turn text IS the schema-constrained JSON, so we harvest it from\n // `accumulatedContent` instead of issuing a second provider call.\n if (\n this.finalStructuredOutput &&\n this.toolPhase !== 'wait' &&\n !this.isCancelled() &&\n !this.finalizationError &&\n !this.earlyTermination\n ) {\n if (this.finalStructuredOutput.nativeCombined === true) {\n yield* this.harvestCombinedStructuredOutput()\n } else {\n yield* this.runStructuredFinalization()\n }\n }\n\n // Call terminal hook (skip when waiting for client — stream is paused, not finished).\n // Priority: finalizationError → onError; otherwise normal onFinish.\n // Skip on cancellation — the finally block routes aborts to onAbort.\n if (\n !this.terminalHookCalled &&\n this.toolPhase !== 'wait' &&\n !this.isCancelled()\n ) {\n if (this.finalizationError) {\n this.terminalHookCalled = true\n const errForHook = new Error(\n this.finalizationError.message,\n this.finalizationError.cause !== undefined\n ? { cause: this.finalizationError.cause }\n : undefined,\n )\n if (this.finalizationError.code !== undefined) {\n Object.defineProperty(errForHook, 'code', {\n value: this.finalizationError.code,\n enumerable: true,\n })\n }\n await this.middlewareRunner.runOnError(this.middlewareCtx, {\n error: errForHook,\n duration: Date.now() - this.streamStartTime,\n })\n } else {\n this.addTerminalAssistantMessages()\n this.terminalHookCalled = true\n await this.middlewareRunner.runOnFinish(this.middlewareCtx, {\n finishReason: this.lastFinishReason,\n duration: Date.now() - this.streamStartTime,\n content: this.accumulatedContent,\n usage: rebuildTokenUsage(\n this.finishedEvent?.usage,\n tanstackMetadata(this.finishedEvent ?? undefined)?.usage,\n ),\n })\n }\n }\n } catch (error: unknown) {\n if (\n error instanceof Error &&\n error.name === 'InterruptReplaySignal' &&\n 'continuationRunId' in error &&\n typeof error.continuationRunId === 'string'\n ) {\n this.terminalHookCalled = true\n yield* this.pipeThroughMiddleware({\n type: EventType.RUN_FINISHED,\n timestamp: Date.now(),\n threadId: this.threadId,\n runId: this.runIdOverride ?? this.requestId,\n outcome: { type: 'success' },\n result: {\n replayed: true,\n continuationRunId: error.continuationRunId,\n },\n })\n return\n }\n const interruptFailure = structuralInterruptFailure(error)\n if (interruptFailure) {\n this.terminalHookCalled = true\n this.logger.errors('chat interrupt resume failed', {\n error,\n threadId: this.middlewareCtx.threadId,\n })\n await this.middlewareRunner.runOnError(this.middlewareCtx, {\n error: interruptFailure.error,\n duration: Date.now() - this.streamStartTime,\n })\n yield this.buildInterruptRunErrorChunk(error)\n return\n }\n if (!this.terminalHookCalled) {\n this.terminalHookCalled = true\n if (error instanceof MiddlewareAbortError) {\n // Middleware abort decision — call onAbort, not onError\n this.abortReason = error.message\n await this.middlewareRunner.runOnAbort(this.middlewareCtx, {\n reason: error.message,\n duration: Date.now() - this.streamStartTime,\n cancelRequested: isCancelRequestedReason(error.message),\n })\n } else {\n // Genuine error — call onError\n this.logger.errors('chat run failed', {\n error,\n threadId: this.middlewareCtx.threadId,\n })\n await this.middlewareRunner.runOnError(this.middlewareCtx, {\n error,\n duration: Date.now() - this.streamStartTime,\n })\n }\n }\n // Don't rethrow middleware abort errors — the run just stops gracefully\n if (!(error instanceof MiddlewareAbortError)) {\n throw error\n }\n } finally {\n // Check for abort terminal hook\n if (!this.terminalHookCalled && this.isCancelled()) {\n this.terminalHookCalled = true\n const reason = this.resolveAbortReason()\n await this.middlewareRunner.runOnAbort(this.middlewareCtx, {\n reason,\n duration: Date.now() - this.streamStartTime,\n cancelRequested: isCancelRequestedReason(reason),\n })\n }\n\n // Await deferred promises (non-blocking side effects)\n if (this.deferredPromises.length > 0) {\n await Promise.allSettled(this.deferredPromises)\n }\n }\n }\n\n private beforeRun(): void {\n this.streamStartTime = Date.now()\n const { tools, metadata } = this.params\n\n // Gather flattened options into an object for context\n const options: Record<string, unknown> = {}\n if (metadata !== undefined) options.metadata = metadata\n\n this.eventOptions = Object.keys(options).length > 0 ? options : undefined\n this.eventToolNames = tools?.map((t) => t.name)\n\n // Update middleware context with computed fields\n this.middlewareCtx.options = this.eventOptions\n this.middlewareCtx.toolNames = this.eventToolNames\n }\n\n private async beginCycle(): Promise<void> {\n if (this.cyclePhase === 'processText') {\n await this.beginIteration()\n }\n }\n\n private endCycle(): void {\n if (this.cyclePhase === 'processText') {\n this.cyclePhase = 'executeToolCalls'\n return\n }\n\n this.cyclePhase = 'processText'\n this.iterationCount++\n }\n\n private async beginIteration(): Promise<void> {\n this.currentMessageId = this.createId('msg')\n this.currentMessageCreatedAt = new Date()\n this.streamIdentityCaptured = false\n this.accumulatedContent = ''\n this.accumulatedThinking = []\n this.currentThinkingContent = ''\n this.currentThinkingSignature = ''\n\n this.finishedEvent = null\n this.streamedToolErrorResults.clear()\n\n // Update mutable context fields\n this.middlewareCtx.currentMessageId = this.currentMessageId\n this.middlewareCtx.accumulatedContent = ''\n\n // Notify middleware of new iteration (devtools emits assistant message:created here)\n await this.middlewareRunner.runOnIteration(this.middlewareCtx, {\n iteration: this.iterationCount,\n messageId: this.currentMessageId,\n })\n }\n\n private async *streamModelResponse(): AsyncGenerator<StreamChunk> {\n const { metadata, modelOptions } = this.params\n const tools = this.tools\n\n // Convert tool schemas to JSON Schema before passing to adapter\n const toolsWithJsonSchemas = tools.map((tool) => ({\n ...tool,\n inputSchema: tool.inputSchema\n ? convertSchemaToJsonSchema(tool.inputSchema)\n : undefined,\n outputSchema: tool.outputSchema\n ? convertSchemaToJsonSchema(tool.outputSchema)\n : undefined,\n }))\n\n this.middlewareCtx.phase = 'modelStream'\n\n const providerName =\n (this.adapter as { provider?: string }).provider ?? this.adapter.name\n this.logger.request(\n `activity=chat provider=${providerName} model=${this.params.model} messages=${this.messages.length} tools=${this.tools.length} stream=true`,\n {\n provider: providerName,\n model: this.params.model,\n messageCount: this.messages.length,\n toolCount: this.tools.length,\n },\n )\n\n // When the adapter declared `supportsCombinedToolsAndSchema()`, the\n // activity layer set `nativeCombined: true` and we forward the\n // pre-converted JSON Schema into the regular chatStream call. The\n // adapter wires it into the upstream request (e.g. `response_format`,\n // `text.format`, `output_format`) so the model's final-turn text is\n // schema-constrained and the engine can harvest it from the agent loop\n // without a separate finalization round-trip.\n const combinedSchema =\n this.finalStructuredOutput?.nativeCombined === true\n ? this.finalStructuredOutput.jsonSchema\n : undefined\n\n const { approvals } = this.collectClientState()\n const adapterApprovals = new Map<string, boolean>()\n for (const [approvalId, resolution] of approvals) {\n adapterApprovals.set(\n approvalId,\n typeof resolution === 'boolean' ? resolution : resolution.approved,\n )\n }\n\n for await (const raw of this.adapter.chatStream({\n model: this.params.model,\n messages: this.providerMessages,\n tools: toolsWithJsonSchemas,\n metadata,\n request: this.effectiveRequest,\n modelOptions,\n systemPrompts: this.systemPrompts,\n logger: this.logger,\n threadId: this.threadId,\n runId: this.runIdOverride,\n parentRunId: this.parentRunIdOverride,\n // Expose provided capabilities (e.g. sandbox) to harness adapters.\n capabilities: this.middlewareCtx,\n // Client approval decisions, for harness interactive-approval resolution.\n approvals: adapterApprovals,\n ...(combinedSchema ? { outputSchema: combinedSchema } : {}),\n })) {\n if (this.isCancelled()) {\n break\n }\n\n this.totalChunkCount++\n\n this.handleStreamChunk(raw)\n\n // Native combined mode: synthesize `structured-output.start` BEFORE\n // the first TEXT_MESSAGE_START so the client-side StreamProcessor\n // routes the schema-constrained JSON deltas into a\n // StructuredOutputPart. We delay synthesis until we actually see\n // text starting — intermediate tool-call iterations don't need it,\n // and emitting at run-start would wrap tool-call commentary into a\n // structured-output part too.\n if (\n raw.type === EventType.CUSTOM &&\n raw.name === 'structured-output.start'\n ) {\n this.combinedStartEmitted = true\n const startValue = raw.value\n if (\n startValue &&\n typeof startValue === 'object' &&\n 'messageId' in startValue &&\n typeof startValue.messageId === 'string'\n ) {\n this.combinedStructuredMessageId = startValue.messageId\n this.captureStructuredOutputMessageIdentity(startValue.messageId)\n }\n }\n\n let outboundChunk: AdapterYieldChunk = raw\n if (\n this.finalStructuredOutput?.source === 'event' &&\n raw.type === EventType.CUSTOM &&\n raw.name === 'structured-output.complete'\n ) {\n const parsed = readStructuredOutputCompleteValue(raw.value)\n if (parsed) {\n const object = this.finalStructuredOutput.normalize\n ? this.finalStructuredOutput.normalize(parsed.object)\n : parsed.object\n this.structuredOutputResult = { data: object, rawText: parsed.raw }\n this.combinedCompleteEmitted = true\n const value = raw.value\n const completeMessageId = readCustomEventMessageId(value)\n if (completeMessageId) {\n this.combinedStructuredMessageId = completeMessageId\n this.captureStructuredOutputMessageIdentity(completeMessageId)\n }\n if (object !== parsed.object && value && typeof value === 'object') {\n outboundChunk = { ...raw, value: { ...value, object } }\n }\n }\n }\n\n if (\n this.finalStructuredOutput?.nativeCombined === true &&\n this.finalStructuredOutput.yieldChunks &&\n this.finalStructuredOutput.source !== 'event' &&\n !this.combinedStartEmitted &&\n raw.type === EventType.TEXT_MESSAGE_START\n ) {\n this.combinedStartEmitted = true\n const messageId =\n typeof raw.messageId === 'string' && raw.messageId !== ''\n ? raw.messageId\n : generateMessageId()\n this.combinedStructuredMessageId = messageId\n const synthStart: StreamChunk = {\n type: EventType.CUSTOM,\n name: 'structured-output.start',\n value: { messageId },\n timestamp: Date.now(),\n }\n const synthOutputs = await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n synthStart,\n )\n yield* this.emitPublicChunks(synthOutputs)\n }\n\n const outputChunks = await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n outboundChunk,\n )\n // When a streaming structured-output finalization step will run after\n // the agent loop, suppress the agent-loop's RUN_STARTED/RUN_FINISHED\n // here — the finalization step emits the single outer lifecycle pair\n // that reaches the consumer.\n //\n // Native combined mode does NOT issue a second adapter stream — the\n // agent loop's lifecycle IS the outer pair the consumer sees.\n const suppressAgentLifecycle =\n !!this.finalStructuredOutput &&\n this.finalStructuredOutput.yieldChunks &&\n this.finalStructuredOutput.nativeCombined !== true\n for (const outputChunk of outputChunks) {\n for (const spec of normalizeStreamChunk(\n outputChunk as AdapterYieldChunk,\n )) {\n restorePublicUsage(spec)\n if (\n suppressAgentLifecycle &&\n (spec.type === EventType.RUN_STARTED ||\n spec.type === EventType.RUN_FINISHED)\n ) {\n continue\n }\n if (spec.type === EventType.RUN_FINISHED) {\n this.deferredModelRunFinishedChunks.push(spec)\n continue\n }\n if (this.shouldDeferToolCallRunFinished(spec)) {\n this.deferredToolCallRunFinishedChunks.push(spec)\n continue\n }\n if (spec.type === EventType.RUN_STARTED) {\n if (this.hasPublicRunStarted) continue\n this.hasPublicRunStarted = true\n }\n this.logger.output(`type=${spec.type}`, { chunk: spec })\n yield spec\n this.middlewareCtx.chunkIndex++\n }\n }\n\n if (raw.type === EventType.RUN_FINISHED) {\n await this.runOnUsageFromChunk(raw)\n }\n\n // Drain any sandbox.file events emitted while processing this chunk.\n yield* this.drainSandboxFileQueue()\n yield* this.drainMiddlewareCustomQueue()\n\n if (this.earlyTermination) {\n break\n }\n }\n\n // Drain any remaining sandbox.file events emitted after the stream ended.\n yield* this.drainSandboxFileQueue()\n yield* this.drainMiddlewareCustomQueue()\n }\n\n private handleStreamChunk(chunk: AdapterYieldChunk): void {\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- AG-UI EventType enum members vs string-literal case labels; default branch handles untraced events.\n switch (chunk.type) {\n // AG-UI Events\n case 'TEXT_MESSAGE_START':\n if (typeof chunk.messageId === 'string' && chunk.messageId !== '') {\n this.captureStreamMessageIdentity(chunk.messageId)\n }\n break\n case 'TEXT_MESSAGE_CONTENT':\n this.handleTextMessageContentEvent(chunk)\n break\n case 'TOOL_CALL_START':\n this.handleToolCallStartEvent(chunk)\n break\n case 'TOOL_CALL_ARGS':\n this.handleToolCallArgsEvent(chunk)\n break\n case 'TOOL_CALL_END':\n this.handleToolCallEndEvent(chunk)\n break\n case 'TOOL_CALL_RESULT':\n this.handleToolCallResultEvent(chunk)\n break\n case 'RUN_FINISHED':\n this.handleRunFinishedEvent(chunk)\n break\n case 'RUN_ERROR':\n this.handleRunErrorEvent(chunk)\n break\n case 'STEP_STARTED':\n this.handleStepStartedEvent()\n break\n case 'STEP_FINISHED':\n this.handleStepFinishedEvent(chunk)\n break\n\n case 'REASONING_MESSAGE_CONTENT':\n this.handleReasoningMessageContentEvent(chunk)\n break\n\n case 'REASONING_ENCRYPTED_VALUE':\n this.handleReasoningEncryptedValueEvent(chunk)\n break\n\n case 'REASONING_START':\n case 'REASONING_MESSAGE_START':\n case 'REASONING_MESSAGE_END':\n case 'REASONING_END':\n // No special handling needed\n break\n\n default:\n // RUN_STARTED, TEXT_MESSAGE_END, STATE_SNAPSHOT, STATE_DELTA, CUSTOM\n // - no special handling needed in chat activity\n break\n }\n }\n\n // ===========================\n // AG-UI Event Handlers\n // ===========================\n\n private handleTextMessageContentEvent(chunk: TextMessageContentEvent): void {\n const extra = chunk as AdapterYieldChunk\n // Adapters still emit leftover cumulative `content` on RAW yields.\n // Alignment suppresses already-delivered deltas, so this snapshot is\n // what a takeover saves as the full assistant text.\n if (typeof extra.content === 'string' && extra.content !== '') {\n this.accumulatedContent = extra.content\n } else {\n this.accumulatedContent += chunk.delta\n }\n this.middlewareCtx.accumulatedContent = this.accumulatedContent\n }\n\n private captureStreamMessageIdentity(messageId: string): void {\n this.currentMessageId = messageId\n this.middlewareCtx.currentMessageId = messageId\n if (!this.streamIdentityCaptured) {\n this.currentMessageCreatedAt = new Date()\n this.streamIdentityCaptured = true\n }\n }\n\n private captureStructuredOutputMessageIdentity(messageId: string): void {\n this.structuredOutputMessageId = messageId\n this.structuredOutputMessageCreatedAt ??= new Date()\n }\n\n private handleToolCallStartEvent(chunk: ToolCallStartEvent): void {\n if (\n typeof chunk.parentMessageId === 'string' &&\n chunk.parentMessageId !== ''\n ) {\n this.captureStreamMessageIdentity(chunk.parentMessageId)\n }\n this.toolCallManager.addToolCallStartEvent(chunk)\n const metadata = chunk.metadata\n const thoughtSignature =\n metadata != null &&\n typeof metadata === 'object' &&\n 'thoughtSignature' in metadata &&\n typeof metadata.thoughtSignature === 'string' &&\n metadata.thoughtSignature !== ''\n ? metadata.thoughtSignature\n : undefined\n if (thoughtSignature === undefined) return\n const call = this.toolCallManager\n .getToolCalls()\n .find((candidate) => candidate.id === chunk.toolCallId)\n if (!call) return\n call.metadata = {\n ...(call.metadata != null && typeof call.metadata === 'object'\n ? call.metadata\n : {}),\n thoughtSignature,\n }\n }\n\n private handleToolCallArgsEvent(chunk: ToolCallArgsEvent): void {\n this.toolCallManager.addToolCallArgsEvent(chunk)\n }\n\n private handleToolCallEndEvent(chunk: ToolCallEndEvent): void {\n this.toolCallManager.completeToolCall(chunk)\n const end = chunk as AdapterYieldChunk\n const state = end.state ?? tanstackMetadata(end)?.state\n if (state !== 'output-error' || end.result === undefined) return\n this.handleToolCallResultEvent({\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: chunk.toolCallId,\n content: Array.isArray(end.result)\n ? JSON.stringify(end.result)\n : end.result,\n messageId: chunk.toolCallId,\n metadata: { tanstack: { state: 'output-error' } },\n })\n }\n\n private handleToolCallResultEvent(chunk: ToolCallResultEvent): void {\n const isOutputError = tanstackMetadata(chunk)?.state === 'output-error'\n if (!isOutputError) return\n\n const toolCall = this.toolCallManager\n .getToolCalls()\n .find((candidate) => candidate.id === chunk.toolCallId)\n if (!toolCall) return\n\n this.streamedToolErrorResults.set(chunk.toolCallId, {\n toolCallId: chunk.toolCallId,\n toolName: toolCall.function.name,\n result: chunk.content,\n state: 'output-error',\n })\n }\n\n private handleRunFinishedEvent(chunk: AdapterYieldChunk): void {\n this.finishedEvent = chunk as RunFinishedEvent\n const raw = chunk\n const top = raw.finishReason\n this.lastFinishReason =\n top === 'stop' ||\n top === 'length' ||\n top === 'content_filter' ||\n top === 'tool_calls' ||\n top === null\n ? top\n : (tanstackMetadata(chunk)?.finishReason ?? null)\n }\n\n private async runOnUsageFromChunk(\n chunk: RunFinishedEvent | AdapterYieldChunk,\n ): Promise<void> {\n const rebuilt = rebuildTokenUsage(\n chunk.usage,\n tanstackMetadata(chunk)?.usage,\n )\n if (rebuilt) {\n await this.middlewareRunner.runOnUsage(this.middlewareCtx, rebuilt)\n }\n }\n\n private handleRunErrorEvent(\n chunk: Extract<StreamChunk, { type: 'RUN_ERROR' }>,\n ): void {\n this.earlyTermination = true\n if (this.finalizationError === null) {\n const message = chunk.message || 'Run failed'\n this.finalizationError = {\n message,\n ...(chunk.code !== undefined ? { code: chunk.code } : {}),\n }\n }\n }\n\n private finalizeCurrentThinkingStep(): void {\n if (this.currentThinkingContent || this.currentThinkingSignature) {\n this.accumulatedThinking.push({\n content: this.currentThinkingContent,\n ...(this.currentThinkingSignature && {\n signature: this.currentThinkingSignature,\n }),\n })\n this.currentThinkingContent = ''\n this.currentThinkingSignature = ''\n }\n }\n\n private handleStepStartedEvent(): void {\n this.finalizeCurrentThinkingStep()\n }\n\n private handleStepFinishedEvent(chunk: AdapterYieldChunk): void {\n if (typeof chunk.signature === 'string' && chunk.signature !== '') {\n this.currentThinkingSignature = chunk.signature\n }\n }\n\n private handleReasoningMessageContentEvent(\n chunk: Extract<StreamChunk, { type: 'REASONING_MESSAGE_CONTENT' }>,\n ): void {\n this.currentThinkingContent += chunk.delta\n }\n\n private handleReasoningEncryptedValueEvent(\n chunk: ReasoningEncryptedValueEvent,\n ): void {\n if (chunk.subtype === 'tool-call') {\n const call = this.messages\n .flatMap((message) => message.toolCalls ?? [])\n .find((toolCall) => toolCall.id === chunk.entityId)\n if (call) {\n call.metadata = {\n ...(call.metadata != null && typeof call.metadata === 'object'\n ? call.metadata\n : {}),\n thoughtSignature: chunk.encryptedValue,\n }\n }\n return\n }\n this.currentThinkingSignature = chunk.encryptedValue\n }\n\n /**\n * Tools available for execution this turn. The discovery tool is dropped\n * from the advertised set (`this.tools`) once every lazy tool is discovered,\n * but a model may still re-request discovery; this widens execution lookup\n * to include it so such calls don't fail with \"Unknown tool\". Centralised so\n * both execution sites (`processToolCalls` and `checkForPendingToolCalls`)\n * stay in sync.\n */\n private resolveExecutableTools(\n toolCalls: ReadonlyArray<ToolCall>,\n ): ReadonlyArray<AnyTool> {\n return this.lazyToolManager.getExecutableTools(\n this.tools,\n toolCalls.map((tc) => tc.function.name),\n )\n }\n\n private async *checkForPendingToolCalls(): AsyncGenerator<\n StreamChunk,\n ToolPhaseResult,\n void\n > {\n const pendingToolCalls = this.getPendingToolCallsFromMessages()\n if (pendingToolCalls.length === 0) {\n return 'continue'\n }\n\n const finishEvent = this.createSyntheticFinishedEvent()\n\n // Count is deduped so wait→resume after a live turn does not double-count.\n // Per-turn execution caps are app middleware via onBeforeToolCall skip.\n this.recordToolCalls(pendingToolCalls)\n\n // Handle undiscovered lazy tool calls with self-correcting error messages\n const undiscoveredLazyResults: Array<ToolResult> = []\n const executablePendingCalls = pendingToolCalls.filter((tc) => {\n if (this.lazyToolManager.isUndiscoveredLazyTool(tc.function.name)) {\n undiscoveredLazyResults.push({\n toolCallId: tc.id,\n toolName: tc.function.name,\n result: {\n error: this.lazyToolManager.getUndiscoveredToolError(\n tc.function.name,\n ),\n },\n state: 'output-error',\n })\n return false\n }\n return true\n })\n\n // Non-executed outcomes (undiscovered lazy). Emitted after executed\n // results so the stream prefers real results first. Per-turn skips are\n // produced by middleware via onBeforeToolCall and appear in execution results.\n const deferredErrorResults = [...undiscoveredLazyResults]\n\n // Build args lookup so buildToolResultChunks can emit TOOL_CALL_START +\n // TOOL_CALL_ARGS before TOOL_CALL_END during continuation re-executions.\n const argsMap = new Map<string, string>()\n for (const tc of pendingToolCalls) {\n argsMap.set(tc.id, tc.function.arguments)\n }\n\n if (executablePendingCalls.length === 0) {\n if (deferredErrorResults.length > 0) {\n for (const chunk of this.buildToolResultChunks(\n deferredErrorResults,\n finishEvent,\n argsMap,\n )) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n }\n return 'continue'\n }\n\n this.middlewareCtx.phase = 'beforeTools'\n if (\n yield* this.emitBoundaryInterrupts(\n 'beforeTools',\n finishEvent,\n executablePendingCalls,\n )\n ) {\n this.setToolPhase('wait')\n return 'wait'\n }\n\n const { approvals, clientToolResults } = this.collectClientState()\n\n const generator = executeToolCalls(\n executablePendingCalls,\n this.resolveExecutableTools(executablePendingCalls),\n approvals,\n clientToolResults,\n (eventName, data) => this.createCustomEventChunk(eventName, data),\n {\n onBeforeToolCall: async (toolCall, tool, args) => {\n this.logger.tools(`phase=before name=${toolCall.function.name}`, {\n name: toolCall.function.name,\n args,\n })\n const hookCtx = {\n toolCall,\n tool,\n args,\n toolName: toolCall.function.name,\n toolCallId: toolCall.id,\n }\n return this.middlewareRunner.runOnBeforeToolCall(\n this.middlewareCtx,\n hookCtx,\n )\n },\n onAfterToolCall: async (info) => {\n this.logger.tools(`phase=after name=${info.toolName}`, {\n name: info.toolName,\n result: info.result,\n })\n await this.middlewareRunner.runOnAfterToolCall(\n this.middlewareCtx,\n info,\n )\n },\n },\n this.middlewareCtx.context,\n this.toolAbortSignal,\n {\n deniedToolResults: this.resumeDeniedToolResults,\n cancelledToolCallIds: this.resumeCancelledToolCallIds,\n },\n )\n\n // Consume the async generator, yielding custom events and collecting the return value\n const executionResult = yield* this.drainToolCallGenerator(generator)\n\n // Check if middleware aborted during pending tool execution\n if (this.isMiddlewareAborted()) {\n this.setToolPhase('stop')\n return 'stop'\n }\n\n const allResults = [...executionResult.results, ...deferredErrorResults]\n\n // Notify middleware of tool phase completion (devtools emits aggregate events here)\n yield* this.runWhileYielding(\n this.middlewareRunner.runOnToolPhaseComplete(this.middlewareCtx, {\n toolCalls: pendingToolCalls,\n results: allResults,\n needsApproval: executionResult.needsApproval,\n needsClientExecution: executionResult.needsClientExecution,\n }),\n )\n\n if (\n executionResult.needsApproval.length > 0 ||\n executionResult.needsClientExecution.length > 0\n ) {\n this.discardDeferredToolCallRunFinishedChunks()\n\n if (allResults.length > 0) {\n for (const chunk of this.buildToolResultChunks(\n allResults,\n finishEvent,\n )) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n }\n\n const emitted = yield* this.emitActionableInterruptBoundary(\n finishEvent,\n executionResult.needsApproval,\n executionResult.needsClientExecution,\n )\n this.setToolPhase(emitted ? 'wait' : 'stop')\n return emitted ? 'wait' : 'stop'\n }\n\n const toolResultChunks = this.buildToolResultChunks(allResults, finishEvent)\n\n for (const chunk of toolResultChunks) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n\n return 'continue'\n }\n\n private async *processToolCalls(): AsyncGenerator<StreamChunk, void, void> {\n if (!this.shouldExecuteToolPhase()) {\n // Text-only turn — clear per-turn count so strategies see 0 tools.\n this.lastTurnToolCallCount = 0\n this.setToolPhase('stop')\n return\n }\n\n const toolCalls = this.toolCallManager.getToolCalls()\n const finishEvent = this.finishedEvent\n\n if (!finishEvent || toolCalls.length === 0) {\n this.lastTurnToolCallCount = 0\n this.setToolPhase('stop')\n return\n }\n\n // Count every model-emitted tool call. Per-turn execution caps are app\n // middleware via onBeforeToolCall skip.\n this.recordToolCalls(toolCalls)\n\n this.addAssistantToolCallMessage(toolCalls)\n\n // Handle undiscovered lazy tool calls with self-correcting error messages\n const undiscoveredLazyResults: Array<ToolResult> = []\n const executableToolCalls = toolCalls.filter((tc) => {\n if (this.streamedToolErrorResults.has(tc.id)) {\n return false\n }\n if (this.lazyToolManager.isUndiscoveredLazyTool(tc.function.name)) {\n undiscoveredLazyResults.push({\n toolCallId: tc.id,\n toolName: tc.function.name,\n result: {\n error: this.lazyToolManager.getUndiscoveredToolError(\n tc.function.name,\n ),\n },\n state: 'output-error',\n })\n return false\n }\n return true\n })\n\n // Non-executed outcomes. Per-turn skips come from middleware and appear in\n // execution results.\n const deferredErrorResults = [\n ...this.streamedToolErrorResults.values(),\n ...undiscoveredLazyResults,\n ]\n\n if (executableToolCalls.length === 0) {\n yield* this.flushDeferredToolCallRunFinishedChunks()\n // All tool calls already have error results — emit them, then continue\n // the loop (strategy / onShouldContinue may stop).\n if (deferredErrorResults.length > 0) {\n for (const chunk of this.buildToolResultChunks(\n deferredErrorResults,\n finishEvent,\n )) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n }\n this.toolCallManager.clear()\n this.setToolPhase('continue')\n return\n }\n this.middlewareCtx.phase = 'beforeTools'\n\n if (\n yield* this.emitBoundaryInterrupts(\n 'beforeTools',\n finishEvent,\n executableToolCalls,\n )\n ) {\n this.setToolPhase('wait')\n return\n }\n\n const { approvals, clientToolResults } = this.collectClientState()\n\n const generator = executeToolCalls(\n executableToolCalls,\n this.resolveExecutableTools(executableToolCalls),\n approvals,\n clientToolResults,\n (eventName, data) => this.createCustomEventChunk(eventName, data),\n {\n onBeforeToolCall: async (toolCall, tool, args) => {\n this.logger.tools(`phase=before name=${toolCall.function.name}`, {\n name: toolCall.function.name,\n args,\n })\n const hookCtx = {\n toolCall,\n tool,\n args,\n toolName: toolCall.function.name,\n toolCallId: toolCall.id,\n }\n return this.middlewareRunner.runOnBeforeToolCall(\n this.middlewareCtx,\n hookCtx,\n )\n },\n onAfterToolCall: async (info) => {\n this.logger.tools(`phase=after name=${info.toolName}`, {\n name: info.toolName,\n result: info.result,\n })\n await this.middlewareRunner.runOnAfterToolCall(\n this.middlewareCtx,\n info,\n )\n },\n },\n this.middlewareCtx.context,\n this.toolAbortSignal,\n {\n deniedToolResults: this.resumeDeniedToolResults,\n cancelledToolCallIds: this.resumeCancelledToolCallIds,\n },\n )\n\n // Consume the async generator, yielding custom events and collecting the return value\n const executionResult = yield* this.drainToolCallGenerator(generator)\n\n this.middlewareCtx.phase = 'afterTools'\n\n // Check if middleware aborted during tool execution\n if (this.isMiddlewareAborted()) {\n this.setToolPhase('stop')\n return\n }\n\n // Executed results first, then deferred errors (fan-out skips / undiscovered)\n const allResults = [...executionResult.results, ...deferredErrorResults]\n\n // Notify middleware of tool phase completion (devtools emits aggregate events here)\n yield* this.runWhileYielding(\n this.middlewareRunner.runOnToolPhaseComplete(this.middlewareCtx, {\n toolCalls,\n results: allResults,\n needsApproval: executionResult.needsApproval,\n needsClientExecution: executionResult.needsClientExecution,\n }),\n )\n\n const afterToolBoundaryChunks = this.buildToolResultChunks(\n allResults,\n finishEvent,\n )\n const afterToolRequests = yield* this.runWhileYielding(\n this.middlewareRunner.runOnInterruptBoundary(\n this.middlewareCtx as ChatMiddlewareContext<TContext> & {\n phase: 'afterTools'\n },\n ),\n )\n if (afterToolRequests.length > 0) {\n for (const chunk of afterToolBoundaryChunks) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n yield* this.emitBoundaryInterrupts(\n 'afterTools',\n finishEvent,\n toolCalls,\n afterToolRequests,\n )\n this.setToolPhase('wait')\n return\n }\n\n if (\n executionResult.needsApproval.length > 0 ||\n executionResult.needsClientExecution.length > 0\n ) {\n if (allResults.length > 0) {\n for (const chunk of afterToolBoundaryChunks) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n }\n\n const emitted = yield* this.emitActionableInterruptBoundary(\n finishEvent,\n executionResult.needsApproval,\n executionResult.needsClientExecution,\n )\n this.setToolPhase(emitted ? 'wait' : 'stop')\n return\n }\n\n yield* this.flushDeferredToolCallRunFinishedChunks()\n\n const toolResultChunks = afterToolBoundaryChunks\n\n for (const chunk of toolResultChunks) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n\n // Refresh tools if lazy tools were discovered in this batch\n if (this.lazyToolManager.hasNewlyDiscoveredTools()) {\n this.tools = this.lazyToolManager.getActiveTools()\n this.toolCallManager = new ToolCallManager<\n ReadonlyArray<AnyTool>,\n TContext\n >(this.tools)\n this.setToolPhase('continue')\n return\n }\n\n this.toolCallManager.clear()\n\n this.setToolPhase('continue')\n }\n\n private shouldDeferToolCallRunFinished(chunk: StreamChunk): boolean {\n return (\n chunk.type === EventType.RUN_FINISHED &&\n this.lastFinishReason === 'tool_calls' &&\n this.tools.length > 0 &&\n this.toolCallManager.hasToolCalls()\n )\n }\n\n private *flushDeferredToolCallRunFinishedChunks(): Generator<StreamChunk> {\n for (const chunk of this.deferredToolCallRunFinishedChunks) {\n this.logger.output(`type=${chunk.type}`, { chunk })\n yield chunk\n this.middlewareCtx.chunkIndex++\n }\n this.deferredToolCallRunFinishedChunks = []\n }\n\n private *flushDeferredModelRunFinishedChunks(): Generator<StreamChunk> {\n for (const chunk of this.deferredModelRunFinishedChunks) {\n this.logger.output(`type=${chunk.type}`, { chunk })\n yield chunk\n this.middlewareCtx.chunkIndex++\n }\n this.deferredModelRunFinishedChunks = []\n }\n\n private async *emitSyntheticRunStarted(\n finishEvent: RunFinishedEvent,\n ): AsyncGenerator<StreamChunk, void, void> {\n if (this.hasPublicRunStarted) return\n yield* this.pipeThroughMiddleware({\n type: EventType.RUN_STARTED,\n runId: finishEvent.runId,\n threadId: finishEvent.threadId,\n timestamp: Date.now(),\n })\n }\n\n private async *emitSuccessfulEarlyTermination(): AsyncGenerator<\n StreamChunk,\n void,\n void\n > {\n // `stop` is a finished run, not another tool cycle. `tool_calls` here\n // makes the client auto-send after afterTools, so reject looks stuck.\n this.lastFinishReason = 'stop'\n const finishEvent = this.createSyntheticFinishedEvent('stop')\n yield* this.emitSyntheticRunStarted(finishEvent)\n yield* this.pipeThroughMiddleware({\n ...finishEvent,\n timestamp: Date.now(),\n outcome: { type: 'success' },\n })\n }\n\n private discardDeferredToolCallRunFinishedChunks(): void {\n this.deferredToolCallRunFinishedChunks = []\n }\n\n private shouldExecuteToolPhase(): boolean {\n return (\n this.lastFinishReason === 'tool_calls' &&\n this.tools.length > 0 &&\n this.toolCallManager.hasToolCalls()\n )\n }\n\n private addAssistantToolCallMessage(toolCalls: Array<ToolCall>): void {\n this.finalizeCurrentThinkingStep()\n\n this.messages = [\n ...this.messages,\n {\n role: 'assistant',\n content: this.accumulatedContent || null,\n toolCalls,\n id: this.currentMessageId ?? undefined,\n createdAt: this.currentMessageCreatedAt ?? undefined,\n ...(this.accumulatedThinking.length > 0 && {\n thinking: this.accumulatedThinking,\n }),\n },\n ]\n this.middlewareCtx.messages = this.messages\n }\n\n private addTerminalAssistantMessages(): void {\n this.finalizeCurrentThinkingStep()\n\n const structuredResult = this.structuredOutputResult\n const raw = structuredResult\n ? structuredResult.rawText || safeJsonStringify(structuredResult.data)\n : ''\n const structuredOutput: StructuredOutputPart | undefined = structuredResult\n ? {\n type: 'structured-output',\n status: 'complete',\n data: structuredResult.data,\n partial: structuredResult.data,\n raw,\n ...(structuredResult.reasoning !== undefined\n ? { reasoning: structuredResult.reasoning }\n : {}),\n }\n : undefined\n const nativeCombined = this.finalStructuredOutput?.nativeCombined === true\n const eventSourced = this.finalStructuredOutput?.source === 'event'\n const structuredId =\n this.structuredOutputMessageId ??\n this.combinedStructuredMessageId ??\n this.currentMessageId ??\n this.createId('msg')\n // Codex, OpenCode, ACP, and grok-build reuse the last text messageId\n // on structured-output.complete. Split only when the event uses a\n // different id (Claude Code). Same-id output stays on one message.\n const splitStructuredMessage =\n Boolean(structuredOutput) &&\n (!nativeCombined || eventSourced) &&\n this.currentMessageId != null &&\n structuredId !== this.currentMessageId\n const messages = [...this.middlewareCtx.messages]\n const existingStructuredIndex = messages.findIndex(\n (message) => message.role === 'assistant' && message.id === structuredId,\n )\n const currentTurnAlreadyRecorded = messages.some(\n (message) =>\n message.role === 'assistant' && message.id === this.currentMessageId,\n )\n const thinking =\n this.accumulatedThinking.length > 0 ? this.accumulatedThinking : undefined\n const startedLength = messages.length\n\n if (structuredOutput && existingStructuredIndex >= 0) {\n const existing = messages[existingStructuredIndex]\n if (existing) {\n messages[existingStructuredIndex] = {\n ...existing,\n content: raw || existing.content,\n structuredOutput,\n }\n }\n } else if (structuredOutput && !splitStructuredMessage) {\n if (!currentTurnAlreadyRecorded) {\n messages.push({\n role: 'assistant',\n content: this.accumulatedContent || raw || null,\n id: structuredId,\n createdAt:\n this.currentMessageCreatedAt ??\n this.structuredOutputMessageCreatedAt ??\n new Date(),\n structuredOutput,\n ...(thinking ? { thinking } : {}),\n })\n }\n } else {\n if (\n !currentTurnAlreadyRecorded &&\n (this.accumulatedContent !== '' || thinking)\n ) {\n messages.push({\n role: 'assistant',\n content: this.accumulatedContent || null,\n id: this.currentMessageId ?? this.createId('msg'),\n createdAt: this.currentMessageCreatedAt ?? new Date(),\n ...(thinking ? { thinking } : {}),\n })\n }\n if (structuredOutput) {\n messages.push({\n role: 'assistant',\n content: raw || null,\n id: structuredId,\n createdAt: this.structuredOutputMessageCreatedAt ?? new Date(),\n structuredOutput,\n })\n }\n }\n\n if (messages.length === startedLength && existingStructuredIndex < 0) {\n return\n }\n\n this.messages = messages\n this.middlewareCtx.messages = this.messages\n }\n\n /**\n * Extract client state (approvals and client tool results) from original messages.\n * This is called in the constructor BEFORE converting to ModelMessage format,\n * because the parts array (which contains approval state) is lost during conversion.\n */\n private extractClientStateFromOriginalMessages(\n originalMessages: Array<any>,\n ): {\n approvals: Map<string, ToolApprovalResolution>\n clientToolResults: Map<string, any>\n } {\n const approvals = new Map<string, ToolApprovalResolution>()\n const clientToolResults = new Map<string, any>()\n\n for (const message of originalMessages) {\n // Check for UIMessage format (parts array) - extract client tool results and approvals\n if (message.role === 'assistant' && message.parts) {\n for (const part of message.parts) {\n if (part.type === 'tool-call') {\n // Extract client tool results (tools without approval that have output)\n if (part.output !== undefined && !part.approval) {\n clientToolResults.set(part.id, part.output)\n }\n // Extract approval responses from UIMessage format parts\n if (\n part.approval?.id &&\n part.approval?.approved !== undefined &&\n part.state === 'approval-responded'\n ) {\n approvals.set(part.approval.id, part.approval.approved)\n }\n }\n }\n }\n }\n\n return { approvals, clientToolResults }\n }\n\n private collectClientState(): {\n approvals: Map<string, ToolApprovalResolution>\n clientToolResults: Map<string, any>\n } {\n // Start with the initial client state extracted from original messages\n const approvals = new Map(this.initialApprovals)\n const clientToolResults = new Map(this.initialClientToolResults)\n for (const [approvalId, approved] of this.resumeApprovals) {\n approvals.set(approvalId, approved)\n }\n for (const [toolCallId, result] of this.resumeClientToolResults) {\n clientToolResults.set(toolCallId, result)\n }\n\n // Also check current messages for any additional tool results (from server tools)\n for (const message of this.messages) {\n // Check for ModelMessage format (role: 'tool' messages contain tool results)\n // This handles results sent back from the client after executing client-side tools\n if (message.role === 'tool' && message.toolCallId) {\n // Parse content back to original output (was stringified by\n // uiMessageToModelMessages). Multimodal results carry an\n // Array<ContentPart> directly — pass it through without parsing.\n let output: unknown\n if (Array.isArray(message.content)) {\n output = message.content\n } else {\n try {\n output = JSON.parse(message.content as string)\n } catch {\n output = message.content\n }\n }\n // Skip approval response messages (they have pendingExecution marker)\n // These are NOT real client tool results — they are synthetic tool messages\n // created by uiMessageToModelMessages for approved-but-not-yet-executed tools.\n // Treating them as results would prevent the server from requesting actual\n // client-side execution after approval (see GitHub issue #225).\n if (\n output &&\n typeof output === 'object' &&\n (output as any).pendingExecution === true\n ) {\n continue\n }\n clientToolResults.set(message.toolCallId, output)\n }\n }\n\n return { approvals, clientToolResults }\n }\n\n private genericInterruptId(): string {\n return this.createId('interrupt')\n }\n\n private buildActionableInterrupts(\n approvals: Array<ApprovalRequest>,\n clientRequests: Array<ClientToolRequest>,\n genericRequests: ReadonlyArray<\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n > = [],\n genericInterruptIds: ReadonlyArray<string> = [],\n ): Array<Interrupt> {\n const interrupts: Array<Interrupt> = []\n\n for (const approval of approvals) {\n const tool = this.tools.find(\n (candidate) => candidate.name === approval.toolName,\n ) as RuntimeToolWithApproval | undefined\n const normalized = normalizeApprovalSchema(\n tool?.approvalSchema,\n tool?.inputSchema,\n )\n interrupts.push({\n id: approval.approvalId,\n // Display hint only. `reason` is free-form AG-UI text that another\n // producer can also spell `tool_call`, so it never decides ownership —\n // the binding in `metadata` does.\n reason: 'tool_call',\n message: `Approval required to run ${approval.toolName}`,\n toolCallId: approval.toolCallId,\n responseSchema: normalized.responseSchema,\n metadata: {\n kind: 'approval',\n toolName: approval.toolName,\n input: approval.input,\n [interruptBindingMetadataKey]: {\n v: INTERRUPT_BINDING_VERSION,\n kind: 'tool-approval',\n interruptId: approval.approvalId,\n toolName: approval.toolName,\n toolCallId: approval.toolCallId,\n originalArgs: approval.input,\n inputSchemaHash: hashSchemaInput(tool?.inputSchema),\n approvalSchemaHash: normalized.approvalSchemaHash,\n responseSchemaHash: normalized.responseSchemaHash,\n },\n },\n })\n }\n\n for (const clientTool of clientRequests) {\n const tool = this.tools.find(\n (candidate) => candidate.name === clientTool.toolName,\n )\n const responseSchema = convertSchemaToJsonSchema(tool?.outputSchema) ?? {}\n interrupts.push({\n id: `client_tool_${clientTool.toolCallId}`,\n reason: 'tanstack:client_tool_execution',\n message: `Client tool ${clientTool.toolName} is ready to run`,\n toolCallId: clientTool.toolCallId,\n responseSchema,\n metadata: {\n kind: 'client_tool',\n toolName: clientTool.toolName,\n input: clientTool.input,\n [interruptBindingMetadataKey]: {\n v: INTERRUPT_BINDING_VERSION,\n kind: 'client-tool-execution',\n interruptId: `client_tool_${clientTool.toolCallId}`,\n toolName: clientTool.toolName,\n toolCallId: clientTool.toolCallId,\n outputSchemaHash: hashSchemaInput(tool?.outputSchema),\n responseSchemaHash: digestInterruptJson(\n canonicalInterruptJson(responseSchema),\n ),\n },\n },\n })\n }\n\n for (const [index, request] of genericRequests.entries()) {\n const batchIndex = interrupts.length\n const id = genericInterruptIds[index]\n if (!id) throw new Error('Generic interrupt id is unavailable.')\n const preEmission = createInterruptBinding(request, { batchIndex })\n interrupts.push({\n id,\n reason: request.reason,\n message: request.message,\n ...(preEmission.descriptor.responseSchemaCanonicalJson !== undefined\n ? {\n responseSchema: JSON.parse(\n preEmission.descriptor.responseSchemaCanonicalJson,\n ),\n }\n : {}),\n ...(request.expiresAt !== undefined\n ? { expiresAt: request.expiresAt }\n : {}),\n metadata: {\n [interruptBindingMetadataKey]: {\n v: INTERRUPT_BINDING_VERSION,\n kind: 'generic',\n interruptId: id,\n definitionId: preEmission.descriptor.definitionId,\n key: preEmission.descriptor.key,\n batchIndex,\n ...(request.expiresAt !== undefined\n ? { expiresAt: request.expiresAt }\n : {}),\n ...(preEmission.descriptor.payloadSchemaHash\n ? {\n payloadSchemaHash: preEmission.descriptor.payloadSchemaHash,\n }\n : {}),\n ...(preEmission.descriptor.responseSchemaHash !== undefined\n ? {\n responseSchemaHash: preEmission.descriptor.responseSchemaHash,\n }\n : {}),\n },\n ...(preEmission.payload !== undefined\n ? { [INTERRUPT_PAYLOAD_METADATA_KEY]: preEmission.payload }\n : {}),\n },\n })\n }\n\n const ids = new Set<string>()\n for (const interrupt of interrupts) {\n if (ids.has(interrupt.id)) {\n throw new Error(\n `Duplicate interrupt id in final batch: ${interrupt.id}`,\n )\n }\n ids.add(interrupt.id)\n }\n\n return interrupts\n }\n\n private buildInterruptFinishedChunk(\n finishEvent: RunFinishedEvent,\n approvals: Array<ApprovalRequest>,\n clientRequests: Array<ClientToolRequest>,\n genericRequests: ReadonlyArray<\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n > = [],\n genericInterruptIds?: ReadonlyArray<string>,\n ): StreamChunk {\n return {\n ...finishEvent,\n timestamp: Date.now(),\n outcome: {\n type: 'interrupt',\n interrupts: this.buildActionableInterrupts(\n approvals,\n clientRequests,\n genericRequests,\n genericInterruptIds,\n ),\n },\n }\n }\n\n private buildMessagesSnapshotChunk(): StreamChunk {\n const withIds = this.messages.map((message, index) => ({\n ...message,\n id:\n message.id ||\n `snapshot_${this.runIdOverride ?? this.requestId}_${index}`,\n }))\n return {\n type: EventType.MESSAGES_SNAPSHOT,\n timestamp: Date.now(),\n messages: uiMessagesToWire(modelMessagesToUIMessages(withIds), {\n includeSnapshotStructuredOutput: true,\n }),\n }\n }\n\n private publicInterruptTerminal(chunk: StreamChunk): StreamChunk {\n if (\n chunk.type !== EventType.RUN_FINISHED ||\n chunk.outcome?.type !== 'interrupt'\n ) {\n return chunk\n }\n return {\n ...chunk,\n outcome: {\n ...chunk.outcome,\n interrupts: chunk.outcome.interrupts.map((interrupt) => {\n if (\n !interrupt.metadata ||\n typeof interrupt.metadata !== 'object' ||\n Array.isArray(interrupt.metadata)\n ) {\n return interrupt\n }\n const metadata = { ...interrupt.metadata }\n const binding = normalizePublicInterruptBinding(\n metadata[interruptBindingMetadataKey],\n interrupt.id,\n )\n if (binding) {\n metadata[interruptBindingMetadataKey] = binding\n } else {\n delete metadata[interruptBindingMetadataKey]\n }\n return { ...interrupt, metadata }\n }),\n },\n }\n }\n\n private interruptFailure(error: unknown): {\n message: string\n code: string\n errors?: ReadonlyArray<InterruptSubmissionError>\n } {\n const structured = structuralInterruptFailure(error)\n if (structured) {\n return {\n message: structured.error.message,\n code: structured.errors[0]?.code ?? 'server',\n errors: structured.errors,\n }\n }\n if (error && typeof error === 'object' && 'errors' in error) {\n const errors = error.errors\n if (Array.isArray(errors)) {\n const first = errors[0]\n if (first && typeof first === 'object') {\n const message =\n 'message' in first && typeof first.message === 'string'\n ? first.message\n : 'Interrupt persistence failed.'\n const code =\n 'code' in first && typeof first.code === 'string'\n ? first.code\n : 'server'\n return { message, code }\n }\n }\n }\n return {\n message:\n error instanceof Error\n ? error.message\n : 'Interrupt persistence failed.',\n code: 'server',\n }\n }\n\n private buildInterruptRunErrorChunk(error: unknown): StreamChunk {\n const failure = this.interruptFailure(error)\n return withTanstackMetadata(\n {\n type: EventType.RUN_ERROR,\n timestamp: Date.now(),\n message: failure.message,\n code: failure.code,\n },\n {\n runId: this.runIdOverride ?? this.requestId,\n threadId: this.threadId,\n ...(failure.errors !== undefined\n ? { interruptErrors: failure.errors }\n : {}),\n },\n ) as StreamChunk\n }\n\n private async *emitInterruptRunError(\n error: unknown,\n ): AsyncGenerator<StreamChunk, void, void> {\n const failure = this.interruptFailure(error)\n this.finalizationError = {\n message: failure.message,\n code: failure.code,\n cause: error,\n }\n yield* this.pipeThroughMiddleware(this.buildInterruptRunErrorChunk(error))\n }\n\n private async *emitActionableInterruptBoundary(\n finishEvent: RunFinishedEvent,\n approvals: Array<ApprovalRequest>,\n clientRequests: Array<ClientToolRequest>,\n genericRequests: ReadonlyArray<\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n > = [],\n ): AsyncGenerator<StreamChunk, boolean, void> {\n yield* this.emitSyntheticRunStarted(finishEvent)\n const genericInterruptIds = genericRequests.map(() =>\n this.genericInterruptId(),\n )\n const terminal = this.completeEphemeralInterruptBindings(\n this.buildInterruptFinishedChunk(\n finishEvent,\n approvals,\n clientRequests,\n genericRequests,\n genericInterruptIds,\n ),\n )\n let terminalOutputs: Array<StreamChunk>\n try {\n terminalOutputs = [\n ...this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(this.middlewareCtx, terminal),\n ),\n ]\n } catch (error) {\n yield* this.emitInterruptRunError(error)\n return false\n }\n\n yield* this.pipeThroughMiddleware(this.buildMessagesSnapshotChunk())\n if (this.params.state !== undefined) {\n yield* this.pipeThroughMiddleware({\n type: EventType.STATE_SNAPSHOT,\n timestamp: Date.now(),\n snapshot: this.params.state,\n })\n }\n for (const output of terminalOutputs) {\n yield this.publicInterruptTerminal(output)\n }\n return true\n }\n\n private async *emitBoundaryInterrupts(\n phase: 'beforeModel' | 'afterModel' | 'beforeTools' | 'afterTools',\n finishEvent: RunFinishedEvent,\n toolCalls: ReadonlyArray<ToolCall> = [],\n requests?: ReadonlyArray<\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n >,\n ): AsyncGenerator<StreamChunk, boolean, void> {\n this.middlewareCtx.phase = phase\n const boundaryRequests =\n requests ??\n (yield* this.runWhileYielding(\n this.middlewareRunner.runOnInterruptBoundary(\n this.middlewareCtx as ChatMiddlewareContext<TContext> & {\n phase: typeof phase\n },\n ),\n ))\n if (boundaryRequests.length === 0) return false\n for (const request of boundaryRequests) {\n if (\n this.interruptDefinitions.get(request.definition.id) !==\n request.definition\n ) {\n throw new Error(\n `Generic interrupt definition ${request.definition.id} is not registered on this chat.`,\n )\n }\n }\n if (phase === 'afterModel') {\n if (this.toolCallManager.hasToolCalls()) {\n this.addAssistantToolCallMessage(this.toolCallManager.getToolCalls())\n } else {\n this.addAssistantTextMessageForInterrupt()\n }\n }\n const actionable = this.getBoundaryActionableToolRequests(toolCalls)\n yield* this.emitActionableInterruptBoundary(\n finishEvent,\n actionable.approvals,\n actionable.clientRequests,\n boundaryRequests,\n )\n return true\n }\n\n private addAssistantTextMessageForInterrupt(): void {\n if (this.accumulatedContent.length === 0) return\n this.messages = [\n ...this.messages,\n { role: 'assistant', content: this.accumulatedContent },\n ]\n this.middlewareCtx.messages = this.messages\n }\n\n private getBoundaryActionableToolRequests(\n toolCalls: ReadonlyArray<ToolCall>,\n ): {\n approvals: Array<ApprovalRequest>\n clientRequests: Array<ClientToolRequest>\n } {\n const { approvals, clientToolResults } = this.collectClientState()\n const approvalRequests: Array<ApprovalRequest> = []\n const clientRequests: Array<ClientToolRequest> = []\n for (const toolCall of toolCalls) {\n const tool = this.resolveExecutableTools([toolCall]).find(\n (candidate) => candidate.name === toolCall.function.name,\n ) as RuntimeToolWithApproval | undefined\n if (!tool) continue\n let input: unknown = {}\n try {\n const parsed = JSON.parse(toolCall.function.arguments.trim() || '{}')\n input = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n input = {}\n }\n const approvalId = `approval_${toolCall.id}`\n if (tool.needsApproval && !approvals.has(approvalId)) {\n approvalRequests.push({\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input,\n approvalId,\n })\n } else if (\n !tool.execute &&\n !clientToolResults.has(toolCall.id) &&\n !this.resumeCancelledToolCallIds.has(toolCall.id)\n ) {\n clientRequests.push({\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input,\n })\n }\n }\n return { approvals: approvalRequests, clientRequests }\n }\n\n private completeEphemeralInterruptBindings(chunk: StreamChunk): StreamChunk {\n if (\n chunk.type !== EventType.RUN_FINISHED ||\n chunk.outcome?.type !== 'interrupt'\n ) {\n return chunk\n }\n const interruptedRunId = this.runIdOverride ?? this.requestId\n return {\n ...chunk,\n outcome: {\n ...chunk.outcome,\n interrupts: chunk.outcome.interrupts.map((interrupt) => {\n if (\n !interrupt.metadata ||\n typeof interrupt.metadata !== 'object' ||\n Array.isArray(interrupt.metadata)\n ) {\n return interrupt\n }\n const metadata = { ...interrupt.metadata }\n const unopened = metadata[interruptBindingMetadataKey]\n if (\n unopened === null ||\n typeof unopened !== 'object' ||\n Array.isArray(unopened)\n ) {\n return interrupt\n }\n metadata[interruptBindingMetadataKey] = {\n ...unopened,\n interruptedRunId,\n generation: 0,\n }\n return { ...interrupt, metadata }\n }),\n },\n }\n }\n\n private buildToolResultChunks(\n results: Array<ToolResult>,\n _finishEvent: RunFinishedEvent,\n argsMap?: Map<string, string>,\n ): Array<AdapterYieldChunk> {\n const chunks: Array<AdapterYieldChunk> = []\n\n for (const result of results) {\n // `content` is the canonical value for the tool `ModelMessage` — it may\n // be an `Array<ContentPart>` (multimodal) which the adapters convert to\n // structured provider output on the next iteration. `wireContent` is the\n // string form emitted on TOOL_CALL_RESULT.content (string-only per the\n // AG-UI spec); the multimodal array travels via the message itself.\n const content = normalizeToolResult(result.result)\n const wireContent =\n typeof content === 'string' ? content : JSON.stringify(content)\n\n // argsMap is set only on continuation re-executions, where the adapter\n // never streamed these calls. Otherwise it already emitted END, so a\n // second one here would be an orphan that fails verifyEvents (#519).\n if (argsMap) {\n chunks.push({\n type: EventType.TOOL_CALL_START,\n timestamp: Date.now(),\n toolCallId: result.toolCallId,\n toolCallName: result.toolName,\n toolName: result.toolName,\n })\n\n const args = argsMap.get(result.toolCallId) ?? '{}'\n chunks.push({\n type: EventType.TOOL_CALL_ARGS,\n timestamp: Date.now(),\n toolCallId: result.toolCallId,\n delta: args,\n })\n\n chunks.push({\n type: EventType.TOOL_CALL_END,\n timestamp: Date.now(),\n toolCallId: result.toolCallId,\n })\n }\n\n const parentMessageId = [...this.messages]\n .reverse()\n .find((message) => message.role === 'assistant')?.id\n const resultChunk = {\n type: EventType.TOOL_CALL_RESULT,\n timestamp: Date.now(),\n messageId: parentMessageId || result.toolCallId,\n toolCallId: result.toolCallId,\n content: wireContent,\n role: 'tool' as const,\n }\n chunks.push(\n (result.state === 'output-error'\n ? withTanstackMetadata(resultChunk, { state: result.state })\n : resultChunk) as StreamChunk,\n )\n\n // If a placeholder tool message exists for this toolCallId (created by\n // uiMessageToModelMessages for an approval-responded part with no\n // output yet), replace it with the real result. Otherwise the LLM sees\n // both messages — and since the Anthropic adapter dedupes tool_result\n // blocks by tool_use_id keeping the first match, the placeholder wins\n // and the real result is dropped (see issue #532).\n const placeholderIdx = this.messages.findIndex((m) => {\n if (m.role !== 'tool' || m.toolCallId !== result.toolCallId) {\n return false\n }\n if (typeof m.content !== 'string') return false\n try {\n return JSON.parse(m.content)?.pendingExecution === true\n } catch {\n return false\n }\n })\n\n const newToolMessage: ModelMessage = {\n role: 'tool',\n content,\n toolCallId: result.toolCallId,\n }\n\n if (placeholderIdx >= 0) {\n this.messages = [\n ...this.messages.slice(0, placeholderIdx),\n newToolMessage,\n ...this.messages.slice(placeholderIdx + 1),\n ]\n } else {\n this.messages = [...this.messages, newToolMessage]\n }\n this.middlewareCtx.messages = this.messages\n }\n\n return chunks\n }\n\n private getPendingToolCallsFromMessages(): Array<ToolCall> {\n // Build a set of completed tool IDs, but exclude tools with pendingExecution marker\n // (these are approved tools that still need to execute)\n const completedToolIds = new Set<string>()\n\n for (const message of this.messages) {\n if (message.role === 'tool' && message.toolCallId) {\n // Check if this is an approval response with pendingExecution marker\n let hasPendingExecution = false\n if (typeof message.content === 'string') {\n try {\n const parsed = JSON.parse(message.content)\n if (parsed.pendingExecution === true) {\n hasPendingExecution = true\n }\n } catch {\n // Not JSON, treat as regular tool result\n }\n }\n\n // Only mark as complete if NOT pending execution\n if (!hasPendingExecution) {\n completedToolIds.add(message.toolCallId)\n }\n }\n }\n\n const pending: Array<ToolCall> = []\n\n for (const message of this.messages) {\n if (message.role === 'assistant' && message.toolCalls) {\n for (const toolCall of message.toolCalls) {\n // Provider-executed tool calls (e.g. Anthropic `web_search`) were\n // already run by the provider; they carry no client result, so they\n // would otherwise look \"pending\" forever and the loop would try (and\n // fail) to execute them client-side. Skip them.\n if (isProviderExecutedToolCall(toolCall)) {\n continue\n }\n if (!completedToolIds.has(toolCall.id)) {\n pending.push(toolCall)\n }\n }\n }\n }\n\n return pending\n }\n\n /**\n * Find a tool call by id in message history (including already-completed ones).\n * Used when the client has already attached a tool result for UI before resume.\n */\n private findToolCallInMessages(toolCallId: string): ToolCall | undefined {\n for (const message of this.messages) {\n if (message.role !== 'assistant' || !message.toolCalls) continue\n for (const toolCall of message.toolCalls) {\n if (toolCall.id === toolCallId) return toolCall\n }\n }\n return undefined\n }\n\n /**\n * Tool calls that must be reconstructed as interrupt pending for ephemeral\n * resume. Includes outstanding tools plus client tools that already have\n * results in history when the resume batch still carries `client_tool_*`\n * entries (the client writes local tool results before submitting resume).\n */\n private getToolCallsForEphemeralResume(\n resume: ReadonlyArray<{ interruptId: string }> | undefined,\n ): Array<ToolCall> {\n const pending = this.getPendingToolCallsFromMessages()\n const byId = new Map(pending.map((toolCall) => [toolCall.id, toolCall]))\n for (const entry of resume ?? []) {\n // Recover tool calls the client already finalized in history for two\n // resume-batch cases that no longer look \"pending\":\n // - `client_tool_*`: a client tool wrote its output before resuming.\n // - `approval_*`: a DENIED approval wrote its denial result, so the\n // call reads as completed. Without this it drops out of the\n // reconstructed batch and the resume entry fails as unknown-interrupt.\n let toolCallId: string | undefined\n if (entry.interruptId.startsWith('client_tool_')) {\n toolCallId = entry.interruptId.slice('client_tool_'.length)\n } else if (entry.interruptId.startsWith('approval_')) {\n toolCallId = entry.interruptId.slice('approval_'.length)\n }\n if (toolCallId === undefined || byId.has(toolCallId)) continue\n const toolCall = this.findToolCallInMessages(toolCallId)\n if (toolCall && !isProviderExecutedToolCall(toolCall)) {\n pending.push(toolCall)\n byId.set(toolCallId, toolCall)\n }\n }\n return pending\n }\n\n private createSyntheticFinishedEvent(\n finishReason: 'stop' | 'tool_calls' = 'tool_calls',\n ): RunFinishedEvent {\n return withTanstackMetadata(\n {\n type: EventType.RUN_FINISHED,\n runId: this.runIdOverride ?? this.requestId,\n threadId: this.threadId,\n timestamp: Date.now(),\n },\n { finishReason, model: this.params.model },\n ) as RunFinishedEvent\n }\n\n private async shouldContinue(): Promise<boolean> {\n // Always enter the tool-execution half-cycle after a model turn.\n if (this.cyclePhase === 'executeToolCalls') {\n return true\n }\n\n const state = {\n iterationCount: this.iterationCount,\n messages: this.messages,\n finishReason: this.lastFinishReason,\n toolCallCount: this.toolCallCount,\n lastTurnToolCallCount: this.lastTurnToolCallCount,\n }\n\n // Evaluate strategy and middleware unconditionally (even when the\n // strategy already says stop) so every onShouldContinue observer still\n // sees the final counters; AND all three at the end.\n const strategyContinues = this.loopStrategy(state)\n const middlewareContinues = await this.middlewareRunner.runOnShouldContinue(\n this.middlewareCtx,\n state,\n )\n\n return (\n strategyContinues && middlewareContinues && this.toolPhase === 'continue'\n )\n }\n\n /**\n * Record tool calls (deduped by id) toward `toolCallCount` /\n * `lastTurnToolCallCount` for strategies and middleware `onShouldContinue`.\n *\n * Used for both live model turns and pending/resume batches. IDs already\n * counted in this run (e.g. wait→resume after a live turn) are not\n * re-added to `toolCallCount`. Per-turn execution caps are app middleware\n * (`onBeforeToolCall` skip), not engine policy.\n */\n private recordToolCalls(toolCalls: Array<ToolCall>): void {\n this.lastTurnToolCallCount = toolCalls.length\n let newlyCounted = 0\n for (const tc of toolCalls) {\n if (!this.countedToolCallIds.has(tc.id)) {\n this.countedToolCallIds.add(tc.id)\n newlyCounted++\n }\n }\n this.toolCallCount += newlyCounted\n }\n\n private isAborted(): boolean {\n return !!this.effectiveSignal?.aborted\n }\n\n private isMiddlewareAborted(): boolean {\n return !!this.middlewareAbortController?.signal.aborted\n }\n\n private isCancelled(): boolean {\n return this.isAborted() || this.isMiddlewareAborted()\n }\n\n /**\n * The reason to report on `AbortInfo` for a cancelled run.\n *\n * `this.abortReason` only ever holds a *middleware*-initiated reason\n * (`ctx.abort(reason)` / `MiddlewareAbortError`). A caller that aborts its own\n * controller — `abortController.abort(RUN_CANCEL_REASON)`, the in-process\n * cancel channel — never touches that field, so the reason has to be read back\n * off the caller's signal, which is the signal `isCancelled()` consults via\n * `isAborted()`. A signal aborted with no reason carries a DOMException rather\n * than a string, so non-string reasons are reported as absent.\n */\n private resolveAbortReason(): string | undefined {\n if (this.abortReason !== undefined) return this.abortReason\n const signalReason: unknown = this.effectiveSignal?.reason\n return typeof signalReason === 'string' ? signalReason : undefined\n }\n\n /**\n * Whether this run's teardown declared its abort a DETACH — see\n * {@link RunDetachedCapability}. Only `withSandbox`'s `onAbort` publishes it,\n * and only for a plain, intentless disconnect of a detachable run, so every\n * other exit path answers `false`.\n *\n * Surfaced on the engine (rather than the ctx being handed out) so the\n * capability read stays inside core, and so the delivery sink learns the\n * verdict through {@link publishRunDetachedSignal} instead of reaching into a\n * middleware context it has no business holding.\n *\n * @internal\n */\n wasDetached(): boolean {\n return getRunDetached(this.middlewareCtx, { optional: true }) === true\n }\n\n /**\n * The delivery socket closed while this run was still going.\n *\n * Notifies every subscriber (see {@link RunDisconnectCapability}) and RETURNS\n * IMMEDIATELY. Synchronous on purpose: it is called from\n * `ReadableStream.cancel()`, which must not be made to wait on a run-store\n * write, and the caller ({@link notifyRunDisconnected}) has no consumer left to\n * report to anyway.\n *\n * Subscribers therefore run CONCURRENTLY with the still-executing run — which is\n * the entire point. The run is typically suspended inside a slow middleware\n * `setup` at this moment, so anything dispatched from the run's own unwinding\n * would be minutes late. Nothing on this path aborts the run: a durable run\n * outlives its viewer.\n *\n * Each subscriber's promise is parked on `deferredPromises`, which the run awaits\n * in its `finally`, so bookkeeping cannot be lost to a race with the run's own\n * completion even though nothing awaits it here.\n *\n * IDEMPOTENT. A second cancel, or one arriving after a terminal hook already ran,\n * is ignored: the terminal hooks own the run's outcome, and re-stamping\n * `detachedSince` on a run that has already finished would hand a completed run\n * to the reaper as reclaimable work.\n *\n * @internal\n */\n notifyDisconnected(): void {\n if (this.disconnected || this.terminalHookCalled) return\n this.disconnected = true\n for (const listener of this.disconnectListeners) {\n this.runDisconnectListener(listener)\n }\n }\n\n /**\n * Invoke one disconnect listener, isolated and with its failure SWALLOWED after\n * logging.\n *\n * There is no caller left to report to — the socket this would report on is the\n * one that just closed — and a rejection parked on `deferredPromises` would\n * surface as the run's failure, replacing a healthy outcome with a bookkeeping\n * error. Isolation matters for the usual reason too: one subscriber's failing\n * write must not skip the next one's.\n */\n private runDisconnectListener(listener: () => void | Promise<void>): void {\n let result: void | Promise<void>\n try {\n result = listener()\n } catch (error) {\n this.logger.errors('run disconnect listener failed', { error })\n return\n }\n if (result === undefined) return\n this.deferredPromises.push(\n result.catch((error: unknown) => {\n this.logger.errors('run disconnect listener failed', { error })\n }),\n )\n }\n\n /**\n * Run the final structured-output adapter call through the middleware\n * pipeline. Yields chunks to the caller only when\n * `this.finalStructuredOutput.yieldChunks` is true; otherwise consumes\n * silently while still piping through middleware.\n *\n * On success, populates this.structuredOutputResult.\n * On failure, populates this.finalizationError.\n */\n private async *runStructuredFinalization(): AsyncGenerator<StreamChunk> {\n if (!this.finalStructuredOutput) {\n throw new Error(\n 'runStructuredFinalization called without finalStructuredOutput config',\n )\n }\n\n this.middlewareCtx.phase = 'structuredOutput'\n\n // Build the structured-output config view. `tools` is intentionally\n // excluded from the type because it isn't forwarded to the structured-\n // output adapter call — including it here would be misleading API.\n const baseConfig = this.buildMiddlewareConfig()\n const { tools: _omitTools, ...baseWithoutTools } = baseConfig\n let structuredConfig: StructuredOutputMiddlewareConfig = {\n ...baseWithoutTools,\n outputSchema: this.finalStructuredOutput.jsonSchema,\n }\n\n // 1) onStructuredOutputConfig — middleware can transform messages, options, outputSchema\n structuredConfig = yield* this.runWhileYielding(\n this.middlewareRunner.runOnStructuredOutputConfig(\n this.middlewareCtx,\n structuredConfig,\n ),\n )\n\n // 2) onConfig — phase-aware general-purpose middleware re-runs at the\n // boundary. Re-attach the engine's current tools so onConfig observers\n // see the live tool set (they still won't be forwarded to the structured\n // call — same constraint applies — but the view is consistent with the\n // ChatMiddlewareConfig shape).\n const { outputSchema: pinnedSchema, ...chatConfigSlice } = structuredConfig\n const postOnConfig = yield* this.runWhileYielding(\n this.middlewareRunner.runOnConfig(this.middlewareCtx, {\n ...chatConfigSlice,\n tools: baseConfig.tools,\n }),\n )\n\n // Apply merged config back to engine state\n this.applyMiddlewareConfig(postOnConfig)\n\n // Build the StructuredOutputOptions the adapter expects.\n // `this.adapter` is already `TAdapter extends AnyTextAdapter` per the\n // class generics — no cast needed.\n const structuredCallOptions = {\n chatOptions: {\n model: this.params.model,\n messages: this.providerMessages,\n metadata: postOnConfig.metadata,\n modelOptions: postOnConfig.modelOptions,\n systemPrompts: postOnConfig.systemPrompts,\n logger: this.logger,\n threadId: this.threadId,\n runId: this.runIdOverride,\n parentRunId: this.parentRunIdOverride,\n ...(this.effectiveRequest ? { request: this.effectiveRequest } : {}),\n },\n outputSchema: pinnedSchema,\n }\n\n // Select the provider call: native streaming if available, else synthesized fallback.\n // The fallback path captures the original adapter error so the engine can\n // attach it as `finalizationError.cause` (the RUN_ERROR wire shape only\n // carries `message` and `code`, losing stack/cause/provider properties).\n let fallbackAdapterError: unknown = undefined\n const providerStream = this.adapter.structuredOutputStream\n ? this.adapter.structuredOutputStream(structuredCallOptions)\n : fallbackStructuredOutputStream(\n this.adapter,\n structuredCallOptions,\n (err) => {\n fallbackAdapterError = err\n },\n )\n\n // ============================================================\n // structured-output.start synthesis\n // ============================================================\n // The client-side StreamProcessor (PR #577) requires a CUSTOM\n // `structured-output.start` event BEFORE the JSON TEXT_MESSAGE_CONTENT\n // deltas — that's how it routes deltas into a `StructuredOutputPart`\n // rather than a plain `TextPart`. No adapter currently emits this,\n // so the engine synthesizes one (and tracks whether the adapter\n // emitted its own to avoid duplicating).\n //\n // Synthesis fires before the FIRST TEXT_MESSAGE_* event from the inner\n // stream, OR before a pre-delta RUN_ERROR (so the client can construct\n // an errored structured-output placeholder).\n let startEmitted = false\n let structuredMessageId: string | null = null\n\n const extractMessageId = (c: StreamChunk): string | null => {\n if (\n c.type === EventType.TEXT_MESSAGE_START ||\n c.type === EventType.TEXT_MESSAGE_CONTENT ||\n c.type === EventType.TEXT_MESSAGE_END\n ) {\n return typeof c.messageId === 'string' && c.messageId !== ''\n ? c.messageId\n : null\n }\n return null\n }\n\n // The synthetic event is inserted before its trigger, so share that\n // trigger's timestamp rather than making the earlier event sort later.\n const buildSynthesizedStart = (timestamp = Date.now()): StreamChunk => {\n const idForStart = structuredMessageId ?? generateMessageId()\n structuredMessageId = idForStart\n this.captureStructuredOutputMessageIdentity(idForStart)\n return {\n type: EventType.CUSTOM,\n name: 'structured-output.start',\n value: { messageId: idForStart },\n timestamp,\n }\n }\n\n const runChunkMiddleware = (\n synthChunk: StreamChunk,\n ): Promise<Array<StreamChunk>> =>\n this.middlewareRunner.runOnChunk(this.middlewareCtx, synthChunk)\n\n // Track whether a RUN_ERROR has been yielded to streaming consumers so\n // we don't emit a duplicate synthetic one at the end.\n let runErrorYielded = false\n\n // Pipe chunks through middleware; yield to consumer only when yieldChunks=true\n for await (const raw of providerStream) {\n // Honor cancellation between chunks (mirrors streamModelResponse).\n if (this.isCancelled()) {\n break\n }\n\n {\n const chunk = raw\n // Detect adapter-emitted structured-output.start so we don't duplicate\n if (\n !startEmitted &&\n chunk.type === EventType.CUSTOM &&\n chunk.name === 'structured-output.start'\n ) {\n startEmitted = true\n }\n\n // Capture the assistant messageId off any text-message event so the\n // synthesized start (when needed) uses the SAME id the deltas carry\n if (!structuredMessageId) {\n const extracted = extractMessageId(chunk)\n if (extracted) {\n structuredMessageId = extracted\n this.captureStructuredOutputMessageIdentity(extracted)\n }\n }\n\n // Synthesis only matters for the streaming client path — the agentic\n // Promise path consumes chunks internally and returns a Promise, so\n // there's no client-side StreamProcessor to route deltas for.\n if (this.finalStructuredOutput.yieldChunks) {\n // Synthesize start before the FIRST TEXT_MESSAGE_* event\n if (\n !startEmitted &&\n (chunk.type === EventType.TEXT_MESSAGE_START ||\n chunk.type === EventType.TEXT_MESSAGE_CONTENT ||\n chunk.type === EventType.TEXT_MESSAGE_END)\n ) {\n startEmitted = true\n const synthStart = buildSynthesizedStart(chunk.timestamp)\n yield* this.emitPublicChunks(await runChunkMiddleware(synthStart))\n }\n\n // Synthesize start before a pre-delta RUN_ERROR so the client can\n // construct an errored placeholder structured-output part instead\n // of a silent UI.\n if (!startEmitted && chunk.type === EventType.RUN_ERROR) {\n startEmitted = true\n const synthStart = buildSynthesizedStart(chunk.timestamp)\n yield* this.emitPublicChunks(await runChunkMiddleware(synthStart))\n }\n }\n\n // 7a. Targeted state updates only.\n // We deliberately do NOT call `handleStreamChunk(chunk)` here — that\n // would mutate agent-loop state with finalization data:\n // - TEXT_MESSAGE_CONTENT deltas would pollute `accumulatedContent`\n // (raw JSON would leak into `info.content` on onFinish)\n // - RUN_FINISHED would overwrite `finishedEvent` + `lastFinishReason`\n // (finalization's 'stop' would overwrite the agent-loop's real\n // finish reason)\n // - STEP_FINISHED would pollute `currentThinkingContent`\n // Finalization is a separate phase from the agent loop; its state must\n // not cross-contaminate. The explicit branches below capture the only\n // bits we actually need from this stream.\n // All narrowing below is via the discriminated-union `chunk.type`\n // — no `as` casts.\n\n // The chunk forwarded to middleware/consumers. Replaced below only for\n // the structured-output.complete event, whose `object` we normalize\n // (un-widen) so streaming consumers see the same cleaned payload the\n // Promise<T> path validates and returns.\n let outboundChunk: StreamChunk = chunk\n\n if (\n chunk.type === EventType.CUSTOM &&\n chunk.name === 'structured-output.complete'\n ) {\n const parsed = readStructuredOutputCompleteValue(chunk.value)\n if (parsed) {\n const object = this.finalStructuredOutput.normalize\n ? this.finalStructuredOutput.normalize(parsed.object)\n : parsed.object\n this.structuredOutputResult = {\n data: object,\n rawText: parsed.raw,\n ...(parsed.reasoning !== undefined\n ? { reasoning: parsed.reasoning }\n : {}),\n }\n // Rewrite the outbound event so the yielded chunk carries the\n // normalized object (the original `chunk.value` still holds the\n // widened one). Preserve every other field — `raw`, `reasoning` —\n // by spreading the original value.\n const value = chunk.value\n if (\n object !== parsed.object &&\n value &&\n typeof value === 'object'\n ) {\n outboundChunk = { ...chunk, value: { ...value, object } }\n }\n }\n }\n\n if (chunk.type === EventType.RUN_FINISHED) {\n await this.runOnUsageFromChunk(chunk)\n }\n\n if (chunk.type === EventType.RUN_ERROR) {\n // RunErrorEvent already exposes `message` and `code` after narrowing.\n this.finalizationError = {\n message: chunk.message,\n ...(chunk.code ? { code: chunk.code } : {}),\n ...(fallbackAdapterError !== undefined\n ? { cause: fallbackAdapterError }\n : {}),\n }\n }\n\n // 7b. Pipe through middleware\n const outputChunks = await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n outboundChunk,\n )\n\n // 7c. Decide consumer visibility — only yieldChunks=true callers get them.\n // We do NOT strip the finalization stream's RUN_STARTED/RUN_FINISHED:\n // they are the single outer lifecycle pair the consumer sees (the\n // agent-loop's pair was suppressed in streamModelResponse when\n // finalStructuredOutput.yieldChunks is true).\n if (this.finalStructuredOutput.yieldChunks) {\n for (const spec of this.emitPublicChunks(outputChunks)) {\n if (spec.type === EventType.RUN_ERROR) {\n runErrorYielded = true\n }\n yield spec\n }\n }\n\n // 7d. Terminate on error\n if (this.finalizationError) {\n break\n }\n }\n\n if (this.isCancelled() || this.finalizationError) {\n break\n }\n }\n\n // Mid-finalization abort: don't attribute a missing-result error.\n // Let the engine's `finally` block in `run()` route to `onAbort` instead\n // of mis-routing through `onError`.\n if (this.isCancelled()) {\n return\n }\n\n // Empty stream / missing complete event\n if (!this.structuredOutputResult && !this.finalizationError) {\n this.finalizationError = {\n message: 'missing structured result',\n code: 'structured-output-missing-result',\n }\n }\n\n // Run schema validation INSIDE the engine — before the terminal hook\n // chooser runs. Per spec §7.3, validation failures must route through\n // `onError`, not `onFinish`. We do this by writing to `finalizationError`\n // so the chooser in `run()` picks `onError`.\n if (\n this.structuredOutputResult &&\n !this.finalizationError &&\n this.finalStructuredOutput.validate\n ) {\n try {\n const validated = this.finalStructuredOutput.validate(\n this.structuredOutputResult.data,\n )\n this.validatedStructuredOutput = validated\n this.hasValidatedStructuredOutput = true\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err)\n this.finalizationError = {\n message,\n code: 'structured-output-validation-failed',\n cause: err,\n }\n }\n }\n\n // Streaming consumers must see a RUN_ERROR for finalization failures\n // (missing-result, validation-failed, or a finalizationError set after\n // a structured-output.complete already yielded). Without this synthetic\n // emission, the `for await` on the engine ends silently for the client.\n //\n // Skip when a RUN_ERROR was already yielded from the inner stream\n // (otherwise the consumer would see two error events for one failure).\n if (\n this.finalizationError &&\n this.finalStructuredOutput.yieldChunks &&\n !runErrorYielded\n ) {\n // Empty-stream case: no in-loop synthesis fired because no chunks\n // arrived. Synthesize `structured-output.start` here so the client-side\n // StreamProcessor can route the upcoming RUN_ERROR to a\n // `StructuredOutputPart` instead of dropping it as an orphan error.\n if (!startEmitted) {\n const synthStart = buildSynthesizedStart()\n yield* this.emitPublicChunks(await runChunkMiddleware(synthStart))\n startEmitted = true\n }\n\n const errChunk: StreamChunk = {\n type: EventType.RUN_ERROR,\n timestamp: Date.now(),\n message: this.finalizationError.message,\n ...(this.finalizationError.code\n ? { code: this.finalizationError.code }\n : {}),\n }\n yield* this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(this.middlewareCtx, errChunk),\n )\n }\n }\n\n /**\n * Native combined mode: harvest the structured output from the agent\n * loop's accumulated final-turn text (no separate provider call).\n *\n * The adapter wired `outputSchema` into the regular `chatStream` request,\n * so the model's final-turn text is the schema-constrained JSON. We parse\n * `this.accumulatedContent`, populate `this.structuredOutputResult`, emit\n * a synthetic `structured-output.complete` (and a `structured-output.start`\n * if one wasn't emitted earlier — only happens on the streaming path when\n * the model returned no text at all), and run the validate callback when\n * present. Failures populate `this.finalizationError` so the engine's\n * terminal-hook chooser routes to `onError` (per spec §7.3).\n *\n * The `'structuredOutput'` middleware phase intentionally does NOT fire on\n * this path — middleware sees the run through `beforeModel` / `modelStream`\n * as usual. See PR #605 / issue #605 for the design rationale.\n */\n private async *harvestCombinedStructuredOutput(): AsyncGenerator<StreamChunk> {\n if (!this.finalStructuredOutput) {\n throw new Error(\n 'harvestCombinedStructuredOutput called without finalStructuredOutput config',\n )\n }\n\n const yieldChunks = this.finalStructuredOutput.yieldChunks\n const source = this.finalStructuredOutput.source ?? 'text'\n\n if (source === 'event') {\n if (!this.structuredOutputResult) {\n this.finalizationError = {\n message: 'missing structured result',\n code: 'structured-output-missing-result',\n }\n }\n } else {\n const rawText = this.accumulatedContent\n\n // Empty final-turn text means the agent loop terminated without the\n // model emitting any assistant content (e.g. early termination after\n // tool calls). Mirror the fallback path's \"missing structured result\"\n // error rather than silently returning undefined.\n if (rawText.length === 0) {\n this.finalizationError = {\n message: 'missing structured result',\n code: 'structured-output-missing-result',\n }\n } else {\n try {\n const parsed: unknown = JSON.parse(rawText)\n // Normalize (un-widen) before storing so the synthesized\n // structured-output.complete chunk and the Promise<T> result both\n // carry the cleaned payload. JSON.parse preserves provider nulls, so\n // this is where native-combined output gets its widening undone.\n const data = this.finalStructuredOutput.normalize\n ? this.finalStructuredOutput.normalize(parsed)\n : parsed\n this.structuredOutputResult = { data, rawText }\n } catch (err: unknown) {\n const detail =\n rawText.slice(0, 200) + (rawText.length > 200 ? '...' : '')\n this.finalizationError = {\n message: `Failed to parse structured output as JSON. Content: ${detail}`,\n code: 'structured-output-parse-failed',\n cause: err,\n }\n }\n }\n }\n\n // Validate against the Standard Schema (when supplied). Validation\n // failures route through onError just like the fallback path.\n if (\n this.structuredOutputResult &&\n !this.finalizationError &&\n this.finalStructuredOutput.validate\n ) {\n try {\n const validated = this.finalStructuredOutput.validate(\n this.structuredOutputResult.data,\n )\n this.validatedStructuredOutput = validated\n this.hasValidatedStructuredOutput = true\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err)\n this.finalizationError = {\n message,\n code: 'structured-output-validation-failed',\n cause: err,\n }\n }\n }\n\n if (!yieldChunks) {\n // Promise<T> path: state is populated, nothing to yield. The\n // activity-layer caller pulls `structuredOutputResult` /\n // `validatedStructuredOutput` directly.\n return\n }\n\n // Streaming path: emit a synthetic `structured-output.start` if the\n // model produced no text at all (so the client snaps an errored\n // StructuredOutputPart rather than nothing). The normal path already\n // emitted start before the first TEXT_MESSAGE_START in\n // `streamModelResponse`.\n if (!this.combinedStartEmitted) {\n this.combinedStartEmitted = true\n const messageId = this.combinedStructuredMessageId ?? generateMessageId()\n this.combinedStructuredMessageId = messageId\n const synthStart: StreamChunk = {\n type: EventType.CUSTOM,\n name: 'structured-output.start',\n value: { messageId },\n timestamp: Date.now(),\n }\n yield* this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(this.middlewareCtx, synthStart),\n )\n }\n\n // On success, emit the synthetic `structured-output.complete` carrying\n // the parsed object + raw text. Pin the messageId so the client-side\n // handler can target the right UIMessage even when the agent loop's\n // terminal RUN_FINISHED has already cleared `activeMessageIds` (the\n // complete event yields AFTER the loop ends, by which point\n // `getActiveAssistantMessageId()` returns null and would otherwise drop\n // the event silently).\n if (\n this.structuredOutputResult &&\n !this.finalizationError &&\n !this.combinedCompleteEmitted\n ) {\n const completeChunk: StreamChunk = {\n type: EventType.CUSTOM,\n name: 'structured-output.complete',\n value: {\n object: this.structuredOutputResult.data,\n raw: this.structuredOutputResult.rawText,\n ...(this.combinedStructuredMessageId\n ? { messageId: this.combinedStructuredMessageId }\n : {}),\n },\n timestamp: Date.now(),\n }\n yield* this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n completeChunk,\n ),\n )\n }\n\n // On failure, emit a synthetic RUN_ERROR so the streaming consumer's\n // `for await` doesn't end silently. Mirrors the fallback path.\n if (this.finalizationError) {\n const errChunk: StreamChunk = {\n type: EventType.RUN_ERROR,\n timestamp: Date.now(),\n message: this.finalizationError.message,\n ...(this.finalizationError.code\n ? { code: this.finalizationError.code }\n : {}),\n }\n yield* this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(this.middlewareCtx, errChunk),\n )\n }\n }\n\n private buildMiddlewareConfig(): ChatMiddlewareConfig {\n return {\n messages: this.messages,\n providerMessages: this.messages,\n systemPrompts: [...this.systemPrompts],\n tools: [...this.tools],\n resume: this.params.resume,\n resumeToolState: {\n approvals: this.resumeApprovals,\n clientToolResults: this.resumeClientToolResults,\n deniedToolResults: this.resumeDeniedToolResults,\n cancelledToolCallIds: this.resumeCancelledToolCallIds,\n },\n metadata: this.params.metadata,\n modelOptions: this.params.modelOptions,\n }\n }\n\n private async applyEphemeralInterruptResume(\n config: ChatMiddlewareConfig,\n ): Promise<void> {\n if ((config.resume?.length ?? 0) === 0) {\n return\n }\n\n const interruptedRunId = this.parentRunIdOverride\n if (!interruptedRunId) {\n throw new InterruptResumeValidationError([\n {\n scope: 'batch',\n threadId: this.threadId,\n interruptedRunId: this.runIdOverride ?? this.requestId,\n generation: 0,\n interruptIds: config.resume?.map((entry) => entry.interruptId) ?? [],\n code: 'stale',\n message:\n 'Interrupt continuation requires parentRunId to identify the interrupted run.',\n source: 'server',\n retryable: false,\n },\n ])\n }\n\n const approvalRequests: Array<ApprovalRequest> = []\n const clientRequests: Array<ClientToolRequest> = []\n // Prefer resume-aware reconstruction so client-tool outputs already written\n // into history for UI still validate against the resume batch.\n const pendingToolCalls = this.getToolCallsForEphemeralResume(config.resume)\n const resumeInterruptIds = new Set(\n config.resume?.map((entry) => entry.interruptId),\n )\n const toolInputs = new Map<string, unknown>()\n const toolsByCallId = new Map<string, AnyRuntimeTool>()\n const clientExecutionCallIds = new Set<string>()\n\n for (const toolCall of pendingToolCalls) {\n const tool = this.tools.find(\n (candidate) => candidate.name === toolCall.function.name,\n )\n if (!tool) continue\n toolsByCallId.set(toolCall.id, tool)\n let input: unknown = {}\n try {\n const parsed = JSON.parse(toolCall.function.arguments.trim() || '{}')\n input = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n input = {}\n }\n toolInputs.set(toolCall.id, input)\n if (\n !tool.execute &&\n resumeInterruptIds.has(`client_tool_${toolCall.id}`)\n ) {\n clientExecutionCallIds.add(toolCall.id)\n }\n }\n\n // Mirror executeToolCalls' scheduling boundary. Server execution remains\n // gated while any approval is outstanding, but plain client tools are\n // represented in the same interrupt batch because requesting their output\n // does not execute a server-side effect.\n for (const toolCall of pendingToolCalls) {\n const tool = toolsByCallId.get(toolCall.id)\n if (tool?.needsApproval && !clientExecutionCallIds.has(toolCall.id)) {\n approvalRequests.push({\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input: toolInputs.get(toolCall.id) ?? {},\n approvalId: `approval_${toolCall.id}`,\n })\n }\n }\n\n for (const toolCall of pendingToolCalls) {\n const tool = toolsByCallId.get(toolCall.id)\n if (\n tool !== undefined &&\n !tool.execute &&\n (!tool.needsApproval || clientExecutionCallIds.has(toolCall.id))\n ) {\n clientRequests.push({\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input: toolInputs.get(toolCall.id) ?? {},\n })\n }\n }\n\n const genericPending = this.getGenericContinuationPending(interruptedRunId)\n const pending: Array<{\n interruptId: string\n payload: unknown\n binding: InterruptBinding\n genericRequest?: GenericInterruptRequest<\n InterruptDefinition<any, any, any, any>\n >\n }> = this.buildActionableInterrupts(\n approvalRequests,\n clientRequests,\n ).flatMap((descriptor) => {\n const unopened = readUnopenedInterruptBinding(descriptor)\n return unopened\n ? [\n {\n interruptId: descriptor.id,\n payload: descriptor,\n binding: {\n ...unopened,\n interruptedRunId,\n generation: 0,\n } satisfies InterruptBinding,\n },\n ]\n : []\n })\n pending.push(...genericPending)\n const validated = await validateInterruptResumeBatch({\n threadId: this.threadId,\n interruptedRunId,\n generation: 0,\n pending,\n resume: config.resume,\n tools: this.tools,\n })\n if (validated.errors.length > 0 || !validated.resumeToolState) {\n throw new InterruptResumeValidationError(validated.errors)\n }\n\n // A client-tool execution interrupt can only be emitted after an\n // approval-required client tool was approved in the preceding ephemeral\n // run. Reconstruct that phase marker from the trusted `client_tool_*`\n // continuation so executeToolCalls consumes the validated client output\n // instead of asking for approval again.\n const approvals = new Map(validated.resumeToolState.approvals)\n for (const request of clientRequests) {\n if (toolsByCallId.get(request.toolCallId)?.needsApproval) {\n approvals.set(request.toolCallId, true)\n }\n }\n this.applyResumeToolState({\n ...validated.resumeToolState,\n approvals,\n })\n\n const genericResolutions = validated.resumeToolState.genericInterrupts\n if (genericPending.length > 0 && genericResolutions) {\n const resolutions = genericPending\n .sort((left, right) => {\n const leftIndex =\n left.binding.kind === 'generic' ? (left.binding.batchIndex ?? 0) : 0\n const rightIndex =\n right.binding.kind === 'generic'\n ? (right.binding.batchIndex ?? 0)\n : 0\n return leftIndex - rightIndex\n })\n .flatMap((record) => {\n const resolution = genericResolutions.get(record.interruptId)\n if (!resolution || !record.genericRequest) return []\n return [\n resolution.status === 'resolved'\n ? {\n request: record.genericRequest,\n status: 'resolved' as const,\n response: resolution.payload,\n }\n : {\n request: record.genericRequest,\n status: 'cancelled' as const,\n },\n ]\n })\n const collection: InterruptResolutionCollection = {\n for: (definition) =>\n resolutions.filter(\n (resolution) => resolution.request.definition === definition,\n ) as never,\n all: (\n ...definitions: Array<InterruptDefinition<any, any, any, any>>\n ) =>\n definitions.length === 0\n ? resolutions\n : resolutions.filter((resolution) =>\n definitions.includes(resolution.request.definition),\n ),\n }\n const policy = await this.middlewareRunner.runOnInterruptResolution(\n this.middlewareCtx,\n collection,\n )\n if (policy.toolResume === 'stop') {\n this.earlyTermination = true\n } else if (policy.toolResume === 'cancel') {\n for (const request of pendingToolCalls) {\n this.resumeCancelledToolCallIds.add(request.id)\n }\n }\n }\n }\n\n private getGenericContinuationPending(interruptedRunId: string): Array<{\n interruptId: string\n payload: unknown\n binding: InterruptBinding\n genericRequest: GenericInterruptRequest<\n InterruptDefinition<any, any, any, any>\n >\n }> {\n const fail = (message: string): never => {\n throw new InterruptResumeValidationError([\n {\n scope: 'batch',\n threadId: this.threadId,\n interruptedRunId,\n generation: 0,\n interruptIds: [],\n code: 'stale',\n message,\n source: 'server',\n retryable: false,\n },\n ])\n }\n const pending: Array<{\n interruptId: string\n payload: unknown\n binding: InterruptBinding\n genericRequest: GenericInterruptRequest<\n InterruptDefinition<any, any, any, any>\n >\n }> = []\n const ids = new Set<string>()\n const batchIndexes = new Set<number>()\n for (const resumeItem of this.params.resume ?? []) {\n const parsed = readGenericInterruptContinuation(resumeItem.metadata)\n if (parsed.status === 'absent') continue\n if (parsed.status === 'invalid') {\n return fail(parsed.message)\n }\n const entry = parsed.value\n const id = resumeItem.interruptId\n const definition = this.interruptDefinitions.get(entry.definitionId)\n if (!definition) {\n return fail(\n `Generic interrupt definition ${entry.definitionId} is unavailable.`,\n )\n }\n if (ids.has(id) || batchIndexes.has(entry.batchIndex)) {\n return fail(\n 'Generic interrupt continuation contains duplicate entries.',\n )\n }\n ids.add(id)\n batchIndexes.add(entry.batchIndex)\n let request: GenericInterruptRequest<\n InterruptDefinition<any, any, any, any>\n >\n try {\n request = rehydrateInterruptRequest(definition, {\n key: entry.key,\n reason: entry.reason,\n message: entry.message,\n ...(typeof entry.expiresAt === 'string'\n ? { expiresAt: entry.expiresAt }\n : {}),\n ...(Object.prototype.hasOwnProperty.call(entry, 'payload')\n ? { payload: entry.payload }\n : {}),\n })\n } catch (error) {\n return fail(\n `Generic interrupt continuation ${id} is invalid: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n const emitted = createInterruptBinding(request, {\n batchIndex: entry.batchIndex,\n })\n if (\n entry.responseSchemaHash !== emitted.descriptor.responseSchemaHash ||\n entry.payloadSchemaHash !== emitted.descriptor.payloadSchemaHash\n ) {\n return fail(\n `Generic interrupt continuation ${id} does not match its definition.`,\n )\n }\n pending.push({\n interruptId: id,\n payload: {\n id,\n ...(emitted.descriptor.responseSchemaCanonicalJson !== undefined\n ? {\n responseSchema: JSON.parse(\n emitted.descriptor.responseSchemaCanonicalJson,\n ),\n }\n : {}),\n },\n binding: {\n v: INTERRUPT_BINDING_VERSION,\n kind: 'generic',\n interruptId: id,\n interruptedRunId,\n generation: 0,\n definitionId: entry.definitionId,\n key: entry.key,\n batchIndex: entry.batchIndex,\n ...(typeof entry.expiresAt === 'string'\n ? { expiresAt: entry.expiresAt }\n : {}),\n ...(emitted.descriptor.payloadSchemaHash\n ? { payloadSchemaHash: emitted.descriptor.payloadSchemaHash }\n : {}),\n ...(entry.responseSchemaHash !== undefined\n ? { responseSchemaHash: entry.responseSchemaHash }\n : {}),\n },\n genericRequest: request,\n })\n }\n return pending\n }\n\n private applyResumeToolState(state: ChatResumeToolState | undefined): void {\n if (state?.approvals) {\n for (const [approvalId, resolution] of state.approvals) {\n this.resumeApprovals.set(approvalId, resolution)\n }\n }\n if (state?.clientToolResults) {\n for (const [toolCallId, result] of state.clientToolResults) {\n this.resumeClientToolResults.set(toolCallId, result)\n }\n }\n if (state?.deniedToolResults) {\n for (const [toolCallId, result] of state.deniedToolResults) {\n this.resumeDeniedToolResults.set(toolCallId, result)\n }\n }\n if (state?.cancelledToolCallIds) {\n for (const toolCallId of state.cancelledToolCallIds) {\n this.resumeCancelledToolCallIds.add(toolCallId)\n }\n }\n if (state?.genericInterrupts) {\n for (const [interruptId, resolution] of state.genericInterrupts) {\n this.resumeGenericInterrupts.set(interruptId, resolution)\n }\n }\n if (state?.genericInterruptRequests) {\n for (const [interruptId, request] of state.genericInterruptRequests) {\n this.resumeGenericInterruptRequests.set(interruptId, request)\n }\n }\n }\n\n private async applyDurableGenericInterruptResolution(): Promise<void> {\n if (this.resumeGenericInterruptRequests.size === 0) return\n const resolutions = [\n ...this.resumeGenericInterruptRequests.entries(),\n ].flatMap(([interruptId, request]) => {\n const resolution = this.resumeGenericInterrupts.get(interruptId)\n if (!resolution) return []\n return [\n resolution.status === 'resolved'\n ? {\n request,\n status: 'resolved' as const,\n response: resolution.payload,\n }\n : { request, status: 'cancelled' as const },\n ]\n })\n const collection: InterruptResolutionCollection = {\n for: (definition) =>\n resolutions.filter(\n (resolution) => resolution.request.definition === definition,\n ) as never,\n all: (...definitions: Array<InterruptDefinition<any, any, any, any>>) =>\n definitions.length === 0\n ? resolutions\n : resolutions.filter((resolution) =>\n definitions.includes(resolution.request.definition),\n ),\n }\n const policy = await this.middlewareRunner.runOnInterruptResolution(\n this.middlewareCtx,\n collection,\n )\n if (policy.toolResume === 'stop') {\n this.earlyTermination = true\n } else if (policy.toolResume === 'cancel') {\n for (const toolCall of this.getPendingToolCallsFromMessages()) {\n this.resumeCancelledToolCallIds.add(toolCall.id)\n }\n }\n }\n\n private applyMiddlewareConfig(config: ChatMiddlewareConfig): void {\n this.applyResumeToolState(config.resumeToolState)\n this.messages = config.messages\n this.providerMessages = config.providerMessages ?? config.messages\n this.systemPrompts = config.systemPrompts\n assertUniqueToolNames(config.tools)\n this.tools = config.tools\n this.params = {\n ...this.params,\n metadata: config.metadata,\n modelOptions: config.modelOptions,\n }\n\n // Sync context fields that depend on config\n this.middlewareCtx.messages = this.messages\n this.middlewareCtx.systemPrompts = this.systemPrompts\n this.middlewareCtx.hasTools = this.tools.length > 0\n this.middlewareCtx.toolNames = this.tools.map((t) => t.name)\n this.middlewareCtx.modelOptions = config.modelOptions\n }\n\n private setToolPhase(phase: ToolPhaseResult): void {\n this.toolPhase = phase\n }\n\n /**\n * Spec-normalize middleware output, then yield to the public iterable.\n * Engine state and `onChunk` already saw the raw chunk.\n */\n private *emitPublicChunks(\n outputs: Array<StreamChunk>,\n ): Generator<StreamChunk, void, void> {\n for (const output of outputs) {\n for (const spec of normalizeStreamChunk(output as AdapterYieldChunk)) {\n restorePublicUsage(spec)\n if (spec.type === EventType.RUN_STARTED) {\n if (this.hasPublicRunStarted) continue\n this.hasPublicRunStarted = true\n }\n yield spec\n this.middlewareCtx.chunkIndex++\n }\n }\n }\n\n /**\n * Pipe a single internal chunk through middleware, then spec-normalize\n * before the public `for await` stream.\n */\n private async *pipeThroughMiddleware(\n chunk: AdapterYieldChunk,\n ): AsyncGenerator<StreamChunk, void, void> {\n const afterMw = await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n chunk,\n )\n yield* this.emitPublicChunks(afterMw)\n if (!this.drainingMiddlewareCustom) {\n yield* this.drainMiddlewareCustomQueue()\n }\n }\n\n /**\n * Drain CUSTOM chunks pushed by `ctx.emitCustomEvent` through middleware\n * and into the public stream. If the run has not yet sent `RUN_STARTED`,\n * emit that first so CUSTOM events are not the first wire event.\n */\n private async *drainMiddlewareCustomQueue(): AsyncGenerator<StreamChunk> {\n if (this.drainingMiddlewareCustom) return\n if (this.middlewareCustomQueue.length === 0) return\n this.drainingMiddlewareCustom = true\n try {\n yield* this.emitSyntheticRunStarted(this.createSyntheticFinishedEvent())\n while (this.middlewareCustomQueue.length > 0) {\n const chunk = this.middlewareCustomQueue.shift()\n if (chunk) yield* this.pipeThroughMiddleware(chunk)\n }\n } finally {\n this.drainingMiddlewareCustom = false\n }\n }\n\n /**\n * Await `work` while yielding any `emitCustomEvent` chunks as they arrive.\n */\n private async *runWhileYielding<T>(\n work: Promise<T>,\n ): AsyncGenerator<StreamChunk, T> {\n let settled = false\n let result: T | undefined\n let error: unknown\n const done = work.then(\n (value) => {\n settled = true\n result = value\n },\n (err: unknown) => {\n settled = true\n error = err\n },\n )\n\n while (!settled) {\n yield* this.drainMiddlewareCustomQueue()\n if (settled) break\n await Promise.race([\n done,\n new Promise<void>((resolve) => {\n if (this.middlewareCustomQueue.length > 0) {\n resolve()\n return\n }\n this.middlewareCustomWaiters.push(resolve)\n }),\n ])\n }\n\n yield* this.drainMiddlewareCustomQueue()\n if (error !== undefined) throw error\n return result as T\n }\n\n /**\n * Drain queued `sandbox.file` chunks (emitted via the SandboxRuntime sink)\n * through the middleware pipeline and into the public stream.\n */\n private async *drainSandboxFileQueue(): AsyncGenerator<StreamChunk> {\n while (this.sandboxFileQueue.length > 0) {\n const chunk = this.sandboxFileQueue.shift()\n if (chunk) yield* this.pipeThroughMiddleware(chunk)\n }\n }\n\n /**\n * Drain an executeToolCalls async generator, yielding any CustomEvent chunks\n * through the middleware pipeline and returning the final ExecuteToolCallsResult.\n */\n private async *drainToolCallGenerator(\n generator: AsyncGenerator<\n CustomEvent,\n {\n results: Array<ToolResult>\n needsApproval: Array<ApprovalRequest>\n needsClientExecution: Array<ClientToolRequest>\n },\n void\n >,\n ): AsyncGenerator<\n StreamChunk,\n {\n results: Array<ToolResult>\n needsApproval: Array<ApprovalRequest>\n needsClientExecution: Array<ClientToolRequest>\n },\n void\n > {\n let pending = generator.next()\n while (true) {\n const next = yield* this.runWhileYielding(pending)\n if (next.done) return next.value\n yield* this.pipeThroughMiddleware(next.value)\n pending = generator.next()\n }\n }\n\n private createCustomEventChunk(\n eventName: string,\n value: Record<string, unknown>,\n ): CustomEvent {\n return {\n type: EventType.CUSTOM,\n timestamp: Date.now(),\n name: eventName,\n value,\n }\n }\n\n private createId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n }\n}\n\n// ===========================\n// Activity Implementation\n// ===========================\n\n/**\n * Text activity - handles agentic text generation, one-shot text generation, and agentic structured output.\n *\n * This activity supports four modes:\n * 1. **Streaming agentic text**: Stream responses with automatic tool execution\n * 2. **Streaming one-shot text**: Simple streaming request/response without tools\n * 3. **Non-streaming text**: Returns collected text as a string (stream: false)\n * 4. **Agentic structured output**: Run tools, then return structured data\n *\n * @example Full agentic text (streaming with tools)\n * ```ts\n * import { chat } from '@tanstack/ai'\n * import { openaiText } from '@tanstack/ai-openai'\n *\n * for await (const chunk of chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'What is the weather?' }],\n * tools: [weatherTool]\n * })) {\n * if (chunk.type === 'TEXT_MESSAGE_CONTENT') {\n * console.log(chunk.delta)\n * }\n * }\n * ```\n *\n * @example One-shot text (streaming without tools)\n * ```ts\n * for await (const chunk of chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * })) {\n * console.log(chunk)\n * }\n * ```\n *\n * @example Non-streaming text (stream: false)\n * ```ts\n * const text = await chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Hello!' }],\n * stream: false\n * })\n * // text is a string with the full response\n * ```\n *\n * @example Agentic structured output (tools + structured response)\n * ```ts\n * import { z } from 'zod'\n *\n * const result = await chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Research and summarize the topic' }],\n * tools: [researchTool, analyzeTool],\n * outputSchema: z.object({\n * summary: z.string(),\n * keyPoints: z.array(z.string())\n * })\n * })\n * // result is { summary: string, keyPoints: string[] }\n * ```\n */\nexport function chat<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined = undefined,\n TStream extends boolean = boolean,\n const TTools extends TextActivityOptions<\n TAdapter,\n TSchema,\n TStream,\n any\n >['tools'] = TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'],\n const TInterrupts extends ReadonlyArray<\n InterruptDefinition<any, any, any, any>\n > = [],\n TContext = unknown,\n const TMiddleware extends Array<unknown> | undefined = undefined,\n>(\n options: TextActivityOptionsWithContext<\n TAdapter,\n TSchema,\n TStream,\n TTools,\n TInterrupts,\n TContext,\n TMiddleware\n >,\n): TextActivityResult<TSchema, TStream, TTools> {\n validateInterruptDefinitions(options.interrupts)\n validateCapabilities(\n readRuntimeMiddleware(options.middleware) ?? [],\n options.adapter,\n )\n if (options.tools) {\n assertUniqueToolNames(options.tools)\n }\n\n const { outputSchema, stream } = options\n\n if (outputSchema && stream === true) {\n return runStreamingStructuredOutput(\n toRuntimeTextActivityOptions(options, {\n outputSchema,\n stream: true,\n }),\n ) as TextActivityResult<TSchema, TStream, TTools>\n }\n\n if (outputSchema) {\n return runAgenticStructuredOutput(\n toRuntimeTextActivityOptions(options, {\n outputSchema,\n stream: false,\n }),\n ) as TextActivityResult<TSchema, TStream, TTools>\n }\n\n if (stream === false) {\n return runNonStreamingText(\n toRuntimeTextActivityOptions(options, {\n outputSchema: undefined,\n stream: false,\n }),\n ) as TextActivityResult<TSchema, TStream, TTools>\n }\n\n return runStreamingText(\n toRuntimeTextActivityOptions(options, {\n outputSchema: undefined,\n stream: true,\n }),\n ) as TextActivityResult<TSchema, TStream, TTools>\n}\n\ntype RuntimeTextActivityOptions<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined,\n TStream extends boolean,\n> = Omit<TextActivityOptions<TAdapter, TSchema, TStream, any>, 'middleware'> & {\n middleware?: Array<AnyChatMiddleware>\n}\n\nfunction readRuntimeMiddleware(\n middleware: unknown,\n): Array<AnyChatMiddleware> | undefined {\n if (middleware === undefined) return undefined\n if (!Array.isArray(middleware)) {\n throw new TypeError('Chat middleware must be an array.')\n }\n return middleware\n}\n\nfunction toRuntimeTextActivityOptions<\n TAdapter extends AnyTextAdapter,\n TInputSchema extends SchemaInput | undefined,\n TInputStream extends boolean,\n TOutputSchema extends SchemaInput | undefined,\n TOutputStream extends boolean,\n TTools extends TextActivityOptions<\n TAdapter,\n TInputSchema,\n TInputStream,\n any\n >['tools'],\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TContext,\n TMiddleware extends Array<unknown> | undefined,\n>(\n options: TextActivityOptionsWithContext<\n TAdapter,\n TInputSchema,\n TInputStream,\n TTools,\n TInterrupts,\n TContext,\n TMiddleware\n >,\n overrides: { outputSchema: TOutputSchema; stream: TOutputStream },\n): RuntimeTextActivityOptions<TAdapter, TOutputSchema, TOutputStream> {\n const { middleware, ...rest } = options\n return {\n ...rest,\n ...overrides,\n ...(middleware === undefined\n ? {}\n : { middleware: readRuntimeMiddleware(middleware) }),\n }\n}\n\nfunction validateInterruptDefinitions(\n definitions:\n | ReadonlyArray<InterruptDefinition<any, any, any, any>>\n | undefined,\n): void {\n if (!definitions) return\n const seen = new Set<string>()\n for (const definition of definitions) {\n if (seen.has(definition.id)) {\n throw new Error(`Duplicate interrupt definition id: ${definition.id}`)\n }\n seen.add(definition.id)\n }\n}\n\n/**\n * The slice of the engine that the durable delivery sink reaches back into, in\n * BOTH directions: it reads the detach verdict (`wasDetached`) and pushes the\n * socket-closed fact in (`notifyDisconnected`). Filled by the generator body as\n * soon as its engine exists.\n */\ninterface DeliveryEngineRef {\n current?: {\n wasDetached: () => boolean\n notifyDisconnected: () => void\n }\n}\n\n/**\n * Publish both delivery-side seams for `stream`.\n *\n * Shared by the two streaming paths so they cannot drift apart — the\n * structured-output path having been wired for one seam and not the other is\n * exactly the bug `publishRunDetachedSignal` picked up last time (a durable\n * `chat({ outputSchema, stream: true })` could never detach).\n */\nfunction publishDeliverySeams(\n stream: object,\n engineRef: DeliveryEngineRef,\n): void {\n // A thunk, evaluated on the sink's teardown path: the engine does not exist\n // yet, and the verdict it will report is only written during `onAbort`.\n publishRunDetachedSignal(\n stream,\n () => engineRef.current?.wasDetached() === true,\n )\n // The inbound direction. Dropped if the socket closes before the body has run\n // far enough to have an engine, which is correct: there is no run state to\n // record yet, and `setup` has not begun, so nothing is leaked by not knowing.\n publishRunDisconnectHandler(stream, () => {\n engineRef.current?.notifyDisconnected()\n })\n}\n\n/**\n * Run streaming text (agentic or one-shot depending on tools).\n *\n * A thin, NON-generator wrapper, because the stream object is also the key the\n * durable delivery sink looks the run's detach verdict up under (see\n * `../../delivery-detach`) and delivers its disconnect notification through (see\n * `../../delivery-disconnect`). A generator function cannot reach the generator it\n * returns, so the identity has to be minted out here and the engine reached back\n * through `engineRef`, which the body fills as soon as its engine exists.\n */\nfunction runStreamingText(\n options: RuntimeTextActivityOptions<AnyTextAdapter, undefined, boolean>,\n): AsyncIterable<StreamChunk> {\n const engineRef: DeliveryEngineRef = {}\n const stream = streamTextChunks(options, engineRef)\n publishDeliverySeams(stream, engineRef)\n return stream\n}\n\nasync function* streamTextChunks(\n options: RuntimeTextActivityOptions<AnyTextAdapter, undefined, boolean>,\n engineRef: DeliveryEngineRef,\n): AsyncIterable<StreamChunk> {\n const { adapter, middleware, context, debug, mcp, ...textOptions } = options\n const model = adapter.model\n const logger = resolveDebugOption(debug)\n\n const mcpManager = MCPManager.from(mcp)\n const mcpTools = await mcpManager.discover()\n if (mcpTools.length > 0) {\n textOptions.tools = [...(textOptions.tools ?? []), ...mcpTools]\n }\n\n const engine = new TextEngine(\n {\n adapter,\n params: { ...textOptions, model, logger } as TextOptions<\n Record<string, any>,\n Record<string, any>,\n any\n >,\n middleware,\n context,\n },\n logger,\n )\n engineRef.current = engine\n\n try {\n for await (const chunk of engine.run()) {\n yield chunk\n }\n } finally {\n await mcpManager.dispose()\n }\n}\n\n/**\n * Run non-streaming text - collects all content and returns as a string.\n * Runs the full agentic loop (if tools are provided) but returns collected text.\n */\nfunction runNonStreamingText(\n options: RuntimeTextActivityOptions<AnyTextAdapter, undefined, false>,\n): Promise<string> {\n const stream = runStreamingText({\n ...options,\n stream: true,\n })\n\n return streamToText(stream)\n}\n\n/**\n * Run agentic structured output:\n * 1. Execute the full agentic loop (with tools)\n * 2. Once complete, call adapter.structuredOutput with the conversation context\n * 3. Validate and return the structured result\n */\nasync function runAgenticStructuredOutput<TSchema extends SchemaInput>(\n options: RuntimeTextActivityOptions<AnyTextAdapter, TSchema, boolean>,\n): Promise<InferSchemaType<TSchema>> {\n const {\n adapter,\n outputSchema,\n middleware,\n context,\n debug,\n mcp,\n ...textOptions\n } = options\n const model = adapter.model\n const logger = resolveDebugOption(debug)\n\n if (!outputSchema) {\n throw new Error('outputSchema is required for structured output')\n }\n\n // Same strict-conversion as the streaming path (`forStructuredOutput: true`)\n // so the same Zod schema produces the same JSON Schema regardless of\n // stream mode — Promise<T> and stream:true must not diverge here. The same\n // pass also records a `nullWideningMap`: optional fields are widened to\n // `required` + nullable for the provider, which then returns `null` for an\n // absent optional — a `null` the original `.optional()` (`T | undefined`)\n // schema would otherwise reject. The map pinpoints exactly those synthesized\n // nulls so `undoNullWidening` can drop them while preserving the ones a\n // `.nullable()` field genuinely allows.\n const { jsonSchema, nullWideningMap } =\n convertSchemaForStructuredOutput(outputSchema)\n if (!jsonSchema) {\n throw new Error('Failed to convert output schema to JSON Schema')\n }\n\n // Un-widening runs in the engine the moment the structured output is\n // captured (`finalStructuredOutput.normalize`), so it applies uniformly to\n // every adapter and to both stream modes — the engine is the only layer\n // holding the schema's `nullWideningMap`. Validation then runs on the\n // already-normalized data, so `validate` is a plain Standard Schema parse.\n const normalize = (data: unknown): unknown =>\n undoNullWidening(data, nullWideningMap)\n\n // Validation runs INSIDE the engine (per spec §7.3) so validation failures\n // route through the engine's terminal-hook chooser as `onError`. We pass a\n // `validate` callback when the schema is a Standard Schema; otherwise we\n // pass through the (normalized) data and the engine returns it unchanged.\n const validate = isStandardSchema(outputSchema)\n ? (data: unknown): unknown =>\n parseWithStandardSchema<InferSchemaType<TSchema>>(outputSchema, data)\n : undefined\n\n // Per issue #605: same capability check as the streaming path. When the\n // adapter handles tools + schema natively, the engine skips the separate\n // structured-output finalization call and harvests the JSON from the\n // agent loop's accumulated final-turn text.\n const nativeCombined =\n adapter.supportsCombinedToolsAndSchema?.(options.modelOptions) === true\n const source =\n adapter.combinedStructuredOutputSource?.(options.modelOptions) ?? 'text'\n\n const mcpManager = MCPManager.from(mcp)\n const mcpTools = await mcpManager.discover()\n if (mcpTools.length > 0) {\n textOptions.tools = [...(textOptions.tools ?? []), ...mcpTools]\n }\n\n const engine = new TextEngine(\n {\n adapter,\n params: { ...textOptions, model, logger } as TextOptions<\n Record<string, unknown>,\n Record<string, unknown>,\n any\n >,\n middleware,\n context,\n finalStructuredOutput: {\n jsonSchema,\n yieldChunks: false,\n normalize,\n ...(validate ? { validate } : {}),\n ...(nativeCombined ? { nativeCombined: true } : {}),\n source,\n },\n },\n logger,\n )\n\n try {\n // Consume the stream — chunks pipe through middleware but are not yielded externally\n for await (const _chunk of engine.run()) {\n // intentionally empty\n }\n } finally {\n await mcpManager.dispose()\n }\n\n const finalizationError = engine.getFinalizationError()\n if (finalizationError) {\n const err = new Error(\n finalizationError.message,\n finalizationError.cause !== undefined\n ? { cause: finalizationError.cause }\n : undefined,\n )\n if (finalizationError.code !== undefined) {\n Object.defineProperty(err, 'code', {\n value: finalizationError.code,\n enumerable: true,\n })\n }\n throw err\n }\n\n // If a validator ran, return the validated value (typed by InferSchemaType\n // via the callback closure). Otherwise return the raw data.\n const validated = engine.getValidatedStructuredOutput()\n if (validated) {\n return validated.value as InferSchemaType<TSchema>\n }\n\n const result = engine.getStructuredOutputResult()\n if (!result) {\n throw new Error('structured output finalization produced no result')\n }\n return result.data as InferSchemaType<TSchema>\n}\n\n/**\n * Parse the `value` payload of a `structured-output.complete` CUSTOM event\n * into a typed shape, returning `null` if the runtime payload doesn't match.\n *\n * Uses an `unknown`-input runtime check rather than `as` casts so the engine\n * stays cast-free in its hot path.\n */\nfunction readCustomEventMessageId(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined\n if (!('messageId' in value)) return undefined\n const messageId = value.messageId\n return typeof messageId === 'string' && messageId !== ''\n ? messageId\n : undefined\n}\n\nfunction readStructuredOutputCompleteValue(\n value: unknown,\n): { object: unknown; raw: string; reasoning?: string } | null {\n if (typeof value !== 'object' || value === null) return null\n if (!('object' in value) || !('raw' in value)) return null\n const raw = (value as { raw: unknown }).raw\n if (typeof raw !== 'string') return null\n const reasoningField = (value as { reasoning?: unknown }).reasoning\n const reasoning =\n typeof reasoningField === 'string' ? reasoningField : undefined\n return {\n object: (value as { object: unknown }).object,\n raw,\n ...(reasoning !== undefined ? { reasoning } : {}),\n }\n}\n\n/**\n * Synthesize a streaming structured-output stream by wrapping a non-streaming\n * `structuredOutput` call. Used when an adapter doesn't implement\n * `structuredOutputStream` natively.\n *\n * `onAdapterError`, when provided, is invoked with the raw error from\n * `adapter.structuredOutput` before the synthesized RUN_ERROR is yielded.\n * The engine uses this to preserve the original error (stack, cause, custom\n * properties like provider `status`/`code`) as `finalizationError.cause`,\n * because the RUN_ERROR wire shape only carries `message` and `code`.\n */\nasync function* fallbackStructuredOutputStream(\n adapter: AnyTextAdapter,\n options: StructuredOutputOptions<Record<string, unknown>>,\n onAdapterError?: (err: unknown) => void,\n): AsyncIterable<AdapterYieldChunk> {\n const { chatOptions } = options\n // Synthesize run/thread/message IDs only when the caller didn't supply them.\n // Prefix `fallback-` (not `mock-`) because this is production fallback code\n // used by adapters without native `structuredOutputStream`, not test fixtures.\n const fallbackRand = Math.random().toString(36).slice(2)\n const runId = chatOptions.runId ?? `fallback-${Date.now()}-${fallbackRand}`\n const threadId =\n chatOptions.threadId ?? `fallback-${Date.now()}-${fallbackRand}`\n const messageId = `fallback-${Date.now()}-${fallbackRand}`\n const model = chatOptions.model\n const startedAt = Date.now()\n\n yield {\n type: EventType.RUN_STARTED,\n runId,\n threadId,\n model,\n timestamp: startedAt,\n }\n\n let result: StructuredOutputResult<unknown>\n try {\n result = await adapter.structuredOutput(options)\n } catch (error) {\n onAdapterError?.(error)\n const message = error instanceof Error ? error.message : String(error)\n yield {\n type: EventType.RUN_ERROR,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n message,\n error: { message },\n }\n return\n }\n\n yield {\n type: EventType.TEXT_MESSAGE_START,\n messageId,\n role: 'assistant',\n model,\n timestamp: Date.now(),\n }\n\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId,\n delta: result.rawText,\n model,\n timestamp: Date.now(),\n }\n\n yield {\n type: EventType.TEXT_MESSAGE_END,\n messageId,\n model,\n timestamp: Date.now(),\n }\n\n yield {\n type: EventType.CUSTOM,\n name: 'structured-output.complete',\n value: { object: result.data, raw: result.rawText },\n model,\n timestamp: Date.now(),\n }\n\n yield {\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n finishReason: 'stop',\n // Forward adapter-reported token usage so consumers reading\n // `RUN_FINISHED.usage` (and the engine's `runOnUsage` middleware hook) see\n // it on the fallback path, mirroring the native streaming path. The\n // conditional spread avoids emitting `usage: undefined` for adapters that\n // don't report it. See #758.\n ...(result.usage ? { usage: result.usage } : {}),\n }\n}\n\n/**\n * Run streaming structured output via the TextEngine, with the engine's\n * `finalStructuredOutput.yieldChunks: true` mode. The agent loop's\n * RUN_STARTED/RUN_FINISHED are suppressed; the structured-output finalization\n * step's pair brackets the run for the consumer.\n *\n * Standard Schema *validation* is intentionally NOT run on this path — it is\n * the consumer's responsibility. This is a deliberate asymmetry vs.\n * `runAgenticStructuredOutput` (Promise<T> path), which DOES validate inside\n * the engine and routes validation failures through `onError`. The reason:\n * streaming consumers typically render partial JSON progressively (via\n * `parsePartialJSON` or `useChat`'s `partial` slot) and validate downstream\n * after assembly. Running validation server-side would force a hard error\n * on partial-by-design payloads. See `docs/structured-outputs/overview.md`.\n *\n * Null-widening normalization, however, IS run on both paths: the\n * `structured-output.complete` CUSTOM event is forwarded with its `value.object`\n * already un-widened (synthesized strict-mode nulls dropped, genuine\n * `.nullable()` nulls kept), so a consumer validating the assembled object\n * against the original schema doesn't choke on a `null` for an `.optional()`\n * field. Same `convertSchemaForStructuredOutput` pass and same\n * `undoNullWidening` map as the Promise<T> path — the two must not diverge.\n *\n * Pre-flight validation (missing schema, unconvertible schema) throws\n * synchronously at call time rather than as a yielded RUN_ERROR mid-stream —\n * those are programmer errors, not runtime conditions.\n */\nfunction runStreamingStructuredOutput<TSchema extends SchemaInput>(\n options: RuntimeTextActivityOptions<AnyTextAdapter, TSchema, true>,\n): StructuredOutputStream<InferSchemaType<TSchema>> {\n const { outputSchema } = options\n\n if (!outputSchema) {\n throw new Error('outputSchema is required for streaming structured output')\n }\n\n // forStructuredOutput strict-converts the schema once at the activity\n // boundary, capturing the null-widening map so the engine can un-widen the\n // provider's response before it reaches the consumer. Adapters can re-convert\n // if their wire format diverges, but the default flow hands them a\n // strict-ready schema.\n const { jsonSchema, nullWideningMap } =\n convertSchemaForStructuredOutput(outputSchema)\n if (!jsonSchema) {\n throw new Error('Failed to convert output schema to JSON Schema')\n }\n const normalize = (data: unknown): unknown =>\n undoNullWidening(data, nullWideningMap)\n\n // The implementation generator yields the broader internal type\n // (`StreamChunk | StructuredOutputCompleteEvent<T>`) so middleware and\n // tool-emitted CustomEvents can flow through. Core approval/client-tool\n // waits are represented by RUN_FINISHED interrupt outcomes, not by direct\n // CUSTOM wait events.\n // The contained cast keeps the public stream type focused on\n // structured-output completion.\n //\n // Same seam as `runStreamingText`: this wrapper is NOT a generator, so the\n // stream identity can be minted here and the engine reached back through\n // `engineRef` once the impl body has its engine. Without this a durable\n // structured-output stream could never detach — the sink would find no verdict\n // and terminalize a healthy detached run's log — nor survive a disconnect.\n const engineRef: DeliveryEngineRef = {}\n const stream = runStreamingStructuredOutputImpl(\n options,\n jsonSchema,\n normalize,\n engineRef,\n )\n publishDeliverySeams(stream, engineRef)\n return stream as StructuredOutputStream<InferSchemaType<TSchema>>\n}\n\n/**\n * Internal generator return type — broader than the public\n * `StructuredOutputStream<T>`. The structured-output completion event remains\n * the pinned public CUSTOM event for this stream; approval and client-tool\n * waits now surface as RUN_FINISHED interrupt outcomes. At runtime, tools can\n * still emit arbitrary user-defined `CustomEvent`s through the\n * `emitCustomEvent` context API; those flow\n * through this generator with `name: string` and are widened out at the\n * public boundary because keeping them would collapse the typed narrow back\n * to `any`. The cast inside `runStreamingStructuredOutput` is where that\n * widening happens.\n */\ntype StructuredOutputStreamInternal<T> = AsyncIterable<\n StreamChunk | StructuredOutputCompleteEvent<T>\n>\n\nasync function* runStreamingStructuredOutputImpl<TSchema extends SchemaInput>(\n options: RuntimeTextActivityOptions<AnyTextAdapter, TSchema, true>,\n jsonSchema: NonNullable<ReturnType<typeof convertSchemaToJsonSchema>>,\n normalize: (data: unknown) => unknown,\n engineRef: DeliveryEngineRef,\n): StructuredOutputStreamInternal<InferSchemaType<TSchema>> {\n const {\n adapter,\n outputSchema,\n middleware,\n context,\n debug,\n mcp,\n ...textOptions\n } = options\n const model = adapter.model\n const logger = resolveDebugOption(debug)\n\n // Per issue #605: adapters that natively combine tools + schema-constrained\n // output in one streaming call (modern OpenAI, Anthropic 4.5+, Gemini 3+,\n // Grok 4+) opt in via `supportsCombinedToolsAndSchema()`. The engine then\n // forwards the schema into the regular `chatStream` call and harvests the\n // structured result from the agent loop's accumulated text — no separate\n // finalization round-trip, and the `'structuredOutput'` middleware phase\n // does not fire.\n const nativeCombined =\n adapter.supportsCombinedToolsAndSchema?.(options.modelOptions) === true\n const source =\n adapter.combinedStructuredOutputSource?.(options.modelOptions) ?? 'text'\n\n const mcpManager = MCPManager.from(mcp)\n const mcpTools = await mcpManager.discover()\n if (mcpTools.length > 0) {\n textOptions.tools = [...(textOptions.tools ?? []), ...mcpTools]\n }\n\n // Inputs may be UIMessages (from useChat) or ModelMessages (from server-side\n // callers). TextEngine handles the conversion uniformly.\n const engine = new TextEngine(\n {\n adapter,\n params: { ...textOptions, model, logger } as TextOptions<\n Record<string, unknown>,\n Record<string, unknown>,\n any\n >,\n middleware,\n context,\n finalStructuredOutput: {\n jsonSchema,\n yieldChunks: true,\n normalize,\n ...(nativeCombined ? { nativeCombined: true } : {}),\n source,\n },\n },\n logger,\n )\n engineRef.current = engine\n\n try {\n for await (const chunk of engine.run()) {\n yield chunk\n }\n } finally {\n await mcpManager.dispose()\n }\n\n // Standard Schema validation for the streaming variant remains the\n // consumer's responsibility — they read the CUSTOM 'structured-output.complete'\n // from the yielded stream. (Null-widening normalization, by contrast, already\n // ran inside the engine via `normalize`, so the object they read is un-widened.)\n void outputSchema\n}\n\n// Re-export adapter types\nexport type {\n TextAdapter,\n TextAdapterConfig,\n StructuredOutputOptions,\n StructuredOutputResult,\n} from './adapter'\nexport { BaseTextAdapter } from './adapter'\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/activities/chat/index.ts"],"sourcesContent":["/**\n * Text Activity\n *\n * Handles agentic text generation, one-shot text generation, and agentic structured output.\n * This is a self-contained module with implementation, types, and JSDoc.\n */\n\nimport { devtoolsMiddleware } from '@tanstack/ai-event-client'\nimport { undoNullWidening } from '@tanstack/ai-utils'\nimport { streamToText } from '../../stream-to-response.js'\nimport { resolveDebugOption } from '../../logger/resolve'\nimport { EventType } from '../../types'\nimport {\n INTERRUPT_BINDING_METADATA_KEY,\n InterruptResumeValidationError,\n readInterruptBinding,\n readUnopenedInterruptBinding,\n validateInterruptResumeBatch,\n} from '../../interrupt-resume'\nimport { INTERRUPT_BINDING_VERSION } from '../../interrupts'\nimport {\n INTERRUPT_PAYLOAD_METADATA_KEY,\n createInterruptBinding,\n rehydrateInterruptRequest,\n} from '../../interrupt-definition'\nimport { readGenericInterruptContinuation } from '../../generic-interrupt-continuation'\nimport type {\n GenericInterruptRequest,\n InterruptDefinition,\n} from '../../interrupt-definition'\nimport {\n canonicalInterruptJson,\n digestInterruptJson,\n} from '../../interrupt-serialization'\nimport { rebuildTokenUsage } from '../../utilities/ag-ui-usage'\nimport { uiMessagesToWire } from '../../utilities/ag-ui-wire'\nimport {\n tanstackMetadata,\n withTanstackMetadata,\n} from '../../utilities/merge-metadata'\nimport { normalizeStreamChunk } from '../../utilities/normalize-stream-chunk'\nimport { restorePublicUsage } from '../../utilities/restore-inbound-chunk'\nimport type { AdapterYieldChunk } from '../../utilities/adapter-yield-chunk'\nimport { normalizeToolResult } from '../../utilities/tool-result'\nimport { isProviderExecutedToolCall } from '../../utilities/provider-executed'\nimport { LazyToolManager } from './tools/lazy-tool-manager'\nimport { assertUniqueToolNames } from './tools/unique-tool-names'\nimport {\n MiddlewareAbortError,\n ToolCallManager,\n executeToolCalls,\n} from './tools/tool-calls'\nimport {\n convertSchemaForStructuredOutput,\n convertSchemaToJsonSchema,\n isStandardSchema,\n parseWithStandardSchema,\n} from './tools/schema-converter'\nimport {\n hashSchemaInput,\n normalizeApprovalSchema,\n} from './tools/approval-schema'\nimport { maxIterations as maxIterationsStrategy } from './agent-loop-strategies'\nimport { isCancelRequestedReason } from './cancel'\nimport {\n appendUiResourceToModelMessages,\n convertMessagesToModelMessages,\n generateMessageId,\n modelMessagesToUIMessages,\n safeJsonStringify,\n uiResourcePartFromCustomValue,\n} from './messages'\nimport { MiddlewareRunner } from './middleware/compose'\nimport { getRunDetached } from './middleware/run-store'\nimport { publishRunDetachedSignal } from '../../delivery-detach'\nimport { publishRunDisconnectHandler } from '../../delivery-disconnect'\nimport { provideSandboxRuntime } from './middleware/sandbox-runtime'\nimport { provideRunDisconnect } from './middleware/run-disconnect'\nimport { CapabilityRegistry } from './middleware/capabilities'\nimport { validateCapabilities } from './middleware/validate'\nimport { MCPManager } from './mcp/manager'\nimport type {\n InterruptBinding,\n InterruptSubmissionError,\n ToolApprovalResolution,\n} from '../../interrupts'\nimport type {\n ApprovalRequest,\n ClientToolRequest,\n ToolResult,\n} from './tools/tool-calls'\nimport type { ApprovalSchemaConfig } from './tools/tool-definition'\nimport type {\n AnyTextAdapter,\n StructuredOutputOptions,\n StructuredOutputResult,\n} from './adapter'\nimport type {\n AgentLoopStrategy,\n AnyTool,\n ChatStream,\n ConstrainedModelMessage,\n CustomEvent,\n InferSchemaType,\n Interrupt,\n JSONSchema,\n LazyToolsConfig,\n ModelMessage,\n ProviderTool,\n RunFinishedEvent,\n SchemaInput,\n StreamChunk,\n StructuredOutputCompleteEvent,\n StructuredOutputPart,\n StructuredOutputStream,\n TextMessageContentEvent,\n TextOptions,\n ToolCall,\n ToolCallArgsEvent,\n ReasoningEncryptedValueEvent,\n ToolCallEndEvent,\n ToolCallResultEvent,\n ToolCallStartEvent,\n UIMessage,\n} from '../../types'\nimport type {\n AnyChatMiddleware,\n ChatMiddleware,\n ChatMiddlewareConfig,\n ChatMiddlewareContext,\n ChatResumeGenericResolution,\n ChatResumeToolState,\n InterruptResolutionCollection,\n SandboxFileHookEvent,\n StructuredOutputMiddlewareConfig,\n} from './middleware/types'\nimport { provideGenericInterruptDefinitionRegistry } from './middleware/generic-interrupts'\nimport type { CheckCoverage } from './middleware/builder'\nimport type { SystemPrompt } from '../../system-prompts'\nimport type { InternalLogger } from '../../logger/internal-logger'\nimport type { DebugOption } from '../../logger/types'\nimport type {\n ContextFromMiddleware,\n ContextFromTool,\n DefinedContext,\n MergeContext,\n UnionToIntersection,\n} from './runtime-context-types'\nimport type { ChatMCPOptions } from './mcp/types'\n\n// ===========================\n// Activity Kind\n// ===========================\n\n/** The adapter kind this activity handles */\nexport const kind = 'text' as const\n\ntype AnyRuntimeTool = AnyTool\ntype RuntimeToolWithApproval = AnyRuntimeTool & {\n approvalSchema?: ApprovalSchemaConfig\n}\nconst interruptBindingMetadataKey = INTERRUPT_BINDING_METADATA_KEY\n\ninterface StructuralInterruptFailure {\n error: Error\n errors: ReadonlyArray<InterruptSubmissionError>\n}\n\nfunction isInterruptSubmissionError(\n value: unknown,\n): value is InterruptSubmissionError {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n return false\n }\n if (\n !('scope' in value) ||\n !('code' in value) ||\n !('message' in value) ||\n !('source' in value) ||\n !('retryable' in value) ||\n !('threadId' in value) ||\n !('interruptedRunId' in value) ||\n !('generation' in value) ||\n typeof value.code !== 'string' ||\n typeof value.message !== 'string' ||\n typeof value.retryable !== 'boolean' ||\n typeof value.threadId !== 'string' ||\n typeof value.interruptedRunId !== 'string' ||\n typeof value.generation !== 'number'\n ) {\n return false\n }\n if (value.scope === 'item') {\n return (\n 'interruptId' in value &&\n typeof value.interruptId === 'string' &&\n (value.source === 'client' || value.source === 'server')\n )\n }\n return (\n value.scope === 'batch' &&\n 'interruptIds' in value &&\n Array.isArray(value.interruptIds) &&\n value.interruptIds.every((id) => typeof id === 'string') &&\n (value.source === 'client' ||\n value.source === 'server' ||\n value.source === 'transport')\n )\n}\n\nfunction structuralInterruptFailure(\n error: unknown,\n): StructuralInterruptFailure | undefined {\n if (\n !(error instanceof Error) ||\n error.name !== 'InterruptResumeValidationError' ||\n !('errors' in error) ||\n !Array.isArray(error.errors) ||\n error.errors.length === 0 ||\n !error.errors.every(isInterruptSubmissionError)\n ) {\n return undefined\n }\n return {\n error,\n errors: error.errors,\n }\n}\n\nfunction normalizePublicInterruptBinding(\n value: unknown,\n expectedInterruptId: string,\n): InterruptBinding | undefined {\n return readInterruptBinding({\n id: expectedInterruptId,\n reason: '',\n metadata: { [INTERRUPT_BINDING_METADATA_KEY]: value },\n })\n}\n\n// The leaf context-inference primitives (KnownContext, MergeContext,\n// UnionToIntersection, DefinedContext, ContextFromTool, ContextFromMiddleware)\n// are shared with the tool execution layer — see ./runtime-context-types.\ntype ContextFromConsumer<T> = ContextFromTool<T> | ContextFromMiddleware<T>\n\ntype RequiredContextFromConsumerUnion<T> = T extends unknown\n ? undefined extends ContextFromConsumer<T>\n ? never\n : ContextFromConsumer<T>\n : never\n\ntype ContextFromConsumerUnion<T> = [\n UnionToIntersection<DefinedContext<ContextFromConsumer<T>>>,\n] extends [never]\n ? never\n : [RequiredContextFromConsumerUnion<T>] extends [never]\n ? UnionToIntersection<DefinedContext<ContextFromConsumer<T>>> | undefined\n : UnionToIntersection<DefinedContext<ContextFromConsumer<T>>>\n\ntype ContextFromArray<T> = T extends readonly [infer THead, ...infer TTail]\n ? MergeContext<ContextFromConsumer<THead>, ContextFromArray<TTail>>\n : T extends ReadonlyArray<infer TItem>\n ? ContextFromConsumerUnion<TItem>\n : never\n\ntype ContextFromInputs<TTools, TMiddleware> = MergeContext<\n ContextFromArray<NonNullable<TTools>>,\n ContextFromArray<NonNullable<TMiddleware>>\n>\n\ntype InferredContext<TTools, TMiddleware> = [\n ContextFromInputs<TTools, TMiddleware>,\n] extends [never]\n ? unknown\n : ContextFromInputs<TTools, TMiddleware>\n\ntype RegistryInterrupt<\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n> = [TInterrupts[number]] extends [never] ? never : TInterrupts[number]\n\ntype DuplicateInterruptDefinitionId<\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TSeenIds extends string = never,\n> = TInterrupts extends readonly [infer THead, ...infer TTail]\n ? THead extends InterruptDefinition<infer TId, any, any, any>\n ? string extends TId\n ? TTail extends ReadonlyArray<InterruptDefinition<any, any, any, any>>\n ? DuplicateInterruptDefinitionId<TTail, TSeenIds>\n : never\n : TId extends TSeenIds\n ? TId\n : TTail extends ReadonlyArray<InterruptDefinition<any, any, any, any>>\n ? DuplicateInterruptDefinitionId<TTail, TSeenIds | TId>\n : never\n : never\n : never\n\ntype CheckUniqueInterruptDefinitions<\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n> = [DuplicateInterruptDefinitionId<TInterrupts>] extends [never]\n ? unknown\n : {\n readonly '✖ Duplicate interrupt definition id in chat({ interrupts }).': never\n }\n\ntype InlineChatContext<TTools, TContext> = MergeContext<\n ContextFromArray<NonNullable<TTools>>,\n TContext\n>\n\ntype RegistryChatMiddleware<\n TContext,\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n> = ChatMiddleware<TContext, RegistryInterrupt<TInterrupts>>\n\ntype MiddlewareInterruptDefinitions<TMiddleware> =\n TMiddleware extends ReadonlyArray<infer TMiddlewareItem>\n ? TMiddlewareItem extends ChatMiddleware<any, infer TDefinitions>\n ? TDefinitions\n : never\n : never\n\ntype IsAny<TValue> = 0 extends 1 & TValue ? true : false\n\ntype CheckInterruptRegistry<\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TMiddleware,\n> =\n IsAny<MiddlewareInterruptDefinitions<TMiddleware>> extends true\n ? unknown\n : [MiddlewareInterruptDefinitions<TMiddleware>] extends [never]\n ? unknown\n : [\n Exclude<\n MiddlewareInterruptDefinitions<TMiddleware>,\n RegistryInterrupt<TInterrupts>\n >,\n ] extends [never]\n ? unknown\n : {\n readonly '✖ Middleware emits an interrupt definition that is not registered in chat({ interrupts }).': never\n }\n\ntype RuntimeContextOption<TTools, TMiddleware, TContext> = [\n MergeContext<ContextFromInputs<TTools, TMiddleware>, TContext>,\n] extends [never]\n ? { context?: TContext }\n : undefined extends MergeContext<\n ContextFromInputs<TTools, TMiddleware>,\n TContext\n >\n ? {\n context?: MergeContext<ContextFromInputs<TTools, TMiddleware>, TContext>\n }\n : {\n context: MergeContext<ContextFromInputs<TTools, TMiddleware>, TContext>\n }\n\ntype ExactMiddlewareOption<\n TTools,\n TContext,\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TMiddleware extends Array<unknown> | undefined,\n> = [TMiddleware] extends [undefined]\n ? Array<\n RegistryChatMiddleware<\n InlineChatContext<TTools, TContext>,\n NoInfer<TInterrupts>\n >\n >\n : TMiddleware &\n (TMiddleware extends Array<\n RegistryChatMiddleware<\n InlineChatContext<TTools, NoInfer<TContext>>,\n NoInfer<TInterrupts>\n >\n >\n ? Array<\n RegistryChatMiddleware<\n InlineChatContext<TTools, TContext>,\n NoInfer<TInterrupts>\n >\n >\n : CheckInterruptRegistry<TInterrupts, TMiddleware>) &\n CheckCoverage<Extract<TMiddleware, ReadonlyArray<AnyChatMiddleware>>>\n\ntype TextActivityOptionsWithContext<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined,\n TStream extends boolean,\n TTools extends TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'],\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>> =\n [],\n TContext = unknown,\n TMiddleware extends Array<unknown> | undefined = undefined,\n> = Omit<\n TextActivityOptions<TAdapter, TSchema, TStream, any>,\n 'tools' | 'middleware' | 'context' | 'interrupts'\n> & {\n tools?: TTools\n interrupts?: TInterrupts & CheckUniqueInterruptDefinitions<TInterrupts>\n middleware?: ExactMiddlewareOption<TTools, TContext, TInterrupts, TMiddleware>\n} & RuntimeContextOption<TTools, TMiddleware, TContext>\n\n// ===========================\n// Activity Options Type\n// ===========================\n\n/**\n * Options for the text activity.\n * Types are extracted directly from the adapter (which has pre-resolved generics).\n *\n * @template TAdapter - The text adapter type (created by a provider function)\n * @template TSchema - Optional Standard Schema for structured output\n * @template TStream - Whether to stream the output (default: true)\n * @template TContext - Runtime context value threaded to middleware hooks and server tools\n */\nexport interface TextActivityOptions<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined,\n TStream extends boolean,\n TContext = unknown,\n> {\n /** The text adapter to use (created by a provider function like openaiText('gpt-5.5')) */\n adapter: TAdapter\n /**\n * Conversation messages. Accepts:\n * - `ConstrainedModelMessage` — content types constrained by the adapter's input modalities.\n * - `ModelMessage` — unconstrained model message (e.g., forwarded from an AG-UI wire payload).\n * - `UIMessage` — parts-based UI representation; converted internally via `convertMessagesToModelMessages`.\n *\n * The three shapes can be mixed in a single array (e.g., when forwarding a wire payload that includes both anchor UIMessages and AG-UI fan-out ModelMessages).\n */\n messages?:\n | Array<\n | UIMessage\n | ModelMessage\n | ConstrainedModelMessage<{\n inputModalities: TAdapter['~types']['inputModalities']\n messageMetadataByModality: TAdapter['~types']['messageMetadataByModality']\n }>\n >\n | undefined\n /**\n * System prompts to prepend to the conversation.\n *\n * Accepts plain strings or `{ content, metadata }` objects. The `metadata`\n * field is typed by the adapter — Anthropic narrows it to\n * `AnthropicSystemPromptMetadata` (with `cache_control` for prompt\n * caching), providers without per-prompt metadata reject the field\n * entirely.\n */\n systemPrompts?:\n | Array<SystemPrompt<TAdapter['~types']['systemPromptMetadata']>>\n | undefined\n /**\n * Tools for function calling (auto-executed when called).\n *\n * Accepts two shapes:\n * - User-defined tools via `toolDefinition()` — plain `Tool`, always assignable.\n * - Provider tools from `@tanstack/ai-<provider>/tools` (e.g. `webSearchTool`)\n * — branded and type-checked against the selected model's\n * `supports.tools` list. Passing an unsupported tool produces a\n * compile-time error on the array element.\n */\n tools?:\n | ReadonlyArray<\n | (AnyRuntimeTool & { readonly '~toolKind'?: never })\n | ProviderTool<string, TAdapter['~types']['toolCapabilities'][number]>\n >\n | undefined\n /**\n * Hand MCP clients/pools to chat(): their tools are discovered at run start\n * and merged into the run; `connection` controls whether chat() closes them\n * when the run ends. See docs/tools/mcp.md \"Managing MCP clients with chat()\".\n */\n mcp?: ChatMCPOptions\n /** Additional metadata to attach to the request. */\n metadata?: TextOptions['metadata']\n /** Model-specific provider options (type comes from adapter) */\n modelOptions?: TAdapter['~types']['providerOptions']\n /** AbortController for cancellation */\n abortController?: TextOptions['abortController']\n /** Strategy for controlling the agent loop */\n agentLoopStrategy?: TextOptions['agentLoopStrategy']\n /**\n * Optional configuration for lazy-tool discovery (tools marked `lazy: true`).\n * Tunes how much of each lazy tool's description appears in the discovery\n * catalog. Optional — defaults to `{ includeDescription: 'none' }`.\n */\n lazyToolsConfig?: LazyToolsConfig\n /** Unique conversation identifier for tracking */\n conversationId?: TextOptions['conversationId']\n /** Thread/conversation ID for AG-UI protocol. Auto-generated if not provided. */\n threadId?: TextOptions['threadId']\n /** Run ID override for AG-UI protocol. Auto-generated by adapter if not provided. */\n runId?: TextOptions['runId']\n /** Parent run ID for AG-UI protocol nested run correlation. */\n parentRunId?: TextOptions['parentRunId']\n /** Application state mirrored in a STATE_SNAPSHOT before an interrupt terminal. */\n state?: TextOptions['state']\n /**\n * AG-UI interrupt resume responses. Persistence middleware validates these\n * before accepting new input on a thread with pending interrupts.\n */\n resume?: TextOptions['resume']\n /**\n * Optional Standard Schema for structured output.\n * When provided, the activity will:\n * 1. Run the full agentic loop (executing tools as needed)\n * 2. Once complete, return a Promise with the parsed output matching the schema\n *\n * Supports any Standard Schema compliant library (Zod v4+, ArkType, Valibot, etc.)\n *\n * @example\n * ```ts\n * const result = await chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Generate a person' }],\n * outputSchema: z.object({ name: z.string(), age: z.number() })\n * })\n * // result is { name: string, age: number }\n * ```\n */\n outputSchema?: TSchema\n /**\n * Whether to stream the text result.\n * When true (default), returns a ChatStream for streaming output.\n * When false, returns a Promise<string> with the collected text content.\n *\n * Note: If outputSchema is provided, this option is ignored and the result\n * is always a Promise<InferSchemaType<TSchema>>.\n *\n * @default true\n *\n * @example Non-streaming text\n * ```ts\n * const text = await chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Hello!' }],\n * stream: false\n * })\n * // text is a string with the full response\n * ```\n */\n stream?: TStream\n /**\n * Optional middleware array for observing/transforming chat behavior.\n * Middleware hooks are called in array order. See {@link ChatMiddleware} for available hooks.\n *\n * @example\n * ```ts\n * const stream = chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [...],\n * middleware: [loggingMiddleware, redactionMiddleware],\n * })\n * ```\n */\n middleware?: Array<ChatMiddleware<TContext>>\n /**\n * First-party generic interrupt definitions for this chat call.\n * Register the same definitions on the client to type payloads and answers.\n */\n interrupts?: ReadonlyArray<InterruptDefinition<any, any, any, any>>\n /**\n * Runtime context value passed to middleware hooks and server tools.\n */\n context?: TContext\n /**\n * Enable debug logging. Pass `true` to enable all categories with the default\n * console logger, `false` to silence everything, or a `DebugConfig` object for\n * granular control and/or a custom `Logger`. Defaults to `undefined`, which\n * means only the `errors` category is active.\n */\n debug?: DebugOption\n}\n\n// ===========================\n// Chat Options Helper\n// ===========================\n\n/**\n * Create typed options for the chat() function without executing.\n * This is useful for pre-defining configurations with full type inference.\n *\n * @example\n * ```ts\n * const chatOptions = createChatOptions({\n * adapter: anthropicText('claude-sonnet-4-5'),\n * })\n *\n * const stream = chat({ ...chatOptions, messages })\n * ```\n */\nexport function createChatOptions<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined = undefined,\n TStream extends boolean = true,\n const TTools extends TextActivityOptions<\n TAdapter,\n TSchema,\n TStream,\n any\n >['tools'] = TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'],\n const TInterrupts extends ReadonlyArray<\n InterruptDefinition<any, any, any, any>\n > = [],\n TContext = unknown,\n const TMiddleware extends Array<unknown> | undefined = undefined,\n>(\n options: TextActivityOptionsWithContext<\n TAdapter,\n TSchema,\n TStream,\n TTools,\n TInterrupts,\n TContext,\n TMiddleware\n >,\n): Omit<\n TextActivityOptions<\n TAdapter,\n TSchema,\n TStream,\n InferredContext<TTools, TMiddleware>\n >,\n 'tools' | 'middleware' | 'interrupts' | 'context'\n> & {\n tools?: TTools\n interrupts?: TInterrupts\n middleware?: ExactMiddlewareOption<TTools, TContext, TInterrupts, TMiddleware>\n} & RuntimeContextOption<TTools, TMiddleware, TContext> {\n return options\n}\n\n// ===========================\n// Activity Result Type\n// ===========================\n\n/**\n * Result type for the text activity.\n * - If outputSchema is provided AND stream is explicitly true:\n * StructuredOutputStream<InferSchemaType<TSchema>> — yields raw JSON deltas\n * via TEXT_MESSAGE_CONTENT plus a terminal StructuredOutputCompleteEvent\n * carrying the validated object.\n * - If outputSchema is provided without explicit stream:true:\n * Promise<InferSchemaType<TSchema>>.\n * - If stream is explicitly false (no schema): Promise<string>.\n * - Otherwise (default): ChatStream.\n *\n * `[TStream] extends [true]` is used (not `TStream extends true`) so that the\n * default `boolean` value of `TStream` does *not* match the streaming branch.\n * Without this, plain `chat({ outputSchema })` would type as a stream while\n * the runtime returns a Promise — see issue #526.\n */\nexport type TextActivityResult<\n TSchema extends SchemaInput | undefined,\n TStream extends boolean = boolean,\n // Unconstrained so `chat()` can forward its inferred `options['tools']` type\n // (which may be `undefined` or the broad `AnyRuntimeTool | ProviderTool`\n // array) directly; non-tool-array inputs normalize to the default below.\n TTools = ReadonlyArray<AnyTool>,\n> = TSchema extends SchemaInput\n ? [TStream] extends [true]\n ? StructuredOutputStream<InferSchemaType<TSchema>>\n : Promise<InferSchemaType<TSchema>>\n : [TStream] extends [false]\n ? Promise<string>\n : TTools extends infer _TTools\n ? ChatStream\n : ChatStream\n\n// ===========================\n// ChatEngine Implementation\n// ===========================\n\ninterface TextEngineConfig<\n TAdapter extends AnyTextAdapter,\n TContext = unknown,\n TParams extends TextOptions<any, any, TContext> = TextOptions<\n any,\n any,\n TContext\n >,\n> {\n adapter: TAdapter\n systemPrompts?: Array<SystemPrompt>\n params: TParams\n middleware?: Array<AnyChatMiddleware>\n context?: TContext\n /**\n * If set, after the agent loop finishes the engine runs a\n * structured-output finalization step through the same middleware\n * pipeline. See `runStructuredFinalization` for the flow.\n *\n * - jsonSchema: the JSON Schema to send to the provider\n * - yieldChunks: when true, finalization chunks are yielded to the caller\n * (used by runStreamingStructuredOutput). When false, chunks are\n * consumed internally for middleware visibility but not yielded\n * (used by runAgenticStructuredOutput).\n * - normalize: optional schema-aware transform applied to the captured\n * structured-output object the moment it enters the engine — BEFORE it is\n * stored, validated, or yielded. Used to undo strict-mode null-widening\n * (`undoNullWidening`): strict schemas widen optional fields to\n * `required` + nullable so the provider returns `null` for an absent\n * optional, and this strips exactly those synthesized nulls while keeping\n * the ones a `.nullable()` field genuinely allows. Applied here (not in\n * the adapter) because the engine is the only layer holding the original\n * schema's null-widening map, and applying it at capture fixes BOTH the\n * streaming chunk and the Promise<T> result with one transform.\n * - validate: optional callback invoked AFTER `normalize` and AFTER the\n * structured-output result is captured, but BEFORE the terminal hook\n * fires. If it throws, the engine records a `finalizationError` and fires\n * `onError` instead of `onFinish` (per spec §7.3). On success, the\n * returned value is stored as the validated result and retrievable via\n * `getValidatedStructuredOutput()`. Used by `runAgenticStructuredOutput`\n * to perform Standard Schema validation inside the engine.\n * - nativeCombined: when true, the adapter declared\n * `supportsCombinedToolsAndSchema()` and the engine wires `jsonSchema`\n * into the regular `chatStream` call instead of running a separate\n * finalization round-trip. The `'structuredOutput'` middleware phase\n * does NOT fire on this path — middleware sees the run through\n * `beforeModel` / `modelStream` as usual.\n * - source: how to take the combined object. `'text'` (default) parses\n * accumulated assistant text. `'event'` reads an adapter-emitted\n * `structured-output.complete` and does not parse prose.\n */\n finalStructuredOutput?: {\n jsonSchema: JSONSchema\n yieldChunks: boolean\n normalize?: (data: unknown) => unknown\n validate?: (data: unknown) => unknown\n nativeCombined?: boolean\n source?: 'text' | 'event'\n }\n}\n\ntype ToolPhaseResult = 'continue' | 'stop' | 'wait'\ntype CyclePhase = 'processText' | 'executeToolCalls'\n\n/**\n * Combine two optional AbortSignals into one that aborts when either does.\n * Returns the other signal directly when one is absent or already aborted.\n * (Manual implementation — `AbortSignal.any` requires Node >= 20.3.)\n */\nfunction combineAbortSignals(\n a: AbortSignal | undefined,\n b: AbortSignal | undefined,\n): AbortSignal | undefined {\n if (!a) return b\n if (!b) return a\n if (a.aborted) return a\n if (b.aborted) return b\n const controller = new AbortController()\n const onAbort = (source: AbortSignal) => () => {\n controller.abort(source.reason)\n }\n a.addEventListener('abort', onAbort(a), { once: true })\n b.addEventListener('abort', onAbort(b), { once: true })\n return controller.signal\n}\n\nclass TextEngine<\n TAdapter extends AnyTextAdapter,\n TContext = unknown,\n TParams extends TextOptions<any, any, TContext> = TextOptions<\n any,\n any,\n TContext\n >,\n> {\n private readonly adapter: TAdapter\n private readonly interruptDefinitions: ReadonlyMap<\n string,\n InterruptDefinition<any, any, any, any>\n >\n private params: TParams\n private systemPrompts: Array<SystemPrompt>\n private tools: Array<AnyRuntimeTool>\n private readonly loopStrategy: AgentLoopStrategy\n private toolCallManager: ToolCallManager<ReadonlyArray<AnyTool>, TContext>\n private readonly lazyToolManager: LazyToolManager\n /** A public interruption terminal must always have this run's start event. */\n private hasPublicRunStarted = false\n private readonly initialMessageCount: number\n private readonly requestId: string\n private readonly streamId: string\n private readonly effectiveRequest?: Request | RequestInit\n private readonly effectiveSignal?: AbortSignal\n\n private messages: Array<ModelMessage>\n private providerMessages: Array<ModelMessage>\n private iterationCount = 0\n /** Cumulative tool calls counted in this run (emitted + pending resume). */\n private toolCallCount = 0\n /** Tool calls in the most recent budgeted batch (0 when none). */\n private lastTurnToolCallCount = 0\n /** Tool call IDs already counted toward `toolCallCount` (avoids double-count on resume). */\n private readonly countedToolCallIds = new Set<string>()\n private lastFinishReason: string | null = null\n private streamStartTime = 0\n private totalChunkCount = 0\n private currentMessageId: string | null = null\n private currentMessageCreatedAt: Date | null = null\n private streamIdentityCaptured = false\n private accumulatedContent = ''\n private accumulatedThinking: Array<{ content: string; signature?: string }> =\n []\n private currentThinkingContent = ''\n private currentThinkingSignature = ''\n private eventOptions?: Record<string, unknown> | undefined\n private eventToolNames?: Array<string>\n private finishedEvent: RunFinishedEvent | null = null\n private readonly streamedToolErrorResults = new Map<string, ToolResult>()\n private deferredToolCallRunFinishedChunks: Array<StreamChunk> = []\n /** The model terminal is held until afterModel can choose an interrupt. */\n private deferredModelRunFinishedChunks: Array<StreamChunk> = []\n\n private earlyTermination = false\n private toolPhase: ToolPhaseResult = 'continue'\n private cyclePhase: CyclePhase = 'processText'\n // Client state extracted from initial messages (before conversion to ModelMessage)\n private readonly initialApprovals: Map<string, ToolApprovalResolution>\n private readonly initialClientToolResults: Map<string, any>\n private readonly resumeApprovals = new Map<string, ToolApprovalResolution>()\n private readonly resumeClientToolResults = new Map<string, any>()\n private readonly resumeDeniedToolResults = new Map<string, unknown>()\n private readonly resumeCancelledToolCallIds = new Set<string>()\n private readonly resumeGenericInterrupts = new Map<\n string,\n ChatResumeGenericResolution\n >()\n private readonly resumeGenericInterruptRequests = new Map<\n string,\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n >()\n\n // AG-UI protocol IDs\n private readonly threadId: string\n private readonly runIdOverride?: string\n private readonly parentRunIdOverride?: string\n\n // Middleware support\n private readonly middlewareRunner: MiddlewareRunner<\n TContext,\n InterruptDefinition<any, any, any, any>\n >\n private readonly middlewareCtx: ChatMiddlewareContext<TContext>\n private readonly sandboxFileQueue: Array<StreamChunk> = []\n private readonly middlewareCustomQueue: Array<StreamChunk> = []\n private middlewareCustomWaiters: Array<() => void> = []\n private drainingMiddlewareCustom = false\n private readonly deferredPromises: Array<Promise<unknown>> = []\n private abortReason?: string\n private readonly middlewareAbortController?: AbortController\n // Combines the caller's signal with middleware abort() so running tools\n // observe both cancellation sources via ctx.abortSignal.\n private readonly toolAbortSignal?: AbortSignal\n private terminalHookCalled = false\n /**\n * Latched the first time the delivery socket closes; see `notifyDisconnected`.\n * Also read by `subscribe` so a listener registered AFTER the disconnect (a\n * middleware whose `setup` was still running at the time — the common case) is\n * called immediately rather than never.\n */\n private disconnected = false\n private readonly disconnectListeners: Array<() => void | Promise<void>> = []\n\n private readonly logger: InternalLogger\n\n // Structured-output finalization state (populated by runStructuredFinalization)\n private structuredOutputResult: {\n data: unknown\n rawText: string\n reasoning?: string\n } | null = null\n private structuredOutputMessageId: string | null = null\n private structuredOutputMessageCreatedAt: Date | null = null\n // Native combined mode: tracks whether we've already emitted the synthetic\n // `structured-output.start` event before the schema-constrained final-turn\n // text begins streaming. The event must precede the first\n // TEXT_MESSAGE_START so the client-side StreamProcessor routes the JSON\n // deltas into a StructuredOutputPart instead of a plain TextPart.\n private combinedStartEmitted = false\n // Native combined mode: messageId we want the synthetic\n // `structured-output.start` (and any error emitted before deltas arrive)\n // to carry, so the client matches it to the streaming text deltas.\n private combinedStructuredMessageId: string | null = null\n // Holds the validated value when `finalStructuredOutput.validate` is provided\n // and succeeds. Distinct from `structuredOutputResult.data` (the normalized\n // but unvalidated payload from the structured-output.complete chunk).\n private validatedStructuredOutput: unknown = undefined\n private hasValidatedStructuredOutput = false\n private finalizationError: {\n message: string\n code?: string\n cause?: unknown\n } | null = null\n private combinedCompleteEmitted = false\n private readonly finalStructuredOutput?: {\n jsonSchema: JSONSchema\n yieldChunks: boolean\n normalize?: (data: unknown) => unknown\n validate?: (data: unknown) => unknown\n nativeCombined?: boolean\n source?: 'text' | 'event'\n }\n\n constructor(\n config: TextEngineConfig<TAdapter, TContext, TParams>,\n logger: InternalLogger,\n ) {\n this.logger = logger\n this.adapter = config.adapter\n this.interruptDefinitions = new Map(\n (\n (\n config.params as TParams & {\n interrupts?: ReadonlyArray<InterruptDefinition<any, any, any, any>>\n }\n ).interrupts ?? []\n ).map((definition) => [definition.id, definition]),\n )\n this.finalStructuredOutput = config.finalStructuredOutput\n this.params = config.params\n this.systemPrompts = config.params.systemPrompts || []\n this.loopStrategy =\n config.params.agentLoopStrategy || maxIterationsStrategy(5)\n this.initialMessageCount = config.params.messages.length\n\n // Extract client state (approvals, client tool results) from original messages BEFORE conversion\n // This preserves UIMessage parts data that would be lost during conversion to ModelMessage\n const { approvals, clientToolResults } =\n this.extractClientStateFromOriginalMessages(\n config.params.messages as Array<any>,\n )\n this.initialApprovals = approvals\n this.initialClientToolResults = clientToolResults\n\n // Convert messages to ModelMessage format (handles both UIMessage and ModelMessage input)\n // This ensures consistent internal format regardless of what the client sends\n this.messages = convertMessagesToModelMessages(config.params.messages)\n this.providerMessages = this.messages\n\n // Initialize lazy tool manager after messages are converted (needs message history for scanning)\n assertUniqueToolNames(config.params.tools || [])\n this.lazyToolManager = new LazyToolManager(\n config.params.tools || [],\n this.messages,\n config.params.lazyToolsConfig,\n )\n this.tools = this.lazyToolManager.getActiveTools()\n this.toolCallManager = new ToolCallManager<\n ReadonlyArray<AnyTool>,\n TContext\n >(this.tools)\n this.requestId = this.createId('chat')\n this.streamId = this.createId('stream')\n this.effectiveRequest = config.params.abortController\n ? { signal: config.params.abortController.signal }\n : undefined\n this.effectiveSignal = config.params.abortController?.signal\n // `conversationId` is the legacy alias of `threadId` — accept it\n // as a fallback so `chat({ conversationId })` keeps working, with\n // explicit `threadId` winning when both are set.\n this.threadId =\n config.params.threadId ||\n config.params.conversationId ||\n this.createId('thread')\n this.runIdOverride = config.params.runId\n this.parentRunIdOverride = config.params.parentRunId\n\n // Initialize middleware — devtools first. Spec stripping for the AG-UI\n // wire happens in toServerSentEventsStream, so in-process chat()\n // consumers still see TokenUsage and tool aliases.\n const allMiddleware: Array<\n ChatMiddleware<TContext, InterruptDefinition<any, any, any, any>>\n > = [devtoolsMiddleware(), ...(config.middleware || [])]\n this.middlewareRunner = new MiddlewareRunner(allMiddleware, logger)\n this.middlewareAbortController = new AbortController()\n this.toolAbortSignal = combineAbortSignals(\n this.effectiveSignal,\n this.middlewareAbortController.signal,\n )\n this.middlewareCtx = {\n requestId: this.requestId,\n streamId: this.streamId,\n runId: this.runIdOverride ?? this.requestId,\n parentRunId: this.parentRunIdOverride,\n threadId: this.threadId,\n // Legacy alias kept on the ctx so middleware that reads\n // `ctx.conversationId` keeps working. Always equals `threadId`.\n conversationId: this.threadId,\n phase: 'init',\n iteration: 0,\n chunkIndex: 0,\n signal: this.effectiveSignal,\n abort: (reason?: string) => {\n this.abortReason = reason\n this.middlewareAbortController?.abort(reason)\n },\n emitCustomEvent: (name, value) => {\n this.middlewareCustomQueue.push(\n this.createCustomEventChunk(name, value),\n )\n const waiters = this.middlewareCustomWaiters\n this.middlewareCustomWaiters = []\n for (const waiter of waiters) waiter()\n },\n context: config.context as TContext,\n defer: (promise: Promise<unknown>) => {\n this.deferredPromises.push(promise)\n },\n // Provider / adapter info\n activity: 'chat',\n provider: config.adapter.name,\n model: config.params.model,\n source: 'server',\n streaming: true,\n // Config-derived (updated in beforeRun and applyMiddlewareConfig)\n systemPrompts: this.systemPrompts,\n toolNames: undefined,\n options: undefined,\n modelOptions: config.params.modelOptions,\n // Computed\n messageCount: this.initialMessageCount,\n hasTools: this.tools.length > 0,\n // Mutable per-iteration\n currentMessageId: null,\n accumulatedContent: '',\n // References\n messages: this.messages,\n createId: (prefix: string) => this.createId(prefix),\n // Capability bookkeeping for this request (populated by middleware setup)\n capabilities: new CapabilityRegistry(),\n // Convenience accessors that delegate to a capability handle's own\n // tuple getter/provider, keyed by this context. `getX(ctx)` and\n // `ctx.get(X)` are interchangeable.\n get: (capability) => capability[0](this.middlewareCtx),\n getOptional: (capability) =>\n capability[0](this.middlewareCtx, { optional: true }),\n provide: (capability, value) => capability[1](this.middlewareCtx, value),\n }\n\n // Provide the internal RunDisconnect capability BEFORE `setup` runs, so a\n // middleware can subscribe from inside its own `setup` — which is where the\n // subscription has to happen, because `setup` is the long await the common\n // disconnect lands in.\n //\n // `subscribe` calls back IMMEDIATELY when the socket has already closed. That\n // ordering is load-bearing rather than defensive: a middleware whose `setup`\n // was still running during the disconnect would otherwise register a listener\n // for an event that has already been and gone, and silently never detach.\n provideRunDisconnect(this.middlewareCtx, {\n subscribe: (listener) => {\n this.disconnectListeners.push(listener)\n if (this.disconnected) this.runDisconnectListener(listener)\n },\n })\n\n provideGenericInterruptDefinitionRegistry(this.middlewareCtx, {\n definitions: this.interruptDefinitions,\n })\n\n // Provide the internal SandboxRuntime capability so harness adapters and\n // sandbox middleware can emit file events. The sink logs, fans the event\n // out through the middleware `onFile*` hooks (fire-and-forget), and queues\n // a `sandbox.file` custom chunk to be drained into the public stream.\n provideSandboxRuntime(this.middlewareCtx, {\n logger: this.logger,\n emit: (event: SandboxFileHookEvent) => {\n this.logger.sandbox(`file ${event.type} ${event.path}`, {\n event: {\n type: event.type,\n path: event.path,\n timestamp: event.timestamp,\n },\n })\n void this.middlewareRunner\n .runSandboxFile(this.middlewareCtx, event)\n .catch((err: unknown) => {\n this.logger.errors('sandbox file hook failed', { error: err })\n })\n this.sandboxFileQueue.push(\n this.createCustomEventChunk('sandbox.file', {\n type: event.type,\n path: event.path,\n timestamp: event.timestamp,\n }),\n )\n },\n emitFileDiff: (value: { path: string; diff: string }) => {\n this.sandboxFileQueue.push(\n this.createCustomEventChunk('sandbox.file.diff', value),\n )\n },\n })\n }\n\n /** Get the accumulated content after the chat loop completes */\n getAccumulatedContent(): string {\n return this.accumulatedContent\n }\n\n /** Get the final messages array after the chat loop completes */\n getMessages(): Array<ModelMessage> {\n return this.messages\n }\n\n /** Returns the structured-output result if finalization ran successfully. */\n getStructuredOutputResult(): { data: unknown; rawText: string } | null {\n return this.structuredOutputResult\n }\n\n /**\n * Returns the validated structured-output value (the result of running\n * `finalStructuredOutput.validate` against the raw structured-output data)\n * wrapped in a `{ value }` object so callers can distinguish \"no validation\n * happened\" from \"validation produced undefined\". Returns `null` when no\n * validator was configured or validation hasn't been performed yet.\n */\n getValidatedStructuredOutput(): { value: unknown } | null {\n return this.hasValidatedStructuredOutput\n ? { value: this.validatedStructuredOutput }\n : null\n }\n\n /** Returns the recorded finalization error, if any. */\n getFinalizationError(): {\n message: string\n code?: string\n cause?: unknown\n } | null {\n return this.finalizationError\n }\n\n async *run(): AsyncGenerator<StreamChunk> {\n this.beforeRun()\n this.logger.agentLoop('run started', {\n threadId: this.middlewareCtx.threadId,\n })\n\n try {\n // Provision capabilities before any consumer (onConfig onward) can read them\n yield* this.runWhileYielding(\n this.middlewareRunner.runSetup(this.middlewareCtx),\n )\n\n // Run initial onConfig (phase = init)\n this.middlewareCtx.phase = 'init'\n const initialConfig = this.buildMiddlewareConfig()\n const transformedConfig = yield* this.runWhileYielding(\n this.middlewareRunner.runOnConfig(this.middlewareCtx, initialConfig),\n )\n this.applyMiddlewareConfig(transformedConfig)\n await this.applyEphemeralInterruptResume(transformedConfig)\n await this.applyDurableGenericInterruptResolution()\n\n // Run onStart (devtools middleware emits text:request:started and initial messages here)\n yield* this.runWhileYielding(\n this.middlewareRunner.runOnStart(this.middlewareCtx),\n )\n\n if (this.earlyTermination) {\n yield* this.emitSuccessfulEarlyTermination()\n if (!this.terminalHookCalled) {\n this.terminalHookCalled = true\n await this.middlewareRunner.runOnFinish(this.middlewareCtx, {\n finishReason: this.lastFinishReason,\n duration: Date.now() - this.streamStartTime,\n content: this.accumulatedContent,\n usage: rebuildTokenUsage(\n this.finishedEvent?.usage,\n tanstackMetadata(this.finishedEvent ?? undefined)?.usage,\n ),\n })\n }\n return\n }\n\n const pendingPhase = yield* this.checkForPendingToolCalls()\n if (pendingPhase === 'wait') {\n return\n }\n\n // Skip the agent loop entirely when there are no tools AND a separate\n // structured-output finalization will run. Without tools the model has\n // nothing to do in the loop, so executing one iteration would burn an\n // extra provider call before the finalization request.\n //\n // Native combined mode does NOT skip — the agent loop itself produces\n // the schema-constrained final answer in one pass (model emits the\n // schema-constrained text on its natural final turn). Even with zero\n // tools, the single chatStream call IS the structured-output call.\n const skipAgentLoop =\n !!this.finalStructuredOutput &&\n this.tools.length === 0 &&\n this.finalStructuredOutput.nativeCombined !== true\n\n if (!skipAgentLoop) {\n do {\n if (this.earlyTermination) break\n if (this.isCancelled()) return\n\n this.logger.agentLoop(`iteration=${this.middlewareCtx.iteration}`, {\n iteration: this.middlewareCtx.iteration,\n })\n\n yield* this.runWhileYielding(this.beginCycle())\n\n if (this.cyclePhase === 'processText') {\n // Run onConfig before each model call (phase = beforeModel)\n this.middlewareCtx.phase = 'beforeModel'\n this.middlewareCtx.iteration = this.iterationCount\n const iterConfig = this.buildMiddlewareConfig()\n const iterTransformedConfig = yield* this.runWhileYielding(\n this.middlewareRunner.runOnConfig(this.middlewareCtx, iterConfig),\n )\n this.applyMiddlewareConfig(iterTransformedConfig)\n\n if (\n yield* this.emitBoundaryInterrupts(\n 'beforeModel',\n this.createSyntheticFinishedEvent(),\n )\n ) {\n this.setToolPhase('wait')\n return\n }\n\n yield* this.streamModelResponse()\n\n if (this.earlyTermination) break\n\n if (\n yield* this.emitBoundaryInterrupts(\n 'afterModel',\n this.finishedEvent ?? this.createSyntheticFinishedEvent(),\n )\n ) {\n this.setToolPhase('wait')\n return\n }\n if (this.shouldExecuteToolPhase()) {\n this.deferredToolCallRunFinishedChunks.push(\n ...this.deferredModelRunFinishedChunks,\n )\n this.deferredModelRunFinishedChunks = []\n } else if (!this.finalStructuredOutput?.nativeCombined) {\n yield* this.flushDeferredModelRunFinishedChunks()\n }\n } else {\n yield* this.processToolCalls()\n }\n\n this.endCycle()\n } while (yield* this.runWhileYielding(this.shouldContinue()))\n }\n\n this.logger.agentLoop('run finished', {\n finishReason: this.lastFinishReason,\n })\n\n // After the agent loop ends, if a structured-output finalization was\n // requested AND the run hasn't already errored/aborted, run it through\n // the middleware pipeline. The terminal hook fires once at the very\n // end (after finalization), not after the agent loop.\n // Actionable waits already emitted a RUN_FINISHED interrupt terminal, so\n // do not run finalization after `processToolCalls()` pauses the stream.\n //\n // Native combined mode takes a different path: the agent loop's final-\n // turn text IS the schema-constrained JSON, so we harvest it from\n // `accumulatedContent` instead of issuing a second provider call.\n if (\n this.finalStructuredOutput &&\n this.toolPhase !== 'wait' &&\n !this.isCancelled() &&\n !this.finalizationError &&\n !this.earlyTermination\n ) {\n if (this.finalStructuredOutput.nativeCombined === true) {\n yield* this.harvestCombinedStructuredOutput()\n if (!this.finalizationError && !this.isCancelled()) {\n yield* this.flushDeferredModelRunFinishedChunks()\n }\n } else {\n yield* this.runStructuredFinalization()\n }\n }\n\n // Call terminal hook (skip when waiting for client — stream is paused, not finished).\n // Priority: finalizationError → onError; otherwise normal onFinish.\n // Skip on cancellation — the finally block routes aborts to onAbort.\n if (\n !this.terminalHookCalled &&\n this.toolPhase !== 'wait' &&\n !this.isCancelled()\n ) {\n if (this.finalizationError) {\n this.terminalHookCalled = true\n const errForHook = new Error(\n this.finalizationError.message,\n this.finalizationError.cause !== undefined\n ? { cause: this.finalizationError.cause }\n : undefined,\n )\n if (this.finalizationError.code !== undefined) {\n Object.defineProperty(errForHook, 'code', {\n value: this.finalizationError.code,\n enumerable: true,\n })\n }\n await this.middlewareRunner.runOnError(this.middlewareCtx, {\n error: errForHook,\n duration: Date.now() - this.streamStartTime,\n })\n } else {\n this.addTerminalAssistantMessages()\n this.terminalHookCalled = true\n await this.middlewareRunner.runOnFinish(this.middlewareCtx, {\n finishReason: this.lastFinishReason,\n duration: Date.now() - this.streamStartTime,\n content: this.accumulatedContent,\n usage: rebuildTokenUsage(\n this.finishedEvent?.usage,\n tanstackMetadata(this.finishedEvent ?? undefined)?.usage,\n ),\n })\n }\n }\n } catch (error: unknown) {\n if (\n error instanceof Error &&\n error.name === 'InterruptReplaySignal' &&\n 'continuationRunId' in error &&\n typeof error.continuationRunId === 'string'\n ) {\n this.terminalHookCalled = true\n yield* this.pipeThroughMiddleware({\n type: EventType.RUN_FINISHED,\n timestamp: Date.now(),\n threadId: this.threadId,\n runId: this.runIdOverride ?? this.requestId,\n outcome: { type: 'success' },\n result: {\n replayed: true,\n continuationRunId: error.continuationRunId,\n },\n })\n return\n }\n const interruptFailure = structuralInterruptFailure(error)\n if (interruptFailure) {\n this.terminalHookCalled = true\n this.logger.errors('chat interrupt resume failed', {\n error,\n threadId: this.middlewareCtx.threadId,\n })\n await this.middlewareRunner.runOnError(this.middlewareCtx, {\n error: interruptFailure.error,\n duration: Date.now() - this.streamStartTime,\n })\n yield this.buildInterruptRunErrorChunk(error)\n return\n }\n if (!this.terminalHookCalled) {\n this.terminalHookCalled = true\n if (error instanceof MiddlewareAbortError) {\n // Middleware abort decision — call onAbort, not onError\n this.abortReason = error.message\n await this.middlewareRunner.runOnAbort(this.middlewareCtx, {\n reason: error.message,\n duration: Date.now() - this.streamStartTime,\n cancelRequested: isCancelRequestedReason(error.message),\n })\n } else {\n // Genuine error — call onError\n this.logger.errors('chat run failed', {\n error,\n threadId: this.middlewareCtx.threadId,\n })\n await this.middlewareRunner.runOnError(this.middlewareCtx, {\n error,\n duration: Date.now() - this.streamStartTime,\n })\n }\n }\n // Don't rethrow middleware abort errors — the run just stops gracefully\n if (!(error instanceof MiddlewareAbortError)) {\n throw error\n }\n } finally {\n // Check for abort terminal hook\n if (!this.terminalHookCalled && this.isCancelled()) {\n this.terminalHookCalled = true\n const reason = this.resolveAbortReason()\n await this.middlewareRunner.runOnAbort(this.middlewareCtx, {\n reason,\n duration: Date.now() - this.streamStartTime,\n cancelRequested: isCancelRequestedReason(reason),\n })\n }\n\n // Await deferred promises (non-blocking side effects)\n if (this.deferredPromises.length > 0) {\n await Promise.allSettled(this.deferredPromises)\n }\n }\n }\n\n private beforeRun(): void {\n this.streamStartTime = Date.now()\n const { tools, metadata } = this.params\n\n // Gather flattened options into an object for context\n const options: Record<string, unknown> = {}\n if (metadata !== undefined) options.metadata = metadata\n\n this.eventOptions = Object.keys(options).length > 0 ? options : undefined\n this.eventToolNames = tools?.map((t) => t.name)\n\n // Update middleware context with computed fields\n this.middlewareCtx.options = this.eventOptions\n this.middlewareCtx.toolNames = this.eventToolNames\n }\n\n private async beginCycle(): Promise<void> {\n if (this.cyclePhase === 'processText') {\n await this.beginIteration()\n }\n }\n\n private endCycle(): void {\n if (this.cyclePhase === 'processText') {\n this.cyclePhase = 'executeToolCalls'\n return\n }\n\n this.cyclePhase = 'processText'\n this.iterationCount++\n }\n\n private async beginIteration(): Promise<void> {\n this.currentMessageId = this.createId('msg')\n this.currentMessageCreatedAt = new Date()\n this.streamIdentityCaptured = false\n this.accumulatedContent = ''\n this.accumulatedThinking = []\n this.currentThinkingContent = ''\n this.currentThinkingSignature = ''\n\n this.finishedEvent = null\n this.streamedToolErrorResults.clear()\n\n // Update mutable context fields\n this.middlewareCtx.currentMessageId = this.currentMessageId\n this.middlewareCtx.accumulatedContent = ''\n\n // Notify middleware of new iteration (devtools emits assistant message:created here)\n await this.middlewareRunner.runOnIteration(this.middlewareCtx, {\n iteration: this.iterationCount,\n messageId: this.currentMessageId,\n })\n }\n\n private async *streamModelResponse(): AsyncGenerator<StreamChunk> {\n const { metadata, modelOptions } = this.params\n const tools = this.tools\n\n // Convert tool schemas to JSON Schema before passing to adapter\n const toolsWithJsonSchemas = tools.map((tool) => ({\n ...tool,\n inputSchema: tool.inputSchema\n ? convertSchemaToJsonSchema(tool.inputSchema)\n : undefined,\n outputSchema: tool.outputSchema\n ? convertSchemaToJsonSchema(tool.outputSchema)\n : undefined,\n }))\n\n this.middlewareCtx.phase = 'modelStream'\n\n const providerName =\n (this.adapter as { provider?: string }).provider ?? this.adapter.name\n this.logger.request(\n `activity=chat provider=${providerName} model=${this.params.model} messages=${this.messages.length} tools=${this.tools.length} stream=true`,\n {\n provider: providerName,\n model: this.params.model,\n messageCount: this.messages.length,\n toolCount: this.tools.length,\n },\n )\n\n // When the adapter declared `supportsCombinedToolsAndSchema()`, the\n // activity layer set `nativeCombined: true` and we forward the\n // pre-converted JSON Schema into the regular chatStream call. The\n // adapter wires it into the upstream request (e.g. `response_format`,\n // `text.format`, `output_format`) so the model's final-turn text is\n // schema-constrained and the engine can harvest it from the agent loop\n // without a separate finalization round-trip.\n const combinedSchema =\n this.finalStructuredOutput?.nativeCombined === true\n ? this.finalStructuredOutput.jsonSchema\n : undefined\n\n const { approvals } = this.collectClientState()\n const adapterApprovals = new Map<string, boolean>()\n for (const [approvalId, resolution] of approvals) {\n adapterApprovals.set(\n approvalId,\n typeof resolution === 'boolean' ? resolution : resolution.approved,\n )\n }\n\n for await (const raw of this.adapter.chatStream({\n model: this.params.model,\n messages: this.providerMessages,\n tools: toolsWithJsonSchemas,\n metadata,\n request: this.effectiveRequest,\n modelOptions,\n systemPrompts: this.systemPrompts,\n logger: this.logger,\n threadId: this.threadId,\n runId: this.runIdOverride,\n parentRunId: this.parentRunIdOverride,\n // Expose provided capabilities (e.g. sandbox) to harness adapters.\n capabilities: this.middlewareCtx,\n // Client approval decisions, for harness interactive-approval resolution.\n approvals: adapterApprovals,\n ...(combinedSchema ? { outputSchema: combinedSchema } : {}),\n })) {\n if (this.isCancelled()) {\n break\n }\n\n this.totalChunkCount++\n\n this.handleStreamChunk(raw)\n\n // Native combined mode: synthesize `structured-output.start` BEFORE\n // the first TEXT_MESSAGE_START so the client-side StreamProcessor\n // routes the schema-constrained JSON deltas into a\n // StructuredOutputPart. We delay synthesis until we actually see\n // text starting — intermediate tool-call iterations don't need it,\n // and emitting at run-start would wrap tool-call commentary into a\n // structured-output part too.\n if (\n raw.type === EventType.CUSTOM &&\n raw.name === 'structured-output.start'\n ) {\n this.combinedStartEmitted = true\n const startValue = raw.value\n if (\n startValue &&\n typeof startValue === 'object' &&\n 'messageId' in startValue &&\n typeof startValue.messageId === 'string'\n ) {\n this.combinedStructuredMessageId = startValue.messageId\n this.captureStructuredOutputMessageIdentity(startValue.messageId)\n }\n }\n\n let outboundChunk: AdapterYieldChunk = raw\n if (\n this.finalStructuredOutput?.source === 'event' &&\n raw.type === EventType.CUSTOM &&\n raw.name === 'structured-output.complete'\n ) {\n const parsed = readStructuredOutputCompleteValue(raw.value)\n if (parsed) {\n const object = this.finalStructuredOutput.normalize\n ? this.finalStructuredOutput.normalize(parsed.object)\n : parsed.object\n this.structuredOutputResult = { data: object, rawText: parsed.raw }\n this.combinedCompleteEmitted = true\n const value = raw.value\n const completeMessageId = readCustomEventMessageId(value)\n if (completeMessageId) {\n this.combinedStructuredMessageId = completeMessageId\n this.captureStructuredOutputMessageIdentity(completeMessageId)\n }\n if (object !== parsed.object && value && typeof value === 'object') {\n outboundChunk = { ...raw, value: { ...value, object } }\n }\n }\n }\n\n if (\n this.finalStructuredOutput?.nativeCombined === true &&\n this.finalStructuredOutput.yieldChunks &&\n this.finalStructuredOutput.source !== 'event' &&\n !this.combinedStartEmitted &&\n raw.type === EventType.TEXT_MESSAGE_START\n ) {\n this.combinedStartEmitted = true\n const messageId =\n typeof raw.messageId === 'string' && raw.messageId !== ''\n ? raw.messageId\n : generateMessageId()\n this.combinedStructuredMessageId = messageId\n const synthStart: StreamChunk = {\n type: EventType.CUSTOM,\n name: 'structured-output.start',\n value: { messageId },\n timestamp: Date.now(),\n }\n const synthOutputs = await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n synthStart,\n )\n yield* this.emitPublicChunks(synthOutputs)\n }\n\n const outputChunks = await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n outboundChunk,\n )\n // When a streaming structured-output finalization step will run after\n // the agent loop, suppress the agent-loop's RUN_STARTED/RUN_FINISHED\n // here — the finalization step emits the single outer lifecycle pair\n // that reaches the consumer.\n //\n // Native combined mode does NOT issue a second adapter stream — the\n // agent loop's lifecycle IS the outer pair the consumer sees.\n const suppressAgentLifecycle =\n !!this.finalStructuredOutput &&\n this.finalStructuredOutput.yieldChunks &&\n this.finalStructuredOutput.nativeCombined !== true\n for (const outputChunk of outputChunks) {\n for (const spec of normalizeStreamChunk(\n outputChunk as AdapterYieldChunk,\n )) {\n restorePublicUsage(spec)\n if (\n suppressAgentLifecycle &&\n (spec.type === EventType.RUN_STARTED ||\n spec.type === EventType.RUN_FINISHED)\n ) {\n continue\n }\n if (spec.type === EventType.RUN_FINISHED) {\n this.deferredModelRunFinishedChunks.push(spec)\n continue\n }\n if (this.shouldDeferToolCallRunFinished(spec)) {\n this.deferredToolCallRunFinishedChunks.push(spec)\n continue\n }\n if (spec.type === EventType.RUN_STARTED) {\n if (this.hasPublicRunStarted) continue\n this.hasPublicRunStarted = true\n }\n this.logger.output(`type=${spec.type}`, { chunk: spec })\n yield spec\n this.middlewareCtx.chunkIndex++\n }\n }\n\n if (raw.type === EventType.RUN_FINISHED) {\n await this.runOnUsageFromChunk(raw)\n }\n\n // Drain any sandbox.file events emitted while processing this chunk.\n yield* this.drainSandboxFileQueue()\n yield* this.drainMiddlewareCustomQueue()\n\n if (this.earlyTermination) {\n break\n }\n }\n\n // Drain any remaining sandbox.file events emitted after the stream ended.\n yield* this.drainSandboxFileQueue()\n yield* this.drainMiddlewareCustomQueue()\n }\n\n private handleStreamChunk(chunk: AdapterYieldChunk): void {\n // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- AG-UI EventType enum members vs string-literal case labels; default branch handles untraced events.\n switch (chunk.type) {\n // AG-UI Events\n case 'TEXT_MESSAGE_START':\n if (typeof chunk.messageId === 'string' && chunk.messageId !== '') {\n this.captureStreamMessageIdentity(chunk.messageId)\n }\n break\n case 'TEXT_MESSAGE_CONTENT':\n this.handleTextMessageContentEvent(chunk)\n break\n case 'TOOL_CALL_START':\n this.handleToolCallStartEvent(chunk)\n break\n case 'TOOL_CALL_ARGS':\n this.handleToolCallArgsEvent(chunk)\n break\n case 'TOOL_CALL_END':\n this.handleToolCallEndEvent(chunk)\n break\n case 'TOOL_CALL_RESULT':\n this.handleToolCallResultEvent(chunk)\n break\n case 'RUN_FINISHED':\n this.handleRunFinishedEvent(chunk)\n break\n case 'RUN_ERROR':\n this.handleRunErrorEvent(chunk)\n break\n case 'STEP_STARTED':\n this.handleStepStartedEvent()\n break\n case 'STEP_FINISHED':\n this.handleStepFinishedEvent(chunk)\n break\n\n case 'REASONING_MESSAGE_CONTENT':\n this.handleReasoningMessageContentEvent(chunk)\n break\n\n case 'REASONING_ENCRYPTED_VALUE':\n this.handleReasoningEncryptedValueEvent(chunk)\n break\n\n case 'REASONING_START':\n case 'REASONING_MESSAGE_START':\n case 'REASONING_MESSAGE_END':\n case 'REASONING_END':\n // No special handling needed\n break\n\n default:\n // RUN_STARTED, TEXT_MESSAGE_END, STATE_SNAPSHOT, STATE_DELTA, CUSTOM\n // - no special handling needed in chat activity\n break\n }\n }\n\n // ===========================\n // AG-UI Event Handlers\n // ===========================\n\n private handleTextMessageContentEvent(chunk: TextMessageContentEvent): void {\n const extra = chunk as AdapterYieldChunk\n // Adapters still emit leftover cumulative `content` on RAW yields.\n // Alignment suppresses already-delivered deltas, so this snapshot is\n // what a takeover saves as the full assistant text.\n if (typeof extra.content === 'string' && extra.content !== '') {\n this.accumulatedContent = extra.content\n } else {\n this.accumulatedContent += chunk.delta\n }\n this.middlewareCtx.accumulatedContent = this.accumulatedContent\n }\n\n private captureStreamMessageIdentity(messageId: string): void {\n this.currentMessageId = messageId\n this.middlewareCtx.currentMessageId = messageId\n if (!this.streamIdentityCaptured) {\n this.currentMessageCreatedAt = new Date()\n this.streamIdentityCaptured = true\n }\n }\n\n private captureStructuredOutputMessageIdentity(messageId: string): void {\n this.structuredOutputMessageId = messageId\n this.structuredOutputMessageCreatedAt ??= new Date()\n }\n\n private handleToolCallStartEvent(chunk: ToolCallStartEvent): void {\n if (\n typeof chunk.parentMessageId === 'string' &&\n chunk.parentMessageId !== ''\n ) {\n this.captureStreamMessageIdentity(chunk.parentMessageId)\n }\n this.toolCallManager.addToolCallStartEvent(chunk)\n const metadata = chunk.metadata\n const thoughtSignature =\n metadata != null &&\n typeof metadata === 'object' &&\n 'thoughtSignature' in metadata &&\n typeof metadata.thoughtSignature === 'string' &&\n metadata.thoughtSignature !== ''\n ? metadata.thoughtSignature\n : undefined\n if (thoughtSignature === undefined) return\n const call = this.toolCallManager\n .getToolCalls()\n .find((candidate) => candidate.id === chunk.toolCallId)\n if (!call) return\n call.metadata = {\n ...(call.metadata != null && typeof call.metadata === 'object'\n ? call.metadata\n : {}),\n thoughtSignature,\n }\n }\n\n private handleToolCallArgsEvent(chunk: ToolCallArgsEvent): void {\n this.toolCallManager.addToolCallArgsEvent(chunk)\n }\n\n private handleToolCallEndEvent(chunk: ToolCallEndEvent): void {\n this.toolCallManager.completeToolCall(chunk)\n const end = chunk as AdapterYieldChunk\n const state = end.state ?? tanstackMetadata(end)?.state\n if (state !== 'output-error' || end.result === undefined) return\n this.handleToolCallResultEvent({\n type: EventType.TOOL_CALL_RESULT,\n toolCallId: chunk.toolCallId,\n content: Array.isArray(end.result)\n ? JSON.stringify(end.result)\n : end.result,\n messageId: chunk.toolCallId,\n metadata: { tanstack: { state: 'output-error' } },\n })\n }\n\n private handleToolCallResultEvent(chunk: ToolCallResultEvent): void {\n const isOutputError = tanstackMetadata(chunk)?.state === 'output-error'\n if (!isOutputError) return\n\n const toolCall = this.toolCallManager\n .getToolCalls()\n .find((candidate) => candidate.id === chunk.toolCallId)\n if (!toolCall) return\n\n this.streamedToolErrorResults.set(chunk.toolCallId, {\n toolCallId: chunk.toolCallId,\n toolName: toolCall.function.name,\n result: chunk.content,\n state: 'output-error',\n })\n }\n\n private handleRunFinishedEvent(chunk: AdapterYieldChunk): void {\n this.finishedEvent = chunk as RunFinishedEvent\n const raw = chunk\n const top = raw.finishReason\n this.lastFinishReason =\n top === 'stop' ||\n top === 'length' ||\n top === 'content_filter' ||\n top === 'tool_calls' ||\n top === null\n ? top\n : (tanstackMetadata(chunk)?.finishReason ?? null)\n }\n\n private async runOnUsageFromChunk(\n chunk: RunFinishedEvent | AdapterYieldChunk,\n ): Promise<void> {\n const rebuilt = rebuildTokenUsage(\n chunk.usage,\n tanstackMetadata(chunk)?.usage,\n )\n if (rebuilt) {\n await this.middlewareRunner.runOnUsage(this.middlewareCtx, rebuilt)\n }\n }\n\n private handleRunErrorEvent(\n chunk: Extract<StreamChunk, { type: 'RUN_ERROR' }>,\n ): void {\n this.earlyTermination = true\n if (this.finalizationError === null) {\n const message = chunk.message || 'Run failed'\n this.finalizationError = {\n message,\n ...(chunk.code !== undefined ? { code: chunk.code } : {}),\n }\n }\n }\n\n private finalizeCurrentThinkingStep(): void {\n if (this.currentThinkingContent || this.currentThinkingSignature) {\n this.accumulatedThinking.push({\n content: this.currentThinkingContent,\n ...(this.currentThinkingSignature && {\n signature: this.currentThinkingSignature,\n }),\n })\n this.currentThinkingContent = ''\n this.currentThinkingSignature = ''\n }\n }\n\n private handleStepStartedEvent(): void {\n this.finalizeCurrentThinkingStep()\n }\n\n private handleStepFinishedEvent(chunk: AdapterYieldChunk): void {\n if (typeof chunk.signature === 'string' && chunk.signature !== '') {\n this.currentThinkingSignature = chunk.signature\n }\n }\n\n private handleReasoningMessageContentEvent(\n chunk: Extract<StreamChunk, { type: 'REASONING_MESSAGE_CONTENT' }>,\n ): void {\n this.currentThinkingContent += chunk.delta\n }\n\n private handleReasoningEncryptedValueEvent(\n chunk: ReasoningEncryptedValueEvent,\n ): void {\n if (chunk.subtype === 'tool-call') {\n const call = this.messages\n .flatMap((message) => message.toolCalls ?? [])\n .find((toolCall) => toolCall.id === chunk.entityId)\n if (call) {\n call.metadata = {\n ...(call.metadata != null && typeof call.metadata === 'object'\n ? call.metadata\n : {}),\n thoughtSignature: chunk.encryptedValue,\n }\n }\n return\n }\n this.currentThinkingSignature = chunk.encryptedValue\n }\n\n /**\n * Tools available for execution this turn. The discovery tool is dropped\n * from the advertised set (`this.tools`) once every lazy tool is discovered,\n * but a model may still re-request discovery; this widens execution lookup\n * to include it so such calls don't fail with \"Unknown tool\". Centralised so\n * both execution sites (`processToolCalls` and `checkForPendingToolCalls`)\n * stay in sync.\n */\n private resolveExecutableTools(\n toolCalls: ReadonlyArray<ToolCall>,\n ): ReadonlyArray<AnyTool> {\n return this.lazyToolManager.getExecutableTools(\n this.tools,\n toolCalls.map((tc) => tc.function.name),\n )\n }\n\n private async *checkForPendingToolCalls(): AsyncGenerator<\n StreamChunk,\n ToolPhaseResult,\n void\n > {\n const pendingToolCalls = this.getPendingToolCallsFromMessages()\n if (pendingToolCalls.length === 0) {\n return 'continue'\n }\n\n const finishEvent = this.createSyntheticFinishedEvent()\n\n // Count is deduped so wait→resume after a live turn does not double-count.\n // Per-turn execution caps are app middleware via onBeforeToolCall skip.\n this.recordToolCalls(pendingToolCalls)\n\n // Handle undiscovered lazy tool calls with self-correcting error messages\n const undiscoveredLazyResults: Array<ToolResult> = []\n const executablePendingCalls = pendingToolCalls.filter((tc) => {\n if (this.lazyToolManager.isUndiscoveredLazyTool(tc.function.name)) {\n undiscoveredLazyResults.push({\n toolCallId: tc.id,\n toolName: tc.function.name,\n result: {\n error: this.lazyToolManager.getUndiscoveredToolError(\n tc.function.name,\n ),\n },\n state: 'output-error',\n })\n return false\n }\n return true\n })\n\n // Non-executed outcomes (undiscovered lazy). Emitted after executed\n // results so the stream prefers real results first. Per-turn skips are\n // produced by middleware via onBeforeToolCall and appear in execution results.\n const deferredErrorResults = [...undiscoveredLazyResults]\n\n // Build args lookup so buildToolResultChunks can emit TOOL_CALL_START +\n // TOOL_CALL_ARGS before TOOL_CALL_END during continuation re-executions.\n const argsMap = new Map<string, string>()\n for (const tc of pendingToolCalls) {\n argsMap.set(tc.id, tc.function.arguments)\n }\n\n if (executablePendingCalls.length === 0) {\n if (deferredErrorResults.length > 0) {\n for (const chunk of this.buildToolResultChunks(\n deferredErrorResults,\n finishEvent,\n argsMap,\n )) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n }\n return 'continue'\n }\n\n this.middlewareCtx.phase = 'beforeTools'\n if (\n yield* this.emitBoundaryInterrupts(\n 'beforeTools',\n finishEvent,\n executablePendingCalls,\n )\n ) {\n this.setToolPhase('wait')\n return 'wait'\n }\n\n const { approvals, clientToolResults } = this.collectClientState()\n\n const generator = executeToolCalls(\n executablePendingCalls,\n this.resolveExecutableTools(executablePendingCalls),\n approvals,\n clientToolResults,\n (eventName, data) => this.createCustomEventChunk(eventName, data),\n {\n onBeforeToolCall: async (toolCall, tool, args) => {\n this.logger.tools(`phase=before name=${toolCall.function.name}`, {\n name: toolCall.function.name,\n args,\n })\n const hookCtx = {\n toolCall,\n tool,\n args,\n toolName: toolCall.function.name,\n toolCallId: toolCall.id,\n }\n return this.middlewareRunner.runOnBeforeToolCall(\n this.middlewareCtx,\n hookCtx,\n )\n },\n onAfterToolCall: async (info) => {\n this.logger.tools(`phase=after name=${info.toolName}`, {\n name: info.toolName,\n result: info.result,\n })\n await this.middlewareRunner.runOnAfterToolCall(\n this.middlewareCtx,\n info,\n )\n },\n },\n this.middlewareCtx.context,\n this.toolAbortSignal,\n {\n deniedToolResults: this.resumeDeniedToolResults,\n cancelledToolCallIds: this.resumeCancelledToolCallIds,\n },\n )\n\n // Consume the async generator, yielding custom events and collecting the return value\n const executionResult = yield* this.drainToolCallGenerator(generator)\n\n // Check if middleware aborted during pending tool execution\n if (this.isMiddlewareAborted()) {\n this.setToolPhase('stop')\n return 'stop'\n }\n\n const allResults = [...executionResult.results, ...deferredErrorResults]\n\n // Notify middleware of tool phase completion (devtools emits aggregate events here)\n yield* this.runWhileYielding(\n this.middlewareRunner.runOnToolPhaseComplete(this.middlewareCtx, {\n toolCalls: pendingToolCalls,\n results: allResults,\n needsApproval: executionResult.needsApproval,\n needsClientExecution: executionResult.needsClientExecution,\n }),\n )\n\n if (\n executionResult.needsApproval.length > 0 ||\n executionResult.needsClientExecution.length > 0\n ) {\n this.discardDeferredToolCallRunFinishedChunks()\n\n if (allResults.length > 0) {\n for (const chunk of this.buildToolResultChunks(\n allResults,\n finishEvent,\n )) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n }\n\n const emitted = yield* this.emitActionableInterruptBoundary(\n finishEvent,\n executionResult.needsApproval,\n executionResult.needsClientExecution,\n )\n this.setToolPhase(emitted ? 'wait' : 'stop')\n return emitted ? 'wait' : 'stop'\n }\n\n const toolResultChunks = this.buildToolResultChunks(allResults, finishEvent)\n\n for (const chunk of toolResultChunks) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n\n return 'continue'\n }\n\n private async *processToolCalls(): AsyncGenerator<StreamChunk, void, void> {\n if (!this.shouldExecuteToolPhase()) {\n // Text-only turn — clear per-turn count so strategies see 0 tools.\n this.lastTurnToolCallCount = 0\n this.setToolPhase('stop')\n return\n }\n\n const toolCalls = this.toolCallManager.getToolCalls()\n const finishEvent = this.finishedEvent\n\n if (!finishEvent || toolCalls.length === 0) {\n this.lastTurnToolCallCount = 0\n this.setToolPhase('stop')\n return\n }\n\n // Count every model-emitted tool call. Per-turn execution caps are app\n // middleware via onBeforeToolCall skip.\n this.recordToolCalls(toolCalls)\n\n this.addAssistantToolCallMessage(toolCalls)\n\n // Handle undiscovered lazy tool calls with self-correcting error messages\n const undiscoveredLazyResults: Array<ToolResult> = []\n const executableToolCalls = toolCalls.filter((tc) => {\n if (this.streamedToolErrorResults.has(tc.id)) {\n return false\n }\n if (this.lazyToolManager.isUndiscoveredLazyTool(tc.function.name)) {\n undiscoveredLazyResults.push({\n toolCallId: tc.id,\n toolName: tc.function.name,\n result: {\n error: this.lazyToolManager.getUndiscoveredToolError(\n tc.function.name,\n ),\n },\n state: 'output-error',\n })\n return false\n }\n return true\n })\n\n // Non-executed outcomes. Per-turn skips come from middleware and appear in\n // execution results.\n const deferredErrorResults = [\n ...this.streamedToolErrorResults.values(),\n ...undiscoveredLazyResults,\n ]\n\n if (executableToolCalls.length === 0) {\n yield* this.flushDeferredToolCallRunFinishedChunks()\n // All tool calls already have error results — emit them, then continue\n // the loop (strategy / onShouldContinue may stop).\n if (deferredErrorResults.length > 0) {\n for (const chunk of this.buildToolResultChunks(\n deferredErrorResults,\n finishEvent,\n )) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n }\n this.toolCallManager.clear()\n this.setToolPhase('continue')\n return\n }\n this.middlewareCtx.phase = 'beforeTools'\n\n if (\n yield* this.emitBoundaryInterrupts(\n 'beforeTools',\n finishEvent,\n executableToolCalls,\n )\n ) {\n this.setToolPhase('wait')\n return\n }\n\n const { approvals, clientToolResults } = this.collectClientState()\n\n const generator = executeToolCalls(\n executableToolCalls,\n this.resolveExecutableTools(executableToolCalls),\n approvals,\n clientToolResults,\n (eventName, data) => this.createCustomEventChunk(eventName, data),\n {\n onBeforeToolCall: async (toolCall, tool, args) => {\n this.logger.tools(`phase=before name=${toolCall.function.name}`, {\n name: toolCall.function.name,\n args,\n })\n const hookCtx = {\n toolCall,\n tool,\n args,\n toolName: toolCall.function.name,\n toolCallId: toolCall.id,\n }\n return this.middlewareRunner.runOnBeforeToolCall(\n this.middlewareCtx,\n hookCtx,\n )\n },\n onAfterToolCall: async (info) => {\n this.logger.tools(`phase=after name=${info.toolName}`, {\n name: info.toolName,\n result: info.result,\n })\n await this.middlewareRunner.runOnAfterToolCall(\n this.middlewareCtx,\n info,\n )\n },\n },\n this.middlewareCtx.context,\n this.toolAbortSignal,\n {\n deniedToolResults: this.resumeDeniedToolResults,\n cancelledToolCallIds: this.resumeCancelledToolCallIds,\n },\n )\n\n // Consume the async generator, yielding custom events and collecting the return value\n const executionResult = yield* this.drainToolCallGenerator(generator)\n\n this.middlewareCtx.phase = 'afterTools'\n\n // Check if middleware aborted during tool execution\n if (this.isMiddlewareAborted()) {\n this.setToolPhase('stop')\n return\n }\n\n // Executed results first, then deferred errors (fan-out skips / undiscovered)\n const allResults = [...executionResult.results, ...deferredErrorResults]\n\n // Notify middleware of tool phase completion (devtools emits aggregate events here)\n yield* this.runWhileYielding(\n this.middlewareRunner.runOnToolPhaseComplete(this.middlewareCtx, {\n toolCalls,\n results: allResults,\n needsApproval: executionResult.needsApproval,\n needsClientExecution: executionResult.needsClientExecution,\n }),\n )\n\n const afterToolBoundaryChunks = this.buildToolResultChunks(\n allResults,\n finishEvent,\n )\n const afterToolRequests = yield* this.runWhileYielding(\n this.middlewareRunner.runOnInterruptBoundary(\n this.middlewareCtx as ChatMiddlewareContext<TContext> & {\n phase: 'afterTools'\n },\n ),\n )\n if (afterToolRequests.length > 0) {\n for (const chunk of afterToolBoundaryChunks) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n yield* this.emitBoundaryInterrupts(\n 'afterTools',\n finishEvent,\n toolCalls,\n afterToolRequests,\n )\n this.setToolPhase('wait')\n return\n }\n\n if (\n executionResult.needsApproval.length > 0 ||\n executionResult.needsClientExecution.length > 0\n ) {\n if (allResults.length > 0) {\n for (const chunk of afterToolBoundaryChunks) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n }\n\n const emitted = yield* this.emitActionableInterruptBoundary(\n finishEvent,\n executionResult.needsApproval,\n executionResult.needsClientExecution,\n )\n this.setToolPhase(emitted ? 'wait' : 'stop')\n return\n }\n\n yield* this.flushDeferredToolCallRunFinishedChunks()\n\n const toolResultChunks = afterToolBoundaryChunks\n\n for (const chunk of toolResultChunks) {\n yield* this.pipeThroughMiddleware(chunk)\n }\n\n // Refresh tools if lazy tools were discovered in this batch\n if (this.lazyToolManager.hasNewlyDiscoveredTools()) {\n this.tools = this.lazyToolManager.getActiveTools()\n this.toolCallManager = new ToolCallManager<\n ReadonlyArray<AnyTool>,\n TContext\n >(this.tools)\n this.setToolPhase('continue')\n return\n }\n\n this.toolCallManager.clear()\n\n this.setToolPhase('continue')\n }\n\n private shouldDeferToolCallRunFinished(chunk: StreamChunk): boolean {\n return (\n chunk.type === EventType.RUN_FINISHED &&\n this.lastFinishReason === 'tool_calls' &&\n this.tools.length > 0 &&\n this.toolCallManager.hasToolCalls()\n )\n }\n\n private *flushDeferredToolCallRunFinishedChunks(): Generator<StreamChunk> {\n for (const chunk of this.deferredToolCallRunFinishedChunks) {\n this.logger.output(`type=${chunk.type}`, { chunk })\n yield chunk\n this.middlewareCtx.chunkIndex++\n }\n this.deferredToolCallRunFinishedChunks = []\n }\n\n private *flushDeferredModelRunFinishedChunks(): Generator<StreamChunk> {\n for (const chunk of this.deferredModelRunFinishedChunks) {\n this.logger.output(`type=${chunk.type}`, { chunk })\n yield chunk\n this.middlewareCtx.chunkIndex++\n }\n this.deferredModelRunFinishedChunks = []\n }\n\n private async *emitSyntheticRunStarted(\n finishEvent: RunFinishedEvent,\n ): AsyncGenerator<StreamChunk, void, void> {\n if (this.hasPublicRunStarted) return\n yield* this.pipeThroughMiddleware({\n type: EventType.RUN_STARTED,\n runId: finishEvent.runId,\n threadId: finishEvent.threadId,\n timestamp: Date.now(),\n })\n }\n\n private async *emitSuccessfulEarlyTermination(): AsyncGenerator<\n StreamChunk,\n void,\n void\n > {\n // `stop` is a finished run, not another tool cycle. `tool_calls` here\n // makes the client auto-send after afterTools, so reject looks stuck.\n this.lastFinishReason = 'stop'\n const finishEvent = this.createSyntheticFinishedEvent('stop')\n yield* this.emitSyntheticRunStarted(finishEvent)\n yield* this.pipeThroughMiddleware({\n ...finishEvent,\n timestamp: Date.now(),\n outcome: { type: 'success' },\n })\n }\n\n private discardDeferredToolCallRunFinishedChunks(): void {\n this.deferredToolCallRunFinishedChunks = []\n }\n\n private shouldExecuteToolPhase(): boolean {\n return (\n this.lastFinishReason === 'tool_calls' &&\n this.tools.length > 0 &&\n this.toolCallManager.hasToolCalls()\n )\n }\n\n private addAssistantToolCallMessage(toolCalls: Array<ToolCall>): void {\n this.finalizeCurrentThinkingStep()\n\n this.messages = [\n ...this.messages,\n {\n role: 'assistant',\n content: this.accumulatedContent || null,\n toolCalls,\n id: this.currentMessageId ?? undefined,\n createdAt: this.currentMessageCreatedAt ?? undefined,\n ...(this.accumulatedThinking.length > 0 && {\n thinking: this.accumulatedThinking,\n }),\n },\n ]\n this.middlewareCtx.messages = this.messages\n }\n\n private addTerminalAssistantMessages(): void {\n this.finalizeCurrentThinkingStep()\n\n const structuredResult = this.structuredOutputResult\n const raw = structuredResult\n ? structuredResult.rawText || safeJsonStringify(structuredResult.data)\n : ''\n const structuredOutput: StructuredOutputPart | undefined = structuredResult\n ? {\n type: 'structured-output',\n status: 'complete',\n data: structuredResult.data,\n partial: structuredResult.data,\n raw,\n ...(structuredResult.reasoning !== undefined\n ? { reasoning: structuredResult.reasoning }\n : {}),\n }\n : undefined\n const nativeCombined = this.finalStructuredOutput?.nativeCombined === true\n const eventSourced = this.finalStructuredOutput?.source === 'event'\n const structuredId =\n this.structuredOutputMessageId ??\n this.combinedStructuredMessageId ??\n this.currentMessageId ??\n this.createId('msg')\n // Codex, OpenCode, ACP, and grok-build reuse the last text messageId\n // on structured-output.complete. Split only when the event uses a\n // different id (Claude Code). Same-id output stays on one message.\n const splitStructuredMessage =\n Boolean(structuredOutput) &&\n (!nativeCombined || eventSourced) &&\n this.currentMessageId != null &&\n structuredId !== this.currentMessageId\n const messages = [...this.middlewareCtx.messages]\n const existingStructuredIndex = messages.findIndex(\n (message) => message.role === 'assistant' && message.id === structuredId,\n )\n const currentTurnAlreadyRecorded = messages.some(\n (message) =>\n message.role === 'assistant' && message.id === this.currentMessageId,\n )\n const thinking =\n this.accumulatedThinking.length > 0 ? this.accumulatedThinking : undefined\n const startedLength = messages.length\n\n if (structuredOutput && existingStructuredIndex >= 0) {\n const existing = messages[existingStructuredIndex]\n if (existing) {\n messages[existingStructuredIndex] = {\n ...existing,\n content: raw || existing.content,\n structuredOutput,\n }\n }\n } else if (structuredOutput && !splitStructuredMessage) {\n if (!currentTurnAlreadyRecorded) {\n messages.push({\n role: 'assistant',\n content: this.accumulatedContent || raw || null,\n id: structuredId,\n createdAt:\n this.currentMessageCreatedAt ??\n this.structuredOutputMessageCreatedAt ??\n new Date(),\n structuredOutput,\n ...(thinking ? { thinking } : {}),\n })\n }\n } else {\n if (\n !currentTurnAlreadyRecorded &&\n (this.accumulatedContent !== '' || thinking)\n ) {\n messages.push({\n role: 'assistant',\n content: this.accumulatedContent || null,\n id: this.currentMessageId ?? this.createId('msg'),\n createdAt: this.currentMessageCreatedAt ?? new Date(),\n ...(thinking ? { thinking } : {}),\n })\n }\n if (structuredOutput) {\n messages.push({\n role: 'assistant',\n content: raw || null,\n id: structuredId,\n createdAt: this.structuredOutputMessageCreatedAt ?? new Date(),\n structuredOutput,\n })\n }\n }\n\n if (messages.length === startedLength && existingStructuredIndex < 0) {\n return\n }\n\n this.messages = messages\n this.middlewareCtx.messages = this.messages\n }\n\n /**\n * Extract client state (approvals and client tool results) from original messages.\n * This is called in the constructor BEFORE converting to ModelMessage format,\n * because the parts array (which contains approval state) is lost during conversion.\n */\n private extractClientStateFromOriginalMessages(\n originalMessages: Array<any>,\n ): {\n approvals: Map<string, ToolApprovalResolution>\n clientToolResults: Map<string, any>\n } {\n const approvals = new Map<string, ToolApprovalResolution>()\n const clientToolResults = new Map<string, any>()\n\n for (const message of originalMessages) {\n // Check for UIMessage format (parts array) - extract client tool results and approvals\n if (message.role === 'assistant' && message.parts) {\n for (const part of message.parts) {\n if (part.type === 'tool-call') {\n // Extract client tool results (tools without approval that have output)\n if (part.output !== undefined && !part.approval) {\n clientToolResults.set(part.id, part.output)\n }\n // Extract approval responses from UIMessage format parts\n if (\n part.approval?.id &&\n part.approval?.approved !== undefined &&\n part.state === 'approval-responded'\n ) {\n approvals.set(part.approval.id, part.approval.approved)\n }\n }\n }\n }\n }\n\n return { approvals, clientToolResults }\n }\n\n private collectClientState(): {\n approvals: Map<string, ToolApprovalResolution>\n clientToolResults: Map<string, any>\n } {\n // Start with the initial client state extracted from original messages\n const approvals = new Map(this.initialApprovals)\n const clientToolResults = new Map(this.initialClientToolResults)\n for (const [approvalId, approved] of this.resumeApprovals) {\n approvals.set(approvalId, approved)\n }\n for (const [toolCallId, result] of this.resumeClientToolResults) {\n clientToolResults.set(toolCallId, result)\n }\n\n // Also check current messages for any additional tool results (from server tools)\n for (const message of this.messages) {\n // Check for ModelMessage format (role: 'tool' messages contain tool results)\n // This handles results sent back from the client after executing client-side tools\n if (message.role === 'tool' && message.toolCallId) {\n // Parse content back to original output (was stringified by\n // uiMessageToModelMessages). Multimodal results carry an\n // Array<ContentPart> directly — pass it through without parsing.\n let output: unknown\n if (Array.isArray(message.content)) {\n output = message.content\n } else {\n try {\n output = JSON.parse(message.content as string)\n } catch {\n output = message.content\n }\n }\n // Skip approval response messages (they have pendingExecution marker)\n // These are NOT real client tool results — they are synthetic tool messages\n // created by uiMessageToModelMessages for approved-but-not-yet-executed tools.\n // Treating them as results would prevent the server from requesting actual\n // client-side execution after approval (see GitHub issue #225).\n if (\n output &&\n typeof output === 'object' &&\n (output as any).pendingExecution === true\n ) {\n continue\n }\n clientToolResults.set(message.toolCallId, output)\n }\n }\n\n return { approvals, clientToolResults }\n }\n\n private genericInterruptId(): string {\n return this.createId('interrupt')\n }\n\n private buildActionableInterrupts(\n approvals: Array<ApprovalRequest>,\n clientRequests: Array<ClientToolRequest>,\n genericRequests: ReadonlyArray<\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n > = [],\n genericInterruptIds: ReadonlyArray<string> = [],\n ): Array<Interrupt> {\n const interrupts: Array<Interrupt> = []\n\n for (const approval of approvals) {\n const tool = this.tools.find(\n (candidate) => candidate.name === approval.toolName,\n ) as RuntimeToolWithApproval | undefined\n const normalized = normalizeApprovalSchema(\n tool?.approvalSchema,\n tool?.inputSchema,\n )\n interrupts.push({\n id: approval.approvalId,\n // Display hint only. `reason` is free-form AG-UI text that another\n // producer can also spell `tool_call`, so it never decides ownership —\n // the binding in `metadata` does.\n reason: 'tool_call',\n message: `Approval required to run ${approval.toolName}`,\n toolCallId: approval.toolCallId,\n responseSchema: normalized.responseSchema,\n metadata: {\n kind: 'approval',\n toolName: approval.toolName,\n input: approval.input,\n [interruptBindingMetadataKey]: {\n v: INTERRUPT_BINDING_VERSION,\n kind: 'tool-approval',\n interruptId: approval.approvalId,\n toolName: approval.toolName,\n toolCallId: approval.toolCallId,\n originalArgs: approval.input,\n inputSchemaHash: hashSchemaInput(tool?.inputSchema),\n approvalSchemaHash: normalized.approvalSchemaHash,\n responseSchemaHash: normalized.responseSchemaHash,\n },\n },\n })\n }\n\n for (const clientTool of clientRequests) {\n const tool = this.tools.find(\n (candidate) => candidate.name === clientTool.toolName,\n )\n const responseSchema = convertSchemaToJsonSchema(tool?.outputSchema) ?? {}\n interrupts.push({\n id: `client_tool_${clientTool.toolCallId}`,\n reason: 'tanstack:client_tool_execution',\n message: `Client tool ${clientTool.toolName} is ready to run`,\n toolCallId: clientTool.toolCallId,\n responseSchema,\n metadata: {\n kind: 'client_tool',\n toolName: clientTool.toolName,\n input: clientTool.input,\n [interruptBindingMetadataKey]: {\n v: INTERRUPT_BINDING_VERSION,\n kind: 'client-tool-execution',\n interruptId: `client_tool_${clientTool.toolCallId}`,\n toolName: clientTool.toolName,\n toolCallId: clientTool.toolCallId,\n outputSchemaHash: hashSchemaInput(tool?.outputSchema),\n responseSchemaHash: digestInterruptJson(\n canonicalInterruptJson(responseSchema),\n ),\n },\n },\n })\n }\n\n for (const [index, request] of genericRequests.entries()) {\n const batchIndex = interrupts.length\n const id = genericInterruptIds[index]\n if (!id) throw new Error('Generic interrupt id is unavailable.')\n const preEmission = createInterruptBinding(request, { batchIndex })\n interrupts.push({\n id,\n reason: request.reason,\n message: request.message,\n ...(preEmission.descriptor.responseSchemaCanonicalJson !== undefined\n ? {\n responseSchema: JSON.parse(\n preEmission.descriptor.responseSchemaCanonicalJson,\n ),\n }\n : {}),\n ...(request.expiresAt !== undefined\n ? { expiresAt: request.expiresAt }\n : {}),\n metadata: {\n [interruptBindingMetadataKey]: {\n v: INTERRUPT_BINDING_VERSION,\n kind: 'generic',\n interruptId: id,\n definitionId: preEmission.descriptor.definitionId,\n key: preEmission.descriptor.key,\n batchIndex,\n ...(request.expiresAt !== undefined\n ? { expiresAt: request.expiresAt }\n : {}),\n ...(preEmission.descriptor.payloadSchemaHash\n ? {\n payloadSchemaHash: preEmission.descriptor.payloadSchemaHash,\n }\n : {}),\n ...(preEmission.descriptor.responseSchemaHash !== undefined\n ? {\n responseSchemaHash: preEmission.descriptor.responseSchemaHash,\n }\n : {}),\n },\n ...(preEmission.payload !== undefined\n ? { [INTERRUPT_PAYLOAD_METADATA_KEY]: preEmission.payload }\n : {}),\n },\n })\n }\n\n const ids = new Set<string>()\n for (const interrupt of interrupts) {\n if (ids.has(interrupt.id)) {\n throw new Error(\n `Duplicate interrupt id in final batch: ${interrupt.id}`,\n )\n }\n ids.add(interrupt.id)\n }\n\n return interrupts\n }\n\n private buildInterruptFinishedChunk(\n finishEvent: RunFinishedEvent,\n approvals: Array<ApprovalRequest>,\n clientRequests: Array<ClientToolRequest>,\n genericRequests: ReadonlyArray<\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n > = [],\n genericInterruptIds?: ReadonlyArray<string>,\n ): StreamChunk {\n return {\n ...finishEvent,\n timestamp: Date.now(),\n outcome: {\n type: 'interrupt',\n interrupts: this.buildActionableInterrupts(\n approvals,\n clientRequests,\n genericRequests,\n genericInterruptIds,\n ),\n },\n }\n }\n\n /**\n * Record a `ui-resource` CUSTOM chunk on the assistant ModelMessage owning\n * its `toolCallId` so the resource survives later MESSAGES_SNAPSHOT chunks\n * (e.g. the interrupt snapshot emitted when the run pauses on a client\n * tool). Mirrors the anchor-preserving approach used for\n * `toolCallMetadata` (#867). See #1397.\n */\n private recordEmittedUiResource(value: unknown): void {\n const part = uiResourcePartFromCustomValue(value)\n if (!part) return\n const next = appendUiResourceToModelMessages(this.messages, part)\n if (next === this.messages) return\n this.messages = next\n this.middlewareCtx.messages = this.messages\n }\n\n private buildMessagesSnapshotChunk(): StreamChunk {\n const withIds = this.messages.map((message, index) => ({\n ...message,\n id:\n message.id ||\n `snapshot_${this.runIdOverride ?? this.requestId}_${index}`,\n }))\n return {\n type: EventType.MESSAGES_SNAPSHOT,\n timestamp: Date.now(),\n messages: uiMessagesToWire(modelMessagesToUIMessages(withIds), {\n includeSnapshotStructuredOutput: true,\n }),\n }\n }\n\n private publicInterruptTerminal(chunk: StreamChunk): StreamChunk {\n if (\n chunk.type !== EventType.RUN_FINISHED ||\n chunk.outcome?.type !== 'interrupt'\n ) {\n return chunk\n }\n return {\n ...chunk,\n outcome: {\n ...chunk.outcome,\n interrupts: chunk.outcome.interrupts.map((interrupt) => {\n if (\n !interrupt.metadata ||\n typeof interrupt.metadata !== 'object' ||\n Array.isArray(interrupt.metadata)\n ) {\n return interrupt\n }\n const metadata = { ...interrupt.metadata }\n const binding = normalizePublicInterruptBinding(\n metadata[interruptBindingMetadataKey],\n interrupt.id,\n )\n if (binding) {\n metadata[interruptBindingMetadataKey] = binding\n } else {\n delete metadata[interruptBindingMetadataKey]\n }\n return { ...interrupt, metadata }\n }),\n },\n }\n }\n\n private interruptFailure(error: unknown): {\n message: string\n code: string\n errors?: ReadonlyArray<InterruptSubmissionError>\n } {\n const structured = structuralInterruptFailure(error)\n if (structured) {\n return {\n message: structured.error.message,\n code: structured.errors[0]?.code ?? 'server',\n errors: structured.errors,\n }\n }\n if (error && typeof error === 'object' && 'errors' in error) {\n const errors = error.errors\n if (Array.isArray(errors)) {\n const first = errors[0]\n if (first && typeof first === 'object') {\n const message =\n 'message' in first && typeof first.message === 'string'\n ? first.message\n : 'Interrupt persistence failed.'\n const code =\n 'code' in first && typeof first.code === 'string'\n ? first.code\n : 'server'\n return { message, code }\n }\n }\n }\n return {\n message:\n error instanceof Error\n ? error.message\n : 'Interrupt persistence failed.',\n code: 'server',\n }\n }\n\n private buildInterruptRunErrorChunk(error: unknown): StreamChunk {\n const failure = this.interruptFailure(error)\n return withTanstackMetadata(\n {\n type: EventType.RUN_ERROR,\n timestamp: Date.now(),\n message: failure.message,\n code: failure.code,\n },\n {\n runId: this.runIdOverride ?? this.requestId,\n threadId: this.threadId,\n ...(failure.errors !== undefined\n ? { interruptErrors: failure.errors }\n : {}),\n },\n ) as StreamChunk\n }\n\n private async *emitInterruptRunError(\n error: unknown,\n ): AsyncGenerator<StreamChunk, void, void> {\n const failure = this.interruptFailure(error)\n this.finalizationError = {\n message: failure.message,\n code: failure.code,\n cause: error,\n }\n yield* this.pipeThroughMiddleware(this.buildInterruptRunErrorChunk(error))\n }\n\n private async *emitActionableInterruptBoundary(\n finishEvent: RunFinishedEvent,\n approvals: Array<ApprovalRequest>,\n clientRequests: Array<ClientToolRequest>,\n genericRequests: ReadonlyArray<\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n > = [],\n ): AsyncGenerator<StreamChunk, boolean, void> {\n yield* this.emitSyntheticRunStarted(finishEvent)\n const genericInterruptIds = genericRequests.map(() =>\n this.genericInterruptId(),\n )\n const terminal = this.completeEphemeralInterruptBindings(\n this.buildInterruptFinishedChunk(\n finishEvent,\n approvals,\n clientRequests,\n genericRequests,\n genericInterruptIds,\n ),\n )\n let terminalOutputs: Array<StreamChunk>\n try {\n terminalOutputs = [\n ...this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(this.middlewareCtx, terminal),\n ),\n ]\n } catch (error) {\n yield* this.emitInterruptRunError(error)\n return false\n }\n\n yield* this.pipeThroughMiddleware(this.buildMessagesSnapshotChunk())\n if (this.params.state !== undefined) {\n yield* this.pipeThroughMiddleware({\n type: EventType.STATE_SNAPSHOT,\n timestamp: Date.now(),\n snapshot: this.params.state,\n })\n }\n for (const output of terminalOutputs) {\n yield this.publicInterruptTerminal(output)\n }\n return true\n }\n\n private async *emitBoundaryInterrupts(\n phase: 'beforeModel' | 'afterModel' | 'beforeTools' | 'afterTools',\n finishEvent: RunFinishedEvent,\n toolCalls: ReadonlyArray<ToolCall> = [],\n requests?: ReadonlyArray<\n GenericInterruptRequest<InterruptDefinition<any, any, any, any>>\n >,\n ): AsyncGenerator<StreamChunk, boolean, void> {\n this.middlewareCtx.phase = phase\n const boundaryRequests =\n requests ??\n (yield* this.runWhileYielding(\n this.middlewareRunner.runOnInterruptBoundary(\n this.middlewareCtx as ChatMiddlewareContext<TContext> & {\n phase: typeof phase\n },\n ),\n ))\n if (boundaryRequests.length === 0) return false\n for (const request of boundaryRequests) {\n if (\n this.interruptDefinitions.get(request.definition.id) !==\n request.definition\n ) {\n throw new Error(\n `Generic interrupt definition ${request.definition.id} is not registered on this chat.`,\n )\n }\n }\n if (phase === 'afterModel') {\n if (this.toolCallManager.hasToolCalls()) {\n this.addAssistantToolCallMessage(this.toolCallManager.getToolCalls())\n } else {\n this.addAssistantTextMessageForInterrupt()\n }\n }\n const actionable = this.getBoundaryActionableToolRequests(toolCalls)\n yield* this.emitActionableInterruptBoundary(\n finishEvent,\n actionable.approvals,\n actionable.clientRequests,\n boundaryRequests,\n )\n return true\n }\n\n private addAssistantTextMessageForInterrupt(): void {\n if (this.accumulatedContent.length === 0) return\n this.messages = [\n ...this.messages,\n { role: 'assistant', content: this.accumulatedContent },\n ]\n this.middlewareCtx.messages = this.messages\n }\n\n private getBoundaryActionableToolRequests(\n toolCalls: ReadonlyArray<ToolCall>,\n ): {\n approvals: Array<ApprovalRequest>\n clientRequests: Array<ClientToolRequest>\n } {\n const { approvals, clientToolResults } = this.collectClientState()\n const approvalRequests: Array<ApprovalRequest> = []\n const clientRequests: Array<ClientToolRequest> = []\n for (const toolCall of toolCalls) {\n const tool = this.resolveExecutableTools([toolCall]).find(\n (candidate) => candidate.name === toolCall.function.name,\n ) as RuntimeToolWithApproval | undefined\n if (!tool) continue\n let input: unknown = {}\n try {\n const parsed = JSON.parse(toolCall.function.arguments.trim() || '{}')\n input = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n input = {}\n }\n const approvalId = `approval_${toolCall.id}`\n if (tool.needsApproval && !approvals.has(approvalId)) {\n approvalRequests.push({\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input,\n approvalId,\n })\n } else if (\n !tool.execute &&\n !clientToolResults.has(toolCall.id) &&\n !this.resumeCancelledToolCallIds.has(toolCall.id)\n ) {\n clientRequests.push({\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input,\n })\n }\n }\n return { approvals: approvalRequests, clientRequests }\n }\n\n private completeEphemeralInterruptBindings(chunk: StreamChunk): StreamChunk {\n if (\n chunk.type !== EventType.RUN_FINISHED ||\n chunk.outcome?.type !== 'interrupt'\n ) {\n return chunk\n }\n const interruptedRunId = this.runIdOverride ?? this.requestId\n return {\n ...chunk,\n outcome: {\n ...chunk.outcome,\n interrupts: chunk.outcome.interrupts.map((interrupt) => {\n if (\n !interrupt.metadata ||\n typeof interrupt.metadata !== 'object' ||\n Array.isArray(interrupt.metadata)\n ) {\n return interrupt\n }\n const metadata = { ...interrupt.metadata }\n const unopened = metadata[interruptBindingMetadataKey]\n if (\n unopened === null ||\n typeof unopened !== 'object' ||\n Array.isArray(unopened)\n ) {\n return interrupt\n }\n metadata[interruptBindingMetadataKey] = {\n ...unopened,\n interruptedRunId,\n generation: 0,\n }\n return { ...interrupt, metadata }\n }),\n },\n }\n }\n\n private buildToolResultChunks(\n results: Array<ToolResult>,\n _finishEvent: RunFinishedEvent,\n argsMap?: Map<string, string>,\n ): Array<AdapterYieldChunk> {\n const chunks: Array<AdapterYieldChunk> = []\n\n for (const result of results) {\n // `content` is the canonical value for the tool `ModelMessage` — it may\n // be an `Array<ContentPart>` (multimodal) which the adapters convert to\n // structured provider output on the next iteration. `wireContent` is the\n // string form emitted on TOOL_CALL_RESULT.content (string-only per the\n // AG-UI spec); the multimodal array travels via the message itself.\n const content = normalizeToolResult(result.result)\n const wireContent =\n typeof content === 'string' ? content : JSON.stringify(content)\n\n // argsMap is set only on continuation re-executions, where the adapter\n // never streamed these calls. Otherwise it already emitted END, so a\n // second one here would be an orphan that fails verifyEvents (#519).\n if (argsMap) {\n chunks.push({\n type: EventType.TOOL_CALL_START,\n timestamp: Date.now(),\n toolCallId: result.toolCallId,\n toolCallName: result.toolName,\n toolName: result.toolName,\n })\n\n const args = argsMap.get(result.toolCallId) ?? '{}'\n chunks.push({\n type: EventType.TOOL_CALL_ARGS,\n timestamp: Date.now(),\n toolCallId: result.toolCallId,\n delta: args,\n })\n\n chunks.push({\n type: EventType.TOOL_CALL_END,\n timestamp: Date.now(),\n toolCallId: result.toolCallId,\n })\n }\n\n const parentMessageId = [...this.messages]\n .reverse()\n .find((message) => message.role === 'assistant')?.id\n const resultChunk = {\n type: EventType.TOOL_CALL_RESULT,\n timestamp: Date.now(),\n messageId: parentMessageId || result.toolCallId,\n toolCallId: result.toolCallId,\n content: wireContent,\n role: 'tool' as const,\n }\n chunks.push(\n (result.state === 'output-error'\n ? withTanstackMetadata(resultChunk, { state: result.state })\n : resultChunk) as StreamChunk,\n )\n\n // If a placeholder tool message exists for this toolCallId (created by\n // uiMessageToModelMessages for an approval-responded part with no\n // output yet), replace it with the real result. Otherwise the LLM sees\n // both messages — and since the Anthropic adapter dedupes tool_result\n // blocks by tool_use_id keeping the first match, the placeholder wins\n // and the real result is dropped (see issue #532).\n const placeholderIdx = this.messages.findIndex((m) => {\n if (m.role !== 'tool' || m.toolCallId !== result.toolCallId) {\n return false\n }\n if (typeof m.content !== 'string') return false\n try {\n return JSON.parse(m.content)?.pendingExecution === true\n } catch {\n return false\n }\n })\n\n const newToolMessage: ModelMessage = {\n role: 'tool',\n content,\n toolCallId: result.toolCallId,\n }\n\n if (placeholderIdx >= 0) {\n this.messages = [\n ...this.messages.slice(0, placeholderIdx),\n newToolMessage,\n ...this.messages.slice(placeholderIdx + 1),\n ]\n } else {\n this.messages = [...this.messages, newToolMessage]\n }\n this.middlewareCtx.messages = this.messages\n }\n\n return chunks\n }\n\n private getPendingToolCallsFromMessages(): Array<ToolCall> {\n // Build a set of completed tool IDs, but exclude tools with pendingExecution marker\n // (these are approved tools that still need to execute)\n const completedToolIds = new Set<string>()\n\n for (const message of this.messages) {\n if (message.role === 'tool' && message.toolCallId) {\n // Check if this is an approval response with pendingExecution marker\n let hasPendingExecution = false\n if (typeof message.content === 'string') {\n try {\n const parsed = JSON.parse(message.content)\n if (parsed.pendingExecution === true) {\n hasPendingExecution = true\n }\n } catch {\n // Not JSON, treat as regular tool result\n }\n }\n\n // Only mark as complete if NOT pending execution\n if (!hasPendingExecution) {\n completedToolIds.add(message.toolCallId)\n }\n }\n }\n\n const pending: Array<ToolCall> = []\n\n for (const message of this.messages) {\n if (message.role === 'assistant' && message.toolCalls) {\n for (const toolCall of message.toolCalls) {\n // Provider-executed tool calls (e.g. Anthropic `web_search`) were\n // already run by the provider; they carry no client result, so they\n // would otherwise look \"pending\" forever and the loop would try (and\n // fail) to execute them client-side. Skip them.\n if (isProviderExecutedToolCall(toolCall)) {\n continue\n }\n if (!completedToolIds.has(toolCall.id)) {\n pending.push(toolCall)\n }\n }\n }\n }\n\n return pending\n }\n\n /**\n * Find a tool call by id in message history (including already-completed ones).\n * Used when the client has already attached a tool result for UI before resume.\n */\n private findToolCallInMessages(toolCallId: string): ToolCall | undefined {\n for (const message of this.messages) {\n if (message.role !== 'assistant' || !message.toolCalls) continue\n for (const toolCall of message.toolCalls) {\n if (toolCall.id === toolCallId) return toolCall\n }\n }\n return undefined\n }\n\n /**\n * Tool calls that must be reconstructed as interrupt pending for ephemeral\n * resume. Includes outstanding tools plus client tools that already have\n * results in history when the resume batch still carries `client_tool_*`\n * entries (the client writes local tool results before submitting resume).\n */\n private getToolCallsForEphemeralResume(\n resume: ReadonlyArray<{ interruptId: string }> | undefined,\n ): Array<ToolCall> {\n const pending = this.getPendingToolCallsFromMessages()\n const byId = new Map(pending.map((toolCall) => [toolCall.id, toolCall]))\n for (const entry of resume ?? []) {\n // Recover tool calls the client already finalized in history for two\n // resume-batch cases that no longer look \"pending\":\n // - `client_tool_*`: a client tool wrote its output before resuming.\n // - `approval_*`: a DENIED approval wrote its denial result, so the\n // call reads as completed. Without this it drops out of the\n // reconstructed batch and the resume entry fails as unknown-interrupt.\n let toolCallId: string | undefined\n if (entry.interruptId.startsWith('client_tool_')) {\n toolCallId = entry.interruptId.slice('client_tool_'.length)\n } else if (entry.interruptId.startsWith('approval_')) {\n toolCallId = entry.interruptId.slice('approval_'.length)\n }\n if (toolCallId === undefined || byId.has(toolCallId)) continue\n const toolCall = this.findToolCallInMessages(toolCallId)\n if (toolCall && !isProviderExecutedToolCall(toolCall)) {\n pending.push(toolCall)\n byId.set(toolCallId, toolCall)\n }\n }\n return pending\n }\n\n private createSyntheticFinishedEvent(\n finishReason: 'stop' | 'tool_calls' = 'tool_calls',\n ): RunFinishedEvent {\n return withTanstackMetadata(\n {\n type: EventType.RUN_FINISHED,\n runId: this.runIdOverride ?? this.requestId,\n threadId: this.threadId,\n timestamp: Date.now(),\n },\n { finishReason, model: this.params.model },\n ) as RunFinishedEvent\n }\n\n private async shouldContinue(): Promise<boolean> {\n // Always enter the tool-execution half-cycle after a model turn.\n if (this.cyclePhase === 'executeToolCalls') {\n return true\n }\n\n const state = {\n iterationCount: this.iterationCount,\n messages: this.messages,\n finishReason: this.lastFinishReason,\n toolCallCount: this.toolCallCount,\n lastTurnToolCallCount: this.lastTurnToolCallCount,\n }\n\n // Evaluate strategy and middleware unconditionally (even when the\n // strategy already says stop) so every onShouldContinue observer still\n // sees the final counters; AND all three at the end.\n const strategyContinues = this.loopStrategy(state)\n const middlewareContinues = await this.middlewareRunner.runOnShouldContinue(\n this.middlewareCtx,\n state,\n )\n\n return (\n strategyContinues && middlewareContinues && this.toolPhase === 'continue'\n )\n }\n\n /**\n * Record tool calls (deduped by id) toward `toolCallCount` /\n * `lastTurnToolCallCount` for strategies and middleware `onShouldContinue`.\n *\n * Used for both live model turns and pending/resume batches. IDs already\n * counted in this run (e.g. wait→resume after a live turn) are not\n * re-added to `toolCallCount`. Per-turn execution caps are app middleware\n * (`onBeforeToolCall` skip), not engine policy.\n */\n private recordToolCalls(toolCalls: Array<ToolCall>): void {\n this.lastTurnToolCallCount = toolCalls.length\n let newlyCounted = 0\n for (const tc of toolCalls) {\n if (!this.countedToolCallIds.has(tc.id)) {\n this.countedToolCallIds.add(tc.id)\n newlyCounted++\n }\n }\n this.toolCallCount += newlyCounted\n }\n\n private isAborted(): boolean {\n return !!this.effectiveSignal?.aborted\n }\n\n private isMiddlewareAborted(): boolean {\n return !!this.middlewareAbortController?.signal.aborted\n }\n\n private isCancelled(): boolean {\n return this.isAborted() || this.isMiddlewareAborted()\n }\n\n /**\n * The reason to report on `AbortInfo` for a cancelled run.\n *\n * `this.abortReason` only ever holds a *middleware*-initiated reason\n * (`ctx.abort(reason)` / `MiddlewareAbortError`). A caller that aborts its own\n * controller — `abortController.abort(RUN_CANCEL_REASON)`, the in-process\n * cancel channel — never touches that field, so the reason has to be read back\n * off the caller's signal, which is the signal `isCancelled()` consults via\n * `isAborted()`. A signal aborted with no reason carries a DOMException rather\n * than a string, so non-string reasons are reported as absent.\n */\n private resolveAbortReason(): string | undefined {\n if (this.abortReason !== undefined) return this.abortReason\n const signalReason: unknown = this.effectiveSignal?.reason\n return typeof signalReason === 'string' ? signalReason : undefined\n }\n\n /**\n * Whether this run's teardown declared its abort a DETACH — see\n * {@link RunDetachedCapability}. Only `withSandbox`'s `onAbort` publishes it,\n * and only for a plain, intentless disconnect of a detachable run, so every\n * other exit path answers `false`.\n *\n * Surfaced on the engine (rather than the ctx being handed out) so the\n * capability read stays inside core, and so the delivery sink learns the\n * verdict through {@link publishRunDetachedSignal} instead of reaching into a\n * middleware context it has no business holding.\n *\n * @internal\n */\n wasDetached(): boolean {\n return getRunDetached(this.middlewareCtx, { optional: true }) === true\n }\n\n /**\n * The delivery socket closed while this run was still going.\n *\n * Notifies every subscriber (see {@link RunDisconnectCapability}) and RETURNS\n * IMMEDIATELY. Synchronous on purpose: it is called from\n * `ReadableStream.cancel()`, which must not be made to wait on a run-store\n * write, and the caller ({@link notifyRunDisconnected}) has no consumer left to\n * report to anyway.\n *\n * Subscribers therefore run CONCURRENTLY with the still-executing run — which is\n * the entire point. The run is typically suspended inside a slow middleware\n * `setup` at this moment, so anything dispatched from the run's own unwinding\n * would be minutes late. Nothing on this path aborts the run: a durable run\n * outlives its viewer.\n *\n * Each subscriber's promise is parked on `deferredPromises`, which the run awaits\n * in its `finally`, so bookkeeping cannot be lost to a race with the run's own\n * completion even though nothing awaits it here.\n *\n * IDEMPOTENT. A second cancel, or one arriving after a terminal hook already ran,\n * is ignored: the terminal hooks own the run's outcome, and re-stamping\n * `detachedSince` on a run that has already finished would hand a completed run\n * to the reaper as reclaimable work.\n *\n * @internal\n */\n notifyDisconnected(): void {\n if (this.disconnected || this.terminalHookCalled) return\n this.disconnected = true\n for (const listener of this.disconnectListeners) {\n this.runDisconnectListener(listener)\n }\n }\n\n /**\n * Invoke one disconnect listener, isolated and with its failure SWALLOWED after\n * logging.\n *\n * There is no caller left to report to — the socket this would report on is the\n * one that just closed — and a rejection parked on `deferredPromises` would\n * surface as the run's failure, replacing a healthy outcome with a bookkeeping\n * error. Isolation matters for the usual reason too: one subscriber's failing\n * write must not skip the next one's.\n */\n private runDisconnectListener(listener: () => void | Promise<void>): void {\n let result: void | Promise<void>\n try {\n result = listener()\n } catch (error) {\n this.logger.errors('run disconnect listener failed', { error })\n return\n }\n if (result === undefined) return\n this.deferredPromises.push(\n result.catch((error: unknown) => {\n this.logger.errors('run disconnect listener failed', { error })\n }),\n )\n }\n\n /**\n * Run the final structured-output adapter call through the middleware\n * pipeline. Yields chunks to the caller only when\n * `this.finalStructuredOutput.yieldChunks` is true; otherwise consumes\n * silently while still piping through middleware.\n *\n * On success, populates this.structuredOutputResult.\n * On failure, populates this.finalizationError.\n */\n private async *runStructuredFinalization(): AsyncGenerator<StreamChunk> {\n if (!this.finalStructuredOutput) {\n throw new Error(\n 'runStructuredFinalization called without finalStructuredOutput config',\n )\n }\n\n this.middlewareCtx.phase = 'structuredOutput'\n\n // Build the structured-output config view. `tools` is intentionally\n // excluded from the type because it isn't forwarded to the structured-\n // output adapter call — including it here would be misleading API.\n const baseConfig = this.buildMiddlewareConfig()\n const { tools: _omitTools, ...baseWithoutTools } = baseConfig\n let structuredConfig: StructuredOutputMiddlewareConfig = {\n ...baseWithoutTools,\n outputSchema: this.finalStructuredOutput.jsonSchema,\n }\n\n // 1) onStructuredOutputConfig — middleware can transform messages, options, outputSchema\n structuredConfig = yield* this.runWhileYielding(\n this.middlewareRunner.runOnStructuredOutputConfig(\n this.middlewareCtx,\n structuredConfig,\n ),\n )\n\n // 2) onConfig — phase-aware general-purpose middleware re-runs at the\n // boundary. Re-attach the engine's current tools so onConfig observers\n // see the live tool set (they still won't be forwarded to the structured\n // call — same constraint applies — but the view is consistent with the\n // ChatMiddlewareConfig shape).\n const { outputSchema: pinnedSchema, ...chatConfigSlice } = structuredConfig\n const postOnConfig = yield* this.runWhileYielding(\n this.middlewareRunner.runOnConfig(this.middlewareCtx, {\n ...chatConfigSlice,\n tools: baseConfig.tools,\n }),\n )\n\n // Apply merged config back to engine state\n this.applyMiddlewareConfig(postOnConfig)\n\n // Build the StructuredOutputOptions the adapter expects.\n // `this.adapter` is already `TAdapter extends AnyTextAdapter` per the\n // class generics — no cast needed.\n const structuredCallOptions = {\n chatOptions: {\n model: this.params.model,\n messages: this.providerMessages,\n metadata: postOnConfig.metadata,\n modelOptions: postOnConfig.modelOptions,\n systemPrompts: postOnConfig.systemPrompts,\n logger: this.logger,\n threadId: this.threadId,\n runId: this.runIdOverride,\n parentRunId: this.parentRunIdOverride,\n ...(this.effectiveRequest ? { request: this.effectiveRequest } : {}),\n },\n outputSchema: pinnedSchema,\n }\n\n // Select the provider call: native streaming if available, else synthesized fallback.\n // The fallback path captures the original adapter error so the engine can\n // attach it as `finalizationError.cause` (the RUN_ERROR wire shape only\n // carries `message` and `code`, losing stack/cause/provider properties).\n let fallbackAdapterError: unknown = undefined\n const providerStream = this.adapter.structuredOutputStream\n ? this.adapter.structuredOutputStream(structuredCallOptions)\n : fallbackStructuredOutputStream(\n this.adapter,\n structuredCallOptions,\n (err) => {\n fallbackAdapterError = err\n },\n )\n\n // ============================================================\n // structured-output.start synthesis\n // ============================================================\n // The client-side StreamProcessor (PR #577) requires a CUSTOM\n // `structured-output.start` event BEFORE the JSON TEXT_MESSAGE_CONTENT\n // deltas — that's how it routes deltas into a `StructuredOutputPart`\n // rather than a plain `TextPart`. No adapter currently emits this,\n // so the engine synthesizes one (and tracks whether the adapter\n // emitted its own to avoid duplicating).\n //\n // Synthesis fires before the FIRST TEXT_MESSAGE_* event from the inner\n // stream, OR before a pre-delta RUN_ERROR (so the client can construct\n // an errored structured-output placeholder).\n let startEmitted = false\n let structuredMessageId: string | null = null\n\n const extractMessageId = (c: StreamChunk): string | null => {\n if (\n c.type === EventType.TEXT_MESSAGE_START ||\n c.type === EventType.TEXT_MESSAGE_CONTENT ||\n c.type === EventType.TEXT_MESSAGE_END\n ) {\n return typeof c.messageId === 'string' && c.messageId !== ''\n ? c.messageId\n : null\n }\n return null\n }\n\n // The synthetic event is inserted before its trigger, so share that\n // trigger's timestamp rather than making the earlier event sort later.\n const buildSynthesizedStart = (timestamp = Date.now()): StreamChunk => {\n const idForStart = structuredMessageId ?? generateMessageId()\n structuredMessageId = idForStart\n this.captureStructuredOutputMessageIdentity(idForStart)\n return {\n type: EventType.CUSTOM,\n name: 'structured-output.start',\n value: { messageId: idForStart },\n timestamp,\n }\n }\n\n const runChunkMiddleware = (\n synthChunk: StreamChunk,\n ): Promise<Array<StreamChunk>> =>\n this.middlewareRunner.runOnChunk(this.middlewareCtx, synthChunk)\n\n // Track whether a RUN_ERROR has been yielded to streaming consumers so\n // we don't emit a duplicate synthetic one at the end.\n let runErrorYielded = false\n\n // Pipe chunks through middleware; yield to consumer only when yieldChunks=true\n for await (const raw of providerStream) {\n // Honor cancellation between chunks (mirrors streamModelResponse).\n if (this.isCancelled()) {\n break\n }\n\n {\n const chunk = raw\n // Detect adapter-emitted structured-output.start so we don't duplicate\n if (\n !startEmitted &&\n chunk.type === EventType.CUSTOM &&\n chunk.name === 'structured-output.start'\n ) {\n startEmitted = true\n }\n\n // Capture the assistant messageId off any text-message event so the\n // synthesized start (when needed) uses the SAME id the deltas carry\n if (!structuredMessageId) {\n const extracted = extractMessageId(chunk)\n if (extracted) {\n structuredMessageId = extracted\n this.captureStructuredOutputMessageIdentity(extracted)\n }\n }\n\n // Synthesis only matters for the streaming client path — the agentic\n // Promise path consumes chunks internally and returns a Promise, so\n // there's no client-side StreamProcessor to route deltas for.\n if (this.finalStructuredOutput.yieldChunks) {\n // Synthesize start before the FIRST TEXT_MESSAGE_* event\n if (\n !startEmitted &&\n (chunk.type === EventType.TEXT_MESSAGE_START ||\n chunk.type === EventType.TEXT_MESSAGE_CONTENT ||\n chunk.type === EventType.TEXT_MESSAGE_END)\n ) {\n startEmitted = true\n const synthStart = buildSynthesizedStart(chunk.timestamp)\n yield* this.emitPublicChunks(await runChunkMiddleware(synthStart))\n }\n\n // Synthesize start before a pre-delta RUN_ERROR so the client can\n // construct an errored placeholder structured-output part instead\n // of a silent UI.\n if (!startEmitted && chunk.type === EventType.RUN_ERROR) {\n startEmitted = true\n const synthStart = buildSynthesizedStart(chunk.timestamp)\n yield* this.emitPublicChunks(await runChunkMiddleware(synthStart))\n }\n }\n\n // 7a. Targeted state updates only.\n // We deliberately do NOT call `handleStreamChunk(chunk)` here — that\n // would mutate agent-loop state with finalization data:\n // - TEXT_MESSAGE_CONTENT deltas would pollute `accumulatedContent`\n // (raw JSON would leak into `info.content` on onFinish)\n // - RUN_FINISHED would overwrite `finishedEvent` + `lastFinishReason`\n // (finalization's 'stop' would overwrite the agent-loop's real\n // finish reason)\n // - STEP_FINISHED would pollute `currentThinkingContent`\n // Finalization is a separate phase from the agent loop; its state must\n // not cross-contaminate. The explicit branches below capture the only\n // bits we actually need from this stream.\n // All narrowing below is via the discriminated-union `chunk.type`\n // — no `as` casts.\n\n // The chunk forwarded to middleware/consumers. Replaced below only for\n // the structured-output.complete event, whose `object` we normalize\n // (un-widen) so streaming consumers see the same cleaned payload the\n // Promise<T> path validates and returns.\n let outboundChunk: StreamChunk = chunk\n\n if (\n chunk.type === EventType.CUSTOM &&\n chunk.name === 'structured-output.complete'\n ) {\n const parsed = readStructuredOutputCompleteValue(chunk.value)\n if (parsed) {\n const object = this.finalStructuredOutput.normalize\n ? this.finalStructuredOutput.normalize(parsed.object)\n : parsed.object\n this.structuredOutputResult = {\n data: object,\n rawText: parsed.raw,\n ...(parsed.reasoning !== undefined\n ? { reasoning: parsed.reasoning }\n : {}),\n }\n // Rewrite the outbound event so the yielded chunk carries the\n // normalized object (the original `chunk.value` still holds the\n // widened one). Preserve every other field — `raw`, `reasoning` —\n // by spreading the original value.\n const value = chunk.value\n if (\n object !== parsed.object &&\n value &&\n typeof value === 'object'\n ) {\n outboundChunk = { ...chunk, value: { ...value, object } }\n }\n }\n }\n\n if (chunk.type === EventType.RUN_FINISHED) {\n await this.runOnUsageFromChunk(chunk)\n }\n\n if (chunk.type === EventType.RUN_ERROR) {\n // RunErrorEvent already exposes `message` and `code` after narrowing.\n this.finalizationError = {\n message: chunk.message,\n ...(chunk.code ? { code: chunk.code } : {}),\n ...(fallbackAdapterError !== undefined\n ? { cause: fallbackAdapterError }\n : {}),\n }\n }\n\n // 7b. Pipe through middleware\n const outputChunks = await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n outboundChunk,\n )\n\n // 7c. Decide consumer visibility — only yieldChunks=true callers get them.\n // We do NOT strip the finalization stream's RUN_STARTED/RUN_FINISHED:\n // they are the single outer lifecycle pair the consumer sees (the\n // agent-loop's pair was suppressed in streamModelResponse when\n // finalStructuredOutput.yieldChunks is true).\n if (this.finalStructuredOutput.yieldChunks) {\n for (const spec of this.emitPublicChunks(outputChunks)) {\n if (spec.type === EventType.RUN_ERROR) {\n runErrorYielded = true\n }\n yield spec\n }\n }\n\n // 7d. Terminate on error\n if (this.finalizationError) {\n break\n }\n }\n\n if (this.isCancelled() || this.finalizationError) {\n break\n }\n }\n\n // Mid-finalization abort: don't attribute a missing-result error.\n // Let the engine's `finally` block in `run()` route to `onAbort` instead\n // of mis-routing through `onError`.\n if (this.isCancelled()) {\n return\n }\n\n // Empty stream / missing complete event\n if (!this.structuredOutputResult && !this.finalizationError) {\n this.finalizationError = {\n message: 'missing structured result',\n code: 'structured-output-missing-result',\n }\n }\n\n // Run schema validation INSIDE the engine — before the terminal hook\n // chooser runs. Per spec §7.3, validation failures must route through\n // `onError`, not `onFinish`. We do this by writing to `finalizationError`\n // so the chooser in `run()` picks `onError`.\n if (\n this.structuredOutputResult &&\n !this.finalizationError &&\n this.finalStructuredOutput.validate\n ) {\n try {\n const validated = this.finalStructuredOutput.validate(\n this.structuredOutputResult.data,\n )\n this.validatedStructuredOutput = validated\n this.hasValidatedStructuredOutput = true\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err)\n this.finalizationError = {\n message,\n code: 'structured-output-validation-failed',\n cause: err,\n }\n }\n }\n\n // Streaming consumers must see a RUN_ERROR for finalization failures\n // (missing-result, validation-failed, or a finalizationError set after\n // a structured-output.complete already yielded). Without this synthetic\n // emission, the `for await` on the engine ends silently for the client.\n //\n // Skip when a RUN_ERROR was already yielded from the inner stream\n // (otherwise the consumer would see two error events for one failure).\n if (\n this.finalizationError &&\n this.finalStructuredOutput.yieldChunks &&\n !runErrorYielded\n ) {\n // Empty-stream case: no in-loop synthesis fired because no chunks\n // arrived. Synthesize `structured-output.start` here so the client-side\n // StreamProcessor can route the upcoming RUN_ERROR to a\n // `StructuredOutputPart` instead of dropping it as an orphan error.\n if (!startEmitted) {\n const synthStart = buildSynthesizedStart()\n yield* this.emitPublicChunks(await runChunkMiddleware(synthStart))\n startEmitted = true\n }\n\n const errChunk: StreamChunk = {\n type: EventType.RUN_ERROR,\n timestamp: Date.now(),\n message: this.finalizationError.message,\n ...(this.finalizationError.code\n ? { code: this.finalizationError.code }\n : {}),\n }\n yield* this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(this.middlewareCtx, errChunk),\n )\n }\n }\n\n /**\n * Native combined mode: harvest the structured output from the agent\n * loop's accumulated final-turn text (no separate provider call).\n *\n * The adapter wired `outputSchema` into the regular `chatStream` request,\n * so the model's final-turn text is the schema-constrained JSON. We parse\n * `this.accumulatedContent`, populate `this.structuredOutputResult`, emit\n * a synthetic `structured-output.complete` (and a `structured-output.start`\n * if one wasn't emitted earlier — only happens on the streaming path when\n * the model returned no text at all), and run the validate callback when\n * present. Failures populate `this.finalizationError` so the engine's\n * terminal-hook chooser routes to `onError` (per spec §7.3).\n *\n * The `'structuredOutput'` middleware phase intentionally does NOT fire on\n * this path — middleware sees the run through `beforeModel` / `modelStream`\n * as usual. See PR #605 / issue #605 for the design rationale.\n */\n private async *harvestCombinedStructuredOutput(): AsyncGenerator<StreamChunk> {\n if (!this.finalStructuredOutput) {\n throw new Error(\n 'harvestCombinedStructuredOutput called without finalStructuredOutput config',\n )\n }\n\n const yieldChunks = this.finalStructuredOutput.yieldChunks\n const source = this.finalStructuredOutput.source ?? 'text'\n\n if (source === 'event') {\n if (!this.structuredOutputResult) {\n this.finalizationError = {\n message: 'missing structured result',\n code: 'structured-output-missing-result',\n }\n }\n } else {\n const rawText = this.accumulatedContent\n\n // Empty final-turn text means the agent loop terminated without the\n // model emitting any assistant content (e.g. early termination after\n // tool calls). Mirror the fallback path's \"missing structured result\"\n // error rather than silently returning undefined.\n if (rawText.length === 0) {\n this.finalizationError = {\n message: 'missing structured result',\n code: 'structured-output-missing-result',\n }\n } else {\n try {\n const parsed: unknown = JSON.parse(rawText)\n // Normalize (un-widen) before storing so the synthesized\n // structured-output.complete chunk and the Promise<T> result both\n // carry the cleaned payload. JSON.parse preserves provider nulls, so\n // this is where native-combined output gets its widening undone.\n const data = this.finalStructuredOutput.normalize\n ? this.finalStructuredOutput.normalize(parsed)\n : parsed\n this.structuredOutputResult = { data, rawText }\n } catch (err: unknown) {\n const detail =\n rawText.slice(0, 200) + (rawText.length > 200 ? '...' : '')\n this.finalizationError = {\n message: `Failed to parse structured output as JSON. Content: ${detail}`,\n code: 'structured-output-parse-failed',\n cause: err,\n }\n }\n }\n }\n\n // Validate against the Standard Schema (when supplied). Validation\n // failures route through onError just like the fallback path.\n if (\n this.structuredOutputResult &&\n !this.finalizationError &&\n this.finalStructuredOutput.validate\n ) {\n try {\n const validated = this.finalStructuredOutput.validate(\n this.structuredOutputResult.data,\n )\n this.validatedStructuredOutput = validated\n this.hasValidatedStructuredOutput = true\n } catch (err: unknown) {\n const message = err instanceof Error ? err.message : String(err)\n this.finalizationError = {\n message,\n code: 'structured-output-validation-failed',\n cause: err,\n }\n }\n }\n\n if (!yieldChunks) {\n // Promise<T> path: state is populated, nothing to yield. The\n // activity-layer caller pulls `structuredOutputResult` /\n // `validatedStructuredOutput` directly.\n return\n }\n\n // Streaming path: emit a synthetic `structured-output.start` if the\n // model produced no text at all (so the client snaps an errored\n // StructuredOutputPart rather than nothing). The normal path already\n // emitted start before the first TEXT_MESSAGE_START in\n // `streamModelResponse`.\n if (!this.combinedStartEmitted) {\n this.combinedStartEmitted = true\n const messageId = this.combinedStructuredMessageId ?? generateMessageId()\n this.combinedStructuredMessageId = messageId\n const synthStart: StreamChunk = {\n type: EventType.CUSTOM,\n name: 'structured-output.start',\n value: { messageId },\n timestamp: Date.now(),\n }\n yield* this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(this.middlewareCtx, synthStart),\n )\n }\n\n // On success, emit the synthetic `structured-output.complete` carrying\n // the parsed object + raw text before the deferred RUN_FINISHED. Pin\n // the messageId so the client targets the schema-constrained turn.\n if (\n this.structuredOutputResult &&\n !this.finalizationError &&\n !this.combinedCompleteEmitted\n ) {\n const completeChunk: StreamChunk = {\n type: EventType.CUSTOM,\n name: 'structured-output.complete',\n value: {\n object: this.structuredOutputResult.data,\n raw: this.structuredOutputResult.rawText,\n ...(this.combinedStructuredMessageId\n ? { messageId: this.combinedStructuredMessageId }\n : {}),\n },\n timestamp: Date.now(),\n }\n yield* this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n completeChunk,\n ),\n )\n }\n\n // On failure, emit a synthetic RUN_ERROR so the streaming consumer's\n // `for await` doesn't end silently. Mirrors the fallback path.\n if (this.finalizationError) {\n const errChunk: StreamChunk = {\n type: EventType.RUN_ERROR,\n timestamp: Date.now(),\n message: this.finalizationError.message,\n ...(this.finalizationError.code\n ? { code: this.finalizationError.code }\n : {}),\n }\n yield* this.emitPublicChunks(\n await this.middlewareRunner.runOnChunk(this.middlewareCtx, errChunk),\n )\n }\n }\n\n private buildMiddlewareConfig(): ChatMiddlewareConfig {\n return {\n messages: this.messages,\n providerMessages: this.messages,\n systemPrompts: [...this.systemPrompts],\n tools: [...this.tools],\n resume: this.params.resume,\n resumeToolState: {\n approvals: this.resumeApprovals,\n clientToolResults: this.resumeClientToolResults,\n deniedToolResults: this.resumeDeniedToolResults,\n cancelledToolCallIds: this.resumeCancelledToolCallIds,\n },\n metadata: this.params.metadata,\n modelOptions: this.params.modelOptions,\n }\n }\n\n private async applyEphemeralInterruptResume(\n config: ChatMiddlewareConfig,\n ): Promise<void> {\n if ((config.resume?.length ?? 0) === 0) {\n return\n }\n\n const interruptedRunId = this.parentRunIdOverride\n if (!interruptedRunId) {\n throw new InterruptResumeValidationError([\n {\n scope: 'batch',\n threadId: this.threadId,\n interruptedRunId: this.runIdOverride ?? this.requestId,\n generation: 0,\n interruptIds: config.resume?.map((entry) => entry.interruptId) ?? [],\n code: 'stale',\n message:\n 'Interrupt continuation requires parentRunId to identify the interrupted run.',\n source: 'server',\n retryable: false,\n },\n ])\n }\n\n const approvalRequests: Array<ApprovalRequest> = []\n const clientRequests: Array<ClientToolRequest> = []\n // Prefer resume-aware reconstruction so client-tool outputs already written\n // into history for UI still validate against the resume batch.\n const pendingToolCalls = this.getToolCallsForEphemeralResume(config.resume)\n const resumeInterruptIds = new Set(\n config.resume?.map((entry) => entry.interruptId),\n )\n const toolInputs = new Map<string, unknown>()\n const toolsByCallId = new Map<string, AnyRuntimeTool>()\n const clientExecutionCallIds = new Set<string>()\n\n for (const toolCall of pendingToolCalls) {\n const tool = this.tools.find(\n (candidate) => candidate.name === toolCall.function.name,\n )\n if (!tool) continue\n toolsByCallId.set(toolCall.id, tool)\n let input: unknown = {}\n try {\n const parsed = JSON.parse(toolCall.function.arguments.trim() || '{}')\n input = parsed && typeof parsed === 'object' ? parsed : {}\n } catch {\n input = {}\n }\n toolInputs.set(toolCall.id, input)\n if (\n !tool.execute &&\n resumeInterruptIds.has(`client_tool_${toolCall.id}`)\n ) {\n clientExecutionCallIds.add(toolCall.id)\n }\n }\n\n // Mirror executeToolCalls' scheduling boundary. Server execution remains\n // gated while any approval is outstanding, but plain client tools are\n // represented in the same interrupt batch because requesting their output\n // does not execute a server-side effect.\n for (const toolCall of pendingToolCalls) {\n const tool = toolsByCallId.get(toolCall.id)\n if (tool?.needsApproval && !clientExecutionCallIds.has(toolCall.id)) {\n approvalRequests.push({\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input: toolInputs.get(toolCall.id) ?? {},\n approvalId: `approval_${toolCall.id}`,\n })\n }\n }\n\n for (const toolCall of pendingToolCalls) {\n const tool = toolsByCallId.get(toolCall.id)\n if (\n tool !== undefined &&\n !tool.execute &&\n (!tool.needsApproval || clientExecutionCallIds.has(toolCall.id))\n ) {\n clientRequests.push({\n toolCallId: toolCall.id,\n toolName: toolCall.function.name,\n input: toolInputs.get(toolCall.id) ?? {},\n })\n }\n }\n\n const genericPending = this.getGenericContinuationPending(interruptedRunId)\n const pending: Array<{\n interruptId: string\n payload: unknown\n binding: InterruptBinding\n genericRequest?: GenericInterruptRequest<\n InterruptDefinition<any, any, any, any>\n >\n }> = this.buildActionableInterrupts(\n approvalRequests,\n clientRequests,\n ).flatMap((descriptor) => {\n const unopened = readUnopenedInterruptBinding(descriptor)\n return unopened\n ? [\n {\n interruptId: descriptor.id,\n payload: descriptor,\n binding: {\n ...unopened,\n interruptedRunId,\n generation: 0,\n } satisfies InterruptBinding,\n },\n ]\n : []\n })\n pending.push(...genericPending)\n const validated = await validateInterruptResumeBatch({\n threadId: this.threadId,\n interruptedRunId,\n generation: 0,\n pending,\n resume: config.resume,\n tools: this.tools,\n })\n if (validated.errors.length > 0 || !validated.resumeToolState) {\n throw new InterruptResumeValidationError(validated.errors)\n }\n\n // A client-tool execution interrupt can only be emitted after an\n // approval-required client tool was approved in the preceding ephemeral\n // run. Reconstruct that phase marker from the trusted `client_tool_*`\n // continuation so executeToolCalls consumes the validated client output\n // instead of asking for approval again.\n const approvals = new Map(validated.resumeToolState.approvals)\n for (const request of clientRequests) {\n if (toolsByCallId.get(request.toolCallId)?.needsApproval) {\n approvals.set(request.toolCallId, true)\n }\n }\n this.applyResumeToolState({\n ...validated.resumeToolState,\n approvals,\n })\n\n const genericResolutions = validated.resumeToolState.genericInterrupts\n if (genericPending.length > 0 && genericResolutions) {\n const resolutions = genericPending\n .sort((left, right) => {\n const leftIndex =\n left.binding.kind === 'generic' ? (left.binding.batchIndex ?? 0) : 0\n const rightIndex =\n right.binding.kind === 'generic'\n ? (right.binding.batchIndex ?? 0)\n : 0\n return leftIndex - rightIndex\n })\n .flatMap((record) => {\n const resolution = genericResolutions.get(record.interruptId)\n if (!resolution || !record.genericRequest) return []\n return [\n resolution.status === 'resolved'\n ? {\n request: record.genericRequest,\n status: 'resolved' as const,\n response: resolution.payload,\n }\n : {\n request: record.genericRequest,\n status: 'cancelled' as const,\n },\n ]\n })\n const collection: InterruptResolutionCollection = {\n for: (definition) =>\n resolutions.filter(\n (resolution) => resolution.request.definition === definition,\n ) as never,\n all: (\n ...definitions: Array<InterruptDefinition<any, any, any, any>>\n ) =>\n definitions.length === 0\n ? resolutions\n : resolutions.filter((resolution) =>\n definitions.includes(resolution.request.definition),\n ),\n }\n const policy = await this.middlewareRunner.runOnInterruptResolution(\n this.middlewareCtx,\n collection,\n )\n if (policy.toolResume === 'stop') {\n this.earlyTermination = true\n } else if (policy.toolResume === 'cancel') {\n for (const request of pendingToolCalls) {\n this.resumeCancelledToolCallIds.add(request.id)\n }\n }\n }\n }\n\n private getGenericContinuationPending(interruptedRunId: string): Array<{\n interruptId: string\n payload: unknown\n binding: InterruptBinding\n genericRequest: GenericInterruptRequest<\n InterruptDefinition<any, any, any, any>\n >\n }> {\n const fail = (message: string): never => {\n throw new InterruptResumeValidationError([\n {\n scope: 'batch',\n threadId: this.threadId,\n interruptedRunId,\n generation: 0,\n interruptIds: [],\n code: 'stale',\n message,\n source: 'server',\n retryable: false,\n },\n ])\n }\n const pending: Array<{\n interruptId: string\n payload: unknown\n binding: InterruptBinding\n genericRequest: GenericInterruptRequest<\n InterruptDefinition<any, any, any, any>\n >\n }> = []\n const ids = new Set<string>()\n const batchIndexes = new Set<number>()\n for (const resumeItem of this.params.resume ?? []) {\n const parsed = readGenericInterruptContinuation(resumeItem.metadata)\n if (parsed.status === 'absent') continue\n if (parsed.status === 'invalid') {\n return fail(parsed.message)\n }\n const entry = parsed.value\n const id = resumeItem.interruptId\n const definition = this.interruptDefinitions.get(entry.definitionId)\n if (!definition) {\n return fail(\n `Generic interrupt definition ${entry.definitionId} is unavailable.`,\n )\n }\n if (ids.has(id) || batchIndexes.has(entry.batchIndex)) {\n return fail(\n 'Generic interrupt continuation contains duplicate entries.',\n )\n }\n ids.add(id)\n batchIndexes.add(entry.batchIndex)\n let request: GenericInterruptRequest<\n InterruptDefinition<any, any, any, any>\n >\n try {\n request = rehydrateInterruptRequest(definition, {\n key: entry.key,\n reason: entry.reason,\n message: entry.message,\n ...(typeof entry.expiresAt === 'string'\n ? { expiresAt: entry.expiresAt }\n : {}),\n ...(Object.prototype.hasOwnProperty.call(entry, 'payload')\n ? { payload: entry.payload }\n : {}),\n })\n } catch (error) {\n return fail(\n `Generic interrupt continuation ${id} is invalid: ${\n error instanceof Error ? error.message : String(error)\n }`,\n )\n }\n const emitted = createInterruptBinding(request, {\n batchIndex: entry.batchIndex,\n })\n if (\n entry.responseSchemaHash !== emitted.descriptor.responseSchemaHash ||\n entry.payloadSchemaHash !== emitted.descriptor.payloadSchemaHash\n ) {\n return fail(\n `Generic interrupt continuation ${id} does not match its definition.`,\n )\n }\n pending.push({\n interruptId: id,\n payload: {\n id,\n ...(emitted.descriptor.responseSchemaCanonicalJson !== undefined\n ? {\n responseSchema: JSON.parse(\n emitted.descriptor.responseSchemaCanonicalJson,\n ),\n }\n : {}),\n },\n binding: {\n v: INTERRUPT_BINDING_VERSION,\n kind: 'generic',\n interruptId: id,\n interruptedRunId,\n generation: 0,\n definitionId: entry.definitionId,\n key: entry.key,\n batchIndex: entry.batchIndex,\n ...(typeof entry.expiresAt === 'string'\n ? { expiresAt: entry.expiresAt }\n : {}),\n ...(emitted.descriptor.payloadSchemaHash\n ? { payloadSchemaHash: emitted.descriptor.payloadSchemaHash }\n : {}),\n ...(entry.responseSchemaHash !== undefined\n ? { responseSchemaHash: entry.responseSchemaHash }\n : {}),\n },\n genericRequest: request,\n })\n }\n return pending\n }\n\n private applyResumeToolState(state: ChatResumeToolState | undefined): void {\n if (state?.approvals) {\n for (const [approvalId, resolution] of state.approvals) {\n this.resumeApprovals.set(approvalId, resolution)\n }\n }\n if (state?.clientToolResults) {\n for (const [toolCallId, result] of state.clientToolResults) {\n this.resumeClientToolResults.set(toolCallId, result)\n }\n }\n if (state?.deniedToolResults) {\n for (const [toolCallId, result] of state.deniedToolResults) {\n this.resumeDeniedToolResults.set(toolCallId, result)\n }\n }\n if (state?.cancelledToolCallIds) {\n for (const toolCallId of state.cancelledToolCallIds) {\n this.resumeCancelledToolCallIds.add(toolCallId)\n }\n }\n if (state?.genericInterrupts) {\n for (const [interruptId, resolution] of state.genericInterrupts) {\n this.resumeGenericInterrupts.set(interruptId, resolution)\n }\n }\n if (state?.genericInterruptRequests) {\n for (const [interruptId, request] of state.genericInterruptRequests) {\n this.resumeGenericInterruptRequests.set(interruptId, request)\n }\n }\n }\n\n private async applyDurableGenericInterruptResolution(): Promise<void> {\n if (this.resumeGenericInterruptRequests.size === 0) return\n const resolutions = [\n ...this.resumeGenericInterruptRequests.entries(),\n ].flatMap(([interruptId, request]) => {\n const resolution = this.resumeGenericInterrupts.get(interruptId)\n if (!resolution) return []\n return [\n resolution.status === 'resolved'\n ? {\n request,\n status: 'resolved' as const,\n response: resolution.payload,\n }\n : { request, status: 'cancelled' as const },\n ]\n })\n const collection: InterruptResolutionCollection = {\n for: (definition) =>\n resolutions.filter(\n (resolution) => resolution.request.definition === definition,\n ) as never,\n all: (...definitions: Array<InterruptDefinition<any, any, any, any>>) =>\n definitions.length === 0\n ? resolutions\n : resolutions.filter((resolution) =>\n definitions.includes(resolution.request.definition),\n ),\n }\n const policy = await this.middlewareRunner.runOnInterruptResolution(\n this.middlewareCtx,\n collection,\n )\n if (policy.toolResume === 'stop') {\n this.earlyTermination = true\n } else if (policy.toolResume === 'cancel') {\n for (const toolCall of this.getPendingToolCallsFromMessages()) {\n this.resumeCancelledToolCallIds.add(toolCall.id)\n }\n }\n }\n\n private applyMiddlewareConfig(config: ChatMiddlewareConfig): void {\n this.applyResumeToolState(config.resumeToolState)\n this.messages = config.messages\n this.providerMessages = config.providerMessages ?? config.messages\n this.systemPrompts = config.systemPrompts\n assertUniqueToolNames(config.tools)\n this.tools = config.tools\n this.params = {\n ...this.params,\n metadata: config.metadata,\n modelOptions: config.modelOptions,\n }\n\n // Sync context fields that depend on config\n this.middlewareCtx.messages = this.messages\n this.middlewareCtx.systemPrompts = this.systemPrompts\n this.middlewareCtx.hasTools = this.tools.length > 0\n this.middlewareCtx.toolNames = this.tools.map((t) => t.name)\n this.middlewareCtx.modelOptions = config.modelOptions\n }\n\n private setToolPhase(phase: ToolPhaseResult): void {\n this.toolPhase = phase\n }\n\n /**\n * Spec-normalize middleware output, then yield to the public iterable.\n * Engine state and `onChunk` already saw the raw chunk.\n */\n private *emitPublicChunks(\n outputs: Array<StreamChunk>,\n ): Generator<StreamChunk, void, void> {\n for (const output of outputs) {\n for (const spec of normalizeStreamChunk(output as AdapterYieldChunk)) {\n restorePublicUsage(spec)\n if (spec.type === EventType.RUN_STARTED) {\n if (this.hasPublicRunStarted) continue\n this.hasPublicRunStarted = true\n }\n // Persist MCP Apps ui-resource emissions onto the tool-call anchor\n // message so interrupt MESSAGES_SNAPSHOT chunks keep them (#1397).\n if (spec.type === EventType.CUSTOM && spec.name === 'ui-resource') {\n this.recordEmittedUiResource((spec as CustomEvent).value)\n }\n yield spec\n this.middlewareCtx.chunkIndex++\n }\n }\n }\n\n /**\n * Pipe a single internal chunk through middleware, then spec-normalize\n * before the public `for await` stream.\n */\n private async *pipeThroughMiddleware(\n chunk: AdapterYieldChunk,\n ): AsyncGenerator<StreamChunk, void, void> {\n const afterMw = await this.middlewareRunner.runOnChunk(\n this.middlewareCtx,\n chunk,\n )\n yield* this.emitPublicChunks(afterMw)\n if (!this.drainingMiddlewareCustom) {\n yield* this.drainMiddlewareCustomQueue()\n }\n }\n\n /**\n * Drain CUSTOM chunks pushed by `ctx.emitCustomEvent` through middleware\n * and into the public stream. If the run has not yet sent `RUN_STARTED`,\n * emit that first so CUSTOM events are not the first wire event.\n */\n private async *drainMiddlewareCustomQueue(): AsyncGenerator<StreamChunk> {\n if (this.drainingMiddlewareCustom) return\n if (this.middlewareCustomQueue.length === 0) return\n this.drainingMiddlewareCustom = true\n try {\n yield* this.emitSyntheticRunStarted(this.createSyntheticFinishedEvent())\n while (this.middlewareCustomQueue.length > 0) {\n const chunk = this.middlewareCustomQueue.shift()\n if (chunk) yield* this.pipeThroughMiddleware(chunk)\n }\n } finally {\n this.drainingMiddlewareCustom = false\n }\n }\n\n /**\n * Await `work` while yielding any `emitCustomEvent` chunks as they arrive.\n */\n private async *runWhileYielding<T>(\n work: Promise<T>,\n ): AsyncGenerator<StreamChunk, T> {\n let settled = false\n let result: T | undefined\n let error: unknown\n const done = work.then(\n (value) => {\n settled = true\n result = value\n },\n (err: unknown) => {\n settled = true\n error = err\n },\n )\n\n while (!settled) {\n yield* this.drainMiddlewareCustomQueue()\n if (settled) break\n await Promise.race([\n done,\n new Promise<void>((resolve) => {\n if (this.middlewareCustomQueue.length > 0) {\n resolve()\n return\n }\n this.middlewareCustomWaiters.push(resolve)\n }),\n ])\n }\n\n yield* this.drainMiddlewareCustomQueue()\n if (error !== undefined) throw error\n return result as T\n }\n\n /**\n * Drain queued `sandbox.file` chunks (emitted via the SandboxRuntime sink)\n * through the middleware pipeline and into the public stream.\n */\n private async *drainSandboxFileQueue(): AsyncGenerator<StreamChunk> {\n while (this.sandboxFileQueue.length > 0) {\n const chunk = this.sandboxFileQueue.shift()\n if (chunk) yield* this.pipeThroughMiddleware(chunk)\n }\n }\n\n /**\n * Drain an executeToolCalls async generator, yielding any CustomEvent chunks\n * through the middleware pipeline and returning the final ExecuteToolCallsResult.\n */\n private async *drainToolCallGenerator(\n generator: AsyncGenerator<\n CustomEvent,\n {\n results: Array<ToolResult>\n needsApproval: Array<ApprovalRequest>\n needsClientExecution: Array<ClientToolRequest>\n },\n void\n >,\n ): AsyncGenerator<\n StreamChunk,\n {\n results: Array<ToolResult>\n needsApproval: Array<ApprovalRequest>\n needsClientExecution: Array<ClientToolRequest>\n },\n void\n > {\n let pending = generator.next()\n while (true) {\n const next = yield* this.runWhileYielding(pending)\n if (next.done) return next.value\n yield* this.pipeThroughMiddleware(next.value)\n pending = generator.next()\n }\n }\n\n private createCustomEventChunk(\n eventName: string,\n value: Record<string, unknown>,\n ): CustomEvent {\n return {\n type: EventType.CUSTOM,\n timestamp: Date.now(),\n name: eventName,\n value,\n }\n }\n\n private createId(prefix: string): string {\n return `${prefix}-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`\n }\n}\n\n// ===========================\n// Activity Implementation\n// ===========================\n\n/**\n * Text activity - handles agentic text generation, one-shot text generation, and agentic structured output.\n *\n * This activity supports four modes:\n * 1. **Streaming agentic text**: Stream responses with automatic tool execution\n * 2. **Streaming one-shot text**: Simple streaming request/response without tools\n * 3. **Non-streaming text**: Returns collected text as a string (stream: false)\n * 4. **Agentic structured output**: Run tools, then return structured data\n *\n * @example Full agentic text (streaming with tools)\n * ```ts\n * import { chat } from '@tanstack/ai'\n * import { openaiText } from '@tanstack/ai-openai'\n *\n * for await (const chunk of chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'What is the weather?' }],\n * tools: [weatherTool]\n * })) {\n * if (chunk.type === 'TEXT_MESSAGE_CONTENT') {\n * console.log(chunk.delta)\n * }\n * }\n * ```\n *\n * @example One-shot text (streaming without tools)\n * ```ts\n * for await (const chunk of chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Hello!' }]\n * })) {\n * console.log(chunk)\n * }\n * ```\n *\n * @example Non-streaming text (stream: false)\n * ```ts\n * const text = await chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Hello!' }],\n * stream: false\n * })\n * // text is a string with the full response\n * ```\n *\n * @example Agentic structured output (tools + structured response)\n * ```ts\n * import { z } from 'zod'\n *\n * const result = await chat({\n * adapter: openaiText('gpt-5.5'),\n * messages: [{ role: 'user', content: 'Research and summarize the topic' }],\n * tools: [researchTool, analyzeTool],\n * outputSchema: z.object({\n * summary: z.string(),\n * keyPoints: z.array(z.string())\n * })\n * })\n * // result is { summary: string, keyPoints: string[] }\n * ```\n */\nexport function chat<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined = undefined,\n TStream extends boolean = boolean,\n const TTools extends TextActivityOptions<\n TAdapter,\n TSchema,\n TStream,\n any\n >['tools'] = TextActivityOptions<TAdapter, TSchema, TStream, any>['tools'],\n const TInterrupts extends ReadonlyArray<\n InterruptDefinition<any, any, any, any>\n > = [],\n TContext = unknown,\n const TMiddleware extends Array<unknown> | undefined = undefined,\n>(\n options: TextActivityOptionsWithContext<\n TAdapter,\n TSchema,\n TStream,\n TTools,\n TInterrupts,\n TContext,\n TMiddleware\n >,\n): TextActivityResult<TSchema, TStream, TTools> {\n validateInterruptDefinitions(options.interrupts)\n validateCapabilities(\n readRuntimeMiddleware(options.middleware) ?? [],\n options.adapter,\n )\n if (options.tools) {\n assertUniqueToolNames(options.tools)\n }\n\n const { outputSchema, stream } = options\n\n if (outputSchema && stream === true) {\n return runStreamingStructuredOutput(\n toRuntimeTextActivityOptions(options, {\n outputSchema,\n stream: true,\n }),\n ) as TextActivityResult<TSchema, TStream, TTools>\n }\n\n if (outputSchema) {\n return runAgenticStructuredOutput(\n toRuntimeTextActivityOptions(options, {\n outputSchema,\n stream: false,\n }),\n ) as TextActivityResult<TSchema, TStream, TTools>\n }\n\n if (stream === false) {\n return runNonStreamingText(\n toRuntimeTextActivityOptions(options, {\n outputSchema: undefined,\n stream: false,\n }),\n ) as TextActivityResult<TSchema, TStream, TTools>\n }\n\n return runStreamingText(\n toRuntimeTextActivityOptions(options, {\n outputSchema: undefined,\n stream: true,\n }),\n ) as TextActivityResult<TSchema, TStream, TTools>\n}\n\ntype RuntimeTextActivityOptions<\n TAdapter extends AnyTextAdapter,\n TSchema extends SchemaInput | undefined,\n TStream extends boolean,\n> = Omit<TextActivityOptions<TAdapter, TSchema, TStream, any>, 'middleware'> & {\n middleware?: Array<AnyChatMiddleware>\n}\n\nfunction readRuntimeMiddleware(\n middleware: unknown,\n): Array<AnyChatMiddleware> | undefined {\n if (middleware === undefined) return undefined\n if (!Array.isArray(middleware)) {\n throw new TypeError('Chat middleware must be an array.')\n }\n return middleware\n}\n\nfunction toRuntimeTextActivityOptions<\n TAdapter extends AnyTextAdapter,\n TInputSchema extends SchemaInput | undefined,\n TInputStream extends boolean,\n TOutputSchema extends SchemaInput | undefined,\n TOutputStream extends boolean,\n TTools extends TextActivityOptions<\n TAdapter,\n TInputSchema,\n TInputStream,\n any\n >['tools'],\n TInterrupts extends ReadonlyArray<InterruptDefinition<any, any, any, any>>,\n TContext,\n TMiddleware extends Array<unknown> | undefined,\n>(\n options: TextActivityOptionsWithContext<\n TAdapter,\n TInputSchema,\n TInputStream,\n TTools,\n TInterrupts,\n TContext,\n TMiddleware\n >,\n overrides: { outputSchema: TOutputSchema; stream: TOutputStream },\n): RuntimeTextActivityOptions<TAdapter, TOutputSchema, TOutputStream> {\n const { middleware, ...rest } = options\n return {\n ...rest,\n ...overrides,\n ...(middleware === undefined\n ? {}\n : { middleware: readRuntimeMiddleware(middleware) }),\n }\n}\n\nfunction validateInterruptDefinitions(\n definitions:\n | ReadonlyArray<InterruptDefinition<any, any, any, any>>\n | undefined,\n): void {\n if (!definitions) return\n const seen = new Set<string>()\n for (const definition of definitions) {\n if (seen.has(definition.id)) {\n throw new Error(`Duplicate interrupt definition id: ${definition.id}`)\n }\n seen.add(definition.id)\n }\n}\n\n/**\n * The slice of the engine that the durable delivery sink reaches back into, in\n * BOTH directions: it reads the detach verdict (`wasDetached`) and pushes the\n * socket-closed fact in (`notifyDisconnected`). Filled by the generator body as\n * soon as its engine exists.\n */\ninterface DeliveryEngineRef {\n current?: {\n wasDetached: () => boolean\n notifyDisconnected: () => void\n }\n}\n\n/**\n * Publish both delivery-side seams for `stream`.\n *\n * Shared by the two streaming paths so they cannot drift apart — the\n * structured-output path having been wired for one seam and not the other is\n * exactly the bug `publishRunDetachedSignal` picked up last time (a durable\n * `chat({ outputSchema, stream: true })` could never detach).\n */\nfunction publishDeliverySeams(\n stream: object,\n engineRef: DeliveryEngineRef,\n): void {\n // A thunk, evaluated on the sink's teardown path: the engine does not exist\n // yet, and the verdict it will report is only written during `onAbort`.\n publishRunDetachedSignal(\n stream,\n () => engineRef.current?.wasDetached() === true,\n )\n // The inbound direction. Dropped if the socket closes before the body has run\n // far enough to have an engine, which is correct: there is no run state to\n // record yet, and `setup` has not begun, so nothing is leaked by not knowing.\n publishRunDisconnectHandler(stream, () => {\n engineRef.current?.notifyDisconnected()\n })\n}\n\n/**\n * Run streaming text (agentic or one-shot depending on tools).\n *\n * A thin, NON-generator wrapper, because the stream object is also the key the\n * durable delivery sink looks the run's detach verdict up under (see\n * `../../delivery-detach`) and delivers its disconnect notification through (see\n * `../../delivery-disconnect`). A generator function cannot reach the generator it\n * returns, so the identity has to be minted out here and the engine reached back\n * through `engineRef`, which the body fills as soon as its engine exists.\n */\nfunction runStreamingText(\n options: RuntimeTextActivityOptions<AnyTextAdapter, undefined, boolean>,\n): AsyncIterable<StreamChunk> {\n const engineRef: DeliveryEngineRef = {}\n const stream = streamTextChunks(options, engineRef)\n publishDeliverySeams(stream, engineRef)\n return stream\n}\n\nasync function* streamTextChunks(\n options: RuntimeTextActivityOptions<AnyTextAdapter, undefined, boolean>,\n engineRef: DeliveryEngineRef,\n): AsyncIterable<StreamChunk> {\n const { adapter, middleware, context, debug, mcp, ...textOptions } = options\n const model = adapter.model\n const logger = resolveDebugOption(debug)\n\n const mcpManager = MCPManager.from(mcp)\n const mcpTools = await mcpManager.discover()\n if (mcpTools.length > 0) {\n textOptions.tools = [...(textOptions.tools ?? []), ...mcpTools]\n }\n\n const engine = new TextEngine(\n {\n adapter,\n params: { ...textOptions, model, logger } as TextOptions<\n Record<string, any>,\n Record<string, any>,\n any\n >,\n middleware,\n context,\n },\n logger,\n )\n engineRef.current = engine\n\n try {\n for await (const chunk of engine.run()) {\n yield chunk\n }\n } finally {\n await mcpManager.dispose()\n }\n}\n\n/**\n * Run non-streaming text - collects all content and returns as a string.\n * Runs the full agentic loop (if tools are provided) but returns collected text.\n */\nfunction runNonStreamingText(\n options: RuntimeTextActivityOptions<AnyTextAdapter, undefined, false>,\n): Promise<string> {\n const stream = runStreamingText({\n ...options,\n stream: true,\n })\n\n return streamToText(stream)\n}\n\n/**\n * Run agentic structured output:\n * 1. Execute the full agentic loop (with tools)\n * 2. Once complete, call adapter.structuredOutput with the conversation context\n * 3. Validate and return the structured result\n */\nasync function runAgenticStructuredOutput<TSchema extends SchemaInput>(\n options: RuntimeTextActivityOptions<AnyTextAdapter, TSchema, boolean>,\n): Promise<InferSchemaType<TSchema>> {\n const {\n adapter,\n outputSchema,\n middleware,\n context,\n debug,\n mcp,\n ...textOptions\n } = options\n const model = adapter.model\n const logger = resolveDebugOption(debug)\n\n if (!outputSchema) {\n throw new Error('outputSchema is required for structured output')\n }\n\n // Same strict-conversion as the streaming path (`forStructuredOutput: true`)\n // so the same Zod schema produces the same JSON Schema regardless of\n // stream mode — Promise<T> and stream:true must not diverge here. The same\n // pass also records a `nullWideningMap`: optional fields are widened to\n // `required` + nullable for the provider, which then returns `null` for an\n // absent optional — a `null` the original `.optional()` (`T | undefined`)\n // schema would otherwise reject. The map pinpoints exactly those synthesized\n // nulls so `undoNullWidening` can drop them while preserving the ones a\n // `.nullable()` field genuinely allows.\n const { jsonSchema, nullWideningMap } =\n convertSchemaForStructuredOutput(outputSchema)\n if (!jsonSchema) {\n throw new Error('Failed to convert output schema to JSON Schema')\n }\n\n // Un-widening runs in the engine the moment the structured output is\n // captured (`finalStructuredOutput.normalize`), so it applies uniformly to\n // every adapter and to both stream modes — the engine is the only layer\n // holding the schema's `nullWideningMap`. Validation then runs on the\n // already-normalized data, so `validate` is a plain Standard Schema parse.\n const normalize = (data: unknown): unknown =>\n undoNullWidening(data, nullWideningMap)\n\n // Validation runs INSIDE the engine (per spec §7.3) so validation failures\n // route through the engine's terminal-hook chooser as `onError`. We pass a\n // `validate` callback when the schema is a Standard Schema; otherwise we\n // pass through the (normalized) data and the engine returns it unchanged.\n const validate = isStandardSchema(outputSchema)\n ? (data: unknown): unknown =>\n parseWithStandardSchema<InferSchemaType<TSchema>>(outputSchema, data)\n : undefined\n\n // Per issue #605: same capability check as the streaming path. When the\n // adapter handles tools + schema natively, the engine skips the separate\n // structured-output finalization call and harvests the JSON from the\n // agent loop's accumulated final-turn text.\n const nativeCombined =\n adapter.supportsCombinedToolsAndSchema?.(options.modelOptions) === true\n const source =\n adapter.combinedStructuredOutputSource?.(options.modelOptions) ?? 'text'\n\n const mcpManager = MCPManager.from(mcp)\n const mcpTools = await mcpManager.discover()\n if (mcpTools.length > 0) {\n textOptions.tools = [...(textOptions.tools ?? []), ...mcpTools]\n }\n\n const engine = new TextEngine(\n {\n adapter,\n params: { ...textOptions, model, logger } as TextOptions<\n Record<string, unknown>,\n Record<string, unknown>,\n any\n >,\n middleware,\n context,\n finalStructuredOutput: {\n jsonSchema,\n yieldChunks: false,\n normalize,\n ...(validate ? { validate } : {}),\n ...(nativeCombined ? { nativeCombined: true } : {}),\n source,\n },\n },\n logger,\n )\n\n try {\n // Consume the stream — chunks pipe through middleware but are not yielded externally\n for await (const _chunk of engine.run()) {\n // intentionally empty\n }\n } finally {\n await mcpManager.dispose()\n }\n\n const finalizationError = engine.getFinalizationError()\n if (finalizationError) {\n const err = new Error(\n finalizationError.message,\n finalizationError.cause !== undefined\n ? { cause: finalizationError.cause }\n : undefined,\n )\n if (finalizationError.code !== undefined) {\n Object.defineProperty(err, 'code', {\n value: finalizationError.code,\n enumerable: true,\n })\n }\n throw err\n }\n\n // If a validator ran, return the validated value (typed by InferSchemaType\n // via the callback closure). Otherwise return the raw data.\n const validated = engine.getValidatedStructuredOutput()\n if (validated) {\n return validated.value as InferSchemaType<TSchema>\n }\n\n const result = engine.getStructuredOutputResult()\n if (!result) {\n throw new Error('structured output finalization produced no result')\n }\n return result.data as InferSchemaType<TSchema>\n}\n\n/**\n * Parse the `value` payload of a `structured-output.complete` CUSTOM event\n * into a typed shape, returning `null` if the runtime payload doesn't match.\n *\n * Uses an `unknown`-input runtime check rather than `as` casts so the engine\n * stays cast-free in its hot path.\n */\nfunction readCustomEventMessageId(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined\n if (!('messageId' in value)) return undefined\n const messageId = value.messageId\n return typeof messageId === 'string' && messageId !== ''\n ? messageId\n : undefined\n}\n\nfunction readStructuredOutputCompleteValue(\n value: unknown,\n): { object: unknown; raw: string; reasoning?: string } | null {\n if (typeof value !== 'object' || value === null) return null\n if (!('object' in value) || !('raw' in value)) return null\n const raw = (value as { raw: unknown }).raw\n if (typeof raw !== 'string') return null\n const reasoningField = (value as { reasoning?: unknown }).reasoning\n const reasoning =\n typeof reasoningField === 'string' ? reasoningField : undefined\n return {\n object: (value as { object: unknown }).object,\n raw,\n ...(reasoning !== undefined ? { reasoning } : {}),\n }\n}\n\n/**\n * Synthesize a streaming structured-output stream by wrapping a non-streaming\n * `structuredOutput` call. Used when an adapter doesn't implement\n * `structuredOutputStream` natively.\n *\n * `onAdapterError`, when provided, is invoked with the raw error from\n * `adapter.structuredOutput` before the synthesized RUN_ERROR is yielded.\n * The engine uses this to preserve the original error (stack, cause, custom\n * properties like provider `status`/`code`) as `finalizationError.cause`,\n * because the RUN_ERROR wire shape only carries `message` and `code`.\n */\nasync function* fallbackStructuredOutputStream(\n adapter: AnyTextAdapter,\n options: StructuredOutputOptions<Record<string, unknown>>,\n onAdapterError?: (err: unknown) => void,\n): AsyncIterable<AdapterYieldChunk> {\n const { chatOptions } = options\n // Synthesize run/thread/message IDs only when the caller didn't supply them.\n // Prefix `fallback-` (not `mock-`) because this is production fallback code\n // used by adapters without native `structuredOutputStream`, not test fixtures.\n const fallbackRand = Math.random().toString(36).slice(2)\n const runId = chatOptions.runId ?? `fallback-${Date.now()}-${fallbackRand}`\n const threadId =\n chatOptions.threadId ?? `fallback-${Date.now()}-${fallbackRand}`\n const messageId = `fallback-${Date.now()}-${fallbackRand}`\n const model = chatOptions.model\n const startedAt = Date.now()\n\n yield {\n type: EventType.RUN_STARTED,\n runId,\n threadId,\n model,\n timestamp: startedAt,\n }\n\n let result: StructuredOutputResult<unknown>\n try {\n result = await adapter.structuredOutput(options)\n } catch (error) {\n onAdapterError?.(error)\n const message = error instanceof Error ? error.message : String(error)\n yield {\n type: EventType.RUN_ERROR,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n message,\n error: { message },\n }\n return\n }\n\n yield {\n type: EventType.TEXT_MESSAGE_START,\n messageId,\n role: 'assistant',\n model,\n timestamp: Date.now(),\n }\n\n yield {\n type: EventType.TEXT_MESSAGE_CONTENT,\n messageId,\n delta: result.rawText,\n model,\n timestamp: Date.now(),\n }\n\n yield {\n type: EventType.TEXT_MESSAGE_END,\n messageId,\n model,\n timestamp: Date.now(),\n }\n\n yield {\n type: EventType.CUSTOM,\n name: 'structured-output.complete',\n value: { object: result.data, raw: result.rawText },\n model,\n timestamp: Date.now(),\n }\n\n yield {\n type: EventType.RUN_FINISHED,\n runId,\n threadId,\n model,\n timestamp: Date.now(),\n finishReason: 'stop',\n // Forward adapter-reported token usage so consumers reading\n // `RUN_FINISHED.usage` (and the engine's `runOnUsage` middleware hook) see\n // it on the fallback path, mirroring the native streaming path. The\n // conditional spread avoids emitting `usage: undefined` for adapters that\n // don't report it. See #758.\n ...(result.usage ? { usage: result.usage } : {}),\n }\n}\n\n/**\n * Run streaming structured output via the TextEngine, with the engine's\n * `finalStructuredOutput.yieldChunks: true` mode. The agent loop's\n * RUN_STARTED/RUN_FINISHED are suppressed; the structured-output finalization\n * step's pair brackets the run for the consumer.\n *\n * Standard Schema *validation* is intentionally NOT run on this path — it is\n * the consumer's responsibility. This is a deliberate asymmetry vs.\n * `runAgenticStructuredOutput` (Promise<T> path), which DOES validate inside\n * the engine and routes validation failures through `onError`. The reason:\n * streaming consumers typically render partial JSON progressively (via\n * `parsePartialJSON` or `useChat`'s `partial` slot) and validate downstream\n * after assembly. Running validation server-side would force a hard error\n * on partial-by-design payloads. See `docs/structured-outputs/overview.md`.\n *\n * Null-widening normalization, however, IS run on both paths: the\n * `structured-output.complete` CUSTOM event is forwarded with its `value.object`\n * already un-widened (synthesized strict-mode nulls dropped, genuine\n * `.nullable()` nulls kept), so a consumer validating the assembled object\n * against the original schema doesn't choke on a `null` for an `.optional()`\n * field. Same `convertSchemaForStructuredOutput` pass and same\n * `undoNullWidening` map as the Promise<T> path — the two must not diverge.\n *\n * Pre-flight validation (missing schema, unconvertible schema) throws\n * synchronously at call time rather than as a yielded RUN_ERROR mid-stream —\n * those are programmer errors, not runtime conditions.\n */\nfunction runStreamingStructuredOutput<TSchema extends SchemaInput>(\n options: RuntimeTextActivityOptions<AnyTextAdapter, TSchema, true>,\n): StructuredOutputStream<InferSchemaType<TSchema>> {\n const { outputSchema } = options\n\n if (!outputSchema) {\n throw new Error('outputSchema is required for streaming structured output')\n }\n\n // forStructuredOutput strict-converts the schema once at the activity\n // boundary, capturing the null-widening map so the engine can un-widen the\n // provider's response before it reaches the consumer. Adapters can re-convert\n // if their wire format diverges, but the default flow hands them a\n // strict-ready schema.\n const { jsonSchema, nullWideningMap } =\n convertSchemaForStructuredOutput(outputSchema)\n if (!jsonSchema) {\n throw new Error('Failed to convert output schema to JSON Schema')\n }\n const normalize = (data: unknown): unknown =>\n undoNullWidening(data, nullWideningMap)\n\n // The implementation generator yields the broader internal type\n // (`StreamChunk | StructuredOutputCompleteEvent<T>`) so middleware and\n // tool-emitted CustomEvents can flow through. Core approval/client-tool\n // waits are represented by RUN_FINISHED interrupt outcomes, not by direct\n // CUSTOM wait events.\n // The contained cast keeps the public stream type focused on\n // structured-output completion.\n //\n // Same seam as `runStreamingText`: this wrapper is NOT a generator, so the\n // stream identity can be minted here and the engine reached back through\n // `engineRef` once the impl body has its engine. Without this a durable\n // structured-output stream could never detach — the sink would find no verdict\n // and terminalize a healthy detached run's log — nor survive a disconnect.\n const engineRef: DeliveryEngineRef = {}\n const stream = runStreamingStructuredOutputImpl(\n options,\n jsonSchema,\n normalize,\n engineRef,\n )\n publishDeliverySeams(stream, engineRef)\n return stream as StructuredOutputStream<InferSchemaType<TSchema>>\n}\n\n/**\n * Internal generator return type — broader than the public\n * `StructuredOutputStream<T>`. The structured-output completion event remains\n * the pinned public CUSTOM event for this stream; approval and client-tool\n * waits now surface as RUN_FINISHED interrupt outcomes. At runtime, tools can\n * still emit arbitrary user-defined `CustomEvent`s through the\n * `emitCustomEvent` context API; those flow\n * through this generator with `name: string` and are widened out at the\n * public boundary because keeping them would collapse the typed narrow back\n * to `any`. The cast inside `runStreamingStructuredOutput` is where that\n * widening happens.\n */\ntype StructuredOutputStreamInternal<T> = AsyncIterable<\n StreamChunk | StructuredOutputCompleteEvent<T>\n>\n\nasync function* runStreamingStructuredOutputImpl<TSchema extends SchemaInput>(\n options: RuntimeTextActivityOptions<AnyTextAdapter, TSchema, true>,\n jsonSchema: NonNullable<ReturnType<typeof convertSchemaToJsonSchema>>,\n normalize: (data: unknown) => unknown,\n engineRef: DeliveryEngineRef,\n): StructuredOutputStreamInternal<InferSchemaType<TSchema>> {\n const {\n adapter,\n outputSchema,\n middleware,\n context,\n debug,\n mcp,\n ...textOptions\n } = options\n const model = adapter.model\n const logger = resolveDebugOption(debug)\n\n // Per issue #605: adapters that natively combine tools + schema-constrained\n // output in one streaming call (modern OpenAI, Anthropic 4.5+, Gemini 3+,\n // Grok 4+) opt in via `supportsCombinedToolsAndSchema()`. The engine then\n // forwards the schema into the regular `chatStream` call and harvests the\n // structured result from the agent loop's accumulated text — no separate\n // finalization round-trip, and the `'structuredOutput'` middleware phase\n // does not fire.\n const nativeCombined =\n adapter.supportsCombinedToolsAndSchema?.(options.modelOptions) === true\n const source =\n adapter.combinedStructuredOutputSource?.(options.modelOptions) ?? 'text'\n\n const mcpManager = MCPManager.from(mcp)\n const mcpTools = await mcpManager.discover()\n if (mcpTools.length > 0) {\n textOptions.tools = [...(textOptions.tools ?? []), ...mcpTools]\n }\n\n // Inputs may be UIMessages (from useChat) or ModelMessages (from server-side\n // callers). TextEngine handles the conversion uniformly.\n const engine = new TextEngine(\n {\n adapter,\n params: { ...textOptions, model, logger } as TextOptions<\n Record<string, unknown>,\n Record<string, unknown>,\n any\n >,\n middleware,\n context,\n finalStructuredOutput: {\n jsonSchema,\n yieldChunks: true,\n normalize,\n ...(nativeCombined ? { nativeCombined: true } : {}),\n source,\n },\n },\n logger,\n )\n engineRef.current = engine\n\n try {\n for await (const chunk of engine.run()) {\n yield chunk\n }\n } finally {\n await mcpManager.dispose()\n }\n\n // Standard Schema validation for the streaming variant remains the\n // consumer's responsibility — they read the CUSTOM 'structured-output.complete'\n // from the yielded stream. (Null-widening normalization, by contrast, already\n // ran inside the engine via `normalize`, so the object they read is un-widened.)\n void outputSchema\n}\n\n// Re-export adapter types\nexport type {\n TextAdapter,\n TextAdapterConfig,\n StructuredOutputOptions,\n StructuredOutputResult,\n} from './adapter'\nexport { BaseTextAdapter } from './adapter'\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2JA,IAAa,OAAO;AAMpB,IAAM,8BAA8B;AAOpC,SAAS,2BACP,OACmC;CACnC,IAAI,UAAU,QAAQ,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GACpE,OAAO;CAET,IACE,EAAE,WAAW,UACb,EAAE,UAAU,UACZ,EAAE,aAAa,UACf,EAAE,YAAY,UACd,EAAE,eAAe,UACjB,EAAE,cAAc,UAChB,EAAE,sBAAsB,UACxB,EAAE,gBAAgB,UAClB,OAAO,MAAM,SAAS,YACtB,OAAO,MAAM,YAAY,YACzB,OAAO,MAAM,cAAc,aAC3B,OAAO,MAAM,aAAa,YAC1B,OAAO,MAAM,qBAAqB,YAClC,OAAO,MAAM,eAAe,UAE5B,OAAO;CAET,IAAI,MAAM,UAAU,QAClB,OACE,iBAAiB,SACjB,OAAO,MAAM,gBAAgB,aAC5B,MAAM,WAAW,YAAY,MAAM,WAAW;CAGnD,OACE,MAAM,UAAU,WAChB,kBAAkB,SAClB,MAAM,QAAQ,MAAM,YAAY,KAChC,MAAM,aAAa,OAAO,OAAO,OAAO,OAAO,QAAQ,MACtD,MAAM,WAAW,YAChB,MAAM,WAAW,YACjB,MAAM,WAAW;AAEvB;AAEA,SAAS,2BACP,OACwC;CACxC,IACE,EAAE,iBAAiB,UACnB,MAAM,SAAS,oCACf,EAAE,YAAY,UACd,CAAC,MAAM,QAAQ,MAAM,MAAM,KAC3B,MAAM,OAAO,WAAW,KACxB,CAAC,MAAM,OAAO,MAAM,0BAA0B,GAE9C;CAEF,OAAO;EACL;EACA,QAAQ,MAAM;CAChB;AACF;AAEA,SAAS,gCACP,OACA,qBAC8B;CAC9B,OAAO,qBAAqB;EAC1B,IAAI;EACJ,QAAQ;EACR,UAAU,GAAG,iCAAiC,MAAM;CACtD,CAAC;AACH;;;;;;;;;;;;;;AAqWA,SAAgB,kBAgBd,SAqBsD;CACtD,OAAO;AACT;;;;;;AAgHA,SAAS,oBACP,GACA,GACyB;CACzB,IAAI,CAAC,GAAG,OAAO;CACf,IAAI,CAAC,GAAG,OAAO;CACf,IAAI,EAAE,SAAS,OAAO;CACtB,IAAI,EAAE,SAAS,OAAO;CACtB,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,WAAW,iBAA8B;EAC7C,WAAW,MAAM,OAAO,MAAM;CAChC;CACA,EAAE,iBAAiB,SAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;CACtD,EAAE,iBAAiB,SAAS,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,CAAC;CACtD,OAAO,WAAW;AACpB;AAEA,IAAM,aAAN,MAQE;CACA;CACA;CAIA;CACA;CACA;CACA;CACA;CACA;;CAEA,sBAA8B;CAC9B;CACA;CACA;CACA;CACA;CAEA;CACA;CACA,iBAAyB;;CAEzB,gBAAwB;;CAExB,wBAAgC;;CAEhC,qCAAsC,IAAI,IAAY;CACtD,mBAA0C;CAC1C,kBAA0B;CAC1B,kBAA0B;CAC1B,mBAA0C;CAC1C,0BAA+C;CAC/C,yBAAiC;CACjC,qBAA6B;CAC7B,sBACE,CAAC;CACH,yBAAiC;CACjC,2BAAmC;CACnC;CACA;CACA,gBAAiD;CACjD,2CAA4C,IAAI,IAAwB;CACxE,oCAAgE,CAAC;;CAEjE,iCAA6D,CAAC;CAE9D,mBAA2B;CAC3B,YAAqC;CACrC,aAAiC;CAEjC;CACA;CACA,kCAAmC,IAAI,IAAoC;CAC3E,0CAA2C,IAAI,IAAiB;CAChE,0CAA2C,IAAI,IAAqB;CACpE,6CAA8C,IAAI,IAAY;CAC9D,0CAA2C,IAAI,IAG7C;CACF,iDAAkD,IAAI,IAGpD;CAGF;CACA;CACA;CAGA;CAIA;CACA,mBAAwD,CAAC;CACzD,wBAA6D,CAAC;CAC9D,0BAAqD,CAAC;CACtD,2BAAmC;CACnC,mBAA6D,CAAC;CAC9D;CACA;CAGA;CACA,qBAA6B;;;;;;;CAO7B,eAAuB;CACvB,sBAA0E,CAAC;CAE3E;CAGA,yBAIW;CACX,4BAAmD;CACnD,mCAAwD;CAMxD,uBAA+B;CAI/B,8BAAqD;CAIrD,4BAA6C,KAAA;CAC7C,+BAAuC;CACvC,oBAIW;CACX,0BAAkC;CAClC;CASA,YACE,QACA,QACA;EACA,KAAK,SAAS;EACd,KAAK,UAAU,OAAO;EACtB,KAAK,uBAAuB,IAAI,KAG1B,OAAO,OAGP,cAAc,CAAC,EAAA,CACjB,KAAK,eAAe,CAAC,WAAW,IAAI,UAAU,CAAC,CACnD;EACA,KAAK,wBAAwB,OAAO;EACpC,KAAK,SAAS,OAAO;EACrB,KAAK,gBAAgB,OAAO,OAAO,iBAAiB,CAAC;EACrD,KAAK,eACH,OAAO,OAAO,qBAAqB,cAAsB,CAAC;EAC5D,KAAK,sBAAsB,OAAO,OAAO,SAAS;EAIlD,MAAM,EAAE,WAAW,sBACjB,KAAK,uCACH,OAAO,OAAO,QAChB;EACF,KAAK,mBAAmB;EACxB,KAAK,2BAA2B;EAIhC,KAAK,WAAW,+BAA+B,OAAO,OAAO,QAAQ;EACrE,KAAK,mBAAmB,KAAK;EAG7B,sBAAsB,OAAO,OAAO,SAAS,CAAC,CAAC;EAC/C,KAAK,kBAAkB,IAAI,gBACzB,OAAO,OAAO,SAAS,CAAC,GACxB,KAAK,UACL,OAAO,OAAO,eAChB;EACA,KAAK,QAAQ,KAAK,gBAAgB,eAAe;EACjD,KAAK,kBAAkB,IAAI,gBAGzB,KAAK,KAAK;EACZ,KAAK,YAAY,KAAK,SAAS,MAAM;EACrC,KAAK,WAAW,KAAK,SAAS,QAAQ;EACtC,KAAK,mBAAmB,OAAO,OAAO,kBAClC,EAAE,QAAQ,OAAO,OAAO,gBAAgB,OAAO,IAC/C,KAAA;EACJ,KAAK,kBAAkB,OAAO,OAAO,iBAAiB;EAItD,KAAK,WACH,OAAO,OAAO,YACd,OAAO,OAAO,kBACd,KAAK,SAAS,QAAQ;EACxB,KAAK,gBAAgB,OAAO,OAAO;EACnC,KAAK,sBAAsB,OAAO,OAAO;EAKzC,MAAM,gBAEF,CAAC,mBAAmB,GAAG,GAAI,OAAO,cAAc,CAAC,CAAE;EACvD,KAAK,mBAAmB,IAAI,iBAAiB,eAAe,MAAM;EAClE,KAAK,4BAA4B,IAAI,gBAAgB;EACrD,KAAK,kBAAkB,oBACrB,KAAK,iBACL,KAAK,0BAA0B,MACjC;EACA,KAAK,gBAAgB;GACnB,WAAW,KAAK;GAChB,UAAU,KAAK;GACf,OAAO,KAAK,iBAAiB,KAAK;GAClC,aAAa,KAAK;GAClB,UAAU,KAAK;GAGf,gBAAgB,KAAK;GACrB,OAAO;GACP,WAAW;GACX,YAAY;GACZ,QAAQ,KAAK;GACb,QAAQ,WAAoB;IAC1B,KAAK,cAAc;IACnB,KAAK,2BAA2B,MAAM,MAAM;GAC9C;GACA,kBAAkB,MAAM,UAAU;IAChC,KAAK,sBAAsB,KACzB,KAAK,uBAAuB,MAAM,KAAK,CACzC;IACA,MAAM,UAAU,KAAK;IACrB,KAAK,0BAA0B,CAAC;IAChC,KAAK,MAAM,UAAU,SAAS,OAAO;GACvC;GACA,SAAS,OAAO;GAChB,QAAQ,YAA8B;IACpC,KAAK,iBAAiB,KAAK,OAAO;GACpC;GAEA,UAAU;GACV,UAAU,OAAO,QAAQ;GACzB,OAAO,OAAO,OAAO;GACrB,QAAQ;GACR,WAAW;GAEX,eAAe,KAAK;GACpB,WAAW,KAAA;GACX,SAAS,KAAA;GACT,cAAc,OAAO,OAAO;GAE5B,cAAc,KAAK;GACnB,UAAU,KAAK,MAAM,SAAS;GAE9B,kBAAkB;GAClB,oBAAoB;GAEpB,UAAU,KAAK;GACf,WAAW,WAAmB,KAAK,SAAS,MAAM;GAElD,cAAc,IAAI,mBAAmB;GAIrC,MAAM,eAAe,WAAW,EAAE,CAAC,KAAK,aAAa;GACrD,cAAc,eACZ,WAAW,EAAE,CAAC,KAAK,eAAe,EAAE,UAAU,KAAK,CAAC;GACtD,UAAU,YAAY,UAAU,WAAW,EAAE,CAAC,KAAK,eAAe,KAAK;EACzE;EAWA,qBAAqB,KAAK,eAAe,EACvC,YAAY,aAAa;GACvB,KAAK,oBAAoB,KAAK,QAAQ;GACtC,IAAI,KAAK,cAAc,KAAK,sBAAsB,QAAQ;EAC5D,EACF,CAAC;EAED,0CAA0C,KAAK,eAAe,EAC5D,aAAa,KAAK,qBACpB,CAAC;EAMD,sBAAsB,KAAK,eAAe;GACxC,QAAQ,KAAK;GACb,OAAO,UAAgC;IACrC,KAAK,OAAO,QAAQ,QAAQ,MAAM,KAAK,GAAG,MAAM,QAAQ,EACtD,OAAO;KACL,MAAM,MAAM;KACZ,MAAM,MAAM;KACZ,WAAW,MAAM;IACnB,EACF,CAAC;IACD,KAAU,iBACP,eAAe,KAAK,eAAe,KAAK,CAAC,CACzC,OAAO,QAAiB;KACvB,KAAK,OAAO,OAAO,4BAA4B,EAAE,OAAO,IAAI,CAAC;IAC/D,CAAC;IACH,KAAK,iBAAiB,KACpB,KAAK,uBAAuB,gBAAgB;KAC1C,MAAM,MAAM;KACZ,MAAM,MAAM;KACZ,WAAW,MAAM;IACnB,CAAC,CACH;GACF;GACA,eAAe,UAA0C;IACvD,KAAK,iBAAiB,KACpB,KAAK,uBAAuB,qBAAqB,KAAK,CACxD;GACF;EACF,CAAC;CACH;;CAGA,wBAAgC;EAC9B,OAAO,KAAK;CACd;;CAGA,cAAmC;EACjC,OAAO,KAAK;CACd;;CAGA,4BAAuE;EACrE,OAAO,KAAK;CACd;;;;;;;;CASA,+BAA0D;EACxD,OAAO,KAAK,+BACR,EAAE,OAAO,KAAK,0BAA0B,IACxC;CACN;;CAGA,uBAIS;EACP,OAAO,KAAK;CACd;CAEA,OAAO,MAAmC;EACxC,KAAK,UAAU;EACf,KAAK,OAAO,UAAU,eAAe,EACnC,UAAU,KAAK,cAAc,SAC/B,CAAC;EAED,IAAI;GAEF,OAAO,KAAK,iBACV,KAAK,iBAAiB,SAAS,KAAK,aAAa,CACnD;GAGA,KAAK,cAAc,QAAQ;GAC3B,MAAM,gBAAgB,KAAK,sBAAsB;GACjD,MAAM,oBAAoB,OAAO,KAAK,iBACpC,KAAK,iBAAiB,YAAY,KAAK,eAAe,aAAa,CACrE;GACA,KAAK,sBAAsB,iBAAiB;GAC5C,MAAM,KAAK,8BAA8B,iBAAiB;GAC1D,MAAM,KAAK,uCAAuC;GAGlD,OAAO,KAAK,iBACV,KAAK,iBAAiB,WAAW,KAAK,aAAa,CACrD;GAEA,IAAI,KAAK,kBAAkB;IACzB,OAAO,KAAK,+BAA+B;IAC3C,IAAI,CAAC,KAAK,oBAAoB;KAC5B,KAAK,qBAAqB;KAC1B,MAAM,KAAK,iBAAiB,YAAY,KAAK,eAAe;MAC1D,cAAc,KAAK;MACnB,UAAU,KAAK,IAAI,IAAI,KAAK;MAC5B,SAAS,KAAK;MACd,OAAO,kBACL,KAAK,eAAe,OACpB,iBAAiB,KAAK,iBAAiB,KAAA,CAAS,CAAC,EAAE,KACrD;KACF,CAAC;IACH;IACA;GACF;GAGA,KAAI,OADwB,KAAK,yBAAyB,OACrC,QACnB;GAiBF,IAAI,EAJF,CAAC,CAAC,KAAK,yBACP,KAAK,MAAM,WAAW,KACtB,KAAK,sBAAsB,mBAAmB,OAG9C,GAAG;IACD,IAAI,KAAK,kBAAkB;IAC3B,IAAI,KAAK,YAAY,GAAG;IAExB,KAAK,OAAO,UAAU,aAAa,KAAK,cAAc,aAAa,EACjE,WAAW,KAAK,cAAc,UAChC,CAAC;IAED,OAAO,KAAK,iBAAiB,KAAK,WAAW,CAAC;IAE9C,IAAI,KAAK,eAAe,eAAe;KAErC,KAAK,cAAc,QAAQ;KAC3B,KAAK,cAAc,YAAY,KAAK;KACpC,MAAM,aAAa,KAAK,sBAAsB;KAC9C,MAAM,wBAAwB,OAAO,KAAK,iBACxC,KAAK,iBAAiB,YAAY,KAAK,eAAe,UAAU,CAClE;KACA,KAAK,sBAAsB,qBAAqB;KAEhD,IACE,OAAO,KAAK,uBACV,eACA,KAAK,6BAA6B,CACpC,GACA;MACA,KAAK,aAAa,MAAM;MACxB;KACF;KAEA,OAAO,KAAK,oBAAoB;KAEhC,IAAI,KAAK,kBAAkB;KAE3B,IACE,OAAO,KAAK,uBACV,cACA,KAAK,iBAAiB,KAAK,6BAA6B,CAC1D,GACA;MACA,KAAK,aAAa,MAAM;MACxB;KACF;KACA,IAAI,KAAK,uBAAuB,GAAG;MACjC,KAAK,kCAAkC,KACrC,GAAG,KAAK,8BACV;MACA,KAAK,iCAAiC,CAAC;KACzC,OAAO,IAAI,CAAC,KAAK,uBAAuB,gBACtC,OAAO,KAAK,oCAAoC;IAEpD,OACE,OAAO,KAAK,iBAAiB;IAG/B,KAAK,SAAS;GAChB,SAAS,OAAO,KAAK,iBAAiB,KAAK,eAAe,CAAC;GAG7D,KAAK,OAAO,UAAU,gBAAgB,EACpC,cAAc,KAAK,iBACrB,CAAC;GAYD,IACE,KAAK,yBACL,KAAK,cAAc,UACnB,CAAC,KAAK,YAAY,KAClB,CAAC,KAAK,qBACN,CAAC,KAAK,kBACN;IACA,IAAI,KAAK,sBAAsB,mBAAmB,MAAM;KACtD,OAAO,KAAK,gCAAgC;KAC5C,IAAI,CAAC,KAAK,qBAAqB,CAAC,KAAK,YAAY,GAC/C,OAAO,KAAK,oCAAoC;IAEpD,OACE,OAAO,KAAK,0BAA0B;GAE1C;GAKA,IACE,CAAC,KAAK,sBACN,KAAK,cAAc,UACnB,CAAC,KAAK,YAAY,GAClB;IACA,IAAI,KAAK,mBAAmB;KAC1B,KAAK,qBAAqB;KAC1B,MAAM,aAAa,IAAI,MACrB,KAAK,kBAAkB,SACvB,KAAK,kBAAkB,UAAU,KAAA,IAC7B,EAAE,OAAO,KAAK,kBAAkB,MAAM,IACtC,KAAA,CACN;KACA,IAAI,KAAK,kBAAkB,SAAS,KAAA,GAClC,OAAO,eAAe,YAAY,QAAQ;MACxC,OAAO,KAAK,kBAAkB;MAC9B,YAAY;KACd,CAAC;KAEH,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe;MACzD,OAAO;MACP,UAAU,KAAK,IAAI,IAAI,KAAK;KAC9B,CAAC;IACH,OAAO;KACL,KAAK,6BAA6B;KAClC,KAAK,qBAAqB;KAC1B,MAAM,KAAK,iBAAiB,YAAY,KAAK,eAAe;MAC1D,cAAc,KAAK;MACnB,UAAU,KAAK,IAAI,IAAI,KAAK;MAC5B,SAAS,KAAK;MACd,OAAO,kBACL,KAAK,eAAe,OACpB,iBAAiB,KAAK,iBAAiB,KAAA,CAAS,CAAC,EAAE,KACrD;KACF,CAAC;IACH;GACF;EACF,SAAS,OAAgB;GACvB,IACE,iBAAiB,SACjB,MAAM,SAAS,2BACf,uBAAuB,SACvB,OAAO,MAAM,sBAAsB,UACnC;IACA,KAAK,qBAAqB;IAC1B,OAAO,KAAK,sBAAsB;KAChC,MAAM,UAAU;KAChB,WAAW,KAAK,IAAI;KACpB,UAAU,KAAK;KACf,OAAO,KAAK,iBAAiB,KAAK;KAClC,SAAS,EAAE,MAAM,UAAU;KAC3B,QAAQ;MACN,UAAU;MACV,mBAAmB,MAAM;KAC3B;IACF,CAAC;IACD;GACF;GACA,MAAM,mBAAmB,2BAA2B,KAAK;GACzD,IAAI,kBAAkB;IACpB,KAAK,qBAAqB;IAC1B,KAAK,OAAO,OAAO,gCAAgC;KACjD;KACA,UAAU,KAAK,cAAc;IAC/B,CAAC;IACD,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe;KACzD,OAAO,iBAAiB;KACxB,UAAU,KAAK,IAAI,IAAI,KAAK;IAC9B,CAAC;IACD,MAAM,KAAK,4BAA4B,KAAK;IAC5C;GACF;GACA,IAAI,CAAC,KAAK,oBAAoB;IAC5B,KAAK,qBAAqB;IAC1B,IAAI,iBAAiB,sBAAsB;KAEzC,KAAK,cAAc,MAAM;KACzB,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe;MACzD,QAAQ,MAAM;MACd,UAAU,KAAK,IAAI,IAAI,KAAK;MAC5B,iBAAiB,wBAAwB,MAAM,OAAO;KACxD,CAAC;IACH,OAAO;KAEL,KAAK,OAAO,OAAO,mBAAmB;MACpC;MACA,UAAU,KAAK,cAAc;KAC/B,CAAC;KACD,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe;MACzD;MACA,UAAU,KAAK,IAAI,IAAI,KAAK;KAC9B,CAAC;IACH;GACF;GAEA,IAAI,EAAE,iBAAiB,uBACrB,MAAM;EAEV,UAAU;GAER,IAAI,CAAC,KAAK,sBAAsB,KAAK,YAAY,GAAG;IAClD,KAAK,qBAAqB;IAC1B,MAAM,SAAS,KAAK,mBAAmB;IACvC,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe;KACzD;KACA,UAAU,KAAK,IAAI,IAAI,KAAK;KAC5B,iBAAiB,wBAAwB,MAAM;IACjD,CAAC;GACH;GAGA,IAAI,KAAK,iBAAiB,SAAS,GACjC,MAAM,QAAQ,WAAW,KAAK,gBAAgB;EAElD;CACF;CAEA,YAA0B;EACxB,KAAK,kBAAkB,KAAK,IAAI;EAChC,MAAM,EAAE,OAAO,aAAa,KAAK;EAGjC,MAAM,UAAmC,CAAC;EAC1C,IAAI,aAAa,KAAA,GAAW,QAAQ,WAAW;EAE/C,KAAK,eAAe,OAAO,KAAK,OAAO,CAAC,CAAC,SAAS,IAAI,UAAU,KAAA;EAChE,KAAK,iBAAiB,OAAO,KAAK,MAAM,EAAE,IAAI;EAG9C,KAAK,cAAc,UAAU,KAAK;EAClC,KAAK,cAAc,YAAY,KAAK;CACtC;CAEA,MAAc,aAA4B;EACxC,IAAI,KAAK,eAAe,eACtB,MAAM,KAAK,eAAe;CAE9B;CAEA,WAAyB;EACvB,IAAI,KAAK,eAAe,eAAe;GACrC,KAAK,aAAa;GAClB;EACF;EAEA,KAAK,aAAa;EAClB,KAAK;CACP;CAEA,MAAc,iBAAgC;EAC5C,KAAK,mBAAmB,KAAK,SAAS,KAAK;EAC3C,KAAK,0CAA0B,IAAI,KAAK;EACxC,KAAK,yBAAyB;EAC9B,KAAK,qBAAqB;EAC1B,KAAK,sBAAsB,CAAC;EAC5B,KAAK,yBAAyB;EAC9B,KAAK,2BAA2B;EAEhC,KAAK,gBAAgB;EACrB,KAAK,yBAAyB,MAAM;EAGpC,KAAK,cAAc,mBAAmB,KAAK;EAC3C,KAAK,cAAc,qBAAqB;EAGxC,MAAM,KAAK,iBAAiB,eAAe,KAAK,eAAe;GAC7D,WAAW,KAAK;GAChB,WAAW,KAAK;EAClB,CAAC;CACH;CAEA,OAAe,sBAAmD;EAChE,MAAM,EAAE,UAAU,iBAAiB,KAAK;EAIxC,MAAM,uBAHQ,KAAK,MAGgB,KAAK,UAAU;GAChD,GAAG;GACH,aAAa,KAAK,cACd,0BAA0B,KAAK,WAAW,IAC1C,KAAA;GACJ,cAAc,KAAK,eACf,0BAA0B,KAAK,YAAY,IAC3C,KAAA;EACN,EAAE;EAEF,KAAK,cAAc,QAAQ;EAE3B,MAAM,eACH,KAAK,QAAkC,YAAY,KAAK,QAAQ;EACnE,KAAK,OAAO,QACV,0BAA0B,aAAa,SAAS,KAAK,OAAO,MAAM,YAAY,KAAK,SAAS,OAAO,SAAS,KAAK,MAAM,OAAO,eAC9H;GACE,UAAU;GACV,OAAO,KAAK,OAAO;GACnB,cAAc,KAAK,SAAS;GAC5B,WAAW,KAAK,MAAM;EACxB,CACF;EASA,MAAM,iBACJ,KAAK,uBAAuB,mBAAmB,OAC3C,KAAK,sBAAsB,aAC3B,KAAA;EAEN,MAAM,EAAE,cAAc,KAAK,mBAAmB;EAC9C,MAAM,mCAAmB,IAAI,IAAqB;EAClD,KAAK,MAAM,CAAC,YAAY,eAAe,WACrC,iBAAiB,IACf,YACA,OAAO,eAAe,YAAY,aAAa,WAAW,QAC5D;EAGF,WAAW,MAAM,OAAO,KAAK,QAAQ,WAAW;GAC9C,OAAO,KAAK,OAAO;GACnB,UAAU,KAAK;GACf,OAAO;GACP;GACA,SAAS,KAAK;GACd;GACA,eAAe,KAAK;GACpB,QAAQ,KAAK;GACb,UAAU,KAAK;GACf,OAAO,KAAK;GACZ,aAAa,KAAK;GAElB,cAAc,KAAK;GAEnB,WAAW;GACX,GAAI,iBAAiB,EAAE,cAAc,eAAe,IAAI,CAAC;EAC3D,CAAC,GAAG;GACF,IAAI,KAAK,YAAY,GACnB;GAGF,KAAK;GAEL,KAAK,kBAAkB,GAAG;GAS1B,IACE,IAAI,SAAS,UAAU,UACvB,IAAI,SAAS,2BACb;IACA,KAAK,uBAAuB;IAC5B,MAAM,aAAa,IAAI;IACvB,IACE,cACA,OAAO,eAAe,YACtB,eAAe,cACf,OAAO,WAAW,cAAc,UAChC;KACA,KAAK,8BAA8B,WAAW;KAC9C,KAAK,uCAAuC,WAAW,SAAS;IAClE;GACF;GAEA,IAAI,gBAAmC;GACvC,IACE,KAAK,uBAAuB,WAAW,WACvC,IAAI,SAAS,UAAU,UACvB,IAAI,SAAS,8BACb;IACA,MAAM,SAAS,kCAAkC,IAAI,KAAK;IAC1D,IAAI,QAAQ;KACV,MAAM,SAAS,KAAK,sBAAsB,YACtC,KAAK,sBAAsB,UAAU,OAAO,MAAM,IAClD,OAAO;KACX,KAAK,yBAAyB;MAAE,MAAM;MAAQ,SAAS,OAAO;KAAI;KAClE,KAAK,0BAA0B;KAC/B,MAAM,QAAQ,IAAI;KAClB,MAAM,oBAAoB,yBAAyB,KAAK;KACxD,IAAI,mBAAmB;MACrB,KAAK,8BAA8B;MACnC,KAAK,uCAAuC,iBAAiB;KAC/D;KACA,IAAI,WAAW,OAAO,UAAU,SAAS,OAAO,UAAU,UACxD,gBAAgB;MAAE,GAAG;MAAK,OAAO;OAAE,GAAG;OAAO;MAAO;KAAE;IAE1D;GACF;GAEA,IACE,KAAK,uBAAuB,mBAAmB,QAC/C,KAAK,sBAAsB,eAC3B,KAAK,sBAAsB,WAAW,WACtC,CAAC,KAAK,wBACN,IAAI,SAAS,UAAU,oBACvB;IACA,KAAK,uBAAuB;IAC5B,MAAM,YACJ,OAAO,IAAI,cAAc,YAAY,IAAI,cAAc,KACnD,IAAI,YACJ,kBAAkB;IACxB,KAAK,8BAA8B;IACnC,MAAM,aAA0B;KAC9B,MAAM,UAAU;KAChB,MAAM;KACN,OAAO,EAAE,UAAU;KACnB,WAAW,KAAK,IAAI;IACtB;IACA,MAAM,eAAe,MAAM,KAAK,iBAAiB,WAC/C,KAAK,eACL,UACF;IACA,OAAO,KAAK,iBAAiB,YAAY;GAC3C;GAEA,MAAM,eAAe,MAAM,KAAK,iBAAiB,WAC/C,KAAK,eACL,aACF;GAQA,MAAM,yBACJ,CAAC,CAAC,KAAK,yBACP,KAAK,sBAAsB,eAC3B,KAAK,sBAAsB,mBAAmB;GAChD,KAAK,MAAM,eAAe,cACxB,KAAK,MAAM,QAAQ,qBACjB,WACF,GAAG;IACD,mBAAmB,IAAI;IACvB,IACE,2BACC,KAAK,SAAS,UAAU,eACvB,KAAK,SAAS,UAAU,eAE1B;IAEF,IAAI,KAAK,SAAS,UAAU,cAAc;KACxC,KAAK,+BAA+B,KAAK,IAAI;KAC7C;IACF;IACA,IAAI,KAAK,+BAA+B,IAAI,GAAG;KAC7C,KAAK,kCAAkC,KAAK,IAAI;KAChD;IACF;IACA,IAAI,KAAK,SAAS,UAAU,aAAa;KACvC,IAAI,KAAK,qBAAqB;KAC9B,KAAK,sBAAsB;IAC7B;IACA,KAAK,OAAO,OAAO,QAAQ,KAAK,QAAQ,EAAE,OAAO,KAAK,CAAC;IACvD,MAAM;IACN,KAAK,cAAc;GACrB;GAGF,IAAI,IAAI,SAAS,UAAU,cACzB,MAAM,KAAK,oBAAoB,GAAG;GAIpC,OAAO,KAAK,sBAAsB;GAClC,OAAO,KAAK,2BAA2B;GAEvC,IAAI,KAAK,kBACP;EAEJ;EAGA,OAAO,KAAK,sBAAsB;EAClC,OAAO,KAAK,2BAA2B;CACzC;CAEA,kBAA0B,OAAgC;EAExD,QAAQ,MAAM,MAAd;GAEE,KAAK;IACH,IAAI,OAAO,MAAM,cAAc,YAAY,MAAM,cAAc,IAC7D,KAAK,6BAA6B,MAAM,SAAS;IAEnD;GACF,KAAK;IACH,KAAK,8BAA8B,KAAK;IACxC;GACF,KAAK;IACH,KAAK,yBAAyB,KAAK;IACnC;GACF,KAAK;IACH,KAAK,wBAAwB,KAAK;IAClC;GACF,KAAK;IACH,KAAK,uBAAuB,KAAK;IACjC;GACF,KAAK;IACH,KAAK,0BAA0B,KAAK;IACpC;GACF,KAAK;IACH,KAAK,uBAAuB,KAAK;IACjC;GACF,KAAK;IACH,KAAK,oBAAoB,KAAK;IAC9B;GACF,KAAK;IACH,KAAK,uBAAuB;IAC5B;GACF,KAAK;IACH,KAAK,wBAAwB,KAAK;IAClC;GAEF,KAAK;IACH,KAAK,mCAAmC,KAAK;IAC7C;GAEF,KAAK,6BACH,KAAK,mCAAmC,KAAK;EAcjD;CACF;CAMA,8BAAsC,OAAsC;EAC1E,MAAM,QAAQ;EAId,IAAI,OAAO,MAAM,YAAY,YAAY,MAAM,YAAY,IACzD,KAAK,qBAAqB,MAAM;OAEhC,KAAK,sBAAsB,MAAM;EAEnC,KAAK,cAAc,qBAAqB,KAAK;CAC/C;CAEA,6BAAqC,WAAyB;EAC5D,KAAK,mBAAmB;EACxB,KAAK,cAAc,mBAAmB;EACtC,IAAI,CAAC,KAAK,wBAAwB;GAChC,KAAK,0CAA0B,IAAI,KAAK;GACxC,KAAK,yBAAyB;EAChC;CACF;CAEA,uCAA+C,WAAyB;EACtE,KAAK,4BAA4B;EACjC,KAAK,qDAAqC,IAAI,KAAK;CACrD;CAEA,yBAAiC,OAAiC;EAChE,IACE,OAAO,MAAM,oBAAoB,YACjC,MAAM,oBAAoB,IAE1B,KAAK,6BAA6B,MAAM,eAAe;EAEzD,KAAK,gBAAgB,sBAAsB,KAAK;EAChD,MAAM,WAAW,MAAM;EACvB,MAAM,mBACJ,YAAY,QACZ,OAAO,aAAa,YACpB,sBAAsB,YACtB,OAAO,SAAS,qBAAqB,YACrC,SAAS,qBAAqB,KAC1B,SAAS,mBACT,KAAA;EACN,IAAI,qBAAqB,KAAA,GAAW;EACpC,MAAM,OAAO,KAAK,gBACf,aAAa,CAAC,CACd,MAAM,cAAc,UAAU,OAAO,MAAM,UAAU;EACxD,IAAI,CAAC,MAAM;EACX,KAAK,WAAW;GACd,GAAI,KAAK,YAAY,QAAQ,OAAO,KAAK,aAAa,WAClD,KAAK,WACL,CAAC;GACL;EACF;CACF;CAEA,wBAAgC,OAAgC;EAC9D,KAAK,gBAAgB,qBAAqB,KAAK;CACjD;CAEA,uBAA+B,OAA+B;EAC5D,KAAK,gBAAgB,iBAAiB,KAAK;EAC3C,MAAM,MAAM;EAEZ,KADc,IAAI,SAAS,iBAAiB,GAAG,CAAC,EAAE,WACpC,kBAAkB,IAAI,WAAW,KAAA,GAAW;EAC1D,KAAK,0BAA0B;GAC7B,MAAM,UAAU;GAChB,YAAY,MAAM;GAClB,SAAS,MAAM,QAAQ,IAAI,MAAM,IAC7B,KAAK,UAAU,IAAI,MAAM,IACzB,IAAI;GACR,WAAW,MAAM;GACjB,UAAU,EAAE,UAAU,EAAE,OAAO,eAAe,EAAE;EAClD,CAAC;CACH;CAEA,0BAAkC,OAAkC;EAElE,IAAI,EADkB,iBAAiB,KAAK,CAAC,EAAE,UAAU,iBACrC;EAEpB,MAAM,WAAW,KAAK,gBACnB,aAAa,CAAC,CACd,MAAM,cAAc,UAAU,OAAO,MAAM,UAAU;EACxD,IAAI,CAAC,UAAU;EAEf,KAAK,yBAAyB,IAAI,MAAM,YAAY;GAClD,YAAY,MAAM;GAClB,UAAU,SAAS,SAAS;GAC5B,QAAQ,MAAM;GACd,OAAO;EACT,CAAC;CACH;CAEA,uBAA+B,OAAgC;EAC7D,KAAK,gBAAgB;EAErB,MAAM,MAAM,MAAI;EAChB,KAAK,mBACH,QAAQ,UACR,QAAQ,YACR,QAAQ,oBACR,QAAQ,gBACR,QAAQ,OACJ,MACC,iBAAiB,KAAK,CAAC,EAAE,gBAAgB;CAClD;CAEA,MAAc,oBACZ,OACe;EACf,MAAM,UAAU,kBACd,MAAM,OACN,iBAAiB,KAAK,CAAC,EAAE,KAC3B;EACA,IAAI,SACF,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe,OAAO;CAEtE;CAEA,oBACE,OACM;EACN,KAAK,mBAAmB;EACxB,IAAI,KAAK,sBAAsB,MAAM;GACnC,MAAM,UAAU,MAAM,WAAW;GACjC,KAAK,oBAAoB;IACvB;IACA,GAAI,MAAM,SAAS,KAAA,IAAY,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;GACzD;EACF;CACF;CAEA,8BAA4C;EAC1C,IAAI,KAAK,0BAA0B,KAAK,0BAA0B;GAChE,KAAK,oBAAoB,KAAK;IAC5B,SAAS,KAAK;IACd,GAAI,KAAK,4BAA4B,EACnC,WAAW,KAAK,yBAClB;GACF,CAAC;GACD,KAAK,yBAAyB;GAC9B,KAAK,2BAA2B;EAClC;CACF;CAEA,yBAAuC;EACrC,KAAK,4BAA4B;CACnC;CAEA,wBAAgC,OAAgC;EAC9D,IAAI,OAAO,MAAM,cAAc,YAAY,MAAM,cAAc,IAC7D,KAAK,2BAA2B,MAAM;CAE1C;CAEA,mCACE,OACM;EACN,KAAK,0BAA0B,MAAM;CACvC;CAEA,mCACE,OACM;EACN,IAAI,MAAM,YAAY,aAAa;GACjC,MAAM,OAAO,KAAK,SACf,SAAS,YAAY,QAAQ,aAAa,CAAC,CAAC,CAAC,CAC7C,MAAM,aAAa,SAAS,OAAO,MAAM,QAAQ;GACpD,IAAI,MACF,KAAK,WAAW;IACd,GAAI,KAAK,YAAY,QAAQ,OAAO,KAAK,aAAa,WAClD,KAAK,WACL,CAAC;IACL,kBAAkB,MAAM;GAC1B;GAEF;EACF;EACA,KAAK,2BAA2B,MAAM;CACxC;;;;;;;;;CAUA,uBACE,WACwB;EACxB,OAAO,KAAK,gBAAgB,mBAC1B,KAAK,OACL,UAAU,KAAK,OAAO,GAAG,SAAS,IAAI,CACxC;CACF;CAEA,OAAe,2BAIb;EACA,MAAM,mBAAmB,KAAK,gCAAgC;EAC9D,IAAI,iBAAiB,WAAW,GAC9B,OAAO;EAGT,MAAM,cAAc,KAAK,6BAA6B;EAItD,KAAK,gBAAgB,gBAAgB;EAGrC,MAAM,0BAA6C,CAAC;EACpD,MAAM,yBAAyB,iBAAiB,QAAQ,OAAO;GAC7D,IAAI,KAAK,gBAAgB,uBAAuB,GAAG,SAAS,IAAI,GAAG;IACjE,wBAAwB,KAAK;KAC3B,YAAY,GAAG;KACf,UAAU,GAAG,SAAS;KACtB,QAAQ,EACN,OAAO,KAAK,gBAAgB,yBAC1B,GAAG,SAAS,IACd,EACF;KACA,OAAO;IACT,CAAC;IACD,OAAO;GACT;GACA,OAAO;EACT,CAAC;EAKD,MAAM,uBAAuB,CAAC,GAAG,uBAAuB;EAIxD,MAAM,0BAAU,IAAI,IAAoB;EACxC,KAAK,MAAM,MAAM,kBACf,QAAQ,IAAI,GAAG,IAAI,GAAG,SAAS,SAAS;EAG1C,IAAI,uBAAuB,WAAW,GAAG;GACvC,IAAI,qBAAqB,SAAS,GAChC,KAAK,MAAM,SAAS,KAAK,sBACvB,sBACA,aACA,OACF,GACE,OAAO,KAAK,sBAAsB,KAAK;GAG3C,OAAO;EACT;EAEA,KAAK,cAAc,QAAQ;EAC3B,IACE,OAAO,KAAK,uBACV,eACA,aACA,sBACF,GACA;GACA,KAAK,aAAa,MAAM;GACxB,OAAO;EACT;EAEA,MAAM,EAAE,WAAW,sBAAsB,KAAK,mBAAmB;EAEjE,MAAM,YAAY,iBAChB,wBACA,KAAK,uBAAuB,sBAAsB,GAClD,WACA,oBACC,WAAW,SAAS,KAAK,uBAAuB,WAAW,IAAI,GAChE;GACE,kBAAkB,OAAO,UAAU,MAAM,SAAS;IAChD,KAAK,OAAO,MAAM,qBAAqB,SAAS,SAAS,QAAQ;KAC/D,MAAM,SAAS,SAAS;KACxB;IACF,CAAC;IACD,MAAM,UAAU;KACd;KACA;KACA;KACA,UAAU,SAAS,SAAS;KAC5B,YAAY,SAAS;IACvB;IACA,OAAO,KAAK,iBAAiB,oBAC3B,KAAK,eACL,OACF;GACF;GACA,iBAAiB,OAAO,SAAS;IAC/B,KAAK,OAAO,MAAM,oBAAoB,KAAK,YAAY;KACrD,MAAM,KAAK;KACX,QAAQ,KAAK;IACf,CAAC;IACD,MAAM,KAAK,iBAAiB,mBAC1B,KAAK,eACL,IACF;GACF;EACF,GACA,KAAK,cAAc,SACnB,KAAK,iBACL;GACE,mBAAmB,KAAK;GACxB,sBAAsB,KAAK;EAC7B,CACF;EAGA,MAAM,kBAAkB,OAAO,KAAK,uBAAuB,SAAS;EAGpE,IAAI,KAAK,oBAAoB,GAAG;GAC9B,KAAK,aAAa,MAAM;GACxB,OAAO;EACT;EAEA,MAAM,aAAa,CAAC,GAAG,gBAAgB,SAAS,GAAG,oBAAoB;EAGvE,OAAO,KAAK,iBACV,KAAK,iBAAiB,uBAAuB,KAAK,eAAe;GAC/D,WAAW;GACX,SAAS;GACT,eAAe,gBAAgB;GAC/B,sBAAsB,gBAAgB;EACxC,CAAC,CACH;EAEA,IACE,gBAAgB,cAAc,SAAS,KACvC,gBAAgB,qBAAqB,SAAS,GAC9C;GACA,KAAK,yCAAyC;GAE9C,IAAI,WAAW,SAAS,GACtB,KAAK,MAAM,SAAS,KAAK,sBACvB,YACA,WACF,GACE,OAAO,KAAK,sBAAsB,KAAK;GAI3C,MAAM,UAAU,OAAO,KAAK,gCAC1B,aACA,gBAAgB,eAChB,gBAAgB,oBAClB;GACA,KAAK,aAAa,UAAU,SAAS,MAAM;GAC3C,OAAO,UAAU,SAAS;EAC5B;EAEA,MAAM,mBAAmB,KAAK,sBAAsB,YAAY,WAAW;EAE3E,KAAK,MAAM,SAAS,kBAClB,OAAO,KAAK,sBAAsB,KAAK;EAGzC,OAAO;CACT;CAEA,OAAe,mBAA4D;EACzE,IAAI,CAAC,KAAK,uBAAuB,GAAG;GAElC,KAAK,wBAAwB;GAC7B,KAAK,aAAa,MAAM;GACxB;EACF;EAEA,MAAM,YAAY,KAAK,gBAAgB,aAAa;EACpD,MAAM,cAAc,KAAK;EAEzB,IAAI,CAAC,eAAe,UAAU,WAAW,GAAG;GAC1C,KAAK,wBAAwB;GAC7B,KAAK,aAAa,MAAM;GACxB;EACF;EAIA,KAAK,gBAAgB,SAAS;EAE9B,KAAK,4BAA4B,SAAS;EAG1C,MAAM,0BAA6C,CAAC;EACpD,MAAM,sBAAsB,UAAU,QAAQ,OAAO;GACnD,IAAI,KAAK,yBAAyB,IAAI,GAAG,EAAE,GACzC,OAAO;GAET,IAAI,KAAK,gBAAgB,uBAAuB,GAAG,SAAS,IAAI,GAAG;IACjE,wBAAwB,KAAK;KAC3B,YAAY,GAAG;KACf,UAAU,GAAG,SAAS;KACtB,QAAQ,EACN,OAAO,KAAK,gBAAgB,yBAC1B,GAAG,SAAS,IACd,EACF;KACA,OAAO;IACT,CAAC;IACD,OAAO;GACT;GACA,OAAO;EACT,CAAC;EAID,MAAM,uBAAuB,CAC3B,GAAG,KAAK,yBAAyB,OAAO,GACxC,GAAG,uBACL;EAEA,IAAI,oBAAoB,WAAW,GAAG;GACpC,OAAO,KAAK,uCAAuC;GAGnD,IAAI,qBAAqB,SAAS,GAChC,KAAK,MAAM,SAAS,KAAK,sBACvB,sBACA,WACF,GACE,OAAO,KAAK,sBAAsB,KAAK;GAG3C,KAAK,gBAAgB,MAAM;GAC3B,KAAK,aAAa,UAAU;GAC5B;EACF;EACA,KAAK,cAAc,QAAQ;EAE3B,IACE,OAAO,KAAK,uBACV,eACA,aACA,mBACF,GACA;GACA,KAAK,aAAa,MAAM;GACxB;EACF;EAEA,MAAM,EAAE,WAAW,sBAAsB,KAAK,mBAAmB;EAEjE,MAAM,YAAY,iBAChB,qBACA,KAAK,uBAAuB,mBAAmB,GAC/C,WACA,oBACC,WAAW,SAAS,KAAK,uBAAuB,WAAW,IAAI,GAChE;GACE,kBAAkB,OAAO,UAAU,MAAM,SAAS;IAChD,KAAK,OAAO,MAAM,qBAAqB,SAAS,SAAS,QAAQ;KAC/D,MAAM,SAAS,SAAS;KACxB;IACF,CAAC;IACD,MAAM,UAAU;KACd;KACA;KACA;KACA,UAAU,SAAS,SAAS;KAC5B,YAAY,SAAS;IACvB;IACA,OAAO,KAAK,iBAAiB,oBAC3B,KAAK,eACL,OACF;GACF;GACA,iBAAiB,OAAO,SAAS;IAC/B,KAAK,OAAO,MAAM,oBAAoB,KAAK,YAAY;KACrD,MAAM,KAAK;KACX,QAAQ,KAAK;IACf,CAAC;IACD,MAAM,KAAK,iBAAiB,mBAC1B,KAAK,eACL,IACF;GACF;EACF,GACA,KAAK,cAAc,SACnB,KAAK,iBACL;GACE,mBAAmB,KAAK;GACxB,sBAAsB,KAAK;EAC7B,CACF;EAGA,MAAM,kBAAkB,OAAO,KAAK,uBAAuB,SAAS;EAEpE,KAAK,cAAc,QAAQ;EAG3B,IAAI,KAAK,oBAAoB,GAAG;GAC9B,KAAK,aAAa,MAAM;GACxB;EACF;EAGA,MAAM,aAAa,CAAC,GAAG,gBAAgB,SAAS,GAAG,oBAAoB;EAGvE,OAAO,KAAK,iBACV,KAAK,iBAAiB,uBAAuB,KAAK,eAAe;GAC/D;GACA,SAAS;GACT,eAAe,gBAAgB;GAC/B,sBAAsB,gBAAgB;EACxC,CAAC,CACH;EAEA,MAAM,0BAA0B,KAAK,sBACnC,YACA,WACF;EACA,MAAM,oBAAoB,OAAO,KAAK,iBACpC,KAAK,iBAAiB,uBACpB,KAAK,aAGP,CACF;EACA,IAAI,kBAAkB,SAAS,GAAG;GAChC,KAAK,MAAM,SAAS,yBAClB,OAAO,KAAK,sBAAsB,KAAK;GAEzC,OAAO,KAAK,uBACV,cACA,aACA,WACA,iBACF;GACA,KAAK,aAAa,MAAM;GACxB;EACF;EAEA,IACE,gBAAgB,cAAc,SAAS,KACvC,gBAAgB,qBAAqB,SAAS,GAC9C;GACA,IAAI,WAAW,SAAS,GACtB,KAAK,MAAM,SAAS,yBAClB,OAAO,KAAK,sBAAsB,KAAK;GAI3C,MAAM,UAAU,OAAO,KAAK,gCAC1B,aACA,gBAAgB,eAChB,gBAAgB,oBAClB;GACA,KAAK,aAAa,UAAU,SAAS,MAAM;GAC3C;EACF;EAEA,OAAO,KAAK,uCAAuC;EAEnD,MAAM,mBAAmB;EAEzB,KAAK,MAAM,SAAS,kBAClB,OAAO,KAAK,sBAAsB,KAAK;EAIzC,IAAI,KAAK,gBAAgB,wBAAwB,GAAG;GAClD,KAAK,QAAQ,KAAK,gBAAgB,eAAe;GACjD,KAAK,kBAAkB,IAAI,gBAGzB,KAAK,KAAK;GACZ,KAAK,aAAa,UAAU;GAC5B;EACF;EAEA,KAAK,gBAAgB,MAAM;EAE3B,KAAK,aAAa,UAAU;CAC9B;CAEA,+BAAuC,OAA6B;EAClE,OACE,MAAM,SAAS,UAAU,gBACzB,KAAK,qBAAqB,gBAC1B,KAAK,MAAM,SAAS,KACpB,KAAK,gBAAgB,aAAa;CAEtC;CAEA,CAAS,yCAAiE;EACxE,KAAK,MAAM,SAAS,KAAK,mCAAmC;GAC1D,KAAK,OAAO,OAAO,QAAQ,MAAM,QAAQ,EAAE,MAAM,CAAC;GAClD,MAAM;GACN,KAAK,cAAc;EACrB;EACA,KAAK,oCAAoC,CAAC;CAC5C;CAEA,CAAS,sCAA8D;EACrE,KAAK,MAAM,SAAS,KAAK,gCAAgC;GACvD,KAAK,OAAO,OAAO,QAAQ,MAAM,QAAQ,EAAE,MAAM,CAAC;GAClD,MAAM;GACN,KAAK,cAAc;EACrB;EACA,KAAK,iCAAiC,CAAC;CACzC;CAEA,OAAe,wBACb,aACyC;EACzC,IAAI,KAAK,qBAAqB;EAC9B,OAAO,KAAK,sBAAsB;GAChC,MAAM,UAAU;GAChB,OAAO,YAAY;GACnB,UAAU,YAAY;GACtB,WAAW,KAAK,IAAI;EACtB,CAAC;CACH;CAEA,OAAe,iCAIb;EAGA,KAAK,mBAAmB;EACxB,MAAM,cAAc,KAAK,6BAA6B,MAAM;EAC5D,OAAO,KAAK,wBAAwB,WAAW;EAC/C,OAAO,KAAK,sBAAsB;GAChC,GAAG;GACH,WAAW,KAAK,IAAI;GACpB,SAAS,EAAE,MAAM,UAAU;EAC7B,CAAC;CACH;CAEA,2CAAyD;EACvD,KAAK,oCAAoC,CAAC;CAC5C;CAEA,yBAA0C;EACxC,OACE,KAAK,qBAAqB,gBAC1B,KAAK,MAAM,SAAS,KACpB,KAAK,gBAAgB,aAAa;CAEtC;CAEA,4BAAoC,WAAkC;EACpE,KAAK,4BAA4B;EAEjC,KAAK,WAAW,CACd,GAAG,KAAK,UACR;GACE,MAAM;GACN,SAAS,KAAK,sBAAsB;GACpC;GACA,IAAI,KAAK,oBAAoB,KAAA;GAC7B,WAAW,KAAK,2BAA2B,KAAA;GAC3C,GAAI,KAAK,oBAAoB,SAAS,KAAK,EACzC,UAAU,KAAK,oBACjB;EACF,CACF;EACA,KAAK,cAAc,WAAW,KAAK;CACrC;CAEA,+BAA6C;EAC3C,KAAK,4BAA4B;EAEjC,MAAM,mBAAmB,KAAK;EAC9B,MAAM,MAAM,mBACR,iBAAiB,WAAW,kBAAkB,iBAAiB,IAAI,IACnE;EACJ,MAAM,mBAAqD,mBACvD;GACE,MAAM;GACN,QAAQ;GACR,MAAM,iBAAiB;GACvB,SAAS,iBAAiB;GAC1B;GACA,GAAI,iBAAiB,cAAc,KAAA,IAC/B,EAAE,WAAW,iBAAiB,UAAU,IACxC,CAAC;EACP,IACA,KAAA;EACJ,MAAM,iBAAiB,KAAK,uBAAuB,mBAAmB;EACtE,MAAM,eAAe,KAAK,uBAAuB,WAAW;EAC5D,MAAM,eACJ,KAAK,6BACL,KAAK,+BACL,KAAK,oBACL,KAAK,SAAS,KAAK;EAIrB,MAAM,yBACJ,QAAQ,gBAAgB,MACvB,CAAC,kBAAkB,iBACpB,KAAK,oBAAoB,QACzB,iBAAiB,KAAK;EACxB,MAAM,WAAW,CAAC,GAAG,KAAK,cAAc,QAAQ;EAChD,MAAM,0BAA0B,SAAS,WACtC,YAAY,QAAQ,SAAS,eAAe,QAAQ,OAAO,YAC9D;EACA,MAAM,6BAA6B,SAAS,MACzC,YACC,QAAQ,SAAS,eAAe,QAAQ,OAAO,KAAK,gBACxD;EACA,MAAM,WACJ,KAAK,oBAAoB,SAAS,IAAI,KAAK,sBAAsB,KAAA;EACnE,MAAM,gBAAgB,SAAS;EAE/B,IAAI,oBAAoB,2BAA2B,GAAG;GACpD,MAAM,WAAW,SAAS;GAC1B,IAAI,UACF,SAAS,2BAA2B;IAClC,GAAG;IACH,SAAS,OAAO,SAAS;IACzB;GACF;EAEJ,OAAO,IAAI,oBAAoB,CAAC,wBAC1B;OAAA,CAAC,4BACH,SAAS,KAAK;IACZ,MAAM;IACN,SAAS,KAAK,sBAAsB,OAAO;IAC3C,IAAI;IACJ,WACE,KAAK,2BACL,KAAK,oDACL,IAAI,KAAK;IACX;IACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;GACjC,CAAC;EAAA,OAEE;GACL,IACE,CAAC,+BACA,KAAK,uBAAuB,MAAM,WAEnC,SAAS,KAAK;IACZ,MAAM;IACN,SAAS,KAAK,sBAAsB;IACpC,IAAI,KAAK,oBAAoB,KAAK,SAAS,KAAK;IAChD,WAAW,KAAK,2CAA2B,IAAI,KAAK;IACpD,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;GACjC,CAAC;GAEH,IAAI,kBACF,SAAS,KAAK;IACZ,MAAM;IACN,SAAS,OAAO;IAChB,IAAI;IACJ,WAAW,KAAK,oDAAoC,IAAI,KAAK;IAC7D;GACF,CAAC;EAEL;EAEA,IAAI,SAAS,WAAW,iBAAiB,0BAA0B,GACjE;EAGF,KAAK,WAAW;EAChB,KAAK,cAAc,WAAW,KAAK;CACrC;;;;;;CAOA,uCACE,kBAIA;EACA,MAAM,4BAAY,IAAI,IAAoC;EAC1D,MAAM,oCAAoB,IAAI,IAAiB;EAE/C,KAAK,MAAM,WAAW,kBAEpB,IAAI,QAAQ,SAAS,eAAe,QAAQ,OACrC;QAAA,MAAM,QAAQ,QAAQ,OACzB,IAAI,KAAK,SAAS,aAAa;IAE7B,IAAI,KAAK,WAAW,KAAA,KAAa,CAAC,KAAK,UACrC,kBAAkB,IAAI,KAAK,IAAI,KAAK,MAAM;IAG5C,IACE,KAAK,UAAU,MACf,KAAK,UAAU,aAAa,KAAA,KAC5B,KAAK,UAAU,sBAEf,UAAU,IAAI,KAAK,SAAS,IAAI,KAAK,SAAS,QAAQ;GAE1D;;EAKN,OAAO;GAAE;GAAW;EAAkB;CACxC;CAEA,qBAGE;EAEA,MAAM,YAAY,IAAI,IAAI,KAAK,gBAAgB;EAC/C,MAAM,oBAAoB,IAAI,IAAI,KAAK,wBAAwB;EAC/D,KAAK,MAAM,CAAC,YAAY,aAAa,KAAK,iBACxC,UAAU,IAAI,YAAY,QAAQ;EAEpC,KAAK,MAAM,CAAC,YAAY,WAAW,KAAK,yBACtC,kBAAkB,IAAI,YAAY,MAAM;EAI1C,KAAK,MAAM,WAAW,KAAK,UAGzB,IAAI,QAAQ,SAAS,UAAU,QAAQ,YAAY;GAIjD,IAAI;GACJ,IAAI,MAAM,QAAQ,QAAQ,OAAO,GAC/B,SAAS,QAAQ;QAEjB,IAAI;IACF,SAAS,KAAK,MAAM,QAAQ,OAAiB;GAC/C,QAAQ;IACN,SAAS,QAAQ;GACnB;GAOF,IACE,UACA,OAAO,WAAW,YACjB,OAAe,qBAAqB,MAErC;GAEF,kBAAkB,IAAI,QAAQ,YAAY,MAAM;EAClD;EAGF,OAAO;GAAE;GAAW;EAAkB;CACxC;CAEA,qBAAqC;EACnC,OAAO,KAAK,SAAS,WAAW;CAClC;CAEA,0BACE,WACA,gBACA,kBAEI,CAAC,GACL,sBAA6C,CAAC,GAC5B;EAClB,MAAM,aAA+B,CAAC;EAEtC,KAAK,MAAM,YAAY,WAAW;GAChC,MAAM,OAAO,KAAK,MAAM,MACrB,cAAc,UAAU,SAAS,SAAS,QAC7C;GACA,MAAM,aAAa,wBACjB,MAAM,gBACN,MAAM,WACR;GACA,WAAW,KAAK;IACd,IAAI,SAAS;IAIb,QAAQ;IACR,SAAS,4BAA4B,SAAS;IAC9C,YAAY,SAAS;IACrB,gBAAgB,WAAW;IAC3B,UAAU;KACR,MAAM;KACN,UAAU,SAAS;KACnB,OAAO,SAAS;MACf,8BAA8B;MAC7B,GAAA;MACA,MAAM;MACN,aAAa,SAAS;MACtB,UAAU,SAAS;MACnB,YAAY,SAAS;MACrB,cAAc,SAAS;MACvB,iBAAiB,gBAAgB,MAAM,WAAW;MAClD,oBAAoB,WAAW;MAC/B,oBAAoB,WAAW;KACjC;IACF;GACF,CAAC;EACH;EAEA,KAAK,MAAM,cAAc,gBAAgB;GACvC,MAAM,OAAO,KAAK,MAAM,MACrB,cAAc,UAAU,SAAS,WAAW,QAC/C;GACA,MAAM,iBAAiB,0BAA0B,MAAM,YAAY,KAAK,CAAC;GACzE,WAAW,KAAK;IACd,IAAI,eAAe,WAAW;IAC9B,QAAQ;IACR,SAAS,eAAe,WAAW,SAAS;IAC5C,YAAY,WAAW;IACvB;IACA,UAAU;KACR,MAAM;KACN,UAAU,WAAW;KACrB,OAAO,WAAW;MACjB,8BAA8B;MAC7B,GAAA;MACA,MAAM;MACN,aAAa,eAAe,WAAW;MACvC,UAAU,WAAW;MACrB,YAAY,WAAW;MACvB,kBAAkB,gBAAgB,MAAM,YAAY;MACpD,oBAAoB,oBAClB,uBAAuB,cAAc,CACvC;KACF;IACF;GACF,CAAC;EACH;EAEA,KAAK,MAAM,CAAC,OAAO,YAAY,gBAAgB,QAAQ,GAAG;GACxD,MAAM,aAAa,WAAW;GAC9B,MAAM,KAAK,oBAAoB;GAC/B,IAAI,CAAC,IAAI,MAAM,IAAI,MAAM,sCAAsC;GAC/D,MAAM,cAAc,uBAAuB,SAAS,EAAE,WAAW,CAAC;GAClE,WAAW,KAAK;IACd;IACA,QAAQ,QAAQ;IAChB,SAAS,QAAQ;IACjB,GAAI,YAAY,WAAW,gCAAgC,KAAA,IACvD,EACE,gBAAgB,KAAK,MACnB,YAAY,WAAW,2BACzB,EACF,IACA,CAAC;IACL,GAAI,QAAQ,cAAc,KAAA,IACtB,EAAE,WAAW,QAAQ,UAAU,IAC/B,CAAC;IACL,UAAU;MACP,8BAA8B;MAC7B,GAAA;MACA,MAAM;MACN,aAAa;MACb,cAAc,YAAY,WAAW;MACrC,KAAK,YAAY,WAAW;MAC5B;MACA,GAAI,QAAQ,cAAc,KAAA,IACtB,EAAE,WAAW,QAAQ,UAAU,IAC/B,CAAC;MACL,GAAI,YAAY,WAAW,oBACvB,EACE,mBAAmB,YAAY,WAAW,kBAC5C,IACA,CAAC;MACL,GAAI,YAAY,WAAW,uBAAuB,KAAA,IAC9C,EACE,oBAAoB,YAAY,WAAW,mBAC7C,IACA,CAAC;KACP;KACA,GAAI,YAAY,YAAY,KAAA,IACxB,GAAG,iCAAiC,YAAY,QAAQ,IACxD,CAAC;IACP;GACF,CAAC;EACH;EAEA,MAAM,sBAAM,IAAI,IAAY;EAC5B,KAAK,MAAM,aAAa,YAAY;GAClC,IAAI,IAAI,IAAI,UAAU,EAAE,GACtB,MAAM,IAAI,MACR,0CAA0C,UAAU,IACtD;GAEF,IAAI,IAAI,UAAU,EAAE;EACtB;EAEA,OAAO;CACT;CAEA,4BACE,aACA,WACA,gBACA,kBAEI,CAAC,GACL,qBACa;EACb,OAAO;GACL,GAAG;GACH,WAAW,KAAK,IAAI;GACpB,SAAS;IACP,MAAM;IACN,YAAY,KAAK,0BACf,WACA,gBACA,iBACA,mBACF;GACF;EACF;CACF;;;;;;;;CASA,wBAAgC,OAAsB;EACpD,MAAM,OAAO,8BAA8B,KAAK;EAChD,IAAI,CAAC,MAAM;EACX,MAAM,OAAO,gCAAgC,KAAK,UAAU,IAAI;EAChE,IAAI,SAAS,KAAK,UAAU;EAC5B,KAAK,WAAW;EAChB,KAAK,cAAc,WAAW,KAAK;CACrC;CAEA,6BAAkD;EAChD,MAAM,UAAU,KAAK,SAAS,KAAK,SAAS,WAAW;GACrD,GAAG;GACH,IACE,QAAQ,MACR,YAAY,KAAK,iBAAiB,KAAK,UAAU,GAAG;EACxD,EAAE;EACF,OAAO;GACL,MAAM,UAAU;GAChB,WAAW,KAAK,IAAI;GACpB,UAAU,iBAAiB,0BAA0B,OAAO,GAAG,EAC7D,iCAAiC,KACnC,CAAC;EACH;CACF;CAEA,wBAAgC,OAAiC;EAC/D,IACE,MAAM,SAAS,UAAU,gBACzB,MAAM,SAAS,SAAS,aAExB,OAAO;EAET,OAAO;GACL,GAAG;GACH,SAAS;IACP,GAAG,MAAM;IACT,YAAY,MAAM,QAAQ,WAAW,KAAK,cAAc;KACtD,IACE,CAAC,UAAU,YACX,OAAO,UAAU,aAAa,YAC9B,MAAM,QAAQ,UAAU,QAAQ,GAEhC,OAAO;KAET,MAAM,WAAW,EAAE,GAAG,UAAU,SAAS;KACzC,MAAM,UAAU,gCACd,SAAS,8BACT,UAAU,EACZ;KACA,IAAI,SACF,SAAS,+BAA+B;UAExC,OAAO,SAAS;KAElB,OAAO;MAAE,GAAG;MAAW;KAAS;IAClC,CAAC;GACH;EACF;CACF;CAEA,iBAAyB,OAIvB;EACA,MAAM,aAAa,2BAA2B,KAAK;EACnD,IAAI,YACF,OAAO;GACL,SAAS,WAAW,MAAM;GAC1B,MAAM,WAAW,OAAO,EAAE,EAAE,QAAQ;GACpC,QAAQ,WAAW;EACrB;EAEF,IAAI,SAAS,OAAO,UAAU,YAAY,YAAY,OAAO;GAC3D,MAAM,SAAS,MAAM;GACrB,IAAI,MAAM,QAAQ,MAAM,GAAG;IACzB,MAAM,QAAQ,OAAO;IACrB,IAAI,SAAS,OAAO,UAAU,UAS5B,OAAO;KAAE,SAPP,aAAa,SAAS,OAAO,MAAM,YAAY,WAC3C,MAAM,UACN;KAKY,MAHhB,UAAU,SAAS,OAAO,MAAM,SAAS,WACrC,MAAM,OACN;IACiB;GAE3B;EACF;EACA,OAAO;GACL,SACE,iBAAiB,QACb,MAAM,UACN;GACN,MAAM;EACR;CACF;CAEA,4BAAoC,OAA6B;EAC/D,MAAM,UAAU,KAAK,iBAAiB,KAAK;EAC3C,OAAO,qBACL;GACE,MAAM,UAAU;GAChB,WAAW,KAAK,IAAI;GACpB,SAAS,QAAQ;GACjB,MAAM,QAAQ;EAChB,GACA;GACE,OAAO,KAAK,iBAAiB,KAAK;GAClC,UAAU,KAAK;GACf,GAAI,QAAQ,WAAW,KAAA,IACnB,EAAE,iBAAiB,QAAQ,OAAO,IAClC,CAAC;EACP,CACF;CACF;CAEA,OAAe,sBACb,OACyC;EACzC,MAAM,UAAU,KAAK,iBAAiB,KAAK;EAC3C,KAAK,oBAAoB;GACvB,SAAS,QAAQ;GACjB,MAAM,QAAQ;GACd,OAAO;EACT;EACA,OAAO,KAAK,sBAAsB,KAAK,4BAA4B,KAAK,CAAC;CAC3E;CAEA,OAAe,gCACb,aACA,WACA,gBACA,kBAEI,CAAC,GACuC;EAC5C,OAAO,KAAK,wBAAwB,WAAW;EAC/C,MAAM,sBAAsB,gBAAgB,UAC1C,KAAK,mBAAmB,CAC1B;EACA,MAAM,WAAW,KAAK,mCACpB,KAAK,4BACH,aACA,WACA,gBACA,iBACA,mBACF,CACF;EACA,IAAI;EACJ,IAAI;GACF,kBAAkB,CAChB,GAAG,KAAK,iBACN,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe,QAAQ,CACrE,CACF;EACF,SAAS,OAAO;GACd,OAAO,KAAK,sBAAsB,KAAK;GACvC,OAAO;EACT;EAEA,OAAO,KAAK,sBAAsB,KAAK,2BAA2B,CAAC;EACnE,IAAI,KAAK,OAAO,UAAU,KAAA,GACxB,OAAO,KAAK,sBAAsB;GAChC,MAAM,UAAU;GAChB,WAAW,KAAK,IAAI;GACpB,UAAU,KAAK,OAAO;EACxB,CAAC;EAEH,KAAK,MAAM,UAAU,iBACnB,MAAM,KAAK,wBAAwB,MAAM;EAE3C,OAAO;CACT;CAEA,OAAe,uBACb,OACA,aACA,YAAqC,CAAC,GACtC,UAG4C;EAC5C,KAAK,cAAc,QAAQ;EAC3B,MAAM,mBACJ,aACC,OAAO,KAAK,iBACX,KAAK,iBAAiB,uBACpB,KAAK,aAGP,CACF;EACF,IAAI,iBAAiB,WAAW,GAAG,OAAO;EAC1C,KAAK,MAAM,WAAW,kBACpB,IACE,KAAK,qBAAqB,IAAI,QAAQ,WAAW,EAAE,MACnD,QAAQ,YAER,MAAM,IAAI,MACR,gCAAgC,QAAQ,WAAW,GAAG,iCACxD;EAGJ,IAAI,UAAU,cAAc;GAC1B,IAAI,KAAK,gBAAgB,aAAa,GACpC,KAAK,4BAA4B,KAAK,gBAAgB,aAAa,CAAC;QAEpE,KAAK,oCAAoC;EAE7C;EACA,MAAM,aAAa,KAAK,kCAAkC,SAAS;EACnE,OAAO,KAAK,gCACV,aACA,WAAW,WACX,WAAW,gBACX,gBACF;EACA,OAAO;CACT;CAEA,sCAAoD;EAClD,IAAI,KAAK,mBAAmB,WAAW,GAAG;EAC1C,KAAK,WAAW,CACd,GAAG,KAAK,UACR;GAAE,MAAM;GAAa,SAAS,KAAK;EAAmB,CACxD;EACA,KAAK,cAAc,WAAW,KAAK;CACrC;CAEA,kCACE,WAIA;EACA,MAAM,EAAE,WAAW,sBAAsB,KAAK,mBAAmB;EACjE,MAAM,mBAA2C,CAAC;EAClD,MAAM,iBAA2C,CAAC;EAClD,KAAK,MAAM,YAAY,WAAW;GAChC,MAAM,OAAO,KAAK,uBAAuB,CAAC,QAAQ,CAAC,CAAC,CAAC,MAClD,cAAc,UAAU,SAAS,SAAS,SAAS,IACtD;GACA,IAAI,CAAC,MAAM;GACX,IAAI,QAAiB,CAAC;GACtB,IAAI;IACF,MAAM,SAAS,KAAK,MAAM,SAAS,SAAS,UAAU,KAAK,KAAK,IAAI;IACpE,QAAQ,UAAU,OAAO,WAAW,WAAW,SAAS,CAAC;GAC3D,QAAQ;IACN,QAAQ,CAAC;GACX;GACA,MAAM,aAAa,YAAY,SAAS;GACxC,IAAI,KAAK,iBAAiB,CAAC,UAAU,IAAI,UAAU,GACjD,iBAAiB,KAAK;IACpB,YAAY,SAAS;IACrB,UAAU,SAAS,SAAS;IAC5B;IACA;GACF,CAAC;QACI,IACL,CAAC,KAAK,WACN,CAAC,kBAAkB,IAAI,SAAS,EAAE,KAClC,CAAC,KAAK,2BAA2B,IAAI,SAAS,EAAE,GAEhD,eAAe,KAAK;IAClB,YAAY,SAAS;IACrB,UAAU,SAAS,SAAS;IAC5B;GACF,CAAC;EAEL;EACA,OAAO;GAAE,WAAW;GAAkB;EAAe;CACvD;CAEA,mCAA2C,OAAiC;EAC1E,IACE,MAAM,SAAS,UAAU,gBACzB,MAAM,SAAS,SAAS,aAExB,OAAO;EAET,MAAM,mBAAmB,KAAK,iBAAiB,KAAK;EACpD,OAAO;GACL,GAAG;GACH,SAAS;IACP,GAAG,MAAM;IACT,YAAY,MAAM,QAAQ,WAAW,KAAK,cAAc;KACtD,IACE,CAAC,UAAU,YACX,OAAO,UAAU,aAAa,YAC9B,MAAM,QAAQ,UAAU,QAAQ,GAEhC,OAAO;KAET,MAAM,WAAW,EAAE,GAAG,UAAU,SAAS;KACzC,MAAM,WAAW,SAAS;KAC1B,IACE,aAAa,QACb,OAAO,aAAa,YACpB,MAAM,QAAQ,QAAQ,GAEtB,OAAO;KAET,SAAS,+BAA+B;MACtC,GAAG;MACH;MACA,YAAY;KACd;KACA,OAAO;MAAE,GAAG;MAAW;KAAS;IAClC,CAAC;GACH;EACF;CACF;CAEA,sBACE,SACA,cACA,SAC0B;EAC1B,MAAM,SAAmC,CAAC;EAE1C,KAAK,MAAM,UAAU,SAAS;GAM5B,MAAM,UAAU,oBAAoB,OAAO,MAAM;GACjD,MAAM,cACJ,OAAO,YAAY,WAAW,UAAU,KAAK,UAAU,OAAO;GAKhE,IAAI,SAAS;IACX,OAAO,KAAK;KACV,MAAM,UAAU;KAChB,WAAW,KAAK,IAAI;KACpB,YAAY,OAAO;KACnB,cAAc,OAAO;KACrB,UAAU,OAAO;IACnB,CAAC;IAED,MAAM,OAAO,QAAQ,IAAI,OAAO,UAAU,KAAK;IAC/C,OAAO,KAAK;KACV,MAAM,UAAU;KAChB,WAAW,KAAK,IAAI;KACpB,YAAY,OAAO;KACnB,OAAO;IACT,CAAC;IAED,OAAO,KAAK;KACV,MAAM,UAAU;KAChB,WAAW,KAAK,IAAI;KACpB,YAAY,OAAO;IACrB,CAAC;GACH;GAEA,MAAM,kBAAkB,CAAC,GAAG,KAAK,QAAQ,CAAC,CACvC,QAAQ,CAAC,CACT,MAAM,YAAY,QAAQ,SAAS,WAAW,CAAC,EAAE;GACpD,MAAM,cAAc;IAClB,MAAM,UAAU;IAChB,WAAW,KAAK,IAAI;IACpB,WAAW,mBAAmB,OAAO;IACrC,YAAY,OAAO;IACnB,SAAS;IACT,MAAM;GACR;GACA,OAAO,KACJ,OAAO,UAAU,iBACd,qBAAqB,aAAa,EAAE,OAAO,OAAO,MAAM,CAAC,IACzD,WACN;GAQA,MAAM,iBAAiB,KAAK,SAAS,WAAW,MAAM;IACpD,IAAI,EAAE,SAAS,UAAU,EAAE,eAAe,OAAO,YAC/C,OAAO;IAET,IAAI,OAAO,EAAE,YAAY,UAAU,OAAO;IAC1C,IAAI;KACF,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC,EAAE,qBAAqB;IACrD,QAAQ;KACN,OAAO;IACT;GACF,CAAC;GAED,MAAM,iBAA+B;IACnC,MAAM;IACN;IACA,YAAY,OAAO;GACrB;GAEA,IAAI,kBAAkB,GACpB,KAAK,WAAW;IACd,GAAG,KAAK,SAAS,MAAM,GAAG,cAAc;IACxC;IACA,GAAG,KAAK,SAAS,MAAM,iBAAiB,CAAC;GAC3C;QAEA,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,cAAc;GAEnD,KAAK,cAAc,WAAW,KAAK;EACrC;EAEA,OAAO;CACT;CAEA,kCAA2D;EAGzD,MAAM,mCAAmB,IAAI,IAAY;EAEzC,KAAK,MAAM,WAAW,KAAK,UACzB,IAAI,QAAQ,SAAS,UAAU,QAAQ,YAAY;GAEjD,IAAI,sBAAsB;GAC1B,IAAI,OAAO,QAAQ,YAAY,UAC7B,IAAI;IAEF,IADe,KAAK,MAAM,QAAQ,OAC9B,CAAA,CAAO,qBAAqB,MAC9B,sBAAsB;GAE1B,QAAQ,CAER;GAIF,IAAI,CAAC,qBACH,iBAAiB,IAAI,QAAQ,UAAU;EAE3C;EAGF,MAAM,UAA2B,CAAC;EAElC,KAAK,MAAM,WAAW,KAAK,UACzB,IAAI,QAAQ,SAAS,eAAe,QAAQ,WAC1C,KAAK,MAAM,YAAY,QAAQ,WAAW;GAKxC,IAAI,2BAA2B,QAAQ,GACrC;GAEF,IAAI,CAAC,iBAAiB,IAAI,SAAS,EAAE,GACnC,QAAQ,KAAK,QAAQ;EAEzB;EAIJ,OAAO;CACT;;;;;CAMA,uBAA+B,YAA0C;EACvE,KAAK,MAAM,WAAW,KAAK,UAAU;GACnC,IAAI,QAAQ,SAAS,eAAe,CAAC,QAAQ,WAAW;GACxD,KAAK,MAAM,YAAY,QAAQ,WAC7B,IAAI,SAAS,OAAO,YAAY,OAAO;EAE3C;CAEF;;;;;;;CAQA,+BACE,QACiB;EACjB,MAAM,UAAU,KAAK,gCAAgC;EACrD,MAAM,OAAO,IAAI,IAAI,QAAQ,KAAK,aAAa,CAAC,SAAS,IAAI,QAAQ,CAAC,CAAC;EACvE,KAAK,MAAM,SAAS,UAAU,CAAC,GAAG;GAOhC,IAAI;GACJ,IAAI,MAAM,YAAY,WAAW,cAAc,GAC7C,aAAa,MAAM,YAAY,MAAM,EAAqB;QACrD,IAAI,MAAM,YAAY,WAAW,WAAW,GACjD,aAAa,MAAM,YAAY,MAAM,CAAkB;GAEzD,IAAI,eAAe,KAAA,KAAa,KAAK,IAAI,UAAU,GAAG;GACtD,MAAM,WAAW,KAAK,uBAAuB,UAAU;GACvD,IAAI,YAAY,CAAC,2BAA2B,QAAQ,GAAG;IACrD,QAAQ,KAAK,QAAQ;IACrB,KAAK,IAAI,YAAY,QAAQ;GAC/B;EACF;EACA,OAAO;CACT;CAEA,6BACE,eAAsC,cACpB;EAClB,OAAO,qBACL;GACE,MAAM,UAAU;GAChB,OAAO,KAAK,iBAAiB,KAAK;GAClC,UAAU,KAAK;GACf,WAAW,KAAK,IAAI;EACtB,GACA;GAAE;GAAc,OAAO,KAAK,OAAO;EAAM,CAC3C;CACF;CAEA,MAAc,iBAAmC;EAE/C,IAAI,KAAK,eAAe,oBACtB,OAAO;EAGT,MAAM,QAAQ;GACZ,gBAAgB,KAAK;GACrB,UAAU,KAAK;GACf,cAAc,KAAK;GACnB,eAAe,KAAK;GACpB,uBAAuB,KAAK;EAC9B;EAKA,MAAM,oBAAoB,KAAK,aAAa,KAAK;EACjD,MAAM,sBAAsB,MAAM,KAAK,iBAAiB,oBACtD,KAAK,eACL,KACF;EAEA,OACE,qBAAqB,uBAAuB,KAAK,cAAc;CAEnE;;;;;;;;;;CAWA,gBAAwB,WAAkC;EACxD,KAAK,wBAAwB,UAAU;EACvC,IAAI,eAAe;EACnB,KAAK,MAAM,MAAM,WACf,IAAI,CAAC,KAAK,mBAAmB,IAAI,GAAG,EAAE,GAAG;GACvC,KAAK,mBAAmB,IAAI,GAAG,EAAE;GACjC;EACF;EAEF,KAAK,iBAAiB;CACxB;CAEA,YAA6B;EAC3B,OAAO,CAAC,CAAC,KAAK,iBAAiB;CACjC;CAEA,sBAAuC;EACrC,OAAO,CAAC,CAAC,KAAK,2BAA2B,OAAO;CAClD;CAEA,cAA+B;EAC7B,OAAO,KAAK,UAAU,KAAK,KAAK,oBAAoB;CACtD;;;;;;;;;;;;CAaA,qBAAiD;EAC/C,IAAI,KAAK,gBAAgB,KAAA,GAAW,OAAO,KAAK;EAChD,MAAM,eAAwB,KAAK,iBAAiB;EACpD,OAAO,OAAO,iBAAiB,WAAW,eAAe,KAAA;CAC3D;;;;;;;;;;;;;;CAeA,cAAuB;EACrB,OAAO,eAAe,KAAK,eAAe,EAAE,UAAU,KAAK,CAAC,MAAM;CACpE;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4BA,qBAA2B;EACzB,IAAI,KAAK,gBAAgB,KAAK,oBAAoB;EAClD,KAAK,eAAe;EACpB,KAAK,MAAM,YAAY,KAAK,qBAC1B,KAAK,sBAAsB,QAAQ;CAEvC;;;;;;;;;;;CAYA,sBAA8B,UAA4C;EACxE,IAAI;EACJ,IAAI;GACF,SAAS,SAAS;EACpB,SAAS,OAAO;GACd,KAAK,OAAO,OAAO,kCAAkC,EAAE,MAAM,CAAC;GAC9D;EACF;EACA,IAAI,WAAW,KAAA,GAAW;EAC1B,KAAK,iBAAiB,KACpB,OAAO,OAAO,UAAmB;GAC/B,KAAK,OAAO,OAAO,kCAAkC,EAAE,MAAM,CAAC;EAChE,CAAC,CACH;CACF;;;;;;;;;;CAWA,OAAe,4BAAyD;EACtE,IAAI,CAAC,KAAK,uBACR,MAAM,IAAI,MACR,uEACF;EAGF,KAAK,cAAc,QAAQ;EAK3B,MAAM,aAAa,KAAK,sBAAsB;EAC9C,MAAM,EAAE,OAAO,YAAY,GAAG,qBAAqB;EACnD,IAAI,mBAAqD;GACvD,GAAG;GACH,cAAc,KAAK,sBAAsB;EAC3C;EAGA,mBAAmB,OAAO,KAAK,iBAC7B,KAAK,iBAAiB,4BACpB,KAAK,eACL,gBACF,CACF;EAOA,MAAM,EAAE,cAAc,cAAc,GAAG,oBAAoB;EAC3D,MAAM,eAAe,OAAO,KAAK,iBAC/B,KAAK,iBAAiB,YAAY,KAAK,eAAe;GACpD,GAAG;GACH,OAAO,WAAW;EACpB,CAAC,CACH;EAGA,KAAK,sBAAsB,YAAY;EAKvC,MAAM,wBAAwB;GAC5B,aAAa;IACX,OAAO,KAAK,OAAO;IACnB,UAAU,KAAK;IACf,UAAU,aAAa;IACvB,cAAc,aAAa;IAC3B,eAAe,aAAa;IAC5B,QAAQ,KAAK;IACb,UAAU,KAAK;IACf,OAAO,KAAK;IACZ,aAAa,KAAK;IAClB,GAAI,KAAK,mBAAmB,EAAE,SAAS,KAAK,iBAAiB,IAAI,CAAC;GACpE;GACA,cAAc;EAChB;EAMA,IAAI,uBAAgC,KAAA;EACpC,MAAM,iBAAiB,KAAK,QAAQ,yBAChC,KAAK,QAAQ,uBAAuB,qBAAqB,IACzD,+BACE,KAAK,SACL,wBACC,QAAQ;GACP,uBAAuB;EACzB,CACF;EAeJ,IAAI,eAAe;EACnB,IAAI,sBAAqC;EAEzC,MAAM,oBAAoB,MAAkC;GAC1D,IACE,EAAE,SAAS,UAAU,sBACrB,EAAE,SAAS,UAAU,wBACrB,EAAE,SAAS,UAAU,kBAErB,OAAO,OAAO,EAAE,cAAc,YAAY,EAAE,cAAc,KACtD,EAAE,YACF;GAEN,OAAO;EACT;EAIA,MAAM,yBAAyB,YAAY,KAAK,IAAI,MAAmB;GACrE,MAAM,aAAa,uBAAuB,kBAAkB;GAC5D,sBAAsB;GACtB,KAAK,uCAAuC,UAAU;GACtD,OAAO;IACL,MAAM,UAAU;IAChB,MAAM;IACN,OAAO,EAAE,WAAW,WAAW;IAC/B;GACF;EACF;EAEA,MAAM,sBACJ,eAEA,KAAK,iBAAiB,WAAW,KAAK,eAAe,UAAU;EAIjE,IAAI,kBAAkB;EAGtB,WAAW,MAAM,OAAO,gBAAgB;GAEtC,IAAI,KAAK,YAAY,GACnB;GAGF;IACE,MAAM,QAAQ;IAEd,IACE,CAAC,gBACD,MAAM,SAAS,UAAU,UACzB,MAAM,SAAS,2BAEf,eAAe;IAKjB,IAAI,CAAC,qBAAqB;KACxB,MAAM,YAAY,iBAAiB,KAAK;KACxC,IAAI,WAAW;MACb,sBAAsB;MACtB,KAAK,uCAAuC,SAAS;KACvD;IACF;IAKA,IAAI,KAAK,sBAAsB,aAAa;KAE1C,IACE,CAAC,iBACA,MAAM,SAAS,UAAU,sBACxB,MAAM,SAAS,UAAU,wBACzB,MAAM,SAAS,UAAU,mBAC3B;MACA,eAAe;MACf,MAAM,aAAa,sBAAsB,MAAM,SAAS;MACxD,OAAO,KAAK,iBAAiB,MAAM,mBAAmB,UAAU,CAAC;KACnE;KAKA,IAAI,CAAC,gBAAgB,MAAM,SAAS,UAAU,WAAW;MACvD,eAAe;MACf,MAAM,aAAa,sBAAsB,MAAM,SAAS;MACxD,OAAO,KAAK,iBAAiB,MAAM,mBAAmB,UAAU,CAAC;KACnE;IACF;IAqBA,IAAI,gBAA6B;IAEjC,IACE,MAAM,SAAS,UAAU,UACzB,MAAM,SAAS,8BACf;KACA,MAAM,SAAS,kCAAkC,MAAM,KAAK;KAC5D,IAAI,QAAQ;MACV,MAAM,SAAS,KAAK,sBAAsB,YACtC,KAAK,sBAAsB,UAAU,OAAO,MAAM,IAClD,OAAO;MACX,KAAK,yBAAyB;OAC5B,MAAM;OACN,SAAS,OAAO;OAChB,GAAI,OAAO,cAAc,KAAA,IACrB,EAAE,WAAW,OAAO,UAAU,IAC9B,CAAC;MACP;MAKA,MAAM,QAAQ,MAAM;MACpB,IACE,WAAW,OAAO,UAClB,SACA,OAAO,UAAU,UAEjB,gBAAgB;OAAE,GAAG;OAAO,OAAO;QAAE,GAAG;QAAO;OAAO;MAAE;KAE5D;IACF;IAEA,IAAI,MAAM,SAAS,UAAU,cAC3B,MAAM,KAAK,oBAAoB,KAAK;IAGtC,IAAI,MAAM,SAAS,UAAU,WAE3B,KAAK,oBAAoB;KACvB,SAAS,MAAM;KACf,GAAI,MAAM,OAAO,EAAE,MAAM,MAAM,KAAK,IAAI,CAAC;KACzC,GAAI,yBAAyB,KAAA,IACzB,EAAE,OAAO,qBAAqB,IAC9B,CAAC;IACP;IAIF,MAAM,eAAe,MAAM,KAAK,iBAAiB,WAC/C,KAAK,eACL,aACF;IAOA,IAAI,KAAK,sBAAsB,aAC7B,KAAK,MAAM,QAAQ,KAAK,iBAAiB,YAAY,GAAG;KACtD,IAAI,KAAK,SAAS,UAAU,WAC1B,kBAAkB;KAEpB,MAAM;IACR;IAIF,IAAI,KAAK,mBACP;GAEJ;GAEA,IAAI,KAAK,YAAY,KAAK,KAAK,mBAC7B;EAEJ;EAKA,IAAI,KAAK,YAAY,GACnB;EAIF,IAAI,CAAC,KAAK,0BAA0B,CAAC,KAAK,mBACxC,KAAK,oBAAoB;GACvB,SAAS;GACT,MAAM;EACR;EAOF,IACE,KAAK,0BACL,CAAC,KAAK,qBACN,KAAK,sBAAsB,UAE3B,IAAI;GACF,MAAM,YAAY,KAAK,sBAAsB,SAC3C,KAAK,uBAAuB,IAC9B;GACA,KAAK,4BAA4B;GACjC,KAAK,+BAA+B;EACtC,SAAS,KAAc;GACrB,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAC/D,KAAK,oBAAoB;IACvB;IACA,MAAM;IACN,OAAO;GACT;EACF;EAUF,IACE,KAAK,qBACL,KAAK,sBAAsB,eAC3B,CAAC,iBACD;GAKA,IAAI,CAAC,cAAc;IACjB,MAAM,aAAa,sBAAsB;IACzC,OAAO,KAAK,iBAAiB,MAAM,mBAAmB,UAAU,CAAC;IACjE,eAAe;GACjB;GAEA,MAAM,WAAwB;IAC5B,MAAM,UAAU;IAChB,WAAW,KAAK,IAAI;IACpB,SAAS,KAAK,kBAAkB;IAChC,GAAI,KAAK,kBAAkB,OACvB,EAAE,MAAM,KAAK,kBAAkB,KAAK,IACpC,CAAC;GACP;GACA,OAAO,KAAK,iBACV,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe,QAAQ,CACrE;EACF;CACF;;;;;;;;;;;;;;;;;;CAmBA,OAAe,kCAA+D;EAC5E,IAAI,CAAC,KAAK,uBACR,MAAM,IAAI,MACR,6EACF;EAGF,MAAM,cAAc,KAAK,sBAAsB;EAG/C,KAFe,KAAK,sBAAsB,UAAU,YAErC,SACT;OAAA,CAAC,KAAK,wBACR,KAAK,oBAAoB;IACvB,SAAS;IACT,MAAM;GACR;EAAA,OAEG;GACL,MAAM,UAAU,KAAK;GAMrB,IAAI,QAAQ,WAAW,GACrB,KAAK,oBAAoB;IACvB,SAAS;IACT,MAAM;GACR;QAEA,IAAI;IACF,MAAM,SAAkB,KAAK,MAAM,OAAO;IAK1C,MAAM,OAAO,KAAK,sBAAsB,YACpC,KAAK,sBAAsB,UAAU,MAAM,IAC3C;IACJ,KAAK,yBAAyB;KAAE;KAAM;IAAQ;GAChD,SAAS,KAAc;IACrB,MAAM,SACJ,QAAQ,MAAM,GAAG,GAAG,KAAK,QAAQ,SAAS,MAAM,QAAQ;IAC1D,KAAK,oBAAoB;KACvB,SAAS,uDAAuD;KAChE,MAAM;KACN,OAAO;IACT;GACF;EAEJ;EAIA,IACE,KAAK,0BACL,CAAC,KAAK,qBACN,KAAK,sBAAsB,UAE3B,IAAI;GACF,MAAM,YAAY,KAAK,sBAAsB,SAC3C,KAAK,uBAAuB,IAC9B;GACA,KAAK,4BAA4B;GACjC,KAAK,+BAA+B;EACtC,SAAS,KAAc;GACrB,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;GAC/D,KAAK,oBAAoB;IACvB;IACA,MAAM;IACN,OAAO;GACT;EACF;EAGF,IAAI,CAAC,aAIH;EAQF,IAAI,CAAC,KAAK,sBAAsB;GAC9B,KAAK,uBAAuB;GAC5B,MAAM,YAAY,KAAK,+BAA+B,kBAAkB;GACxE,KAAK,8BAA8B;GACnC,MAAM,aAA0B;IAC9B,MAAM,UAAU;IAChB,MAAM;IACN,OAAO,EAAE,UAAU;IACnB,WAAW,KAAK,IAAI;GACtB;GACA,OAAO,KAAK,iBACV,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe,UAAU,CACvE;EACF;EAKA,IACE,KAAK,0BACL,CAAC,KAAK,qBACN,CAAC,KAAK,yBACN;GACA,MAAM,gBAA6B;IACjC,MAAM,UAAU;IAChB,MAAM;IACN,OAAO;KACL,QAAQ,KAAK,uBAAuB;KACpC,KAAK,KAAK,uBAAuB;KACjC,GAAI,KAAK,8BACL,EAAE,WAAW,KAAK,4BAA4B,IAC9C,CAAC;IACP;IACA,WAAW,KAAK,IAAI;GACtB;GACA,OAAO,KAAK,iBACV,MAAM,KAAK,iBAAiB,WAC1B,KAAK,eACL,aACF,CACF;EACF;EAIA,IAAI,KAAK,mBAAmB;GAC1B,MAAM,WAAwB;IAC5B,MAAM,UAAU;IAChB,WAAW,KAAK,IAAI;IACpB,SAAS,KAAK,kBAAkB;IAChC,GAAI,KAAK,kBAAkB,OACvB,EAAE,MAAM,KAAK,kBAAkB,KAAK,IACpC,CAAC;GACP;GACA,OAAO,KAAK,iBACV,MAAM,KAAK,iBAAiB,WAAW,KAAK,eAAe,QAAQ,CACrE;EACF;CACF;CAEA,wBAAsD;EACpD,OAAO;GACL,UAAU,KAAK;GACf,kBAAkB,KAAK;GACvB,eAAe,CAAC,GAAG,KAAK,aAAa;GACrC,OAAO,CAAC,GAAG,KAAK,KAAK;GACrB,QAAQ,KAAK,OAAO;GACpB,iBAAiB;IACf,WAAW,KAAK;IAChB,mBAAmB,KAAK;IACxB,mBAAmB,KAAK;IACxB,sBAAsB,KAAK;GAC7B;GACA,UAAU,KAAK,OAAO;GACtB,cAAc,KAAK,OAAO;EAC5B;CACF;CAEA,MAAc,8BACZ,QACe;EACf,KAAK,OAAO,QAAQ,UAAU,OAAO,GACnC;EAGF,MAAM,mBAAmB,KAAK;EAC9B,IAAI,CAAC,kBACH,MAAM,IAAI,+BAA+B,CACvC;GACE,OAAO;GACP,UAAU,KAAK;GACf,kBAAkB,KAAK,iBAAiB,KAAK;GAC7C,YAAY;GACZ,cAAc,OAAO,QAAQ,KAAK,UAAU,MAAM,WAAW,KAAK,CAAC;GACnE,MAAM;GACN,SACE;GACF,QAAQ;GACR,WAAW;EACb,CACF,CAAC;EAGH,MAAM,mBAA2C,CAAC;EAClD,MAAM,iBAA2C,CAAC;EAGlD,MAAM,mBAAmB,KAAK,+BAA+B,OAAO,MAAM;EAC1E,MAAM,qBAAqB,IAAI,IAC7B,OAAO,QAAQ,KAAK,UAAU,MAAM,WAAW,CACjD;EACA,MAAM,6BAAa,IAAI,IAAqB;EAC5C,MAAM,gCAAgB,IAAI,IAA4B;EACtD,MAAM,yCAAyB,IAAI,IAAY;EAE/C,KAAK,MAAM,YAAY,kBAAkB;GACvC,MAAM,OAAO,KAAK,MAAM,MACrB,cAAc,UAAU,SAAS,SAAS,SAAS,IACtD;GACA,IAAI,CAAC,MAAM;GACX,cAAc,IAAI,SAAS,IAAI,IAAI;GACnC,IAAI,QAAiB,CAAC;GACtB,IAAI;IACF,MAAM,SAAS,KAAK,MAAM,SAAS,SAAS,UAAU,KAAK,KAAK,IAAI;IACpE,QAAQ,UAAU,OAAO,WAAW,WAAW,SAAS,CAAC;GAC3D,QAAQ;IACN,QAAQ,CAAC;GACX;GACA,WAAW,IAAI,SAAS,IAAI,KAAK;GACjC,IACE,CAAC,KAAK,WACN,mBAAmB,IAAI,eAAe,SAAS,IAAI,GAEnD,uBAAuB,IAAI,SAAS,EAAE;EAE1C;EAMA,KAAK,MAAM,YAAY,kBAErB,IADa,cAAc,IAAI,SAAS,EACpC,CAAA,EAAM,iBAAiB,CAAC,uBAAuB,IAAI,SAAS,EAAE,GAChE,iBAAiB,KAAK;GACpB,YAAY,SAAS;GACrB,UAAU,SAAS,SAAS;GAC5B,OAAO,WAAW,IAAI,SAAS,EAAE,KAAK,CAAC;GACvC,YAAY,YAAY,SAAS;EACnC,CAAC;EAIL,KAAK,MAAM,YAAY,kBAAkB;GACvC,MAAM,OAAO,cAAc,IAAI,SAAS,EAAE;GAC1C,IACE,SAAS,KAAA,KACT,CAAC,KAAK,YACL,CAAC,KAAK,iBAAiB,uBAAuB,IAAI,SAAS,EAAE,IAE9D,eAAe,KAAK;IAClB,YAAY,SAAS;IACrB,UAAU,SAAS,SAAS;IAC5B,OAAO,WAAW,IAAI,SAAS,EAAE,KAAK,CAAC;GACzC,CAAC;EAEL;EAEA,MAAM,iBAAiB,KAAK,8BAA8B,gBAAgB;EAC1E,MAAM,UAOD,KAAK,0BACR,kBACA,cACF,CAAC,CAAC,SAAS,eAAe;GACxB,MAAM,WAAW,6BAA6B,UAAU;GACxD,OAAO,WACH,CACE;IACE,aAAa,WAAW;IACxB,SAAS;IACT,SAAS;KACP,GAAG;KACH;KACA,YAAY;IACd;GACF,CACF,IACA,CAAC;EACP,CAAC;EACD,QAAQ,KAAK,GAAG,cAAc;EAC9B,MAAM,YAAY,MAAM,6BAA6B;GACnD,UAAU,KAAK;GACf;GACA,YAAY;GACZ;GACA,QAAQ,OAAO;GACf,OAAO,KAAK;EACd,CAAC;EACD,IAAI,UAAU,OAAO,SAAS,KAAK,CAAC,UAAU,iBAC5C,MAAM,IAAI,+BAA+B,UAAU,MAAM;EAQ3D,MAAM,YAAY,IAAI,IAAI,UAAU,gBAAgB,SAAS;EAC7D,KAAK,MAAM,WAAW,gBACpB,IAAI,cAAc,IAAI,QAAQ,UAAU,CAAC,EAAE,eACzC,UAAU,IAAI,QAAQ,YAAY,IAAI;EAG1C,KAAK,qBAAqB;GACxB,GAAG,UAAU;GACb;EACF,CAAC;EAED,MAAM,qBAAqB,UAAU,gBAAgB;EACrD,IAAI,eAAe,SAAS,KAAK,oBAAoB;GACnD,MAAM,cAAc,eACjB,MAAM,MAAM,UAAU;IAOrB,QALE,KAAK,QAAQ,SAAS,YAAa,KAAK,QAAQ,cAAc,IAAK,MAEnE,MAAM,QAAQ,SAAS,YAClB,MAAM,QAAQ,cAAc,IAC7B;GAER,CAAC,CAAC,CACD,SAAS,WAAW;IACnB,MAAM,aAAa,mBAAmB,IAAI,OAAO,WAAW;IAC5D,IAAI,CAAC,cAAc,CAAC,OAAO,gBAAgB,OAAO,CAAC;IACnD,OAAO,CACL,WAAW,WAAW,aAClB;KACE,SAAS,OAAO;KAChB,QAAQ;KACR,UAAU,WAAW;IACvB,IACA;KACE,SAAS,OAAO;KAChB,QAAQ;IACV,CACN;GACF,CAAC;GAeH,MAAM,SAAS,MAAM,KAAK,iBAAiB,yBACzC,KAAK,eACL;IAfA,MAAM,eACJ,YAAY,QACT,eAAe,WAAW,QAAQ,eAAe,UACpD;IACF,MACE,GAAG,gBAEH,YAAY,WAAW,IACnB,cACA,YAAY,QAAQ,eAClB,YAAY,SAAS,WAAW,QAAQ,UAAU,CACpD;GAIN,CACF;GACA,IAAI,OAAO,eAAe,QACxB,KAAK,mBAAmB;QACnB,IAAI,OAAO,eAAe,UAC/B,KAAK,MAAM,WAAW,kBACpB,KAAK,2BAA2B,IAAI,QAAQ,EAAE;EAGpD;CACF;CAEA,8BAAsC,kBAOnC;EACD,MAAM,QAAQ,YAA2B;GACvC,MAAM,IAAI,+BAA+B,CACvC;IACE,OAAO;IACP,UAAU,KAAK;IACf;IACA,YAAY;IACZ,cAAc,CAAC;IACf,MAAM;IACN;IACA,QAAQ;IACR,WAAW;GACb,CACF,CAAC;EACH;EACA,MAAM,UAOD,CAAC;EACN,MAAM,sBAAM,IAAI,IAAY;EAC5B,MAAM,+BAAe,IAAI,IAAY;EACrC,KAAK,MAAM,cAAc,KAAK,OAAO,UAAU,CAAC,GAAG;GACjD,MAAM,SAAS,iCAAiC,WAAW,QAAQ;GACnE,IAAI,OAAO,WAAW,UAAU;GAChC,IAAI,OAAO,WAAW,WACpB,OAAO,KAAK,OAAO,OAAO;GAE5B,MAAM,QAAQ,OAAO;GACrB,MAAM,KAAK,WAAW;GACtB,MAAM,aAAa,KAAK,qBAAqB,IAAI,MAAM,YAAY;GACnE,IAAI,CAAC,YACH,OAAO,KACL,gCAAgC,MAAM,aAAa,iBACrD;GAEF,IAAI,IAAI,IAAI,EAAE,KAAK,aAAa,IAAI,MAAM,UAAU,GAClD,OAAO,KACL,4DACF;GAEF,IAAI,IAAI,EAAE;GACV,aAAa,IAAI,MAAM,UAAU;GACjC,IAAI;GAGJ,IAAI;IACF,UAAU,0BAA0B,YAAY;KAC9C,KAAK,MAAM;KACX,QAAQ,MAAM;KACd,SAAS,MAAM;KACf,GAAI,OAAO,MAAM,cAAc,WAC3B,EAAE,WAAW,MAAM,UAAU,IAC7B,CAAC;KACL,GAAI,OAAO,UAAU,eAAe,KAAK,OAAO,SAAS,IACrD,EAAE,SAAS,MAAM,QAAQ,IACzB,CAAC;IACP,CAAC;GACH,SAAS,OAAO;IACd,OAAO,KACL,kCAAkC,GAAG,eACnC,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,GAEzD;GACF;GACA,MAAM,UAAU,uBAAuB,SAAS,EAC9C,YAAY,MAAM,WACpB,CAAC;GACD,IACE,MAAM,uBAAuB,QAAQ,WAAW,sBAChD,MAAM,sBAAsB,QAAQ,WAAW,mBAE/C,OAAO,KACL,kCAAkC,GAAG,gCACvC;GAEF,QAAQ,KAAK;IACX,aAAa;IACb,SAAS;KACP;KACA,GAAI,QAAQ,WAAW,gCAAgC,KAAA,IACnD,EACE,gBAAgB,KAAK,MACnB,QAAQ,WAAW,2BACrB,EACF,IACA,CAAC;IACP;IACA,SAAS;KACP,GAAA;KACA,MAAM;KACN,aAAa;KACb;KACA,YAAY;KACZ,cAAc,MAAM;KACpB,KAAK,MAAM;KACX,YAAY,MAAM;KAClB,GAAI,OAAO,MAAM,cAAc,WAC3B,EAAE,WAAW,MAAM,UAAU,IAC7B,CAAC;KACL,GAAI,QAAQ,WAAW,oBACnB,EAAE,mBAAmB,QAAQ,WAAW,kBAAkB,IAC1D,CAAC;KACL,GAAI,MAAM,uBAAuB,KAAA,IAC7B,EAAE,oBAAoB,MAAM,mBAAmB,IAC/C,CAAC;IACP;IACA,gBAAgB;GAClB,CAAC;EACH;EACA,OAAO;CACT;CAEA,qBAA6B,OAA8C;EACzE,IAAI,OAAO,WACT,KAAK,MAAM,CAAC,YAAY,eAAe,MAAM,WAC3C,KAAK,gBAAgB,IAAI,YAAY,UAAU;EAGnD,IAAI,OAAO,mBACT,KAAK,MAAM,CAAC,YAAY,WAAW,MAAM,mBACvC,KAAK,wBAAwB,IAAI,YAAY,MAAM;EAGvD,IAAI,OAAO,mBACT,KAAK,MAAM,CAAC,YAAY,WAAW,MAAM,mBACvC,KAAK,wBAAwB,IAAI,YAAY,MAAM;EAGvD,IAAI,OAAO,sBACT,KAAK,MAAM,cAAc,MAAM,sBAC7B,KAAK,2BAA2B,IAAI,UAAU;EAGlD,IAAI,OAAO,mBACT,KAAK,MAAM,CAAC,aAAa,eAAe,MAAM,mBAC5C,KAAK,wBAAwB,IAAI,aAAa,UAAU;EAG5D,IAAI,OAAO,0BACT,KAAK,MAAM,CAAC,aAAa,YAAY,MAAM,0BACzC,KAAK,+BAA+B,IAAI,aAAa,OAAO;CAGlE;CAEA,MAAc,yCAAwD;EACpE,IAAI,KAAK,+BAA+B,SAAS,GAAG;EACpD,MAAM,cAAc,CAClB,GAAG,KAAK,+BAA+B,QAAQ,CACjD,CAAC,CAAC,SAAS,CAAC,aAAa,aAAa;GACpC,MAAM,aAAa,KAAK,wBAAwB,IAAI,WAAW;GAC/D,IAAI,CAAC,YAAY,OAAO,CAAC;GACzB,OAAO,CACL,WAAW,WAAW,aAClB;IACE;IACA,QAAQ;IACR,UAAU,WAAW;GACvB,IACA;IAAE;IAAS,QAAQ;GAAqB,CAC9C;EACF,CAAC;EAaD,MAAM,SAAS,MAAM,KAAK,iBAAiB,yBACzC,KAAK,eACL;GAbA,MAAM,eACJ,YAAY,QACT,eAAe,WAAW,QAAQ,eAAe,UACpD;GACF,MAAM,GAAG,gBACP,YAAY,WAAW,IACnB,cACA,YAAY,QAAQ,eAClB,YAAY,SAAS,WAAW,QAAQ,UAAU,CACpD;EAIN,CACF;EACA,IAAI,OAAO,eAAe,QACxB,KAAK,mBAAmB;OACnB,IAAI,OAAO,eAAe,UAC/B,KAAK,MAAM,YAAY,KAAK,gCAAgC,GAC1D,KAAK,2BAA2B,IAAI,SAAS,EAAE;CAGrD;CAEA,sBAA8B,QAAoC;EAChE,KAAK,qBAAqB,OAAO,eAAe;EAChD,KAAK,WAAW,OAAO;EACvB,KAAK,mBAAmB,OAAO,oBAAoB,OAAO;EAC1D,KAAK,gBAAgB,OAAO;EAC5B,sBAAsB,OAAO,KAAK;EAClC,KAAK,QAAQ,OAAO;EACpB,KAAK,SAAS;GACZ,GAAG,KAAK;GACR,UAAU,OAAO;GACjB,cAAc,OAAO;EACvB;EAGA,KAAK,cAAc,WAAW,KAAK;EACnC,KAAK,cAAc,gBAAgB,KAAK;EACxC,KAAK,cAAc,WAAW,KAAK,MAAM,SAAS;EAClD,KAAK,cAAc,YAAY,KAAK,MAAM,KAAK,MAAM,EAAE,IAAI;EAC3D,KAAK,cAAc,eAAe,OAAO;CAC3C;CAEA,aAAqB,OAA8B;EACjD,KAAK,YAAY;CACnB;;;;;CAMA,CAAS,iBACP,SACoC;EACpC,KAAK,MAAM,UAAU,SACnB,KAAK,MAAM,QAAQ,qBAAqB,MAA2B,GAAG;GACpE,mBAAmB,IAAI;GACvB,IAAI,KAAK,SAAS,UAAU,aAAa;IACvC,IAAI,KAAK,qBAAqB;IAC9B,KAAK,sBAAsB;GAC7B;GAGA,IAAI,KAAK,SAAS,UAAU,UAAU,KAAK,SAAS,eAClD,KAAK,wBAAyB,KAAqB,KAAK;GAE1D,MAAM;GACN,KAAK,cAAc;EACrB;CAEJ;;;;;CAMA,OAAe,sBACb,OACyC;EACzC,MAAM,UAAU,MAAM,KAAK,iBAAiB,WAC1C,KAAK,eACL,KACF;EACA,OAAO,KAAK,iBAAiB,OAAO;EACpC,IAAI,CAAC,KAAK,0BACR,OAAO,KAAK,2BAA2B;CAE3C;;;;;;CAOA,OAAe,6BAA0D;EACvE,IAAI,KAAK,0BAA0B;EACnC,IAAI,KAAK,sBAAsB,WAAW,GAAG;EAC7C,KAAK,2BAA2B;EAChC,IAAI;GACF,OAAO,KAAK,wBAAwB,KAAK,6BAA6B,CAAC;GACvE,OAAO,KAAK,sBAAsB,SAAS,GAAG;IAC5C,MAAM,QAAQ,KAAK,sBAAsB,MAAM;IAC/C,IAAI,OAAO,OAAO,KAAK,sBAAsB,KAAK;GACpD;EACF,UAAU;GACR,KAAK,2BAA2B;EAClC;CACF;;;;CAKA,OAAe,iBACb,MACgC;EAChC,IAAI,UAAU;EACd,IAAI;EACJ,IAAI;EACJ,MAAM,OAAO,KAAK,MACf,UAAU;GACT,UAAU;GACV,SAAS;EACX,IACC,QAAiB;GAChB,UAAU;GACV,QAAQ;EACV,CACF;EAEA,OAAO,CAAC,SAAS;GACf,OAAO,KAAK,2BAA2B;GACvC,IAAI,SAAS;GACb,MAAM,QAAQ,KAAK,CACjB,MACA,IAAI,SAAe,YAAY;IAC7B,IAAI,KAAK,sBAAsB,SAAS,GAAG;KACzC,QAAQ;KACR;IACF;IACA,KAAK,wBAAwB,KAAK,OAAO;GAC3C,CAAC,CACH,CAAC;EACH;EAEA,OAAO,KAAK,2BAA2B;EACvC,IAAI,UAAU,KAAA,GAAW,MAAM;EAC/B,OAAO;CACT;;;;;CAMA,OAAe,wBAAqD;EAClE,OAAO,KAAK,iBAAiB,SAAS,GAAG;GACvC,MAAM,QAAQ,KAAK,iBAAiB,MAAM;GAC1C,IAAI,OAAO,OAAO,KAAK,sBAAsB,KAAK;EACpD;CACF;;;;;CAMA,OAAe,uBACb,WAiBA;EACA,IAAI,UAAU,UAAU,KAAK;EAC7B,OAAO,MAAM;GACX,MAAM,OAAO,OAAO,KAAK,iBAAiB,OAAO;GACjD,IAAI,KAAK,MAAM,OAAO,KAAK;GAC3B,OAAO,KAAK,sBAAsB,KAAK,KAAK;GAC5C,UAAU,UAAU,KAAK;EAC3B;CACF;CAEA,uBACE,WACA,OACa;EACb,OAAO;GACL,MAAM,UAAU;GAChB,WAAW,KAAK,IAAI;GACpB,MAAM;GACN;EACF;CACF;CAEA,SAAiB,QAAwB;EACvC,OAAO,GAAG,OAAO,GAAG,KAAK,IAAI,EAAE,GAAG,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC;CACzE;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmEA,SAAgB,KAgBd,SAS8C;CAC9C,6BAA6B,QAAQ,UAAU;CAC/C,qBACE,sBAAsB,QAAQ,UAAU,KAAK,CAAC,GAC9C,QAAQ,OACV;CACA,IAAI,QAAQ,OACV,sBAAsB,QAAQ,KAAK;CAGrC,MAAM,EAAE,cAAc,WAAW;CAEjC,IAAI,gBAAgB,WAAW,MAC7B,OAAO,6BACL,6BAA6B,SAAS;EACpC;EACA,QAAQ;CACV,CAAC,CACH;CAGF,IAAI,cACF,OAAO,2BACL,6BAA6B,SAAS;EACpC;EACA,QAAQ;CACV,CAAC,CACH;CAGF,IAAI,WAAW,OACb,OAAO,oBACL,6BAA6B,SAAS;EACpC,cAAc,KAAA;EACd,QAAQ;CACV,CAAC,CACH;CAGF,OAAO,iBACL,6BAA6B,SAAS;EACpC,cAAc,KAAA;EACd,QAAQ;CACV,CAAC,CACH;AACF;AAUA,SAAS,sBACP,YACsC;CACtC,IAAI,eAAe,KAAA,GAAW,OAAO,KAAA;CACrC,IAAI,CAAC,MAAM,QAAQ,UAAU,GAC3B,MAAM,IAAI,UAAU,mCAAmC;CAEzD,OAAO;AACT;AAEA,SAAS,6BAgBP,SASA,WACoE;CACpE,MAAM,EAAE,YAAY,GAAG,SAAS;CAChC,OAAO;EACL,GAAG;EACH,GAAG;EACH,GAAI,eAAe,KAAA,IACf,CAAC,IACD,EAAE,YAAY,sBAAsB,UAAU,EAAE;CACtD;AACF;AAEA,SAAS,6BACP,aAGM;CACN,IAAI,CAAC,aAAa;CAClB,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,cAAc,aAAa;EACpC,IAAI,KAAK,IAAI,WAAW,EAAE,GACxB,MAAM,IAAI,MAAM,sCAAsC,WAAW,IAAI;EAEvE,KAAK,IAAI,WAAW,EAAE;CACxB;AACF;;;;;;;;;AAuBA,SAAS,qBACP,QACA,WACM;CAGN,yBACE,cACM,UAAU,SAAS,YAAY,MAAM,IAC7C;CAIA,4BAA4B,cAAc;EACxC,UAAU,SAAS,mBAAmB;CACxC,CAAC;AACH;;;;;;;;;;;AAYA,SAAS,iBACP,SAC4B;CAC5B,MAAM,YAA+B,CAAC;CACtC,MAAM,SAAS,iBAAiB,SAAS,SAAS;CAClD,qBAAqB,QAAQ,SAAS;CACtC,OAAO;AACT;AAEA,gBAAgB,iBACd,SACA,WAC4B;CAC5B,MAAM,EAAE,SAAS,YAAY,SAAS,OAAO,KAAK,GAAG,gBAAgB;CACrE,MAAM,QAAQ,QAAQ;CACtB,MAAM,SAAS,mBAAmB,KAAK;CAEvC,MAAM,aAAa,WAAW,KAAK,GAAG;CACtC,MAAM,WAAW,MAAM,WAAW,SAAS;CAC3C,IAAI,SAAS,SAAS,GACpB,YAAY,QAAQ,CAAC,GAAI,YAAY,SAAS,CAAC,GAAI,GAAG,QAAQ;CAGhE,MAAM,SAAS,IAAI,WACjB;EACE;EACA,QAAQ;GAAE,GAAG;GAAa;GAAO;EAAO;EAKxC;EACA;CACF,GACA,MACF;CACA,UAAU,UAAU;CAEpB,IAAI;EACF,WAAW,MAAM,SAAS,OAAO,IAAI,GACnC,MAAM;CAEV,UAAU;EACR,MAAM,WAAW,QAAQ;CAC3B;AACF;;;;;AAMA,SAAS,oBACP,SACiB;CACjB,MAAM,SAAS,iBAAiB;EAC9B,GAAG;EACH,QAAQ;CACV,CAAC;CAED,OAAO,aAAa,MAAM;AAC5B;;;;;;;AAQA,eAAe,2BACb,SACmC;CACnC,MAAM,EACJ,SACA,cACA,YACA,SACA,OACA,KACA,GAAG,gBACD;CACJ,MAAM,QAAQ,QAAQ;CACtB,MAAM,SAAS,mBAAmB,KAAK;CAEvC,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,gDAAgD;CAYlE,MAAM,EAAE,YAAY,oBAClB,iCAAiC,YAAY;CAC/C,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,gDAAgD;CAQlE,MAAM,aAAa,SACjB,iBAAiB,MAAM,eAAe;CAMxC,MAAM,WAAW,iBAAiB,YAAY,KACzC,SACC,wBAAkD,cAAc,IAAI,IACtE,KAAA;CAMJ,MAAM,iBACJ,QAAQ,iCAAiC,QAAQ,YAAY,MAAM;CACrE,MAAM,SACJ,QAAQ,iCAAiC,QAAQ,YAAY,KAAK;CAEpE,MAAM,aAAa,WAAW,KAAK,GAAG;CACtC,MAAM,WAAW,MAAM,WAAW,SAAS;CAC3C,IAAI,SAAS,SAAS,GACpB,YAAY,QAAQ,CAAC,GAAI,YAAY,SAAS,CAAC,GAAI,GAAG,QAAQ;CAGhE,MAAM,SAAS,IAAI,WACjB;EACE;EACA,QAAQ;GAAE,GAAG;GAAa;GAAO;EAAO;EAKxC;EACA;EACA,uBAAuB;GACrB;GACA,aAAa;GACb;GACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;GAC/B,GAAI,iBAAiB,EAAE,gBAAgB,KAAK,IAAI,CAAC;GACjD;EACF;CACF,GACA,MACF;CAEA,IAAI;EAEF,WAAW,MAAM,UAAU,OAAO,IAAI;CAGxC,UAAU;EACR,MAAM,WAAW,QAAQ;CAC3B;CAEA,MAAM,oBAAoB,OAAO,qBAAqB;CACtD,IAAI,mBAAmB;EACrB,MAAM,MAAM,IAAI,MACd,kBAAkB,SAClB,kBAAkB,UAAU,KAAA,IACxB,EAAE,OAAO,kBAAkB,MAAM,IACjC,KAAA,CACN;EACA,IAAI,kBAAkB,SAAS,KAAA,GAC7B,OAAO,eAAe,KAAK,QAAQ;GACjC,OAAO,kBAAkB;GACzB,YAAY;EACd,CAAC;EAEH,MAAM;CACR;CAIA,MAAM,YAAY,OAAO,6BAA6B;CACtD,IAAI,WACF,OAAO,UAAU;CAGnB,MAAM,SAAS,OAAO,0BAA0B;CAChD,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,mDAAmD;CAErE,OAAO,OAAO;AAChB;;;;;;;;AASA,SAAS,yBAAyB,OAAoC;CACpE,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO,KAAA;CACxD,IAAI,EAAE,eAAe,QAAQ,OAAO,KAAA;CACpC,MAAM,YAAY,MAAM;CACxB,OAAO,OAAO,cAAc,YAAY,cAAc,KAClD,YACA,KAAA;AACN;AAEA,SAAS,kCACP,OAC6D;CAC7D,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM,OAAO;CACxD,IAAI,EAAE,YAAY,UAAU,EAAE,SAAS,QAAQ,OAAO;CACtD,MAAM,MAAO,MAA2B;CACxC,IAAI,OAAO,QAAQ,UAAU,OAAO;CACpC,MAAM,iBAAkB,MAAkC;CAC1D,MAAM,YACJ,OAAO,mBAAmB,WAAW,iBAAiB,KAAA;CACxD,OAAO;EACL,QAAS,MAA8B;EACvC;EACA,GAAI,cAAc,KAAA,IAAY,EAAE,UAAU,IAAI,CAAC;CACjD;AACF;;;;;;;;;;;;AAaA,gBAAgB,+BACd,SACA,SACA,gBACkC;CAClC,MAAM,EAAE,gBAAgB;CAIxB,MAAM,eAAe,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,MAAM,CAAC;CACvD,MAAM,QAAQ,YAAY,SAAS,YAAY,KAAK,IAAI,EAAE,GAAG;CAC7D,MAAM,WACJ,YAAY,YAAY,YAAY,KAAK,IAAI,EAAE,GAAG;CACpD,MAAM,YAAY,YAAY,KAAK,IAAI,EAAE,GAAG;CAC5C,MAAM,QAAQ,YAAY;CAC1B,MAAM,YAAY,KAAK,IAAI;CAE3B,MAAM;EACJ,MAAM,UAAU;EAChB;EACA;EACA;EACA,WAAW;CACb;CAEA,IAAI;CACJ,IAAI;EACF,SAAS,MAAM,QAAQ,iBAAiB,OAAO;CACjD,SAAS,OAAO;EACd,iBAAiB,KAAK;EACtB,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;EACrE,MAAM;GACJ,MAAM,UAAU;GAChB;GACA;GACA;GACA,WAAW,KAAK,IAAI;GACpB;GACA,OAAO,EAAE,QAAQ;EACnB;EACA;CACF;CAEA,MAAM;EACJ,MAAM,UAAU;EAChB;EACA,MAAM;EACN;EACA,WAAW,KAAK,IAAI;CACtB;CAEA,MAAM;EACJ,MAAM,UAAU;EAChB;EACA,OAAO,OAAO;EACd;EACA,WAAW,KAAK,IAAI;CACtB;CAEA,MAAM;EACJ,MAAM,UAAU;EAChB;EACA;EACA,WAAW,KAAK,IAAI;CACtB;CAEA,MAAM;EACJ,MAAM,UAAU;EAChB,MAAM;EACN,OAAO;GAAE,QAAQ,OAAO;GAAM,KAAK,OAAO;EAAQ;EAClD;EACA,WAAW,KAAK,IAAI;CACtB;CAEA,MAAM;EACJ,MAAM,UAAU;EAChB;EACA;EACA;EACA,WAAW,KAAK,IAAI;EACpB,cAAc;EAMd,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;CAChD;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAS,6BACP,SACkD;CAClD,MAAM,EAAE,iBAAiB;CAEzB,IAAI,CAAC,cACH,MAAM,IAAI,MAAM,0DAA0D;CAQ5E,MAAM,EAAE,YAAY,oBAClB,iCAAiC,YAAY;CAC/C,IAAI,CAAC,YACH,MAAM,IAAI,MAAM,gDAAgD;CAElE,MAAM,aAAa,SACjB,iBAAiB,MAAM,eAAe;CAexC,MAAM,YAA+B,CAAC;CACtC,MAAM,SAAS,iCACb,SACA,YACA,WACA,SACF;CACA,qBAAqB,QAAQ,SAAS;CACtC,OAAO;AACT;AAkBA,gBAAgB,iCACd,SACA,YACA,WACA,WAC0D;CAC1D,MAAM,EACJ,SACA,cACA,YACA,SACA,OACA,KACA,GAAG,gBACD;CACJ,MAAM,QAAQ,QAAQ;CACtB,MAAM,SAAS,mBAAmB,KAAK;CASvC,MAAM,iBACJ,QAAQ,iCAAiC,QAAQ,YAAY,MAAM;CACrE,MAAM,SACJ,QAAQ,iCAAiC,QAAQ,YAAY,KAAK;CAEpE,MAAM,aAAa,WAAW,KAAK,GAAG;CACtC,MAAM,WAAW,MAAM,WAAW,SAAS;CAC3C,IAAI,SAAS,SAAS,GACpB,YAAY,QAAQ,CAAC,GAAI,YAAY,SAAS,CAAC,GAAI,GAAG,QAAQ;CAKhE,MAAM,SAAS,IAAI,WACjB;EACE;EACA,QAAQ;GAAE,GAAG;GAAa;GAAO;EAAO;EAKxC;EACA;EACA,uBAAuB;GACrB;GACA,aAAa;GACb;GACA,GAAI,iBAAiB,EAAE,gBAAgB,KAAK,IAAI,CAAC;GACjD;EACF;CACF,GACA,MACF;CACA,UAAU,UAAU;CAEpB,IAAI;EACF,WAAW,MAAM,SAAS,OAAO,IAAI,GACnC,MAAM;CAEV,UAAU;EACR,MAAM,WAAW,QAAQ;CAC3B;AAOF"}
|