@providerprotocol/ai 0.0.37 → 0.0.39
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 +94 -3
- package/dist/anthropic/index.d.ts +3 -2
- package/dist/cerebras/index.d.ts +3 -2
- package/dist/chunk-3Q5VELKG.js +124 -0
- package/dist/chunk-3Q5VELKG.js.map +1 -0
- package/dist/{chunk-LTEMH3CI.js → chunk-5XPRVUOK.js} +6 -4
- package/dist/{chunk-LTEMH3CI.js.map → chunk-5XPRVUOK.js.map} +1 -1
- package/dist/chunk-7ULSRWDH.js +83 -0
- package/dist/chunk-7ULSRWDH.js.map +1 -0
- package/dist/{chunk-YQLR3XOA.js → chunk-BIBMNP7Y.js} +1 -75
- package/dist/chunk-BIBMNP7Y.js.map +1 -0
- package/dist/{chunk-7GTWHZY2.js → chunk-IDZR4ROP.js} +5 -3
- package/dist/{chunk-7GTWHZY2.js.map → chunk-IDZR4ROP.js.map} +1 -1
- package/dist/{chunk-4RX4VQCB.js → chunk-IIMTP3XC.js} +2 -2
- package/dist/{chunk-ZRVNAET3.js → chunk-KNBODIQU.js} +6 -3
- package/dist/chunk-KNBODIQU.js.map +1 -0
- package/dist/{chunk-FYSZFIZS.js → chunk-O32SBS6S.js} +5 -3
- package/dist/{chunk-FYSZFIZS.js.map → chunk-O32SBS6S.js.map} +1 -1
- package/dist/{chunk-IK6NRCW5.js → chunk-RDC5GYST.js} +7 -7
- package/dist/{chunk-5IWHCXKN.js → chunk-SAMIK4WZ.js} +2 -2
- package/dist/{chunk-EPB3GQNL.js → chunk-U6M3MXNI.js} +11 -2
- package/dist/chunk-U6M3MXNI.js.map +1 -0
- package/dist/{chunk-2YXFLRQ6.js → chunk-WNB5PSY6.js} +2 -2
- package/dist/{chunk-CRP6Y7NF.js → chunk-ZDYEDI2A.js} +2 -2
- package/dist/{embedding-CwZ1ZNWv.d.ts → embedding-iNQCeXfk.d.ts} +1 -1
- package/dist/google/index.d.ts +3 -2
- package/dist/groq/index.d.ts +3 -2
- package/dist/http/index.d.ts +4 -3
- package/dist/{image-stream-CeQHtjxS.d.ts → image-stream-ARno6XlS.d.ts} +1 -1
- package/dist/index.d.ts +8 -7
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/{llm-DS_-l71X.d.ts → llm-CZqlijjK.d.ts} +16 -9
- package/dist/middleware/logging/index.d.ts +3 -2
- package/dist/middleware/parsed-object/index.d.ts +3 -2
- package/dist/middleware/persistence/index.d.ts +3 -2
- package/dist/middleware/pubsub/index.d.ts +5 -4
- package/dist/middleware/pubsub/index.js +49 -3
- package/dist/middleware/pubsub/index.js.map +1 -1
- package/dist/middleware/pubsub/server/express/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/express/index.js +2 -2
- package/dist/middleware/pubsub/server/fastify/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/fastify/index.js +2 -2
- package/dist/middleware/pubsub/server/h3/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/h3/index.js +2 -2
- package/dist/middleware/pubsub/server/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/index.js +5 -5
- package/dist/middleware/pubsub/server/webapi/index.d.ts +3 -2
- package/dist/middleware/pubsub/server/webapi/index.js +2 -2
- package/dist/moonshot/index.d.ts +511 -0
- package/dist/moonshot/index.js +1090 -0
- package/dist/moonshot/index.js.map +1 -0
- package/dist/ollama/index.d.ts +3 -2
- package/dist/openai/index.d.ts +3 -2
- package/dist/openrouter/index.d.ts +3 -2
- package/dist/proxy/index.d.ts +5 -4
- package/dist/proxy/index.js +12 -10
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/server/express/index.d.ts +5 -4
- package/dist/proxy/server/express/index.js +3 -2
- package/dist/proxy/server/fastify/index.d.ts +5 -4
- package/dist/proxy/server/fastify/index.js +3 -2
- package/dist/proxy/server/h3/index.d.ts +19 -17
- package/dist/proxy/server/h3/index.js +3 -2
- package/dist/proxy/server/index.d.ts +5 -4
- package/dist/proxy/server/index.js +9 -8
- package/dist/proxy/server/webapi/index.d.ts +5 -4
- package/dist/proxy/server/webapi/index.js +3 -2
- package/dist/responses/index.d.ts +3 -2
- package/dist/{retry-CgoBNa51.d.ts → retry-C1eJbEMV.d.ts} +1 -1
- package/dist/{stream-sXhBtWjl.d.ts → stream-DVVUIKpz.d.ts} +3 -416
- package/dist/tool-D22EhP5F.d.ts +507 -0
- package/dist/{types-Cr4F0tVy.d.ts → types-CyXF0J7C.d.ts} +16 -3
- package/dist/utils/index.d.ts +65 -1
- package/dist/utils/index.js +15 -1
- package/dist/xai/index.d.ts +3 -2
- package/package.json +22 -3
- package/dist/chunk-EPB3GQNL.js.map +0 -1
- package/dist/chunk-YQLR3XOA.js.map +0 -1
- package/dist/chunk-ZRVNAET3.js.map +0 -1
- /package/dist/{chunk-4RX4VQCB.js.map → chunk-IIMTP3XC.js.map} +0 -0
- /package/dist/{chunk-IK6NRCW5.js.map → chunk-RDC5GYST.js.map} +0 -0
- /package/dist/{chunk-5IWHCXKN.js.map → chunk-SAMIK4WZ.js.map} +0 -0
- /package/dist/{chunk-2YXFLRQ6.js.map → chunk-WNB5PSY6.js.map} +0 -0
- /package/dist/{chunk-CRP6Y7NF.js.map → chunk-ZDYEDI2A.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/content.ts","../src/middleware/runner.ts","../src/core/llm.ts","../src/core/embedding.ts","../src/core/image.ts","../src/core/media/document.ts","../src/core/media/Audio.ts","../src/core/media/Video.ts","../src/types/embedding.ts","../src/index.ts"],"sourcesContent":["/**\n * @fileoverview Content block types for multimodal messages.\n *\n * Defines the various content block types that can be included in\n * user and assistant messages, supporting text, images, audio, video,\n * and arbitrary binary data.\n *\n * @module types/content\n */\n\n/**\n * Content block type constants.\n *\n * Use these constants instead of raw strings for type-safe content handling:\n *\n * @example\n * ```typescript\n * import { ContentBlockType } from 'upp';\n *\n * if (block.type === ContentBlockType.Text) {\n * console.log(block.text);\n * } else if (block.type === ContentBlockType.Image) {\n * console.log(block.mimeType);\n * }\n * ```\n */\nexport const ContentBlockType = {\n /** Text content */\n Text: 'text',\n /** Reasoning/thinking content from extended thinking models */\n Reasoning: 'reasoning',\n /** Image content */\n Image: 'image',\n /** Document content (PDFs, text files) */\n Document: 'document',\n /** Audio content */\n Audio: 'audio',\n /** Video content */\n Video: 'video',\n /** Binary/arbitrary data content */\n Binary: 'binary',\n} as const;\n\n/**\n * Content block type discriminator union.\n *\n * This type is derived from {@link ContentBlockType} constants.\n */\nexport type ContentBlockType = (typeof ContentBlockType)[keyof typeof ContentBlockType];\n\n/**\n * Image source type constants.\n *\n * @example\n * ```typescript\n * import { ImageSourceType } from 'upp';\n *\n * if (source.type === ImageSourceType.Base64) {\n * // Handle base64 encoded image\n * } else if (source.type === ImageSourceType.Url) {\n * // Handle URL reference\n * }\n * ```\n */\nexport const ImageSourceType = {\n /** Base64-encoded image data */\n Base64: 'base64',\n /** URL reference to image */\n Url: 'url',\n /** Raw bytes image data */\n Bytes: 'bytes',\n} as const;\n\n/**\n * Image source type discriminator union.\n *\n * This type is derived from {@link ImageSourceType} constants.\n */\nexport type ImageSourceType = (typeof ImageSourceType)[keyof typeof ImageSourceType];\n\n/**\n * Image source variants for ImageBlock.\n *\n * Images can be provided as base64-encoded strings, URLs, or raw bytes.\n *\n * @example\n * ```typescript\n * // Base64 encoded image\n * const base64Source: ImageSource = {\n * type: 'base64',\n * data: 'iVBORw0KGgo...'\n * };\n *\n * // URL reference\n * const urlSource: ImageSource = {\n * type: 'url',\n * url: 'https://example.com/image.png'\n * };\n *\n * // Raw bytes\n * const bytesSource: ImageSource = {\n * type: 'bytes',\n * data: new Uint8Array([...])\n * };\n * ```\n */\nexport type ImageSource =\n | { type: 'base64'; data: string }\n | { type: 'url'; url: string }\n | { type: 'bytes'; data: Uint8Array };\n\n/**\n * Document source type constants.\n *\n * @example\n * ```typescript\n * import { DocumentSourceType } from 'upp';\n *\n * if (source.type === DocumentSourceType.Base64) {\n * // Handle base64 encoded document (PDF)\n * } else if (source.type === DocumentSourceType.Url) {\n * // Handle URL reference (PDF)\n * } else if (source.type === DocumentSourceType.Text) {\n * // Handle plain text document\n * }\n * ```\n */\nexport const DocumentSourceType = {\n /** Base64-encoded document data (for PDFs) */\n Base64: 'base64',\n /** URL reference to document (for PDFs) */\n Url: 'url',\n /** Plain text document content */\n Text: 'text',\n} as const;\n\n/**\n * Document source type discriminator union.\n *\n * This type is derived from {@link DocumentSourceType} constants.\n */\nexport type DocumentSourceType = (typeof DocumentSourceType)[keyof typeof DocumentSourceType];\n\n/**\n * Document source variants for DocumentBlock.\n *\n * Documents can be provided as base64-encoded data (PDFs), URLs (PDFs), or plain text.\n *\n * @example\n * ```typescript\n * // Base64 encoded PDF\n * const base64Source: DocumentSource = {\n * type: 'base64',\n * data: 'JVBERi0xLjQK...'\n * };\n *\n * // URL reference to PDF\n * const urlSource: DocumentSource = {\n * type: 'url',\n * url: 'https://example.com/document.pdf'\n * };\n *\n * // Plain text document\n * const textSource: DocumentSource = {\n * type: 'text',\n * data: 'This is the document content...'\n * };\n * ```\n */\nexport type DocumentSource =\n | { type: 'base64'; data: string }\n | { type: 'url'; url: string }\n | { type: 'text'; data: string };\n\n/**\n * Text content block.\n *\n * The most common content block type, containing plain text content.\n *\n * @example\n * ```typescript\n * const textBlock: TextBlock = {\n * type: 'text',\n * text: 'Hello, world!'\n * };\n * ```\n */\nexport interface TextBlock {\n /** Discriminator for text blocks */\n type: 'text';\n\n /** The text content */\n text: string;\n}\n\n/**\n * Reasoning content block.\n *\n * Contains model reasoning/thinking from extended thinking or chain-of-thought.\n * This content represents the model's internal reasoning process.\n *\n * @example\n * ```typescript\n * const reasoningBlock: ReasoningBlock = {\n * type: 'reasoning',\n * text: 'Let me think about this step by step...'\n * };\n * ```\n */\nexport interface ReasoningBlock {\n /** Discriminator for reasoning blocks */\n type: 'reasoning';\n\n /** The reasoning/thinking text */\n text: string;\n}\n\n/**\n * Image content block.\n *\n * Contains an image with its source data and metadata.\n *\n * @example\n * ```typescript\n * const imageBlock: ImageBlock = {\n * type: 'image',\n * source: { type: 'url', url: 'https://example.com/photo.jpg' },\n * mimeType: 'image/jpeg',\n * width: 1920,\n * height: 1080\n * };\n * ```\n */\nexport interface ImageBlock {\n /** Discriminator for image blocks */\n type: 'image';\n\n /** The image data source */\n source: ImageSource;\n\n /** MIME type of the image (e.g., 'image/png', 'image/jpeg') */\n mimeType: string;\n\n /** Image width in pixels */\n width?: number;\n\n /** Image height in pixels */\n height?: number;\n}\n\n/**\n * Document content block.\n *\n * Contains a document (PDF or plain text) with its source and metadata.\n * Supports PDF documents via base64 encoding or URL, and plain text content.\n *\n * @example\n * ```typescript\n * // PDF document from base64\n * const pdfBlock: DocumentBlock = {\n * type: 'document',\n * source: { type: 'base64', data: 'JVBERi0xLjQK...' },\n * mimeType: 'application/pdf',\n * title: 'Annual Report'\n * };\n *\n * // Plain text document\n * const textDoc: DocumentBlock = {\n * type: 'document',\n * source: { type: 'text', data: 'Document contents here...' },\n * mimeType: 'text/plain'\n * };\n * ```\n */\nexport interface DocumentBlock {\n /** Discriminator for document blocks */\n type: 'document';\n\n /** The document data source */\n source: DocumentSource;\n\n /** MIME type of the document ('application/pdf' or 'text/plain') */\n mimeType: string;\n\n /** Optional document title (used for citations) */\n title?: string;\n}\n\n/**\n * Audio content block.\n *\n * Contains audio data with its metadata.\n *\n * @example\n * ```typescript\n * const audioBlock: AudioBlock = {\n * type: 'audio',\n * data: audioBytes,\n * mimeType: 'audio/mp3',\n * duration: 120.5\n * };\n * ```\n */\nexport interface AudioBlock {\n /** Discriminator for audio blocks */\n type: 'audio';\n\n /** Raw audio data */\n data: Uint8Array;\n\n /** MIME type of the audio (e.g., 'audio/mp3', 'audio/wav') */\n mimeType: string;\n\n /** Duration in seconds */\n duration?: number;\n}\n\n/**\n * Video content block.\n *\n * Contains video data with its metadata.\n *\n * @example\n * ```typescript\n * const videoBlock: VideoBlock = {\n * type: 'video',\n * data: videoBytes,\n * mimeType: 'video/mp4',\n * duration: 30,\n * width: 1920,\n * height: 1080\n * };\n * ```\n */\nexport interface VideoBlock {\n /** Discriminator for video blocks */\n type: 'video';\n\n /** Raw video data */\n data: Uint8Array;\n\n /** MIME type of the video (e.g., 'video/mp4', 'video/webm') */\n mimeType: string;\n\n /** Duration in seconds */\n duration?: number;\n\n /** Video width in pixels */\n width?: number;\n\n /** Video height in pixels */\n height?: number;\n}\n\n/**\n * Binary content block for arbitrary data.\n *\n * A generic block type for data that doesn't fit other categories.\n *\n * @example\n * ```typescript\n * const binaryBlock: BinaryBlock = {\n * type: 'binary',\n * data: pdfBytes,\n * mimeType: 'application/pdf',\n * metadata: { filename: 'document.pdf', pages: 10 }\n * };\n * ```\n */\nexport interface BinaryBlock {\n /** Discriminator for binary blocks */\n type: 'binary';\n\n /** Raw binary data */\n data: Uint8Array;\n\n /** MIME type of the data */\n mimeType: string;\n\n /** Additional metadata about the binary content */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Union of all content block types.\n *\n * Used when a function or property can accept any type of content block.\n */\nexport type ContentBlock =\n | TextBlock\n | ReasoningBlock\n | ImageBlock\n | DocumentBlock\n | AudioBlock\n | VideoBlock\n | BinaryBlock;\n\n/**\n * Content types allowed in user messages.\n *\n * Users can send any type of content block including binary data.\n */\nexport type UserContent =\n | TextBlock\n | ImageBlock\n | DocumentBlock\n | AudioBlock\n | VideoBlock\n | BinaryBlock;\n\n/**\n * Content types allowed in assistant messages.\n *\n * Assistants can generate text and media but not arbitrary binary data.\n */\nexport type AssistantContent =\n | TextBlock\n | ReasoningBlock\n | ImageBlock\n | AudioBlock\n | VideoBlock;\n\n/**\n * Creates a text content block from a string.\n *\n * @param content - The text content\n * @returns A TextBlock containing the provided text\n *\n * @example\n * ```typescript\n * const block = text('Hello, world!');\n * // { type: 'text', text: 'Hello, world!' }\n * ```\n */\nexport function text(content: string): TextBlock {\n return { type: ContentBlockType.Text, text: content };\n}\n\n/**\n * Creates a reasoning content block from a string.\n *\n * @param content - The reasoning/thinking content\n * @returns A ReasoningBlock containing the provided text\n *\n * @example\n * ```typescript\n * const block = reasoning('Let me think step by step...');\n * // { type: 'reasoning', text: 'Let me think step by step...' }\n * ```\n */\nexport function reasoning(content: string): ReasoningBlock {\n return { type: ContentBlockType.Reasoning, text: content };\n}\n\n/**\n * Type guard for TextBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a TextBlock\n *\n * @example\n * ```typescript\n * if (isTextBlock(block)) {\n * console.log(block.text);\n * }\n * ```\n */\nexport function isTextBlock(block: ContentBlock): block is TextBlock {\n return block.type === ContentBlockType.Text;\n}\n\n/**\n * Type guard for ReasoningBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a ReasoningBlock\n *\n * @example\n * ```typescript\n * if (isReasoningBlock(block)) {\n * console.log(block.text);\n * }\n * ```\n */\nexport function isReasoningBlock(block: ContentBlock): block is ReasoningBlock {\n return block.type === ContentBlockType.Reasoning;\n}\n\n/**\n * Type guard for ImageBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is an ImageBlock\n *\n * @example\n * ```typescript\n * if (isImageBlock(block)) {\n * console.log(block.mimeType, block.width, block.height);\n * }\n * ```\n */\nexport function isImageBlock(block: ContentBlock): block is ImageBlock {\n return block.type === ContentBlockType.Image;\n}\n\n/**\n * Type guard for DocumentBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a DocumentBlock\n *\n * @example\n * ```typescript\n * if (isDocumentBlock(block)) {\n * console.log(block.mimeType, block.title);\n * }\n * ```\n */\nexport function isDocumentBlock(block: ContentBlock): block is DocumentBlock {\n return block.type === ContentBlockType.Document;\n}\n\n/**\n * Type guard for AudioBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is an AudioBlock\n *\n * @example\n * ```typescript\n * if (isAudioBlock(block)) {\n * console.log(block.mimeType, block.duration);\n * }\n * ```\n */\nexport function isAudioBlock(block: ContentBlock): block is AudioBlock {\n return block.type === ContentBlockType.Audio;\n}\n\n/**\n * Type guard for VideoBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a VideoBlock\n *\n * @example\n * ```typescript\n * if (isVideoBlock(block)) {\n * console.log(block.mimeType, block.duration);\n * }\n * ```\n */\nexport function isVideoBlock(block: ContentBlock): block is VideoBlock {\n return block.type === ContentBlockType.Video;\n}\n\n/**\n * Type guard for BinaryBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a BinaryBlock\n *\n * @example\n * ```typescript\n * if (isBinaryBlock(block)) {\n * console.log(block.mimeType, block.metadata);\n * }\n * ```\n */\nexport function isBinaryBlock(block: ContentBlock): block is BinaryBlock {\n return block.type === ContentBlockType.Binary;\n}\n","/**\n * @fileoverview Middleware execution utilities.\n *\n * Provides functions for running middleware hooks in the correct order\n * and creating stream event transformers from middleware arrays.\n *\n * @module middleware/runner\n */\n\nimport type {\n Middleware,\n MiddlewareContext,\n StreamContext,\n} from '../types/middleware.ts';\nimport type { StreamEvent } from '../types/stream.ts';\nimport type { Tool } from '../types/tool.ts';\nimport type { Turn } from '../types/turn.ts';\n\n/**\n * Lifecycle hook names that can be run in forward or reverse order.\n */\nexport type LifecycleHook = 'onStart' | 'onEnd' | 'onRequest' | 'onResponse';\n\n/**\n * Runs a lifecycle hook for all middleware in the specified order.\n *\n * Hooks are run sequentially to maintain consistent ordering.\n * If reverse is true, middleware are processed in reverse array order.\n *\n * @param middlewares - Array of middleware to process\n * @param hook - The hook name to execute\n * @param ctx - The middleware context\n * @param reverse - Whether to run in reverse order (default: false)\n */\nexport async function runHook(\n middlewares: Middleware[],\n hook: LifecycleHook,\n ctx: MiddlewareContext,\n reverse = false\n): Promise<void> {\n const ordered = reverse ? [...middlewares].reverse() : middlewares;\n\n for (const mw of ordered) {\n const fn = mw[hook];\n if (fn) {\n await fn.call(mw, ctx);\n }\n }\n}\n\n/**\n * Runs the onError hook for all middleware that have it.\n *\n * Error hooks are always run for all middleware, regardless of which\n * middleware was active when the error occurred. Errors from error\n * hooks themselves are logged but not re-thrown.\n *\n * @param middlewares - Array of middleware to process\n * @param error - The error that occurred\n * @param ctx - The middleware context\n */\nexport async function runErrorHook(\n middlewares: Middleware[],\n error: Error,\n ctx: MiddlewareContext\n): Promise<void> {\n for (const mw of middlewares) {\n if (mw.onError) {\n try {\n await mw.onError(error, ctx);\n } catch (hookError) {\n // Log but don't throw - error hooks should not cause additional failures\n console.error(`[${mw.name}] Error in onError hook:`, hookError);\n }\n }\n }\n}\n\n/**\n * Runs the onAbort hook for all middleware that have it.\n *\n * Abort hooks are run for all middleware when a request is cancelled.\n * Errors from abort hooks are logged but not re-thrown.\n *\n * @param middlewares - Array of middleware to process\n * @param error - The cancellation error\n * @param ctx - The middleware context\n */\nexport async function runAbortHook(\n middlewares: Middleware[],\n error: Error,\n ctx: MiddlewareContext\n): Promise<void> {\n for (const mw of middlewares) {\n if (mw.onAbort) {\n try {\n await mw.onAbort(error, ctx);\n } catch (hookError) {\n // Log but don't throw - abort hooks should not cause additional failures\n console.error(`[${mw.name}] Error in onAbort hook:`, hookError);\n }\n }\n }\n}\n\n/**\n * Runs tool hooks (onToolCall or onToolResult) for all middleware.\n *\n * Tool hooks are run in forward order for onToolCall and allow middleware\n * to observe or log tool interactions.\n *\n * @param middlewares - Array of middleware to process\n * @param hook - Either 'onToolCall' or 'onToolResult'\n * @param tool - The tool being called/that was called\n * @param data - Parameters (onToolCall) or result (onToolResult)\n * @param ctx - The middleware context\n */\nexport async function runToolHook(\n middlewares: Middleware[],\n hook: 'onToolCall' | 'onToolResult',\n tool: Tool,\n data: unknown,\n ctx: MiddlewareContext\n): Promise<void> {\n for (const mw of middlewares) {\n const fn = mw[hook];\n if (fn) {\n await fn.call(mw, tool, data, ctx);\n }\n }\n}\n\n/**\n * Runs the onTurn hook for all middleware that have it.\n *\n * Turn hooks are run in reverse middleware order.\n *\n * @param middlewares - Array of middleware to process\n * @param turn - The completed Turn\n * @param ctx - The middleware context\n */\nexport async function runTurnHook(\n middlewares: Middleware[],\n turn: Turn,\n ctx: MiddlewareContext\n): Promise<void> {\n const ordered = [...middlewares].reverse();\n for (const mw of ordered) {\n if (mw.onTurn) {\n await mw.onTurn.call(mw, turn, ctx);\n }\n }\n}\n\n/**\n * Creates a stream event transformer from middleware array.\n *\n * The transformer applies onStreamEvent hooks from all middleware in sequence.\n * Each middleware can transform, filter (return null), or expand (return array)\n * events.\n *\n * @param middlewares - Array of middleware to process\n * @param ctx - The stream context\n * @returns A function that transforms stream events\n *\n * @example\n * ```typescript\n * const transformer = createStreamTransformer(middlewares, streamCtx);\n *\n * for await (const event of baseStream) {\n * const result = transformer(event);\n * if (result === null) continue;\n * if (Array.isArray(result)) {\n * for (const e of result) yield e;\n * } else {\n * yield result;\n * }\n * }\n * ```\n */\nexport function createStreamTransformer(\n middlewares: Middleware[],\n ctx: StreamContext\n): (event: StreamEvent) => StreamEvent | StreamEvent[] | null {\n const streamMiddlewares = middlewares.filter((mw) => mw.onStreamEvent);\n\n if (streamMiddlewares.length === 0) {\n return (event) => event;\n }\n\n return (event: StreamEvent): StreamEvent | StreamEvent[] | null => {\n let current: StreamEvent | StreamEvent[] | null = event;\n\n for (const mw of streamMiddlewares) {\n if (current === null) {\n return null;\n }\n\n if (Array.isArray(current)) {\n // Process each event in the array through this middleware\n const results: StreamEvent[] = [];\n for (const e of current) {\n const result = mw.onStreamEvent!(e, ctx);\n if (result === null) {\n continue;\n }\n if (Array.isArray(result)) {\n results.push(...result);\n } else {\n results.push(result);\n }\n }\n current = results.length > 0 ? results : null;\n } else {\n current = mw.onStreamEvent!(current, ctx);\n }\n }\n\n return current;\n };\n}\n\n/**\n * Runs onStreamEnd hook for all middleware that have it.\n *\n * Called after all stream events have been processed.\n *\n * @param middlewares - Array of middleware to process\n * @param ctx - The stream context\n */\nexport async function runStreamEndHook(\n middlewares: Middleware[],\n ctx: StreamContext\n): Promise<void> {\n for (const mw of middlewares) {\n if (mw.onStreamEnd) {\n await mw.onStreamEnd(ctx);\n }\n }\n}\n\n/**\n * Creates a fresh MiddlewareContext for a request.\n *\n * @param modality - The modality ('llm', 'embedding', 'image')\n * @param modelId - The model ID\n * @param provider - The provider name\n * @param streaming - Whether this is a streaming request\n * @param request - The request object\n * @returns A new MiddlewareContext\n */\nexport function createMiddlewareContext(\n modality: 'llm' | 'embedding' | 'image',\n modelId: string,\n provider: string,\n streaming: boolean,\n request: MiddlewareContext['request']\n): MiddlewareContext {\n return {\n modality,\n modelId,\n provider,\n streaming,\n request,\n response: undefined,\n state: new Map(),\n startTime: Date.now(),\n endTime: undefined,\n };\n}\n\n/**\n * Creates a fresh StreamContext for streaming operations.\n *\n * @param state - Shared state map (usually from MiddlewareContext)\n * @returns A new StreamContext\n */\nexport function createStreamContext(\n state: Map<string, unknown>\n): StreamContext {\n return { state };\n}\n","/**\n * @fileoverview LLM instance factory and streaming logic for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating and managing LLM instances,\n * including support for tool execution, streaming responses, and structured output.\n *\n * @module core/llm\n */\n\nimport type {\n LLMOptions,\n LLMInstance,\n LLMRequest,\n InferenceInput,\n BoundLLMModel,\n LLMCapabilities,\n} from '../types/llm.ts';\nimport type { AssistantMessage } from '../types/messages.ts';\nimport type { ContentBlock } from '../types/content.ts';\nimport {\n isTextBlock,\n isImageBlock,\n isDocumentBlock,\n isAudioBlock,\n isVideoBlock,\n isBinaryBlock,\n} from '../types/content.ts';\nimport type { AfterCallResult, BeforeCallResult, Tool, ToolExecution, ToolResult } from '../types/tool.ts';\nimport type { Turn, TokenUsage } from '../types/turn.ts';\nimport type { StreamResult, StreamEvent } from '../types/stream.ts';\nimport type { Thread } from '../types/thread.ts';\nimport type { ProviderConfig, LLMHandler } from '../types/provider.ts';\nimport type { Middleware, MiddlewareContext } from '../types/middleware.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveLLMHandler } from './provider-handlers.ts';\nimport {\n Message,\n UserMessage as UserMessageClass,\n ToolResultMessage,\n isUserMessage,\n} from '../types/messages.ts';\nimport { createTurn, aggregateUsage } from '../types/turn.ts';\nimport {\n createStreamResult,\n toolExecutionStart,\n toolExecutionEnd,\n} from '../types/stream.ts';\nimport { toError, isCancelledError } from '../utils/error.ts';\nimport {\n runHook,\n runErrorHook,\n runAbortHook,\n runToolHook,\n runTurnHook,\n runStreamEndHook,\n createStreamTransformer,\n createMiddlewareContext,\n createStreamContext,\n} from '../middleware/runner.ts';\n\n/** Default maximum iterations for the tool execution loop */\nconst DEFAULT_MAX_ITERATIONS = 10;\nconst TURN_START_INDEX_KEY = 'llm:turnStartIndex';\n\n/**\n * Validates that message content is compatible with provider capabilities.\n *\n * Checks user messages for media types (image, document, video, audio) and throws\n * if the provider does not support the required input modality.\n *\n * @param messages - Messages to validate\n * @param capabilities - Provider's declared capabilities\n * @param providerName - Provider name for error messages\n * @throws {UPPError} When a message contains unsupported media type\n */\nfunction validateMediaCapabilities(\n messages: Message[],\n capabilities: LLMCapabilities,\n providerName: string\n): void {\n for (const msg of messages) {\n if (!isUserMessage(msg)) continue;\n\n for (const block of msg.content) {\n if (block.type === 'image' && !capabilities.imageInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support image input`,\n ErrorCode.InvalidRequest,\n providerName,\n ModalityType.LLM\n );\n }\n if (block.type === 'document' && !capabilities.documentInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support document input`,\n ErrorCode.InvalidRequest,\n providerName,\n ModalityType.LLM\n );\n }\n if (block.type === 'video' && !capabilities.videoInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support video input`,\n ErrorCode.InvalidRequest,\n providerName,\n ModalityType.LLM\n );\n }\n if (block.type === 'audio' && !capabilities.audioInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support audio input`,\n ErrorCode.InvalidRequest,\n providerName,\n ModalityType.LLM\n );\n }\n }\n }\n}\n\n/**\n * Type guard to check if a value is a Message instance.\n *\n * Uses `instanceof` for class instances, with a structural fallback for\n * deserialized or reconstructed Message objects that have the expected shape.\n *\n * @param value - The value to check\n * @returns `true` if the value is a Message instance\n */\nfunction isMessageInstance(value: unknown): value is Message {\n if (value instanceof Message) {\n return true;\n }\n if (typeof value === 'object' && value !== null) {\n const obj = value as Record<string, unknown>;\n const type = obj.type;\n const id = obj.id;\n const timestamp = obj.timestamp;\n const hasValidTimestamp =\n timestamp instanceof Date ||\n (typeof timestamp === 'string' && !Number.isNaN(Date.parse(timestamp)));\n\n if (typeof id !== 'string' || id.length === 0 || !hasValidTimestamp) {\n return false;\n }\n\n if (type === 'user' || type === 'assistant') {\n return Array.isArray(obj.content);\n }\n\n if (type === 'tool_result') {\n return Array.isArray(obj.results);\n }\n }\n return false;\n}\n\n/**\n * Converts an inference input to a Message instance.\n *\n * Handles string inputs, existing Message objects, and ContentBlocks,\n * wrapping non-Message inputs in a UserMessage.\n *\n * @param input - The input to convert (string, Message, or ContentBlock)\n * @returns A Message instance\n */\nfunction inputToMessage(input: InferenceInput): Message {\n if (typeof input === 'string') {\n return new UserMessageClass(input);\n }\n\n if ('type' in input && 'id' in input && 'timestamp' in input) {\n return input as Message;\n }\n\n if (typeof input !== 'object' || input === null || !('type' in input)) {\n throw new Error('Invalid inference input');\n }\n\n const block = input as ContentBlock;\n if (isTextBlock(block)) {\n return new UserMessageClass(block.text);\n }\n\n if (\n isImageBlock(block) ||\n isDocumentBlock(block) ||\n isAudioBlock(block) ||\n isVideoBlock(block) ||\n isBinaryBlock(block)\n ) {\n return new UserMessageClass([block]);\n }\n\n throw new Error('Invalid inference input');\n}\n\n/**\n * Parses flexible input arguments to separate conversation history from new messages.\n *\n * Supports multiple input patterns:\n * - Thread object with existing messages\n * - Message array as history\n * - Direct input (string, Message, or ContentBlock) without history\n *\n * @param historyOrInput - Either conversation history or the first input\n * @param inputs - Additional inputs to convert to messages\n * @returns Object containing separated history and new messages arrays\n */\nfunction parseInputs(\n historyOrInput: Message[] | Thread | InferenceInput,\n inputs: InferenceInput[]\n): { history: Message[]; messages: Message[] } {\n if (\n typeof historyOrInput === 'object' &&\n historyOrInput !== null &&\n 'messages' in historyOrInput &&\n Array.isArray((historyOrInput as Thread).messages)\n ) {\n const thread = historyOrInput as Thread;\n const newMessages = inputs.map(inputToMessage);\n return { history: [...thread.messages], messages: newMessages };\n }\n\n if (Array.isArray(historyOrInput)) {\n if (historyOrInput.length === 0) {\n const newMessages = inputs.map(inputToMessage);\n return { history: [], messages: newMessages };\n }\n const first = historyOrInput[0];\n if (isMessageInstance(first)) {\n const newMessages = inputs.map(inputToMessage);\n return { history: historyOrInput as Message[], messages: newMessages };\n }\n }\n\n const allInputs = [historyOrInput as InferenceInput, ...inputs];\n const newMessages = allInputs.map(inputToMessage);\n return { history: [], messages: newMessages };\n}\n\n/**\n * Resolves the start index for the current turn within the request messages.\n *\n * Uses explicit history IDs when available, then falls back to an optional\n * middleware override, then attempts to locate new input message IDs.\n * If inputs cannot be located and no explicit history is available, defaults\n * to slicing from the start to avoid dropping expanded inputs.\n *\n * @param messages - Full request messages array after middleware\n * @param history - Explicit history messages provided by the caller\n * @param newMessages - New input messages for this request\n * @param requestMessageCount - Message count at request time (before model outputs)\n * @param overrideIndex - Optional override index provided via middleware state\n * @returns The index where the new turn begins\n */\nfunction resolveTurnStartIndex(\n messages: Message[],\n history: Message[],\n newMessages: Message[],\n requestMessageCount: number,\n overrideIndex?: number\n): number {\n if (history.length > 0) {\n const historyIds = new Set(history.map((message) => message.id));\n let lastHistoryIndex = -1;\n for (let i = 0; i < messages.length; i += 1) {\n if (historyIds.has(messages[i]!.id)) {\n lastHistoryIndex = i;\n }\n }\n if (lastHistoryIndex !== -1) {\n return lastHistoryIndex + 1;\n }\n }\n\n if (typeof overrideIndex === 'number' && Number.isFinite(overrideIndex)) {\n return Math.min(Math.max(0, overrideIndex), requestMessageCount);\n }\n\n if (newMessages.length > 0) {\n const newMessageIds = new Set(newMessages.map((message) => message.id));\n const index = messages.findIndex((message) => newMessageIds.has(message.id));\n if (index !== -1) {\n return index;\n }\n }\n\n if (history.length === 0) {\n return 0;\n }\n\n return Math.max(0, requestMessageCount - newMessages.length);\n}\n\n/**\n * Executes tool calls from an assistant message in parallel.\n *\n * Handles the complete tool execution flow including:\n * - Tool lookup and validation\n * - Strategy callbacks (onToolCall, onBeforeCall, onAfterCall, onError)\n * - Approval handlers\n * - Execution tracking and timing\n * - Stream event emission for real-time updates\n * - Middleware tool hooks\n *\n * @param assistantMessage - The assistant message containing tool calls\n * @param tools - Available tools to execute\n * @param toolStrategy - Strategy for controlling tool execution behavior\n * @param executions - Array to collect execution records (mutated in place)\n * @param onEvent - Optional callback for emitting stream events during execution\n * @param middleware - Optional middleware array for tool hooks\n * @param ctx - Optional middleware context\n * @returns Array of tool results to send back to the model\n */\nasync function executeTools(\n assistantMessage: AssistantMessage,\n tools: Tool[],\n toolStrategy: LLMOptions<unknown>['toolStrategy'],\n executions: ToolExecution[],\n onEvent?: (event: StreamEvent) => void,\n middleware: Middleware[] = [],\n ctx?: MiddlewareContext\n): Promise<ToolResult[]> {\n const toolCalls = assistantMessage.toolCalls ?? [];\n const results: ToolResult[] = [];\n\n const toolMap = new Map(tools.map((t) => [t.name, t]));\n\n const promises = toolCalls.map(async (call, index) => {\n const tool = toolMap.get(call.toolName);\n const toolName = tool?.name ?? call.toolName;\n const startTime = Date.now();\n\n onEvent?.(toolExecutionStart(call.toolCallId, toolName, startTime, index));\n\n let effectiveParams = call.arguments;\n\n const endWithError = async (errorMessage: string, approved?: boolean): Promise<ToolResult> => {\n const endTime = Date.now();\n if (tool) {\n await toolStrategy?.onError?.(tool, effectiveParams, new Error(errorMessage));\n }\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams,\n result: errorMessage,\n isError: true,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, errorMessage, true, endTime, index));\n return {\n toolCallId: call.toolCallId,\n result: errorMessage,\n isError: true,\n };\n };\n\n if (!tool) {\n return endWithError(`Tool '${call.toolName}' not found`);\n }\n\n try {\n await toolStrategy?.onToolCall?.(tool, effectiveParams);\n // Run middleware onToolCall hooks\n if (ctx) {\n await runToolHook(middleware, 'onToolCall', tool, effectiveParams, ctx);\n }\n } catch (error) {\n return endWithError(toError(error).message);\n }\n\n if (toolStrategy?.onBeforeCall) {\n let beforeResult: boolean | BeforeCallResult | undefined;\n try {\n beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);\n } catch (error) {\n return endWithError(toError(error).message);\n }\n\n const isBeforeCallResult = (value: unknown): value is BeforeCallResult =>\n typeof value === 'object' && value !== null && 'proceed' in value;\n\n if (isBeforeCallResult(beforeResult)) {\n if (!beforeResult.proceed) {\n return endWithError('Tool execution skipped');\n }\n if (beforeResult.params !== undefined) {\n effectiveParams = beforeResult.params as Record<string, unknown>;\n }\n } else if (!beforeResult) {\n return endWithError('Tool execution skipped');\n }\n }\n\n let approved = true;\n if (tool.approval) {\n try {\n approved = await tool.approval(effectiveParams);\n } catch (error) {\n return endWithError(toError(error).message);\n }\n }\n\n if (!approved) {\n const endTime = Date.now();\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams as Record<string, unknown>,\n result: 'Tool execution denied',\n isError: true,\n duration: endTime - startTime,\n approved: false,\n };\n executions.push(execution);\n\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, 'Tool execution denied by approval handler', true, endTime, index));\n\n return {\n toolCallId: call.toolCallId,\n result: 'Tool execution denied by approval handler',\n isError: true,\n };\n }\n\n try {\n let result = await tool.run(effectiveParams);\n const endTime = Date.now();\n\n if (toolStrategy?.onAfterCall) {\n const afterResult = await toolStrategy.onAfterCall(tool, effectiveParams, result);\n const isAfterCallResult = (value: unknown): value is AfterCallResult =>\n typeof value === 'object' && value !== null && 'result' in value;\n\n if (isAfterCallResult(afterResult)) {\n result = afterResult.result;\n }\n }\n\n // Run middleware onToolResult hooks\n if (ctx) {\n await runToolHook(middleware, 'onToolResult', tool, result, ctx);\n }\n\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams as Record<string, unknown>,\n result,\n isError: false,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, result, false, endTime, index));\n\n return {\n toolCallId: call.toolCallId,\n result,\n isError: false,\n };\n } catch (error) {\n const endTime = Date.now();\n const err = toError(error);\n await toolStrategy?.onError?.(tool, effectiveParams, err);\n\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams as Record<string, unknown>,\n result: err.message,\n isError: true,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, err.message, true, endTime, index));\n\n return {\n toolCallId: call.toolCallId,\n result: err.message,\n isError: true,\n };\n }\n });\n\n results.push(...(await Promise.all(promises)));\n return results;\n}\n\n/**\n * Executes a non-streaming generation request with automatic tool execution loop.\n *\n * Handles the complete lifecycle of a generation request including:\n * - Media capability validation\n * - Iterative tool execution until completion or max iterations\n * - Token usage aggregation across iterations\n * - Structured output extraction\n *\n * @typeParam TParams - Provider-specific parameter type\n * @param model - The bound LLM model to use\n * @param config - Provider configuration options\n * @param system - Optional system prompt\n * @param params - Provider-specific parameters\n * @param tools - Available tools for the model to call\n * @param toolStrategy - Strategy for tool execution behavior\n * @param structure - Schema for structured output\n * @param history - Previous conversation messages\n * @param newMessages - New messages to send\n * @returns A Turn containing all messages, tool executions, and usage\n * @throws {UPPError} When max iterations exceeded or media not supported\n */\nasync function executeGenerate<TParams>(\n model: BoundLLMModel<TParams>,\n config: ProviderConfig,\n system: string | unknown[] | undefined,\n params: TParams | undefined,\n tools: Tool[] | undefined,\n toolStrategy: LLMOptions<TParams>['toolStrategy'],\n structure: LLMOptions<TParams>['structure'],\n history: Message[],\n newMessages: Message[],\n middleware: Middleware[]\n): Promise<Turn> {\n const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n let allMessages: Message[] = [...history, ...newMessages];\n const toolExecutions: ToolExecution[] = [];\n const usages: TokenUsage[] = [];\n let cycles = 0;\n\n let structuredData: unknown;\n let turnStartIndex = history.length;\n\n // Create initial request for middleware context\n const initialRequest: LLMRequest<TParams> = {\n messages: allMessages,\n system,\n params,\n tools,\n structure,\n config,\n };\n\n const ctx = createMiddlewareContext(\n 'llm',\n model.modelId,\n model.provider.name,\n false,\n initialRequest\n );\n\n try {\n // Run middleware start and request hooks\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n allMessages = (ctx.request as LLMRequest<TParams>).messages;\n const requestMessageCount = allMessages.length;\n const overrideIndex = ctx.state.get(TURN_START_INDEX_KEY);\n turnStartIndex = resolveTurnStartIndex(\n allMessages,\n history,\n newMessages,\n requestMessageCount,\n typeof overrideIndex === 'number' ? overrideIndex : undefined\n );\n validateMediaCapabilities(allMessages, model.capabilities, model.provider.name);\n\n while (cycles < maxIterations + 1) {\n cycles++;\n\n const request: LLMRequest<TParams> = {\n messages: allMessages,\n system,\n params,\n tools,\n structure,\n config,\n };\n\n const response = await model.complete(request);\n usages.push(response.usage);\n allMessages.push(response.message);\n\n if (response.data !== undefined) {\n structuredData = response.data;\n }\n\n if (response.message.hasToolCalls && tools && tools.length > 0) {\n if (response.data !== undefined) {\n break;\n }\n\n if (cycles >= maxIterations) {\n await toolStrategy?.onMaxIterations?.(maxIterations);\n throw new UPPError(\n `Tool execution exceeded maximum iterations (${maxIterations})`,\n ErrorCode.InvalidRequest,\n model.provider.name,\n ModalityType.LLM\n );\n }\n\n const results = await executeTools(\n response.message,\n tools,\n toolStrategy,\n toolExecutions,\n undefined,\n middleware,\n ctx\n );\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n\n const data = structure ? structuredData : undefined;\n\n const turn = createTurn(\n allMessages.slice(turnStartIndex),\n toolExecutions,\n aggregateUsage(usages),\n cycles,\n data\n );\n\n // Set response and run end hooks\n ctx.response = {\n message: turn.response,\n usage: turn.usage,\n stopReason: 'end_turn',\n data,\n };\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runTurnHook(middleware, turn, ctx);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return turn;\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw err;\n }\n}\n\n/**\n * Executes a streaming generation request with automatic tool execution loop.\n *\n * Creates an async generator that yields stream events while handling the complete\n * lifecycle of a streaming request. The returned StreamResult provides both the\n * event stream and a promise that resolves to the final Turn.\n *\n * @typeParam TParams - Provider-specific parameter type\n * @param model - The bound LLM model to use\n * @param config - Provider configuration options\n * @param system - Optional system prompt\n * @param params - Provider-specific parameters\n * @param tools - Available tools for the model to call\n * @param toolStrategy - Strategy for tool execution behavior\n * @param structure - Schema for structured output\n * @param history - Previous conversation messages\n * @param newMessages - New messages to send\n * @returns A StreamResult with event generator and turn promise\n * @throws {UPPError} When max iterations exceeded or media not supported\n */\nfunction executeStream<TParams>(\n model: BoundLLMModel<TParams>,\n config: ProviderConfig,\n system: string | unknown[] | undefined,\n params: TParams | undefined,\n tools: Tool[] | undefined,\n toolStrategy: LLMOptions<TParams>['toolStrategy'],\n structure: LLMOptions<TParams>['structure'],\n history: Message[],\n newMessages: Message[],\n middleware: Middleware[]\n): StreamResult {\n const abortController = new AbortController();\n\n let allMessages: Message[] = [...history, ...newMessages];\n const toolExecutions: ToolExecution[] = [];\n const usages: TokenUsage[] = [];\n let cycles = 0;\n let generatorError: Error | null = null;\n let structuredData: unknown;\n let generatorCompleted = false;\n let turnStartIndex = history.length;\n\n // Create middleware contexts\n const initialRequest: LLMRequest<TParams> = {\n messages: allMessages,\n system,\n params,\n tools,\n structure,\n config,\n };\n\n const ctx = createMiddlewareContext(\n 'llm',\n model.modelId,\n model.provider.name,\n true,\n initialRequest\n );\n\n const streamCtx = createStreamContext(ctx.state);\n const transformer = createStreamTransformer(middleware, streamCtx);\n\n let resolveGenerator: () => void;\n let rejectGenerator: (error: Error) => void;\n let generatorSettled = false;\n const generatorDone = new Promise<void>((resolve, reject) => {\n resolveGenerator = () => {\n if (!generatorSettled) {\n generatorSettled = true;\n resolve();\n }\n };\n rejectGenerator = (error: Error) => {\n if (!generatorSettled) {\n generatorSettled = true;\n reject(error);\n }\n };\n });\n void generatorDone.catch((error) => {\n if (!generatorError) {\n generatorError = toError(error);\n }\n });\n\n const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n\n const onAbort = () => {\n const error = new UPPError('Stream cancelled', ErrorCode.Cancelled, model.provider.name, ModalityType.LLM);\n generatorError = error;\n rejectGenerator(error);\n };\n abortController.signal.addEventListener('abort', onAbort, { once: true });\n\n const ensureNotAborted = () => {\n if (abortController.signal.aborted) {\n throw new UPPError('Stream cancelled', ErrorCode.Cancelled, model.provider.name, ModalityType.LLM);\n }\n };\n\n async function* generateStream(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n // Check if already aborted before starting\n ensureNotAborted();\n\n // Run middleware start and request hooks\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n allMessages = (ctx.request as LLMRequest<TParams>).messages;\n const requestMessageCount = allMessages.length;\n const overrideIndex = ctx.state.get(TURN_START_INDEX_KEY);\n turnStartIndex = resolveTurnStartIndex(\n allMessages,\n history,\n newMessages,\n requestMessageCount,\n typeof overrideIndex === 'number' ? overrideIndex : undefined\n );\n validateMediaCapabilities(allMessages, model.capabilities, model.provider.name);\n\n while (cycles < maxIterations + 1) {\n cycles++;\n ensureNotAborted();\n\n const request: LLMRequest<TParams> = {\n messages: allMessages,\n system,\n params,\n tools,\n structure,\n config,\n signal: abortController.signal,\n };\n\n const streamResult = model.stream(request);\n\n for await (const event of streamResult) {\n ensureNotAborted();\n // Apply middleware stream transformer\n const transformed = transformer(event);\n if (transformed === null) continue;\n if (Array.isArray(transformed)) {\n for (const e of transformed) {\n yield e;\n }\n } else {\n yield transformed;\n }\n }\n\n const response = await streamResult.response;\n usages.push(response.usage);\n allMessages.push(response.message);\n\n if (response.data !== undefined) {\n structuredData = response.data;\n }\n\n if (response.message.hasToolCalls && tools && tools.length > 0) {\n if (response.data !== undefined) {\n break;\n }\n\n if (cycles >= maxIterations) {\n await toolStrategy?.onMaxIterations?.(maxIterations);\n throw new UPPError(\n `Tool execution exceeded maximum iterations (${maxIterations})`,\n ErrorCode.InvalidRequest,\n model.provider.name,\n ModalityType.LLM\n );\n }\n\n const toolEvents: StreamEvent[] = [];\n const results = await executeTools(\n response.message,\n tools,\n toolStrategy,\n toolExecutions,\n (event) => toolEvents.push(event),\n middleware,\n ctx\n );\n\n for (const event of toolEvents) {\n ensureNotAborted();\n // Tool events also go through transformer\n const transformed = transformer(event);\n if (transformed === null) continue;\n if (Array.isArray(transformed)) {\n for (const e of transformed) {\n yield e;\n }\n } else {\n yield transformed;\n }\n }\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n\n // Run stream end hooks\n await runStreamEndHook(middleware, streamCtx);\n\n generatorCompleted = true;\n resolveGenerator();\n } catch (error) {\n const err = toError(error);\n generatorError = err;\n if (isCancelledError(err)) {\n await runAbortHook(middleware, err, ctx);\n } else {\n await runErrorHook(middleware, err, ctx);\n }\n rejectGenerator(err);\n throw err;\n } finally {\n abortController.signal.removeEventListener('abort', onAbort);\n if (!generatorCompleted && !generatorSettled) {\n const error = new UPPError('Stream cancelled', ErrorCode.Cancelled, model.provider.name, ModalityType.LLM);\n generatorError = error;\n if (!abortController.signal.aborted) {\n abortController.abort();\n }\n await runAbortHook(middleware, error, ctx);\n rejectGenerator(error);\n }\n }\n }\n\n const createTurnPromise = async (): Promise<Turn> => {\n await generatorDone;\n\n if (generatorError) {\n throw generatorError;\n }\n\n const data = structure ? structuredData : undefined;\n\n const turn = createTurn(\n allMessages.slice(turnStartIndex),\n toolExecutions,\n aggregateUsage(usages),\n cycles,\n data\n );\n\n // Set response and run end hooks\n ctx.response = {\n message: turn.response,\n usage: turn.usage,\n stopReason: 'end_turn',\n data,\n };\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runTurnHook(middleware, turn, ctx);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return turn;\n };\n\n return createStreamResult(generateStream(), createTurnPromise, abortController);\n}\n\n/**\n * Creates an LLM instance configured with the specified options.\n *\n * This is the primary factory function for creating LLM instances. It validates\n * provider capabilities, binds the model, and returns an instance with `generate`\n * and `stream` methods for inference.\n *\n * @typeParam TParams - Provider-specific parameter type for model configuration\n * @param options - Configuration options for the LLM instance\n * @returns A configured LLM instance ready for inference\n * @throws {UPPError} When the provider does not support the LLM modality\n * @throws {UPPError} When structured output is requested but not supported\n * @throws {UPPError} When tools are provided but not supported\n *\n * @example\n * ```typescript\n * import { llm } from 'upp';\n * import { anthropic } from 'upp/providers/anthropic';\n *\n * const assistant = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * system: 'You are a helpful assistant.',\n * tools: [myTool],\n * });\n *\n * const turn = await assistant.generate('Hello, world!');\n * console.log(turn.text);\n * ```\n */\nexport function llm<TParams = unknown>(\n options: LLMOptions<TParams>\n): LLMInstance<TParams> {\n const {\n model: modelRef,\n config: explicitConfig = {},\n params,\n system,\n tools,\n toolStrategy,\n structure,\n middleware = [],\n } = options;\n\n // Merge providerConfig from model reference with explicit config\n // Explicit config takes precedence, with headers being deep-merged\n const providerConfig = modelRef.providerConfig ?? {};\n const config: ProviderConfig = {\n ...providerConfig,\n ...explicitConfig,\n headers: {\n ...providerConfig.headers,\n ...explicitConfig.headers,\n },\n };\n\n // Resolve the correct LLM handler based on model reference options\n // This handles providers with multiple handlers (e.g., OpenAI responses/completions)\n // Cast is safe: ModelInput uses structural typing with unknown for variance, but the\n // actual provider at runtime is a proper Provider with LLMHandler\n const provider = modelRef.provider;\n const llmHandler = resolveLLMHandler(provider, modelRef.options) as LLMHandler<TParams> | undefined;\n\n if (!llmHandler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support LLM modality`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.LLM\n );\n }\n\n // Bind the model\n const boundModel = llmHandler.bind(modelRef.modelId);\n\n // Validate capabilities at bind time\n const capabilities = boundModel.capabilities;\n\n // Check for structured output capability\n if (structure && !capabilities.structuredOutput) {\n throw new UPPError(\n `Provider '${provider.name}' does not support structured output`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.LLM\n );\n }\n\n // Check for tools capability\n if (tools && tools.length > 0 && !capabilities.tools) {\n throw new UPPError(\n `Provider '${provider.name}' does not support tools`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.LLM\n );\n }\n\n // Build the instance\n const instance: LLMInstance<TParams> = {\n model: boundModel,\n system,\n params,\n capabilities,\n\n async generate(\n historyOrInput: Message[] | Thread | InferenceInput,\n ...inputs: InferenceInput[]\n ): Promise<Turn> {\n const { history, messages } = parseInputs(historyOrInput, inputs);\n return executeGenerate(\n boundModel,\n config,\n system,\n params,\n tools,\n toolStrategy,\n structure,\n history,\n messages,\n middleware\n );\n },\n\n stream(\n historyOrInput: Message[] | Thread | InferenceInput,\n ...inputs: InferenceInput[]\n ): StreamResult {\n // Check streaming capability\n if (!capabilities.streaming) {\n throw new UPPError(\n `Provider '${provider.name}' does not support streaming`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.LLM\n );\n }\n const { history, messages } = parseInputs(historyOrInput, inputs);\n return executeStream(\n boundModel,\n config,\n system,\n params,\n tools,\n toolStrategy,\n structure,\n history,\n messages,\n middleware\n );\n },\n };\n\n return instance;\n}\n","/**\n * @fileoverview Embedding instance factory for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating embedding instances\n * that generate vector embeddings from text or other content.\n *\n * @module core/embedding\n */\n\nimport type {\n EmbeddingOptions,\n EmbeddingInstance,\n EmbeddingResult,\n EmbeddingProgress,\n EmbeddingStream,\n EmbedOptions,\n Embedding,\n} from '../types/embedding.ts';\nimport type {\n EmbeddingInput,\n BoundEmbeddingModel,\n EmbeddingResponse,\n ProviderConfig,\n EmbeddingRequest,\n} from '../types/provider.ts';\nimport type { Middleware } from '../types/middleware.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveEmbeddingHandler } from './provider-handlers.ts';\nimport { toError } from '../utils/error.ts';\nimport { runHook, runErrorHook, createMiddlewareContext } from '../middleware/runner.ts';\n\n/**\n * Decode base64-encoded float32 array.\n *\n * @param b64 - Base64-encoded float32 buffer\n * @param providerName - Provider name for error reporting\n * @returns Decoded float array\n */\nfunction decodeBase64(b64: string, providerName: string): number[] {\n try {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const floats = new Float32Array(bytes.buffer);\n return Array.from(floats);\n } catch (error) {\n const cause = error instanceof Error ? error : new Error('Failed to decode base64 vector');\n throw new UPPError(\n 'Invalid base64 embedding vector',\n ErrorCode.InvalidResponse,\n providerName,\n ModalityType.Embedding,\n undefined,\n cause\n );\n }\n}\n\n/**\n * Normalize vector from floats or base64 string to number array.\n *\n * @param vector - Float vector or base64 string\n * @param providerName - Provider name for error reporting\n * @returns Normalized float array\n */\nfunction normalizeVector(vector: number[] | string, providerName: string): number[] {\n if (Array.isArray(vector)) {\n return vector;\n }\n return decodeBase64(vector, providerName);\n}\n\n/**\n * Normalize provider response to public EmbeddingResult.\n *\n * @param response - Provider response\n * @param providerName - Provider name for error reporting\n * @returns Normalized embedding result\n */\nfunction normalizeResponse(response: EmbeddingResponse, providerName: string): EmbeddingResult {\n return {\n embeddings: response.embeddings.map((vec, i) => {\n const vector = normalizeVector(vec.vector, providerName);\n return {\n vector,\n dimensions: vector.length,\n index: vec.index ?? i,\n tokens: vec.tokens,\n metadata: vec.metadata,\n };\n }),\n usage: response.usage,\n metadata: response.metadata,\n };\n}\n\n/**\n * Execute single embed request.\n *\n * @param model - Bound embedding model\n * @param inputs - Input batch\n * @param params - Provider-specific params\n * @param config - Provider configuration\n * @param signal - Abort signal\n * @param inputType - Input type hint for optimization\n * @param middleware - Middleware array\n * @returns Normalized embedding result\n */\nasync function executeEmbed<TParams>(\n model: BoundEmbeddingModel<TParams>,\n inputs: EmbeddingInput[],\n params: TParams | undefined,\n config: EmbeddingOptions<TParams>['config'],\n signal?: AbortSignal,\n inputType?: EmbedOptions['inputType'],\n middleware: Middleware[] = []\n): Promise<EmbeddingResult> {\n const request: EmbeddingRequest<TParams> = {\n inputs,\n params,\n config: config ?? {},\n signal,\n inputType,\n };\n\n const ctx = createMiddlewareContext(\n 'embedding',\n model.modelId,\n model.provider.name,\n false,\n request\n );\n\n try {\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n\n const response = await model.embed(request);\n const result = normalizeResponse(response, model.provider.name);\n\n ctx.response = response;\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return result;\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw err;\n }\n}\n\n/**\n * Create chunked stream for large input sets.\n *\n * @param model - Bound embedding model\n * @param inputs - All embedding inputs\n * @param params - Provider-specific params\n * @param config - Provider configuration\n * @param options - Chunked stream options\n * @param middleware - Middleware array\n * @returns Embedding stream with progress updates\n */\nfunction createChunkedStream<TParams>(\n model: BoundEmbeddingModel<TParams>,\n inputs: EmbeddingInput[],\n params: TParams | undefined,\n config: EmbeddingOptions<TParams>['config'],\n options: EmbedOptions,\n middleware: Middleware[] = []\n): EmbeddingStream {\n const abortController = new AbortController();\n const batchSize = options.batchSize ?? model.maxBatchSize;\n const concurrency = options.concurrency ?? 1;\n\n let resolveResult!: (result: EmbeddingResult) => void;\n let rejectResult!: (error: Error) => void;\n let settled = false;\n const resultPromise = new Promise<EmbeddingResult>((resolve, reject) => {\n resolveResult = (result) => {\n if (!settled) {\n settled = true;\n resolve(result);\n }\n };\n rejectResult = (error) => {\n if (!settled) {\n settled = true;\n reject(error);\n }\n };\n });\n\n const cancelError = () => new UPPError(\n 'Embedding cancelled',\n ErrorCode.Cancelled,\n model.provider.name,\n ModalityType.Embedding\n );\n\n const onAbort = () => {\n rejectResult(cancelError());\n };\n\n abortController.signal.addEventListener('abort', onAbort, { once: true });\n const onExternalAbort = () => abortController.abort();\n if (options.signal) {\n options.signal.addEventListener('abort', onExternalAbort, { once: true });\n }\n\n const cleanupAbortListeners = () => {\n abortController.signal.removeEventListener('abort', onAbort);\n if (options.signal) {\n options.signal.removeEventListener('abort', onExternalAbort);\n }\n };\n\n // Create middleware context for the overall chunked operation\n const request: EmbeddingRequest<TParams> = {\n inputs,\n params,\n config: config ?? {},\n signal: abortController.signal,\n inputType: options.inputType,\n };\n\n const ctx = createMiddlewareContext(\n 'embedding',\n model.modelId,\n model.provider.name,\n true,\n request\n );\n\n async function* generate(): AsyncGenerator<EmbeddingProgress> {\n const total = inputs.length;\n const allEmbeddings: Embedding[] = [];\n let totalTokens = 0;\n\n const batches: Array<{ inputs: EmbeddingInput[]; startIndex: number }> = [];\n for (let i = 0; i < inputs.length; i += batchSize) {\n batches.push({ inputs: inputs.slice(i, i + batchSize), startIndex: i });\n }\n\n try {\n // Run middleware start hooks\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n\n for (let i = 0; i < batches.length; i += concurrency) {\n if (abortController.signal.aborted || options.signal?.aborted) {\n throw cancelError();\n }\n\n const chunk = batches.slice(i, i + concurrency);\n const responses = await Promise.all(\n chunk.map((batch) =>\n model.embed({\n inputs: batch.inputs,\n params,\n config: config ?? {},\n signal: abortController.signal,\n })\n )\n );\n\n const batchEmbeddings: Embedding[] = [];\n for (let responseIndex = 0; responseIndex < responses.length; responseIndex += 1) {\n const response = responses[responseIndex]!;\n const batch = chunk[responseIndex]!;\n for (let vecIndex = 0; vecIndex < response.embeddings.length; vecIndex += 1) {\n const vec = response.embeddings[vecIndex]!;\n const vector = normalizeVector(vec.vector, model.provider.name);\n const resolvedIndex = batch.startIndex + (vec.index ?? vecIndex);\n const emb: Embedding = {\n vector,\n dimensions: vector.length,\n index: resolvedIndex,\n tokens: vec.tokens,\n metadata: vec.metadata,\n };\n batchEmbeddings.push(emb);\n }\n totalTokens += response.usage.totalTokens;\n }\n\n allEmbeddings.push(...batchEmbeddings);\n\n yield {\n embeddings: batchEmbeddings,\n completed: allEmbeddings.length,\n total,\n percent: (allEmbeddings.length / total) * 100,\n };\n }\n\n const orderedEmbeddings = [...allEmbeddings].sort(\n (left, right) => left.index - right.index\n );\n\n const result = {\n embeddings: orderedEmbeddings,\n usage: { totalTokens },\n };\n\n // Run middleware end hooks\n ctx.response = { embeddings: orderedEmbeddings.map((e) => ({ vector: e.vector, index: e.index })), usage: { totalTokens } };\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runHook(middleware, 'onEnd', ctx, true);\n\n resolveResult(result);\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n rejectResult(err);\n throw err;\n } finally {\n cleanupAbortListeners();\n }\n }\n\n const generator = generate();\n\n return {\n [Symbol.asyncIterator]: () => generator,\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n}\n\n/**\n * Creates an embedding instance configured with the specified options.\n *\n * This is the primary factory function for creating embedding instances.\n * It validates provider capabilities, binds the model, and returns an\n * instance with an `embed` method for generating embeddings.\n *\n * @typeParam TParams - Provider-specific parameter type\n * @param options - Configuration options for the embedding instance\n * @returns A configured embedding instance ready for use\n * @throws {UPPError} When the provider does not support the embedding modality\n *\n * @example\n * ```typescript\n * import { embedding } from 'upp';\n * import { openai } from 'upp/openai';\n *\n * const embedder = embedding({\n * model: openai('text-embedding-3-large'),\n * params: { dimensions: 1536 }\n * });\n *\n * // Single input\n * const result = await embedder.embed('Hello world');\n *\n * // Batch input\n * const batch = await embedder.embed(['doc1', 'doc2', 'doc3']);\n *\n * // Large-scale with progress\n * const stream = embedder.embed(documents, { chunked: true });\n * for await (const progress of stream) {\n * console.log(`${progress.percent}% complete`);\n * }\n * ```\n */\nexport function embedding<TParams = unknown>(\n options: EmbeddingOptions<TParams>\n): EmbeddingInstance<TParams> {\n const { model: modelRef, config: explicitConfig = {}, params, middleware = [] } = options;\n const providerConfig = modelRef.providerConfig ?? {};\n const config: ProviderConfig = {\n ...providerConfig,\n ...explicitConfig,\n headers: {\n ...providerConfig.headers,\n ...explicitConfig.headers,\n },\n };\n\n const provider = modelRef.provider;\n const handler = resolveEmbeddingHandler<TParams>(provider);\n if (!handler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support embedding modality`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.Embedding\n );\n }\n\n const boundModel = handler.bind(modelRef.modelId);\n\n function embed(\n input: EmbeddingInput | EmbeddingInput[],\n embedOptions?: EmbedOptions & { chunked?: false }\n ): Promise<EmbeddingResult>;\n function embed(\n input: EmbeddingInput[],\n embedOptions: EmbedOptions & { chunked: true }\n ): EmbeddingStream;\n function embed(\n input: EmbeddingInput | EmbeddingInput[],\n embedOptions?: EmbedOptions\n ): Promise<EmbeddingResult> | EmbeddingStream {\n const inputs = Array.isArray(input) ? input : [input];\n\n if (embedOptions?.chunked) {\n return createChunkedStream(boundModel, inputs, params, config, embedOptions, middleware);\n }\n\n return executeEmbed(boundModel, inputs, params, config, embedOptions?.signal, embedOptions?.inputType, middleware);\n }\n\n return {\n model: boundModel,\n params,\n embed,\n };\n}\n","/**\n * @fileoverview Image generation instance factory for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating image generation instances,\n * including support for text-to-image generation, streaming, and image editing.\n *\n * @module core/image\n */\n\nimport type {\n ImageOptions,\n ImageInstance,\n ImageInput,\n ImageEditInput,\n ImageResult,\n ImageStreamResult,\n ImageStreamEvent,\n ImageGenerateOptions,\n ImageRequest,\n} from '../types/image.ts';\nimport type { ProviderConfig } from '../types/provider.ts';\nimport type { Middleware } from '../types/middleware.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveImageHandler } from './provider-handlers.ts';\nimport { toError } from '../utils/error.ts';\nimport { runHook, runErrorHook, createMiddlewareContext } from '../middleware/runner.ts';\n\n/**\n * Normalizes ImageInput to a prompt string.\n *\n * @param input - Either a string prompt or object with prompt field\n * @returns The prompt string\n */\nfunction normalizeInput(input: ImageInput): string {\n if (typeof input === 'string') {\n return input;\n }\n return input.prompt;\n}\n\n/**\n * Creates an image generation instance configured with the specified options.\n *\n * This is the primary factory function for creating image generation instances.\n * It validates provider capabilities, binds the model, and returns an instance\n * with `generate`, `stream`, and `edit` methods.\n *\n * @typeParam TParams - Provider-specific parameter type for model configuration\n * @param options - Configuration options for the image instance\n * @returns A configured image instance ready for generation\n * @throws {UPPError} When the provider does not support the image modality\n *\n * @example\n * ```typescript\n * import { image } from 'upp';\n * import { openai } from 'upp/providers/openai';\n *\n * const dalle = image({\n * model: openai('dall-e-3'),\n * params: { size: '1024x1024', quality: 'hd' }\n * });\n *\n * const result = await dalle.generate('A sunset over mountains');\n * console.log(result.images.length);\n * ```\n */\nexport function image<TParams = unknown>(\n options: ImageOptions<TParams>\n): ImageInstance<TParams> {\n const { model: modelRef, config: explicitConfig = {}, params, middleware = [] } = options;\n const providerConfig = modelRef.providerConfig ?? {};\n const config: ProviderConfig = {\n ...providerConfig,\n ...explicitConfig,\n headers: {\n ...providerConfig.headers,\n ...explicitConfig.headers,\n },\n };\n\n const provider = modelRef.provider;\n const imageHandler = resolveImageHandler<TParams>(provider);\n if (!imageHandler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support image modality`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.Image\n );\n }\n\n const boundModel = imageHandler.bind(modelRef.modelId);\n\n const capabilities = boundModel.capabilities;\n\n const normalizeImageError = (error: unknown): UPPError => {\n if (error instanceof UPPError) {\n return error;\n }\n const err = toError(error);\n return new UPPError(err.message, ErrorCode.ProviderError, provider.name, ModalityType.Image, undefined, err);\n };\n\n const instance: ImageInstance<TParams> = {\n model: boundModel,\n params,\n capabilities,\n\n async generate(input: ImageInput, generateOptions?: ImageGenerateOptions): Promise<ImageResult> {\n const prompt = normalizeInput(input);\n\n const request: ImageRequest<TParams> = {\n prompt,\n params,\n config,\n signal: generateOptions?.signal,\n };\n\n const ctx = createMiddlewareContext(\n 'image',\n boundModel.modelId,\n provider.name,\n false,\n request\n );\n\n try {\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n\n const response = await boundModel.generate(request);\n\n const result: ImageResult = {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n\n ctx.response = response;\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return result;\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw normalizeImageError(error);\n }\n },\n };\n\n if (capabilities.streaming && boundModel.stream) {\n const streamFn = boundModel.stream;\n instance.stream = function (input: ImageInput): ImageStreamResult {\n const prompt = normalizeInput(input);\n\n const abortController = new AbortController();\n const request: ImageRequest<TParams> = {\n prompt,\n params,\n config,\n signal: abortController.signal,\n };\n\n const ctx = createMiddlewareContext(\n 'image',\n boundModel.modelId,\n provider.name,\n true,\n request\n );\n\n const providerStream = streamFn(request);\n\n const resultPromise = (async () => {\n try {\n const response = await providerStream.response;\n const result = {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n\n ctx.response = response;\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return result;\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw normalizeImageError(error);\n }\n })();\n\n async function* wrappedStream(): AsyncGenerator<ImageStreamEvent, void, unknown> {\n try {\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n\n for await (const event of providerStream) {\n yield event;\n }\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw normalizeImageError(error);\n }\n }\n\n return {\n [Symbol.asyncIterator]: () => wrappedStream(),\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n };\n }\n\n if (capabilities.edit && boundModel.edit) {\n const edit = boundModel.edit;\n instance.edit = async function (input: ImageEditInput): Promise<ImageResult> {\n try {\n const response = await edit({\n image: input.image,\n mask: input.mask,\n prompt: input.prompt,\n params,\n config,\n });\n\n return {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n } catch (error) {\n throw normalizeImageError(error);\n }\n };\n }\n\n return instance;\n}\n\n/**\n * Creates an ImageStreamResult from an async generator.\n *\n * @param generator - The async generator of stream events\n * @param resultPromise - Promise resolving to final result\n * @param abortController - Controller for aborting the operation\n * @returns An ImageStreamResult\n */\nexport function createImageStreamResult(\n generator: AsyncGenerator<ImageStreamEvent, void, unknown>,\n resultPromise: Promise<ImageResult>,\n abortController: AbortController\n): ImageStreamResult {\n return {\n [Symbol.asyncIterator]: () => generator,\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n}\n","/**\n * @fileoverview Document content handling for the Universal Provider Protocol.\n *\n * Provides a unified Document class for working with documents across different sources\n * (file paths, URLs, raw text, base64). Supports PDF and plain text documents with\n * integration into UPP message content blocks.\n *\n * @module core/media/Document\n */\n\nimport type { DocumentSource, DocumentBlock } from '../../types/content.ts';\n\n/**\n * Detects the MIME type of a document based on its file extension.\n *\n * Supports PDF and common text file formats.\n * Returns 'application/octet-stream' for unknown extensions.\n *\n * @param path - File path or filename with extension\n * @returns The detected MIME type string\n */\nfunction detectMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n\n switch (ext) {\n case 'pdf':\n return 'application/pdf';\n case 'txt':\n case 'text':\n case 'md':\n case 'markdown':\n return 'text/plain';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Represents a document that can be used in UPP messages.\n *\n * Documents can be created from various sources (files, URLs, text, base64) and\n * converted to content blocks for provider APIs. The class provides a unified\n * interface regardless of the underlying source type.\n *\n * @example\n * ```typescript\n * // Load PDF from file\n * const pdfDoc = await Document.fromPath('./report.pdf');\n *\n * // Reference PDF by URL\n * const urlDoc = Document.fromUrl('https://example.com/document.pdf');\n *\n * // From plain text\n * const textDoc = Document.fromText('Document content here...');\n *\n * // Use in a message\n * const message = new UserMessage([document.toBlock()]);\n * ```\n */\nexport class Document {\n /** The underlying document source (base64, url, or text) */\n readonly source: DocumentSource;\n /** MIME type of the document ('application/pdf' or 'text/plain') */\n readonly mimeType: string;\n /** Optional document title (used for citations) */\n readonly title?: string;\n\n private constructor(\n source: DocumentSource,\n mimeType: string,\n title?: string\n ) {\n this.source = source;\n this.mimeType = mimeType;\n this.title = title;\n }\n\n /**\n * Whether this document has data loaded in memory.\n *\n * Returns `false` for URL-sourced documents that reference external resources.\n */\n get hasData(): boolean {\n return this.source.type !== 'url';\n }\n\n /**\n * Whether this document is a PDF.\n */\n get isPdf(): boolean {\n return this.mimeType === 'application/pdf';\n }\n\n /**\n * Whether this document is plain text.\n */\n get isText(): boolean {\n return this.mimeType === 'text/plain';\n }\n\n /**\n * Converts the document to a base64-encoded string.\n *\n * @returns The document data as a base64 string\n * @throws {Error} When the source is a URL or plain text\n */\n toBase64(): string {\n if (this.source.type === 'base64') {\n return this.source.data;\n }\n\n throw new Error('Cannot convert to base64. Only base64-sourced documents support this.');\n }\n\n /**\n * Gets the plain text content for text documents.\n *\n * @returns The document text content\n * @throws {Error} When the source is not plain text\n */\n toText(): string {\n if (this.source.type === 'text') {\n return this.source.data;\n }\n\n throw new Error('Cannot get text content. Only text-sourced documents support this.');\n }\n\n /**\n * Gets the URL for URL-sourced documents.\n *\n * @returns The document URL\n * @throws {Error} When the source is not a URL\n */\n toUrl(): string {\n if (this.source.type === 'url') {\n return this.source.url;\n }\n\n throw new Error('This document does not have a URL source.');\n }\n\n /**\n * Converts this Document to a DocumentBlock for use in UPP messages.\n *\n * @returns A DocumentBlock that can be included in message content arrays\n */\n toBlock(): DocumentBlock {\n return {\n type: 'document',\n source: this.source,\n mimeType: this.mimeType,\n title: this.title,\n };\n }\n\n /**\n * Creates a Document by reading a file from disk.\n *\n * The file is read into memory and base64-encoded. MIME type is automatically\n * detected from the file extension.\n *\n * @param path - Path to the document file\n * @param title - Optional document title\n * @returns Promise resolving to a Document with the file contents\n *\n * @example\n * ```typescript\n * const doc = await Document.fromPath('./reports/annual.pdf');\n * const docWithTitle = await Document.fromPath('./report.pdf', 'Annual Report 2024');\n * ```\n */\n static async fromPath(path: string, title?: string): Promise<Document> {\n const file = Bun.file(path);\n const exists = await file.exists();\n if (!exists) {\n throw new Error(`Document file not found at path: ${path}`);\n }\n\n let data: ArrayBuffer;\n try {\n data = await file.arrayBuffer();\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to read document file at path: ${path}. ${message}`);\n }\n\n if (data.byteLength === 0) {\n throw new Error(`Document file is empty at path: ${path}`);\n }\n const base64 = Buffer.from(data).toString('base64');\n const mimeType = detectMimeType(path);\n\n return new Document(\n { type: 'base64', data: base64 },\n mimeType,\n title\n );\n }\n\n /**\n * Creates a Document from a URL reference.\n *\n * The URL is stored as a reference and not fetched. Providers will handle\n * URL fetching if needed. Only PDF URLs are supported.\n * URLs must use the http or https protocol.\n *\n * @param url - URL pointing to the PDF document\n * @param title - Optional document title\n * @returns A Document referencing the URL\n *\n * @example\n * ```typescript\n * const doc = Document.fromUrl('https://example.com/report.pdf');\n * ```\n */\n static fromUrl(url: string, title?: string): Document {\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(url);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid URL';\n throw new Error(`Invalid document URL: ${message}`);\n }\n\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new Error(`Document URL must use http or https: ${url}`);\n }\n\n return new Document(\n { type: 'url', url },\n 'application/pdf',\n title\n );\n }\n\n /**\n * Creates a Document from base64-encoded data.\n *\n * @param base64 - The base64-encoded document data\n * @param mimeType - The MIME type ('application/pdf' or 'text/plain')\n * @param title - Optional document title\n * @returns A Document containing the base64 data\n *\n * @example\n * ```typescript\n * const doc = Document.fromBase64(pdfBase64, 'application/pdf', 'Contract');\n * ```\n */\n static fromBase64(base64: string, mimeType: string, title?: string): Document {\n return new Document(\n { type: 'base64', data: base64 },\n mimeType,\n title\n );\n }\n\n /**\n * Creates a Document from plain text content.\n *\n * @param text - The document text content\n * @param title - Optional document title\n * @returns A Document containing the text\n *\n * @example\n * ```typescript\n * const doc = Document.fromText('This is the document content.', 'Notes');\n * ```\n */\n static fromText(text: string, title?: string): Document {\n return new Document(\n { type: 'text', data: text },\n 'text/plain',\n title\n );\n }\n\n /**\n * Creates a Document from an existing DocumentBlock.\n *\n * Useful for converting content blocks received from providers back\n * into Document instances for further processing.\n *\n * @param block - A DocumentBlock from message content\n * @returns A Document with the block's source and metadata\n */\n static fromBlock(block: DocumentBlock): Document {\n return new Document(\n block.source,\n block.mimeType,\n block.title\n );\n }\n}\n","/**\n * @fileoverview Audio content handling for the Universal Provider Protocol.\n *\n * Provides a unified Audio class for working with audio across different sources\n * (file paths, raw bytes, base64). Supports conversion between formats and\n * integration with UPP message content blocks.\n *\n * @module core/media/Audio\n */\n\nimport type { AudioBlock } from '../../types/content.ts';\n\n/**\n * Detects the MIME type of an audio file based on its file extension.\n *\n * Supports common audio formats: MP3, WAV, OGG, FLAC, AAC, M4A, WebM.\n * Returns 'application/octet-stream' for unknown extensions.\n *\n * Note: Provider support varies. Google Gemini supports MP3, WAV, AIFF, AAC,\n * OGG Vorbis, and FLAC. Opus is NOT supported by Google.\n *\n * @param path - File path or filename with extension\n * @returns The detected MIME type string\n */\nfunction detectMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n\n switch (ext) {\n case 'mp3':\n return 'audio/mp3';\n case 'wav':\n return 'audio/wav';\n case 'ogg':\n case 'oga':\n return 'audio/ogg';\n case 'flac':\n return 'audio/flac';\n case 'aac':\n return 'audio/aac';\n case 'm4a':\n return 'audio/mp4';\n case 'webm':\n return 'audio/webm';\n case 'aiff':\n case 'aif':\n return 'audio/aiff';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Represents an audio file that can be used in UPP messages.\n *\n * Audio can be created from various sources (files, bytes, base64) and\n * converted to different formats as needed by providers. The class provides\n * a unified interface regardless of the underlying source type.\n *\n * Note: Providers have size limits for inline audio data. Google Gemini\n * limits inline data to 20MB per request. For larger files, consider using\n * provider-specific file upload APIs.\n *\n * @example\n * ```typescript\n * // Load from file\n * const fileAudio = await Audio.fromPath('./recording.mp3');\n *\n * // From raw bytes\n * const bytesAudio = Audio.fromBytes(uint8Array, 'audio/wav');\n *\n * // Use in a message\n * const message = new UserMessage([audio.toBlock()]);\n * ```\n */\nexport class Audio {\n /** The audio data as raw bytes */\n readonly data: Uint8Array;\n /** MIME type of the audio (e.g., 'audio/mp3', 'audio/wav') */\n readonly mimeType: string;\n /** Duration in seconds, if known */\n readonly duration?: number;\n\n private constructor(\n data: Uint8Array,\n mimeType: string,\n duration?: number\n ) {\n this.data = data;\n this.mimeType = mimeType;\n this.duration = duration;\n }\n\n /**\n * Gets the size of the audio data in bytes.\n */\n get size(): number {\n return this.data.length;\n }\n\n /**\n * Converts the audio to a base64-encoded string.\n *\n * @returns The audio data as a base64 string\n */\n toBase64(): string {\n return btoa(\n Array.from(this.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n }\n\n /**\n * Converts the audio to a data URL suitable for embedding.\n *\n * @returns A data URL in the format `data:{mimeType};base64,{data}`\n */\n toDataUrl(): string {\n const base64 = this.toBase64();\n return `data:${this.mimeType};base64,${base64}`;\n }\n\n /**\n * Gets the audio data as raw bytes.\n *\n * @returns The audio data as a Uint8Array\n */\n toBytes(): Uint8Array {\n return this.data;\n }\n\n /**\n * Converts this Audio to an AudioBlock for use in UPP messages.\n *\n * @returns An AudioBlock that can be included in message content arrays\n */\n toBlock(): AudioBlock {\n return {\n type: 'audio',\n data: this.data,\n mimeType: this.mimeType,\n duration: this.duration,\n };\n }\n\n /**\n * Creates an Audio by reading a file from disk.\n *\n * The file is read into memory as bytes. MIME type is automatically\n * detected from the file extension.\n *\n * @param path - Path to the audio file\n * @param duration - Optional duration in seconds\n * @returns Promise resolving to an Audio with the file contents\n *\n * @example\n * ```typescript\n * const audio = await Audio.fromPath('./recordings/interview.mp3');\n * ```\n */\n static async fromPath(path: string, duration?: number): Promise<Audio> {\n const file = Bun.file(path);\n const exists = await file.exists();\n if (!exists) {\n throw new Error(`Audio file not found at path: ${path}`);\n }\n\n let arrayBuffer: ArrayBuffer;\n try {\n arrayBuffer = await file.arrayBuffer();\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to read audio file at path: ${path}. ${message}`);\n }\n\n if (arrayBuffer.byteLength === 0) {\n throw new Error(`Audio file is empty at path: ${path}`);\n }\n\n const mimeType = detectMimeType(path);\n\n return new Audio(\n new Uint8Array(arrayBuffer),\n mimeType,\n duration\n );\n }\n\n /**\n * Creates an Audio from raw byte data.\n *\n * @param data - The audio data as a Uint8Array\n * @param mimeType - The MIME type of the audio\n * @param duration - Optional duration in seconds\n * @returns An Audio containing the byte data\n *\n * @example\n * ```typescript\n * const audio = Audio.fromBytes(wavData, 'audio/wav');\n * ```\n */\n static fromBytes(data: Uint8Array, mimeType: string, duration?: number): Audio {\n return new Audio(data, mimeType, duration);\n }\n\n /**\n * Creates an Audio from a base64-encoded string.\n *\n * @param base64 - The base64-encoded audio data (without data URL prefix)\n * @param mimeType - The MIME type of the audio\n * @param duration - Optional duration in seconds\n * @returns An Audio containing the decoded data\n *\n * @example\n * ```typescript\n * const audio = Audio.fromBase64(base64String, 'audio/mp3');\n * ```\n */\n static fromBase64(base64: string, mimeType: string, duration?: number): Audio {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return new Audio(bytes, mimeType, duration);\n }\n\n /**\n * Creates an Audio from an existing AudioBlock.\n *\n * Useful for converting content blocks received from providers back\n * into Audio instances for further processing.\n *\n * @param block - An AudioBlock from message content\n * @returns An Audio with the block's data and metadata\n */\n static fromBlock(block: AudioBlock): Audio {\n return new Audio(\n block.data,\n block.mimeType,\n block.duration\n );\n }\n}\n","/**\n * @fileoverview Video content handling for the Universal Provider Protocol.\n *\n * Provides a unified Video class for working with video across different sources\n * (file paths, raw bytes, base64). Supports conversion between formats and\n * integration with UPP message content blocks.\n *\n * @module core/media/Video\n */\n\nimport type { VideoBlock } from '../../types/content.ts';\n\n/**\n * Detects the MIME type of a video file based on its file extension.\n *\n * Supports common video formats: MP4, WebM, OGV, MOV, AVI, MPEG, WMV, 3GPP, FLV.\n * Returns 'application/octet-stream' for unknown extensions.\n *\n * Note: Provider support varies. Google Gemini supports MP4, MPEG, MOV, AVI,\n * WMV, MPEGPS, FLV, 3GPP, and WebM. MKV is NOT supported by Google.\n *\n * @param path - File path or filename with extension\n * @returns The detected MIME type string\n */\nfunction detectMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n\n switch (ext) {\n case 'mp4':\n case 'm4v':\n return 'video/mp4';\n case 'webm':\n return 'video/webm';\n case 'ogv':\n case 'ogg':\n return 'video/ogg';\n case 'mov':\n return 'video/quicktime';\n case 'avi':\n return 'video/x-msvideo';\n case 'mpeg':\n case 'mpg':\n return 'video/mpeg';\n case 'wmv':\n return 'video/x-ms-wmv';\n case '3gp':\n case '3gpp':\n return 'video/3gpp';\n case 'flv':\n return 'video/x-flv';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Represents a video file that can be used in UPP messages.\n *\n * Video can be created from various sources (files, bytes, base64) and\n * converted to different formats as needed by providers. The class provides\n * a unified interface regardless of the underlying source type.\n *\n * Note: Providers have size limits for inline video data. Google Gemini\n * limits inline data to 20MB per request. For larger files, consider using\n * provider-specific file upload APIs.\n *\n * @example\n * ```typescript\n * // Load from file\n * const fileVideo = await Video.fromPath('./clip.mp4');\n *\n * // From raw bytes\n * const bytesVideo = Video.fromBytes(uint8Array, 'video/webm');\n *\n * // Use in a message\n * const message = new UserMessage([video.toBlock()]);\n * ```\n */\nexport class Video {\n /** The video data as raw bytes */\n readonly data: Uint8Array;\n /** MIME type of the video (e.g., 'video/mp4', 'video/webm') */\n readonly mimeType: string;\n /** Duration in seconds, if known */\n readonly duration?: number;\n /** Video width in pixels, if known */\n readonly width?: number;\n /** Video height in pixels, if known */\n readonly height?: number;\n\n private constructor(\n data: Uint8Array,\n mimeType: string,\n options?: { duration?: number; width?: number; height?: number }\n ) {\n this.data = data;\n this.mimeType = mimeType;\n this.duration = options?.duration;\n this.width = options?.width;\n this.height = options?.height;\n }\n\n /**\n * Gets the size of the video data in bytes.\n */\n get size(): number {\n return this.data.length;\n }\n\n /**\n * Converts the video to a base64-encoded string.\n *\n * @returns The video data as a base64 string\n */\n toBase64(): string {\n return btoa(\n Array.from(this.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n }\n\n /**\n * Converts the video to a data URL suitable for embedding.\n *\n * @returns A data URL in the format `data:{mimeType};base64,{data}`\n */\n toDataUrl(): string {\n const base64 = this.toBase64();\n return `data:${this.mimeType};base64,${base64}`;\n }\n\n /**\n * Gets the video data as raw bytes.\n *\n * @returns The video data as a Uint8Array\n */\n toBytes(): Uint8Array {\n return this.data;\n }\n\n /**\n * Converts this Video to a VideoBlock for use in UPP messages.\n *\n * @returns A VideoBlock that can be included in message content arrays\n */\n toBlock(): VideoBlock {\n return {\n type: 'video',\n data: this.data,\n mimeType: this.mimeType,\n duration: this.duration,\n width: this.width,\n height: this.height,\n };\n }\n\n /**\n * Creates a Video by reading a file from disk.\n *\n * The file is read into memory as bytes. MIME type is automatically\n * detected from the file extension.\n *\n * @param path - Path to the video file\n * @param options - Optional metadata (duration, width, height)\n * @returns Promise resolving to a Video with the file contents\n *\n * @example\n * ```typescript\n * const video = await Video.fromPath('./clips/demo.mp4');\n * const videoWithMeta = await Video.fromPath('./clip.mp4', { duration: 30, width: 1920, height: 1080 });\n * ```\n */\n static async fromPath(\n path: string,\n options?: { duration?: number; width?: number; height?: number }\n ): Promise<Video> {\n const file = Bun.file(path);\n const exists = await file.exists();\n if (!exists) {\n throw new Error(`Video file not found at path: ${path}`);\n }\n\n let arrayBuffer: ArrayBuffer;\n try {\n arrayBuffer = await file.arrayBuffer();\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to read video file at path: ${path}. ${message}`);\n }\n\n if (arrayBuffer.byteLength === 0) {\n throw new Error(`Video file is empty at path: ${path}`);\n }\n\n const mimeType = detectMimeType(path);\n\n return new Video(\n new Uint8Array(arrayBuffer),\n mimeType,\n options\n );\n }\n\n /**\n * Creates a Video from raw byte data.\n *\n * @param data - The video data as a Uint8Array\n * @param mimeType - The MIME type of the video\n * @param options - Optional metadata (duration, width, height)\n * @returns A Video containing the byte data\n *\n * @example\n * ```typescript\n * const video = Video.fromBytes(mp4Data, 'video/mp4');\n * const videoWithMeta = Video.fromBytes(data, 'video/mp4', { duration: 60 });\n * ```\n */\n static fromBytes(\n data: Uint8Array,\n mimeType: string,\n options?: { duration?: number; width?: number; height?: number }\n ): Video {\n return new Video(data, mimeType, options);\n }\n\n /**\n * Creates a Video from a base64-encoded string.\n *\n * @param base64 - The base64-encoded video data (without data URL prefix)\n * @param mimeType - The MIME type of the video\n * @param options - Optional metadata (duration, width, height)\n * @returns A Video containing the decoded data\n *\n * @example\n * ```typescript\n * const video = Video.fromBase64(base64String, 'video/mp4');\n * ```\n */\n static fromBase64(\n base64: string,\n mimeType: string,\n options?: { duration?: number; width?: number; height?: number }\n ): Video {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return new Video(bytes, mimeType, options);\n }\n\n /**\n * Creates a Video from an existing VideoBlock.\n *\n * Useful for converting content blocks received from providers back\n * into Video instances for further processing.\n *\n * @param block - A VideoBlock from message content\n * @returns A Video with the block's data and metadata\n */\n static fromBlock(block: VideoBlock): Video {\n return new Video(\n block.data,\n block.mimeType,\n {\n duration: block.duration,\n width: block.width,\n height: block.height,\n }\n );\n }\n}\n","/**\n * @fileoverview Embedding types for vector embedding generation.\n *\n * Defines the interfaces for configuring and executing embedding operations,\n * including options, instances, requests, responses, and streaming progress.\n *\n * @module types/embedding\n */\n\nimport type {\n ProviderConfig,\n BoundEmbeddingModel,\n EmbeddingInput,\n EmbeddingUsage,\n ProviderIdentity,\n} from './provider.ts';\nimport type { Middleware } from './middleware.ts';\n\n/**\n * Input type hints for provider-specific embedding optimization.\n * Some providers optimize embeddings differently for queries vs documents.\n */\nexport const EmbeddingInputType = {\n /** Input is a document to be stored/indexed */\n Document: 'document',\n /** Input is a query for retrieval/search */\n Query: 'query',\n} as const;\n\nexport type EmbeddingInputType = (typeof EmbeddingInputType)[keyof typeof EmbeddingInputType];\n\n/**\n * Structural type for embedding model input.\n * Uses structural typing to avoid generic variance issues with Provider generics.\n *\n * @remarks\n * This type mirrors {@link ModelReference} while keeping provider options\n * structurally compatible across providers.\n *\n * @see ModelReference\n */\nexport interface EmbeddingModelInput {\n readonly modelId: string;\n readonly provider: ProviderIdentity;\n /** Optional provider configuration merged into requests */\n readonly providerConfig?: Partial<ProviderConfig>;\n}\n\n/**\n * Options for creating an embedding instance with the embedding() function.\n *\n * @typeParam TParams - Provider-specific parameter type\n *\n * @example\n * ```typescript\n * const options: EmbeddingOptions<OpenAIEmbedParams> = {\n * model: openai('text-embedding-3-large'),\n * config: { apiKey: process.env.OPENAI_API_KEY },\n * params: { dimensions: 1536 }\n * };\n * ```\n */\nexport interface EmbeddingOptions<TParams = unknown> {\n /** A model reference from a provider factory */\n model: EmbeddingModelInput;\n\n /** Provider infrastructure configuration */\n config?: ProviderConfig;\n\n /** Provider-specific parameters (passed through unchanged) */\n params?: TParams;\n\n /**\n * Middleware for intercepting and transforming requests and responses.\n *\n * Middleware are executed in array order for request/start hooks,\n * and reverse order for response/end hooks.\n */\n middleware?: Middleware[];\n}\n\n/**\n * Options for embed() calls.\n */\nexport interface EmbedOptions {\n /**\n * Enable chunked processing with progress for large input sets.\n * When true, returns EmbeddingStream instead of Promise.\n */\n chunked?: boolean;\n\n /** Inputs per batch when chunked (default: provider max) */\n batchSize?: number;\n\n /** Concurrent batch limit when chunked (default: 1) */\n concurrency?: number;\n\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n\n /** Hint for embedding optimization (provider-specific) */\n inputType?: EmbeddingInputType;\n}\n\n/**\n * Single embedding vector result.\n */\nexport interface Embedding {\n /** The embedding vector */\n vector: number[];\n\n /** Vector dimensionality */\n dimensions: number;\n\n /** Index corresponding to input array position */\n index: number;\n\n /** Token count for this input (if provider reports) */\n tokens?: number;\n\n /** Provider-specific per-embedding metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Result from embed() call.\n */\nexport interface EmbeddingResult {\n /** Embeddings in same order as inputs */\n embeddings: Embedding[];\n\n /** Usage statistics */\n usage: EmbeddingUsage;\n\n /** Provider-specific response metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Progress update when using chunked mode.\n */\nexport interface EmbeddingProgress {\n /** Embeddings from the latest batch */\n embeddings: Embedding[];\n\n /** Total embeddings completed so far */\n completed: number;\n\n /** Total number of inputs */\n total: number;\n\n /** Percentage complete (0-100) */\n percent: number;\n}\n\n/**\n * Async iterable stream with final result accessor.\n * Returned when embed() is called with { chunked: true }.\n */\nexport interface EmbeddingStream extends AsyncIterable<EmbeddingProgress> {\n /** Promise resolving to complete result after iteration */\n readonly result: Promise<EmbeddingResult>;\n\n /** Abort the operation */\n abort(): void;\n}\n\n/**\n * Embedding instance returned by the embedding() function.\n *\n * @typeParam TParams - Provider-specific parameter type\n *\n * @example\n * ```typescript\n * const embedder = embedding({ model: openai('text-embedding-3-large') });\n *\n * // Single input\n * const result = await embedder.embed('Hello world');\n *\n * // Batch input\n * const batch = await embedder.embed(['doc1', 'doc2', 'doc3']);\n *\n * // Large-scale with progress\n * const stream = embedder.embed(documents, { chunked: true });\n * for await (const progress of stream) {\n * console.log(`${progress.percent}% complete`);\n * }\n * ```\n */\nexport interface EmbeddingInstance<TParams = unknown> {\n /**\n * Generate embeddings for one or more inputs.\n *\n * @param input - Single input or array of inputs\n * @param options - Optional embed options\n * @returns Promise<EmbeddingResult> or EmbeddingStream if chunked\n */\n embed(\n input: EmbeddingInput | EmbeddingInput[],\n options?: EmbedOptions & { chunked?: false }\n ): Promise<EmbeddingResult>;\n embed(\n input: EmbeddingInput[],\n options: EmbedOptions & { chunked: true }\n ): EmbeddingStream;\n embed(\n input: EmbeddingInput | EmbeddingInput[],\n options?: EmbedOptions\n ): Promise<EmbeddingResult> | EmbeddingStream;\n\n /** The bound embedding model */\n readonly model: BoundEmbeddingModel<TParams>;\n\n /** Current parameters */\n readonly params: TParams | undefined;\n}\n","/**\n * @fileoverview Unified Provider Protocol (UPP) - A unified interface for AI model inference\n *\n * UPP provides a consistent API for interacting with multiple AI providers including\n * Anthropic, OpenAI, Google, Ollama, OpenRouter, and xAI. The library handles provider-specific\n * transformations, streaming, tool execution, and error handling.\n *\n * @module @providerprotocol/ai\n * @packageDocumentation\n */\n\n/**\n * LLM instance factory for creating model-bound inference functions.\n *\n * @example Basic usage\n * ```typescript\n * import { llm, anthropic } from '@providerprotocol/ai';\n *\n * const model = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * params: { max_tokens: 1000 }\n * });\n *\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Streaming\n * ```typescript\n * for await (const event of model.stream('Tell me a story')) {\n * if (event.type === 'text') {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n */\nexport { llm } from './core/llm.ts';\n\n/** Embedding instance factory for creating model-bound embedding functions */\nexport { embedding } from './core/embedding.ts';\n\n/** Image generation instance factory for creating model-bound image functions */\nexport { image } from './core/image.ts';\n\n/** Factory for creating custom providers */\nexport { createProvider } from './core/provider.ts';\n\n/** Image content wrapper for multimodal inputs */\nexport { Image } from './core/media/Image.ts';\n\n/** Document content wrapper for PDF and text documents */\nexport { Document } from './core/media/document.ts';\n\n/** Audio content wrapper for audio inputs */\nexport { Audio } from './core/media/Audio.ts';\n\n/** Video content wrapper for video inputs */\nexport { Video } from './core/media/Video.ts';\n\nimport { llm } from './core/llm.ts';\nimport { embedding } from './core/embedding.ts';\nimport { image } from './core/image.ts';\n\n/**\n * UPP namespace object providing alternative import style.\n *\n * @example\n * ```typescript\n * import { ai } from '@providerprotocol/ai';\n *\n * const model = ai.llm({\n * model: openai('gpt-4o'),\n * params: { max_tokens: 1000 }\n * });\n * ```\n */\nexport const ai = {\n /** LLM instance factory */\n llm,\n /** Embedding instance factory */\n embedding,\n /** Image generation instance factory */\n image,\n};\n\nexport * from './types/index.ts';\n\nexport {\n RoundRobinKeys,\n WeightedKeys,\n DynamicKey,\n ExponentialBackoff,\n LinearBackoff,\n NoRetry,\n TokenBucket,\n RetryAfterStrategy,\n} from './http/index.ts';\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BO,IAAM,mBAAmB;AAAA;AAAA,EAE9B,MAAM;AAAA;AAAA,EAEN,WAAW;AAAA;AAAA,EAEX,OAAO;AAAA;AAAA,EAEP,UAAU;AAAA;AAAA,EAEV,OAAO;AAAA;AAAA,EAEP,OAAO;AAAA;AAAA,EAEP,QAAQ;AACV;AAuBO,IAAM,kBAAkB;AAAA;AAAA,EAE7B,QAAQ;AAAA;AAAA,EAER,KAAK;AAAA;AAAA,EAEL,OAAO;AACT;AAwDO,IAAM,qBAAqB;AAAA;AAAA,EAEhC,QAAQ;AAAA;AAAA,EAER,KAAK;AAAA;AAAA,EAEL,MAAM;AACR;AA4SO,SAAS,KAAK,SAA4B;AAC/C,SAAO,EAAE,MAAM,iBAAiB,MAAM,MAAM,QAAQ;AACtD;AAcO,SAAS,UAAU,SAAiC;AACzD,SAAO,EAAE,MAAM,iBAAiB,WAAW,MAAM,QAAQ;AAC3D;AAeO,SAAS,YAAY,OAAyC;AACnE,SAAO,MAAM,SAAS,iBAAiB;AACzC;AAeO,SAAS,iBAAiB,OAA8C;AAC7E,SAAO,MAAM,SAAS,iBAAiB;AACzC;AAeO,SAAS,aAAa,OAA0C;AACrE,SAAO,MAAM,SAAS,iBAAiB;AACzC;AAeO,SAAS,gBAAgB,OAA6C;AAC3E,SAAO,MAAM,SAAS,iBAAiB;AACzC;AAeO,SAAS,aAAa,OAA0C;AACrE,SAAO,MAAM,SAAS,iBAAiB;AACzC;AAeO,SAAS,aAAa,OAA0C;AACrE,SAAO,MAAM,SAAS,iBAAiB;AACzC;AAeO,SAAS,cAAc,OAA2C;AACvE,SAAO,MAAM,SAAS,iBAAiB;AACzC;;;ACzhBA,eAAsB,QACpB,aACA,MACA,KACA,UAAU,OACK;AACf,QAAM,UAAU,UAAU,CAAC,GAAG,WAAW,EAAE,QAAQ,IAAI;AAEvD,aAAW,MAAM,SAAS;AACxB,UAAM,KAAK,GAAG,IAAI;AAClB,QAAI,IAAI;AACN,YAAM,GAAG,KAAK,IAAI,GAAG;AAAA,IACvB;AAAA,EACF;AACF;AAaA,eAAsB,aACpB,aACA,OACA,KACe;AACf,aAAW,MAAM,aAAa;AAC5B,QAAI,GAAG,SAAS;AACd,UAAI;AACF,cAAM,GAAG,QAAQ,OAAO,GAAG;AAAA,MAC7B,SAAS,WAAW;AAElB,gBAAQ,MAAM,IAAI,GAAG,IAAI,4BAA4B,SAAS;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACF;AAYA,eAAsB,aACpB,aACA,OACA,KACe;AACf,aAAW,MAAM,aAAa;AAC5B,QAAI,GAAG,SAAS;AACd,UAAI;AACF,cAAM,GAAG,QAAQ,OAAO,GAAG;AAAA,MAC7B,SAAS,WAAW;AAElB,gBAAQ,MAAM,IAAI,GAAG,IAAI,4BAA4B,SAAS;AAAA,MAChE;AAAA,IACF;AAAA,EACF;AACF;AAcA,eAAsB,YACpB,aACA,MACA,MACA,MACA,KACe;AACf,aAAW,MAAM,aAAa;AAC5B,UAAM,KAAK,GAAG,IAAI;AAClB,QAAI,IAAI;AACN,YAAM,GAAG,KAAK,IAAI,MAAM,MAAM,GAAG;AAAA,IACnC;AAAA,EACF;AACF;AAWA,eAAsB,YACpB,aACA,MACA,KACe;AACf,QAAM,UAAU,CAAC,GAAG,WAAW,EAAE,QAAQ;AACzC,aAAW,MAAM,SAAS;AACxB,QAAI,GAAG,QAAQ;AACb,YAAM,GAAG,OAAO,KAAK,IAAI,MAAM,GAAG;AAAA,IACpC;AAAA,EACF;AACF;AA4BO,SAAS,wBACd,aACA,KAC4D;AAC5D,QAAM,oBAAoB,YAAY,OAAO,CAAC,OAAO,GAAG,aAAa;AAErE,MAAI,kBAAkB,WAAW,GAAG;AAClC,WAAO,CAAC,UAAU;AAAA,EACpB;AAEA,SAAO,CAAC,UAA2D;AACjE,QAAI,UAA8C;AAElD,eAAW,MAAM,mBAAmB;AAClC,UAAI,YAAY,MAAM;AACpB,eAAO;AAAA,MACT;AAEA,UAAI,MAAM,QAAQ,OAAO,GAAG;AAE1B,cAAM,UAAyB,CAAC;AAChC,mBAAW,KAAK,SAAS;AACvB,gBAAM,SAAS,GAAG,cAAe,GAAG,GAAG;AACvC,cAAI,WAAW,MAAM;AACnB;AAAA,UACF;AACA,cAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,oBAAQ,KAAK,GAAG,MAAM;AAAA,UACxB,OAAO;AACL,oBAAQ,KAAK,MAAM;AAAA,UACrB;AAAA,QACF;AACA,kBAAU,QAAQ,SAAS,IAAI,UAAU;AAAA,MAC3C,OAAO;AACL,kBAAU,GAAG,cAAe,SAAS,GAAG;AAAA,MAC1C;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AACF;AAUA,eAAsB,iBACpB,aACA,KACe;AACf,aAAW,MAAM,aAAa;AAC5B,QAAI,GAAG,aAAa;AAClB,YAAM,GAAG,YAAY,GAAG;AAAA,IAC1B;AAAA,EACF;AACF;AAYO,SAAS,wBACd,UACA,SACA,UACA,WACA,SACmB;AACnB,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAU;AAAA,IACV,OAAO,oBAAI,IAAI;AAAA,IACf,WAAW,KAAK,IAAI;AAAA,IACpB,SAAS;AAAA,EACX;AACF;AAQO,SAAS,oBACd,OACe;AACf,SAAO,EAAE,MAAM;AACjB;;;AC5NA,IAAM,yBAAyB;AAC/B,IAAM,uBAAuB;AAa7B,SAAS,0BACP,UACA,cACA,cACM;AACN,aAAW,OAAO,UAAU;AAC1B,QAAI,CAAC,cAAc,GAAG,EAAG;AAEzB,eAAW,SAAS,IAAI,SAAS;AAC/B,UAAI,MAAM,SAAS,WAAW,CAAC,aAAa,YAAY;AACtD,cAAM,IAAI;AAAA,UACR,aAAa,YAAY;AAAA,UACzB,UAAU;AAAA,UACV;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AACA,UAAI,MAAM,SAAS,cAAc,CAAC,aAAa,eAAe;AAC5D,cAAM,IAAI;AAAA,UACR,aAAa,YAAY;AAAA,UACzB,UAAU;AAAA,UACV;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AACA,UAAI,MAAM,SAAS,WAAW,CAAC,aAAa,YAAY;AACtD,cAAM,IAAI;AAAA,UACR,aAAa,YAAY;AAAA,UACzB,UAAU;AAAA,UACV;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AACA,UAAI,MAAM,SAAS,WAAW,CAAC,aAAa,YAAY;AACtD,cAAM,IAAI;AAAA,UACR,aAAa,YAAY;AAAA,UACzB,UAAU;AAAA,UACV;AAAA,UACA,aAAa;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAWA,SAAS,kBAAkB,OAAkC;AAC3D,MAAI,iBAAiB,SAAS;AAC5B,WAAO;AAAA,EACT;AACA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,UAAM,MAAM;AACZ,UAAM,OAAO,IAAI;AACjB,UAAM,KAAK,IAAI;AACf,UAAM,YAAY,IAAI;AACtB,UAAM,oBACJ,qBAAqB,QACpB,OAAO,cAAc,YAAY,CAAC,OAAO,MAAM,KAAK,MAAM,SAAS,CAAC;AAEvE,QAAI,OAAO,OAAO,YAAY,GAAG,WAAW,KAAK,CAAC,mBAAmB;AACnE,aAAO;AAAA,IACT;AAEA,QAAI,SAAS,UAAU,SAAS,aAAa;AAC3C,aAAO,MAAM,QAAQ,IAAI,OAAO;AAAA,IAClC;AAEA,QAAI,SAAS,eAAe;AAC1B,aAAO,MAAM,QAAQ,IAAI,OAAO;AAAA,IAClC;AAAA,EACF;AACA,SAAO;AACT;AAWA,SAAS,eAAe,OAAgC;AACtD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,IAAI,YAAiB,KAAK;AAAA,EACnC;AAEA,MAAI,UAAU,SAAS,QAAQ,SAAS,eAAe,OAAO;AAC5D,WAAO;AAAA,EACT;AAEA,MAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,EAAE,UAAU,QAAQ;AACrE,UAAM,IAAI,MAAM,yBAAyB;AAAA,EAC3C;AAEA,QAAM,QAAQ;AACd,MAAI,YAAY,KAAK,GAAG;AACtB,WAAO,IAAI,YAAiB,MAAM,IAAI;AAAA,EACxC;AAEA,MACE,aAAa,KAAK,KAClB,gBAAgB,KAAK,KACrB,aAAa,KAAK,KAClB,aAAa,KAAK,KAClB,cAAc,KAAK,GACnB;AACA,WAAO,IAAI,YAAiB,CAAC,KAAK,CAAC;AAAA,EACrC;AAEA,QAAM,IAAI,MAAM,yBAAyB;AAC3C;AAcA,SAAS,YACP,gBACA,QAC6C;AAC7C,MACE,OAAO,mBAAmB,YAC1B,mBAAmB,QACnB,cAAc,kBACd,MAAM,QAAS,eAA0B,QAAQ,GACjD;AACA,UAAM,SAAS;AACf,UAAMA,eAAc,OAAO,IAAI,cAAc;AAC7C,WAAO,EAAE,SAAS,CAAC,GAAG,OAAO,QAAQ,GAAG,UAAUA,aAAY;AAAA,EAChE;AAEA,MAAI,MAAM,QAAQ,cAAc,GAAG;AACjC,QAAI,eAAe,WAAW,GAAG;AAC/B,YAAMA,eAAc,OAAO,IAAI,cAAc;AAC7C,aAAO,EAAE,SAAS,CAAC,GAAG,UAAUA,aAAY;AAAA,IAC9C;AACA,UAAM,QAAQ,eAAe,CAAC;AAC9B,QAAI,kBAAkB,KAAK,GAAG;AAC5B,YAAMA,eAAc,OAAO,IAAI,cAAc;AAC7C,aAAO,EAAE,SAAS,gBAA6B,UAAUA,aAAY;AAAA,IACvE;AAAA,EACF;AAEA,QAAM,YAAY,CAAC,gBAAkC,GAAG,MAAM;AAC9D,QAAM,cAAc,UAAU,IAAI,cAAc;AAChD,SAAO,EAAE,SAAS,CAAC,GAAG,UAAU,YAAY;AAC9C;AAiBA,SAAS,sBACP,UACA,SACA,aACA,qBACA,eACQ;AACR,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,aAAa,IAAI,IAAI,QAAQ,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC;AAC/D,QAAI,mBAAmB;AACvB,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK,GAAG;AAC3C,UAAI,WAAW,IAAI,SAAS,CAAC,EAAG,EAAE,GAAG;AACnC,2BAAmB;AAAA,MACrB;AAAA,IACF;AACA,QAAI,qBAAqB,IAAI;AAC3B,aAAO,mBAAmB;AAAA,IAC5B;AAAA,EACF;AAEA,MAAI,OAAO,kBAAkB,YAAY,OAAO,SAAS,aAAa,GAAG;AACvE,WAAO,KAAK,IAAI,KAAK,IAAI,GAAG,aAAa,GAAG,mBAAmB;AAAA,EACjE;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,UAAM,gBAAgB,IAAI,IAAI,YAAY,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC;AACtE,UAAM,QAAQ,SAAS,UAAU,CAAC,YAAY,cAAc,IAAI,QAAQ,EAAE,CAAC;AAC3E,QAAI,UAAU,IAAI;AAChB,aAAO;AAAA,IACT;AAAA,EACF;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,SAAO,KAAK,IAAI,GAAG,sBAAsB,YAAY,MAAM;AAC7D;AAsBA,eAAe,aACb,kBACA,OACA,cACA,YACA,SACA,aAA2B,CAAC,GAC5B,KACuB;AACvB,QAAM,YAAY,iBAAiB,aAAa,CAAC;AACjD,QAAM,UAAwB,CAAC;AAE/B,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAErD,QAAM,WAAW,UAAU,IAAI,OAAO,MAAM,UAAU;AACpD,UAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ;AACtC,UAAM,WAAW,MAAM,QAAQ,KAAK;AACpC,UAAM,YAAY,KAAK,IAAI;AAE3B,cAAU,mBAAmB,KAAK,YAAY,UAAU,WAAW,KAAK,CAAC;AAEzE,QAAI,kBAAkB,KAAK;AAE3B,UAAM,eAAe,OAAO,cAAsBC,cAA4C;AAC5F,YAAM,UAAU,KAAK,IAAI;AACzB,UAAI,MAAM;AACR,cAAM,cAAc,UAAU,MAAM,iBAAiB,IAAI,MAAM,YAAY,CAAC;AAAA,MAC9E;AACA,YAAM,YAA2B;AAAA,QAC/B;AAAA,QACA,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU,UAAU;AAAA,QACpB,UAAAA;AAAA,MACF;AACA,iBAAW,KAAK,SAAS;AACzB,gBAAU,iBAAiB,KAAK,YAAY,UAAU,cAAc,MAAM,SAAS,KAAK,CAAC;AACzF,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI,CAAC,MAAM;AACT,aAAO,aAAa,SAAS,KAAK,QAAQ,aAAa;AAAA,IACzD;AAEA,QAAI;AACF,YAAM,cAAc,aAAa,MAAM,eAAe;AAEtD,UAAI,KAAK;AACP,cAAM,YAAY,YAAY,cAAc,MAAM,iBAAiB,GAAG;AAAA,MACxE;AAAA,IACF,SAAS,OAAO;AACd,aAAO,aAAa,QAAQ,KAAK,EAAE,OAAO;AAAA,IAC5C;AAEA,QAAI,cAAc,cAAc;AAC9B,UAAI;AACJ,UAAI;AACF,uBAAe,MAAM,aAAa,aAAa,MAAM,eAAe;AAAA,MACtE,SAAS,OAAO;AACd,eAAO,aAAa,QAAQ,KAAK,EAAE,OAAO;AAAA,MAC5C;AAEA,YAAM,qBAAqB,CAAC,UAC1B,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa;AAE9D,UAAI,mBAAmB,YAAY,GAAG;AACpC,YAAI,CAAC,aAAa,SAAS;AACzB,iBAAO,aAAa,wBAAwB;AAAA,QAC9C;AACA,YAAI,aAAa,WAAW,QAAW;AACrC,4BAAkB,aAAa;AAAA,QACjC;AAAA,MACF,WAAW,CAAC,cAAc;AACxB,eAAO,aAAa,wBAAwB;AAAA,MAC9C;AAAA,IACF;AAEA,QAAI,WAAW;AACf,QAAI,KAAK,UAAU;AACjB,UAAI;AACF,mBAAW,MAAM,KAAK,SAAS,eAAe;AAAA,MAChD,SAAS,OAAO;AACd,eAAO,aAAa,QAAQ,KAAK,EAAE,OAAO;AAAA,MAC5C;AAAA,IACF;AAEA,QAAI,CAAC,UAAU;AACb,YAAM,UAAU,KAAK,IAAI;AACzB,YAAM,YAA2B;AAAA,QAC/B;AAAA,QACA,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU,UAAU;AAAA,QACpB,UAAU;AAAA,MACZ;AACA,iBAAW,KAAK,SAAS;AAEzB,gBAAU,iBAAiB,KAAK,YAAY,UAAU,6CAA6C,MAAM,SAAS,KAAK,CAAC;AAExH,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI;AACF,UAAI,SAAS,MAAM,KAAK,IAAI,eAAe;AAC3C,YAAM,UAAU,KAAK,IAAI;AAEzB,UAAI,cAAc,aAAa;AAC7B,cAAM,cAAc,MAAM,aAAa,YAAY,MAAM,iBAAiB,MAAM;AAChF,cAAM,oBAAoB,CAAC,UACzB,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY;AAE7D,YAAI,kBAAkB,WAAW,GAAG;AAClC,mBAAS,YAAY;AAAA,QACvB;AAAA,MACF;AAGA,UAAI,KAAK;AACP,cAAM,YAAY,YAAY,gBAAgB,MAAM,QAAQ,GAAG;AAAA,MACjE;AAEA,YAAM,YAA2B;AAAA,QAC/B;AAAA,QACA,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX;AAAA,QACA,SAAS;AAAA,QACT,UAAU,UAAU;AAAA,QACpB;AAAA,MACF;AACA,iBAAW,KAAK,SAAS;AAEzB,gBAAU,iBAAiB,KAAK,YAAY,UAAU,QAAQ,OAAO,SAAS,KAAK,CAAC;AAEpF,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UAAU,KAAK,IAAI;AACzB,YAAM,MAAM,QAAQ,KAAK;AACzB,YAAM,cAAc,UAAU,MAAM,iBAAiB,GAAG;AAExD,YAAM,YAA2B;AAAA,QAC/B;AAAA,QACA,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,QAAQ,IAAI;AAAA,QACZ,SAAS;AAAA,QACT,UAAU,UAAU;AAAA,QACpB;AAAA,MACF;AACA,iBAAW,KAAK,SAAS;AAEzB,gBAAU,iBAAiB,KAAK,YAAY,UAAU,IAAI,SAAS,MAAM,SAAS,KAAK,CAAC;AAExF,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,QAAQ,IAAI;AAAA,QACZ,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,KAAK,GAAI,MAAM,QAAQ,IAAI,QAAQ,CAAE;AAC7C,SAAO;AACT;AAwBA,eAAe,gBACb,OACA,QACA,QACA,QACA,OACA,cACA,WACA,SACA,aACA,YACe;AACf,QAAM,gBAAgB,cAAc,iBAAiB;AACrD,MAAI,cAAyB,CAAC,GAAG,SAAS,GAAG,WAAW;AACxD,QAAM,iBAAkC,CAAC;AACzC,QAAM,SAAuB,CAAC;AAC9B,MAAI,SAAS;AAEb,MAAI;AACJ,MAAI,iBAAiB,QAAQ;AAG7B,QAAM,iBAAsC;AAAA,IAC1C,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,MAAM;AAAA,IACV;AAAA,IACA,MAAM;AAAA,IACN,MAAM,SAAS;AAAA,IACf;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AAEF,UAAM,QAAQ,YAAY,WAAW,GAAG;AACxC,UAAM,QAAQ,YAAY,aAAa,GAAG;AAC1C,kBAAe,IAAI,QAAgC;AACnD,UAAM,sBAAsB,YAAY;AACxC,UAAM,gBAAgB,IAAI,MAAM,IAAI,oBAAoB;AACxD,qBAAiB;AAAA,MACf;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,kBAAkB,WAAW,gBAAgB;AAAA,IACtD;AACA,8BAA0B,aAAa,MAAM,cAAc,MAAM,SAAS,IAAI;AAE9E,WAAO,SAAS,gBAAgB,GAAG;AACjC;AAEA,YAAM,UAA+B;AAAA,QACnC,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,YAAM,WAAW,MAAM,MAAM,SAAS,OAAO;AAC7C,aAAO,KAAK,SAAS,KAAK;AAC1B,kBAAY,KAAK,SAAS,OAAO;AAEjC,UAAI,SAAS,SAAS,QAAW;AAC/B,yBAAiB,SAAS;AAAA,MAC5B;AAEA,UAAI,SAAS,QAAQ,gBAAgB,SAAS,MAAM,SAAS,GAAG;AAC9D,YAAI,SAAS,SAAS,QAAW;AAC/B;AAAA,QACF;AAEA,YAAI,UAAU,eAAe;AAC3B,gBAAM,cAAc,kBAAkB,aAAa;AACnD,gBAAM,IAAI;AAAA,YACR,+CAA+C,aAAa;AAAA,YAC5D,UAAU;AAAA,YACV,MAAM,SAAS;AAAA,YACf,aAAa;AAAA,UACf;AAAA,QACF;AAEA,cAAM,UAAU,MAAM;AAAA,UACpB,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,oBAAY,KAAK,IAAI,kBAAkB,OAAO,CAAC;AAE/C;AAAA,MACF;AAEA;AAAA,IACF;AAEA,UAAM,OAAO,YAAY,iBAAiB;AAE1C,UAAM,OAAO;AAAA,MACX,YAAY,MAAM,cAAc;AAAA,MAChC;AAAA,MACA,eAAe,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAGA,QAAI,WAAW;AAAA,MACb,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,MACZ,YAAY;AAAA,MACZ;AAAA,IACF;AACA,QAAI,UAAU,KAAK,IAAI;AACvB,UAAM,QAAQ,YAAY,cAAc,KAAK,IAAI;AACjD,UAAM,YAAY,YAAY,MAAM,GAAG;AACvC,UAAM,QAAQ,YAAY,SAAS,KAAK,IAAI;AAE5C,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,MAAM,QAAQ,KAAK;AACzB,UAAM,aAAa,YAAY,KAAK,GAAG;AACvC,UAAM;AAAA,EACR;AACF;AAsBA,SAAS,cACP,OACA,QACA,QACA,QACA,OACA,cACA,WACA,SACA,aACA,YACc;AACd,QAAM,kBAAkB,IAAI,gBAAgB;AAE5C,MAAI,cAAyB,CAAC,GAAG,SAAS,GAAG,WAAW;AACxD,QAAM,iBAAkC,CAAC;AACzC,QAAM,SAAuB,CAAC;AAC9B,MAAI,SAAS;AACb,MAAI,iBAA+B;AACnC,MAAI;AACJ,MAAI,qBAAqB;AACzB,MAAI,iBAAiB,QAAQ;AAG7B,QAAM,iBAAsC;AAAA,IAC1C,UAAU;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAM,MAAM;AAAA,IACV;AAAA,IACA,MAAM;AAAA,IACN,MAAM,SAAS;AAAA,IACf;AAAA,IACA;AAAA,EACF;AAEA,QAAM,YAAY,oBAAoB,IAAI,KAAK;AAC/C,QAAM,cAAc,wBAAwB,YAAY,SAAS;AAEjE,MAAI;AACJ,MAAI;AACJ,MAAI,mBAAmB;AACvB,QAAM,gBAAgB,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3D,uBAAmB,MAAM;AACvB,UAAI,CAAC,kBAAkB;AACrB,2BAAmB;AACnB,gBAAQ;AAAA,MACV;AAAA,IACF;AACA,sBAAkB,CAAC,UAAiB;AAClC,UAAI,CAAC,kBAAkB;AACrB,2BAAmB;AACnB,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAAA,EACF,CAAC;AACD,OAAK,cAAc,MAAM,CAAC,UAAU;AAClC,QAAI,CAAC,gBAAgB;AACnB,uBAAiB,QAAQ,KAAK;AAAA,IAChC;AAAA,EACF,CAAC;AAED,QAAM,gBAAgB,cAAc,iBAAiB;AAErD,QAAM,UAAU,MAAM;AACpB,UAAM,QAAQ,IAAI,SAAS,oBAAoB,UAAU,WAAW,MAAM,SAAS,MAAM,aAAa,GAAG;AACzG,qBAAiB;AACjB,oBAAgB,KAAK;AAAA,EACvB;AACA,kBAAgB,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AAExE,QAAM,mBAAmB,MAAM;AAC7B,QAAI,gBAAgB,OAAO,SAAS;AAClC,YAAM,IAAI,SAAS,oBAAoB,UAAU,WAAW,MAAM,SAAS,MAAM,aAAa,GAAG;AAAA,IACnG;AAAA,EACF;AAEA,kBAAgB,iBAA6D;AAC3E,QAAI;AAEF,uBAAiB;AAGjB,YAAM,QAAQ,YAAY,WAAW,GAAG;AACxC,YAAM,QAAQ,YAAY,aAAa,GAAG;AAC1C,oBAAe,IAAI,QAAgC;AACnD,YAAM,sBAAsB,YAAY;AACxC,YAAM,gBAAgB,IAAI,MAAM,IAAI,oBAAoB;AACxD,uBAAiB;AAAA,QACf;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,kBAAkB,WAAW,gBAAgB;AAAA,MACtD;AACA,gCAA0B,aAAa,MAAM,cAAc,MAAM,SAAS,IAAI;AAE9E,aAAO,SAAS,gBAAgB,GAAG;AACjC;AACA,yBAAiB;AAEjB,cAAM,UAA+B;AAAA,UACnC,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ,gBAAgB;AAAA,QAC1B;AAEA,cAAM,eAAe,MAAM,OAAO,OAAO;AAEzC,yBAAiB,SAAS,cAAc;AACtC,2BAAiB;AAEjB,gBAAM,cAAc,YAAY,KAAK;AACrC,cAAI,gBAAgB,KAAM;AAC1B,cAAI,MAAM,QAAQ,WAAW,GAAG;AAC9B,uBAAW,KAAK,aAAa;AAC3B,oBAAM;AAAA,YACR;AAAA,UACF,OAAO;AACL,kBAAM;AAAA,UACR;AAAA,QACF;AAEA,cAAM,WAAW,MAAM,aAAa;AACpC,eAAO,KAAK,SAAS,KAAK;AAC1B,oBAAY,KAAK,SAAS,OAAO;AAEjC,YAAI,SAAS,SAAS,QAAW;AAC/B,2BAAiB,SAAS;AAAA,QAC5B;AAEA,YAAI,SAAS,QAAQ,gBAAgB,SAAS,MAAM,SAAS,GAAG;AAC9D,cAAI,SAAS,SAAS,QAAW;AAC/B;AAAA,UACF;AAEA,cAAI,UAAU,eAAe;AAC3B,kBAAM,cAAc,kBAAkB,aAAa;AACnD,kBAAM,IAAI;AAAA,cACR,+CAA+C,aAAa;AAAA,cAC5D,UAAU;AAAA,cACV,MAAM,SAAS;AAAA,cACf,aAAa;AAAA,YACf;AAAA,UACF;AAEA,gBAAM,aAA4B,CAAC;AACnC,gBAAM,UAAU,MAAM;AAAA,YACpB,SAAS;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA,CAAC,UAAU,WAAW,KAAK,KAAK;AAAA,YAChC;AAAA,YACA;AAAA,UACF;AAEA,qBAAW,SAAS,YAAY;AAC9B,6BAAiB;AAEjB,kBAAM,cAAc,YAAY,KAAK;AACrC,gBAAI,gBAAgB,KAAM;AAC1B,gBAAI,MAAM,QAAQ,WAAW,GAAG;AAC9B,yBAAW,KAAK,aAAa;AAC3B,sBAAM;AAAA,cACR;AAAA,YACF,OAAO;AACL,oBAAM;AAAA,YACR;AAAA,UACF;AAEA,sBAAY,KAAK,IAAI,kBAAkB,OAAO,CAAC;AAE/C;AAAA,QACF;AAEA;AAAA,MACF;AAGA,YAAM,iBAAiB,YAAY,SAAS;AAE5C,2BAAqB;AACrB,uBAAiB;AAAA,IACnB,SAAS,OAAO;AACd,YAAM,MAAM,QAAQ,KAAK;AACzB,uBAAiB;AACjB,UAAI,iBAAiB,GAAG,GAAG;AACzB,cAAM,aAAa,YAAY,KAAK,GAAG;AAAA,MACzC,OAAO;AACL,cAAM,aAAa,YAAY,KAAK,GAAG;AAAA,MACzC;AACA,sBAAgB,GAAG;AACnB,YAAM;AAAA,IACR,UAAE;AACA,sBAAgB,OAAO,oBAAoB,SAAS,OAAO;AAC3D,UAAI,CAAC,sBAAsB,CAAC,kBAAkB;AAC5C,cAAM,QAAQ,IAAI,SAAS,oBAAoB,UAAU,WAAW,MAAM,SAAS,MAAM,aAAa,GAAG;AACzG,yBAAiB;AACjB,YAAI,CAAC,gBAAgB,OAAO,SAAS;AACnC,0BAAgB,MAAM;AAAA,QACxB;AACA,cAAM,aAAa,YAAY,OAAO,GAAG;AACzC,wBAAgB,KAAK;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AAEA,QAAM,oBAAoB,YAA2B;AACnD,UAAM;AAEN,QAAI,gBAAgB;AAClB,YAAM;AAAA,IACR;AAEA,UAAM,OAAO,YAAY,iBAAiB;AAE1C,UAAM,OAAO;AAAA,MACX,YAAY,MAAM,cAAc;AAAA,MAChC;AAAA,MACA,eAAe,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAGA,QAAI,WAAW;AAAA,MACb,SAAS,KAAK;AAAA,MACd,OAAO,KAAK;AAAA,MACZ,YAAY;AAAA,MACZ;AAAA,IACF;AACA,QAAI,UAAU,KAAK,IAAI;AACvB,UAAM,QAAQ,YAAY,cAAc,KAAK,IAAI;AACjD,UAAM,YAAY,YAAY,MAAM,GAAG;AACvC,UAAM,QAAQ,YAAY,SAAS,KAAK,IAAI;AAE5C,WAAO;AAAA,EACT;AAEA,SAAO,mBAAmB,eAAe,GAAG,mBAAmB,eAAe;AAChF;AA+BO,SAAS,IACd,SACsB;AACtB,QAAM;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ,iBAAiB,CAAC;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,CAAC;AAAA,EAChB,IAAI;AAIJ,QAAM,iBAAiB,SAAS,kBAAkB,CAAC;AACnD,QAAM,SAAyB;AAAA,IAC7B,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAG,eAAe;AAAA,MAClB,GAAG,eAAe;AAAA,IACpB;AAAA,EACF;AAMA,QAAM,WAAW,SAAS;AAC1B,QAAM,aAAa,kBAAkB,UAAU,SAAS,OAAO;AAE/D,MAAI,CAAC,YAAY;AACf,UAAM,IAAI;AAAA,MACR,aAAa,SAAS,IAAI;AAAA,MAC1B,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAGA,QAAM,aAAa,WAAW,KAAK,SAAS,OAAO;AAGnD,QAAM,eAAe,WAAW;AAGhC,MAAI,aAAa,CAAC,aAAa,kBAAkB;AAC/C,UAAM,IAAI;AAAA,MACR,aAAa,SAAS,IAAI;AAAA,MAC1B,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAGA,MAAI,SAAS,MAAM,SAAS,KAAK,CAAC,aAAa,OAAO;AACpD,UAAM,IAAI;AAAA,MACR,aAAa,SAAS,IAAI;AAAA,MAC1B,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAGA,QAAM,WAAiC;AAAA,IACrC,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IAEA,MAAM,SACJ,mBACG,QACY;AACf,YAAM,EAAE,SAAS,SAAS,IAAI,YAAY,gBAAgB,MAAM;AAChE,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OACE,mBACG,QACW;AAEd,UAAI,CAAC,aAAa,WAAW;AAC3B,cAAM,IAAI;AAAA,UACR,aAAa,SAAS,IAAI;AAAA,UAC1B,UAAU;AAAA,UACV,SAAS;AAAA,UACT,aAAa;AAAA,QACf;AAAA,MACF;AACA,YAAM,EAAE,SAAS,SAAS,IAAI,YAAY,gBAAgB,MAAM;AAChE,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;ACnhCA,SAAS,aAAa,KAAa,cAAgC;AACjE,MAAI;AACF,UAAM,SAAS,KAAK,GAAG;AACvB,UAAM,QAAQ,IAAI,WAAW,OAAO,MAAM;AAC1C,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,YAAM,CAAC,IAAI,OAAO,WAAW,CAAC;AAAA,IAChC;AACA,UAAM,SAAS,IAAI,aAAa,MAAM,MAAM;AAC5C,WAAO,MAAM,KAAK,MAAM;AAAA,EAC1B,SAAS,OAAO;AACd,UAAM,QAAQ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,gCAAgC;AACzF,UAAM,IAAI;AAAA,MACR;AAAA,MACA,UAAU;AAAA,MACV;AAAA,MACA,aAAa;AAAA,MACb;AAAA,MACA;AAAA,IACF;AAAA,EACF;AACF;AASA,SAAS,gBAAgB,QAA2B,cAAgC;AAClF,MAAI,MAAM,QAAQ,MAAM,GAAG;AACzB,WAAO;AAAA,EACT;AACA,SAAO,aAAa,QAAQ,YAAY;AAC1C;AASA,SAAS,kBAAkB,UAA6B,cAAuC;AAC7F,SAAO;AAAA,IACL,YAAY,SAAS,WAAW,IAAI,CAAC,KAAK,MAAM;AAC9C,YAAM,SAAS,gBAAgB,IAAI,QAAQ,YAAY;AACvD,aAAO;AAAA,QACL;AAAA,QACA,YAAY,OAAO;AAAA,QACnB,OAAO,IAAI,SAAS;AAAA,QACpB,QAAQ,IAAI;AAAA,QACZ,UAAU,IAAI;AAAA,MAChB;AAAA,IACF,CAAC;AAAA,IACD,OAAO,SAAS;AAAA,IAChB,UAAU,SAAS;AAAA,EACrB;AACF;AAcA,eAAe,aACb,OACA,QACA,QACA,QACA,QACA,WACA,aAA2B,CAAC,GACF;AAC1B,QAAM,UAAqC;AAAA,IACzC;AAAA,IACA;AAAA,IACA,QAAQ,UAAU,CAAC;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AAEA,QAAM,MAAM;AAAA,IACV;AAAA,IACA,MAAM;AAAA,IACN,MAAM,SAAS;AAAA,IACf;AAAA,IACA;AAAA,EACF;AAEA,MAAI;AACF,UAAM,QAAQ,YAAY,WAAW,GAAG;AACxC,UAAM,QAAQ,YAAY,aAAa,GAAG;AAE1C,UAAM,WAAW,MAAM,MAAM,MAAM,OAAO;AAC1C,UAAM,SAAS,kBAAkB,UAAU,MAAM,SAAS,IAAI;AAE9D,QAAI,WAAW;AACf,QAAI,UAAU,KAAK,IAAI;AACvB,UAAM,QAAQ,YAAY,cAAc,KAAK,IAAI;AACjD,UAAM,QAAQ,YAAY,SAAS,KAAK,IAAI;AAE5C,WAAO;AAAA,EACT,SAAS,OAAO;AACd,UAAM,MAAM,QAAQ,KAAK;AACzB,UAAM,aAAa,YAAY,KAAK,GAAG;AACvC,UAAM;AAAA,EACR;AACF;AAaA,SAAS,oBACP,OACA,QACA,QACA,QACA,SACA,aAA2B,CAAC,GACX;AACjB,QAAM,kBAAkB,IAAI,gBAAgB;AAC5C,QAAM,YAAY,QAAQ,aAAa,MAAM;AAC7C,QAAM,cAAc,QAAQ,eAAe;AAE3C,MAAI;AACJ,MAAI;AACJ,MAAI,UAAU;AACd,QAAM,gBAAgB,IAAI,QAAyB,CAAC,SAAS,WAAW;AACtE,oBAAgB,CAAC,WAAW;AAC1B,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,gBAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AACA,mBAAe,CAAC,UAAU;AACxB,UAAI,CAAC,SAAS;AACZ,kBAAU;AACV,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,cAAc,MAAM,IAAI;AAAA,IAC5B;AAAA,IACA,UAAU;AAAA,IACV,MAAM,SAAS;AAAA,IACf,aAAa;AAAA,EACf;AAEA,QAAM,UAAU,MAAM;AACpB,iBAAa,YAAY,CAAC;AAAA,EAC5B;AAEA,kBAAgB,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACxE,QAAM,kBAAkB,MAAM,gBAAgB,MAAM;AACpD,MAAI,QAAQ,QAAQ;AAClB,YAAQ,OAAO,iBAAiB,SAAS,iBAAiB,EAAE,MAAM,KAAK,CAAC;AAAA,EAC1E;AAEA,QAAM,wBAAwB,MAAM;AAClC,oBAAgB,OAAO,oBAAoB,SAAS,OAAO;AAC3D,QAAI,QAAQ,QAAQ;AAClB,cAAQ,OAAO,oBAAoB,SAAS,eAAe;AAAA,IAC7D;AAAA,EACF;AAGA,QAAM,UAAqC;AAAA,IACzC;AAAA,IACA;AAAA,IACA,QAAQ,UAAU,CAAC;AAAA,IACnB,QAAQ,gBAAgB;AAAA,IACxB,WAAW,QAAQ;AAAA,EACrB;AAEA,QAAM,MAAM;AAAA,IACV;AAAA,IACA,MAAM;AAAA,IACN,MAAM,SAAS;AAAA,IACf;AAAA,IACA;AAAA,EACF;AAEA,kBAAgB,WAA8C;AAC5D,UAAM,QAAQ,OAAO;AACrB,UAAM,gBAA6B,CAAC;AACpC,QAAI,cAAc;AAElB,UAAM,UAAmE,CAAC;AAC1E,aAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK,WAAW;AACjD,cAAQ,KAAK,EAAE,QAAQ,OAAO,MAAM,GAAG,IAAI,SAAS,GAAG,YAAY,EAAE,CAAC;AAAA,IACxE;AAEA,QAAI;AAEF,YAAM,QAAQ,YAAY,WAAW,GAAG;AACxC,YAAM,QAAQ,YAAY,aAAa,GAAG;AAE1C,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK,aAAa;AACpD,YAAI,gBAAgB,OAAO,WAAW,QAAQ,QAAQ,SAAS;AAC7D,gBAAM,YAAY;AAAA,QACpB;AAEA,cAAM,QAAQ,QAAQ,MAAM,GAAG,IAAI,WAAW;AAC9C,cAAM,YAAY,MAAM,QAAQ;AAAA,UAC9B,MAAM;AAAA,YAAI,CAAC,UACT,MAAM,MAAM;AAAA,cACV,QAAQ,MAAM;AAAA,cACd;AAAA,cACA,QAAQ,UAAU,CAAC;AAAA,cACnB,QAAQ,gBAAgB;AAAA,YAC1B,CAAC;AAAA,UACH;AAAA,QACF;AAEA,cAAM,kBAA+B,CAAC;AACtC,iBAAS,gBAAgB,GAAG,gBAAgB,UAAU,QAAQ,iBAAiB,GAAG;AAChF,gBAAM,WAAW,UAAU,aAAa;AACxC,gBAAM,QAAQ,MAAM,aAAa;AACjC,mBAAS,WAAW,GAAG,WAAW,SAAS,WAAW,QAAQ,YAAY,GAAG;AAC3E,kBAAM,MAAM,SAAS,WAAW,QAAQ;AACxC,kBAAM,SAAS,gBAAgB,IAAI,QAAQ,MAAM,SAAS,IAAI;AAC9D,kBAAM,gBAAgB,MAAM,cAAc,IAAI,SAAS;AACvD,kBAAM,MAAiB;AAAA,cACrB;AAAA,cACA,YAAY,OAAO;AAAA,cACnB,OAAO;AAAA,cACP,QAAQ,IAAI;AAAA,cACZ,UAAU,IAAI;AAAA,YAChB;AACA,4BAAgB,KAAK,GAAG;AAAA,UAC1B;AACA,yBAAe,SAAS,MAAM;AAAA,QAChC;AAEA,sBAAc,KAAK,GAAG,eAAe;AAErC,cAAM;AAAA,UACJ,YAAY;AAAA,UACZ,WAAW,cAAc;AAAA,UACzB;AAAA,UACA,SAAU,cAAc,SAAS,QAAS;AAAA,QAC5C;AAAA,MACF;AAEA,YAAM,oBAAoB,CAAC,GAAG,aAAa,EAAE;AAAA,QAC3C,CAAC,MAAM,UAAU,KAAK,QAAQ,MAAM;AAAA,MACtC;AAEA,YAAM,SAAS;AAAA,QACb,YAAY;AAAA,QACZ,OAAO,EAAE,YAAY;AAAA,MACvB;AAGA,UAAI,WAAW,EAAE,YAAY,kBAAkB,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,YAAY,EAAE;AAC1H,UAAI,UAAU,KAAK,IAAI;AACvB,YAAM,QAAQ,YAAY,cAAc,KAAK,IAAI;AACjD,YAAM,QAAQ,YAAY,SAAS,KAAK,IAAI;AAE5C,oBAAc,MAAM;AAAA,IACtB,SAAS,OAAO;AACd,YAAM,MAAM,QAAQ,KAAK;AACzB,YAAM,aAAa,YAAY,KAAK,GAAG;AACvC,mBAAa,GAAG;AAChB,YAAM;AAAA,IACR,UAAE;AACA,4BAAsB;AAAA,IACxB;AAAA,EACF;AAEA,QAAM,YAAY,SAAS;AAE3B,SAAO;AAAA,IACL,CAAC,OAAO,aAAa,GAAG,MAAM;AAAA,IAC9B,QAAQ;AAAA,IACR,OAAO,MAAM,gBAAgB,MAAM;AAAA,EACrC;AACF;AAqCO,SAAS,UACd,SAC4B;AAC5B,QAAM,EAAE,OAAO,UAAU,QAAQ,iBAAiB,CAAC,GAAG,QAAQ,aAAa,CAAC,EAAE,IAAI;AAClF,QAAM,iBAAiB,SAAS,kBAAkB,CAAC;AACnD,QAAM,SAAyB;AAAA,IAC7B,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAG,eAAe;AAAA,MAClB,GAAG,eAAe;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,WAAW,SAAS;AAC1B,QAAM,UAAU,wBAAiC,QAAQ;AACzD,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI;AAAA,MACR,aAAa,SAAS,IAAI;AAAA,MAC1B,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAEA,QAAM,aAAa,QAAQ,KAAK,SAAS,OAAO;AAUhD,WAAS,MACP,OACA,cAC4C;AAC5C,UAAM,SAAS,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAEpD,QAAI,cAAc,SAAS;AACzB,aAAO,oBAAoB,YAAY,QAAQ,QAAQ,QAAQ,cAAc,UAAU;AAAA,IACzF;AAEA,WAAO,aAAa,YAAY,QAAQ,QAAQ,QAAQ,cAAc,QAAQ,cAAc,WAAW,UAAU;AAAA,EACnH;AAEA,SAAO;AAAA,IACL,OAAO;AAAA,IACP;AAAA,IACA;AAAA,EACF;AACF;;;ACrYA,SAAS,eAAe,OAA2B;AACjD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO;AAAA,EACT;AACA,SAAO,MAAM;AACf;AA4BO,SAAS,MACd,SACwB;AACxB,QAAM,EAAE,OAAO,UAAU,QAAQ,iBAAiB,CAAC,GAAG,QAAQ,aAAa,CAAC,EAAE,IAAI;AAClF,QAAM,iBAAiB,SAAS,kBAAkB,CAAC;AACnD,QAAM,SAAyB;AAAA,IAC7B,GAAG;AAAA,IACH,GAAG;AAAA,IACH,SAAS;AAAA,MACP,GAAG,eAAe;AAAA,MAClB,GAAG,eAAe;AAAA,IACpB;AAAA,EACF;AAEA,QAAM,WAAW,SAAS;AAC1B,QAAM,eAAe,oBAA6B,QAAQ;AAC1D,MAAI,CAAC,cAAc;AACjB,UAAM,IAAI;AAAA,MACR,aAAa,SAAS,IAAI;AAAA,MAC1B,UAAU;AAAA,MACV,SAAS;AAAA,MACT,aAAa;AAAA,IACf;AAAA,EACF;AAEA,QAAM,aAAa,aAAa,KAAK,SAAS,OAAO;AAErD,QAAM,eAAe,WAAW;AAEhC,QAAM,sBAAsB,CAAC,UAA6B;AACxD,QAAI,iBAAiB,UAAU;AAC7B,aAAO;AAAA,IACT;AACA,UAAM,MAAM,QAAQ,KAAK;AACzB,WAAO,IAAI,SAAS,IAAI,SAAS,UAAU,eAAe,SAAS,MAAM,aAAa,OAAO,QAAW,GAAG;AAAA,EAC7G;AAEA,QAAM,WAAmC;AAAA,IACvC,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IAEA,MAAM,SAAS,OAAmB,iBAA8D;AAC9F,YAAM,SAAS,eAAe,KAAK;AAEnC,YAAM,UAAiC;AAAA,QACrC;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,iBAAiB;AAAA,MAC3B;AAEA,YAAM,MAAM;AAAA,QACV;AAAA,QACA,WAAW;AAAA,QACX,SAAS;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAEA,UAAI;AACF,cAAM,QAAQ,YAAY,WAAW,GAAG;AACxC,cAAM,QAAQ,YAAY,aAAa,GAAG;AAE1C,cAAM,WAAW,MAAM,WAAW,SAAS,OAAO;AAElD,cAAM,SAAsB;AAAA,UAC1B,QAAQ,SAAS;AAAA,UACjB,UAAU,SAAS;AAAA,UACnB,OAAO,SAAS;AAAA,QAClB;AAEA,YAAI,WAAW;AACf,YAAI,UAAU,KAAK,IAAI;AACvB,cAAM,QAAQ,YAAY,cAAc,KAAK,IAAI;AACjD,cAAM,QAAQ,YAAY,SAAS,KAAK,IAAI;AAE5C,eAAO;AAAA,MACT,SAAS,OAAO;AACd,cAAM,MAAM,QAAQ,KAAK;AACzB,cAAM,aAAa,YAAY,KAAK,GAAG;AACvC,cAAM,oBAAoB,KAAK;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,aAAa,WAAW,QAAQ;AAC/C,UAAM,WAAW,WAAW;AAC5B,aAAS,SAAS,SAAU,OAAsC;AAChE,YAAM,SAAS,eAAe,KAAK;AAEnC,YAAM,kBAAkB,IAAI,gBAAgB;AAC5C,YAAM,UAAiC;AAAA,QACrC;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,gBAAgB;AAAA,MAC1B;AAEA,YAAM,MAAM;AAAA,QACV;AAAA,QACA,WAAW;AAAA,QACX,SAAS;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAEA,YAAM,iBAAiB,SAAS,OAAO;AAEvC,YAAM,iBAAiB,YAAY;AACjC,YAAI;AACF,gBAAM,WAAW,MAAM,eAAe;AACtC,gBAAM,SAAS;AAAA,YACb,QAAQ,SAAS;AAAA,YACjB,UAAU,SAAS;AAAA,YACnB,OAAO,SAAS;AAAA,UAClB;AAEA,cAAI,WAAW;AACf,cAAI,UAAU,KAAK,IAAI;AACvB,gBAAM,QAAQ,YAAY,cAAc,KAAK,IAAI;AACjD,gBAAM,QAAQ,YAAY,SAAS,KAAK,IAAI;AAE5C,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,gBAAM,MAAM,QAAQ,KAAK;AACzB,gBAAM,aAAa,YAAY,KAAK,GAAG;AACvC,gBAAM,oBAAoB,KAAK;AAAA,QACjC;AAAA,MACF,GAAG;AAEH,sBAAgB,gBAAiE;AAC/E,YAAI;AACF,gBAAM,QAAQ,YAAY,WAAW,GAAG;AACxC,gBAAM,QAAQ,YAAY,aAAa,GAAG;AAE1C,2BAAiB,SAAS,gBAAgB;AACxC,kBAAM;AAAA,UACR;AAAA,QACF,SAAS,OAAO;AACd,gBAAM,MAAM,QAAQ,KAAK;AACzB,gBAAM,aAAa,YAAY,KAAK,GAAG;AACvC,gBAAM,oBAAoB,KAAK;AAAA,QACjC;AAAA,MACF;AAEA,aAAO;AAAA,QACL,CAAC,OAAO,aAAa,GAAG,MAAM,cAAc;AAAA,QAC5C,QAAQ;AAAA,QACR,OAAO,MAAM,gBAAgB,MAAM;AAAA,MACrC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,aAAa,QAAQ,WAAW,MAAM;AACxC,UAAM,OAAO,WAAW;AACxB,aAAS,OAAO,eAAgB,OAA6C;AAC3E,UAAI;AACF,cAAM,WAAW,MAAM,KAAK;AAAA,UAC1B,OAAO,MAAM;AAAA,UACb,MAAM,MAAM;AAAA,UACZ,QAAQ,MAAM;AAAA,UACd;AAAA,UACA;AAAA,QACF,CAAC;AAED,eAAO;AAAA,UACL,QAAQ,SAAS;AAAA,UACjB,UAAU,SAAS;AAAA,UACnB,OAAO,SAAS;AAAA,QAClB;AAAA,MACF,SAAS,OAAO;AACd,cAAM,oBAAoB,KAAK;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC/NA,SAAS,eAAe,MAAsB;AAC5C,QAAM,MAAM,KAAK,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAE/C,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAwBO,IAAM,WAAN,MAAM,UAAS;AAAA;AAAA,EAEX;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAED,YACN,QACA,UACA,OACA;AACA,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,QAAQ;AAAA,EACf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,UAAmB;AACrB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAiB;AACnB,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAkB;AACpB,WAAO,KAAK,aAAa;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAmB;AACjB,QAAI,KAAK,OAAO,SAAS,UAAU;AACjC,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,IAAI,MAAM,uEAAuE;AAAA,EACzF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,SAAiB;AACf,QAAI,KAAK,OAAO,SAAS,QAAQ;AAC/B,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,IAAI,MAAM,oEAAoE;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAgB;AACd,QAAI,KAAK,OAAO,SAAS,OAAO;AAC9B,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,IAAI,MAAM,2CAA2C;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAyB;AACvB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,aAAa,SAAS,MAAc,OAAmC;AACrE,UAAM,OAAO,IAAI,KAAK,IAAI;AAC1B,UAAM,SAAS,MAAM,KAAK,OAAO;AACjC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,oCAAoC,IAAI,EAAE;AAAA,IAC5D;AAEA,QAAI;AACJ,QAAI;AACF,aAAO,MAAM,KAAK,YAAY;AAAA,IAChC,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAM,IAAI,MAAM,yCAAyC,IAAI,KAAK,OAAO,EAAE;AAAA,IAC7E;AAEA,QAAI,KAAK,eAAe,GAAG;AACzB,YAAM,IAAI,MAAM,mCAAmC,IAAI,EAAE;AAAA,IAC3D;AACA,UAAM,SAAS,OAAO,KAAK,IAAI,EAAE,SAAS,QAAQ;AAClD,UAAM,WAAW,eAAe,IAAI;AAEpC,WAAO,IAAI;AAAA,MACT,EAAE,MAAM,UAAU,MAAM,OAAO;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,OAAO,QAAQ,KAAa,OAA0B;AACpD,QAAI;AACJ,QAAI;AACF,kBAAY,IAAI,IAAI,GAAG;AAAA,IACzB,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAM,IAAI,MAAM,yBAAyB,OAAO,EAAE;AAAA,IACpD;AAEA,QAAI,UAAU,aAAa,WAAW,UAAU,aAAa,UAAU;AACrE,YAAM,IAAI,MAAM,wCAAwC,GAAG,EAAE;AAAA,IAC/D;AAEA,WAAO,IAAI;AAAA,MACT,EAAE,MAAM,OAAO,IAAI;AAAA,MACnB;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAO,WAAW,QAAgB,UAAkB,OAA0B;AAC5E,WAAO,IAAI;AAAA,MACT,EAAE,MAAM,UAAU,MAAM,OAAO;AAAA,MAC/B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAAO,SAASC,OAAc,OAA0B;AACtD,WAAO,IAAI;AAAA,MACT,EAAE,MAAM,QAAQ,MAAMA,MAAK;AAAA,MAC3B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,UAAU,OAAgC;AAC/C,WAAO,IAAI;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC7QA,SAASC,gBAAe,MAAsB;AAC5C,QAAM,MAAM,KAAK,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAE/C,UAAQ,KAAK;AAAA,IACX,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAyBO,IAAM,QAAN,MAAM,OAAM;AAAA;AAAA,EAER;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAED,YACN,MACA,UACA,UACA;AACA,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe;AACjB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAmB;AACjB,WAAO;AAAA,MACL,MAAM,KAAK,KAAK,IAAI,EACjB,IAAI,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC,EACjC,KAAK,EAAE;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAoB;AAClB,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,QAAQ,KAAK,QAAQ,WAAW,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAsB;AACpB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,IACjB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,aAAa,SAAS,MAAc,UAAmC;AACrE,UAAM,OAAO,IAAI,KAAK,IAAI;AAC1B,UAAM,SAAS,MAAM,KAAK,OAAO;AACjC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,iCAAiC,IAAI,EAAE;AAAA,IACzD;AAEA,QAAI;AACJ,QAAI;AACF,oBAAc,MAAM,KAAK,YAAY;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAM,IAAI,MAAM,sCAAsC,IAAI,KAAK,OAAO,EAAE;AAAA,IAC1E;AAEA,QAAI,YAAY,eAAe,GAAG;AAChC,YAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAAA,IACxD;AAEA,UAAM,WAAWA,gBAAe,IAAI;AAEpC,WAAO,IAAI;AAAA,MACT,IAAI,WAAW,WAAW;AAAA,MAC1B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAO,UAAU,MAAkB,UAAkB,UAA0B;AAC7E,WAAO,IAAI,OAAM,MAAM,UAAU,QAAQ;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAO,WAAW,QAAgB,UAAkB,UAA0B;AAC5E,UAAM,eAAe,KAAK,MAAM;AAChC,UAAM,QAAQ,IAAI,WAAW,aAAa,MAAM;AAChD,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,YAAM,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,IACtC;AACA,WAAO,IAAI,OAAM,OAAO,UAAU,QAAQ;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,UAAU,OAA0B;AACzC,WAAO,IAAI;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AACF;;;AC3NA,SAASC,gBAAe,MAAsB;AAC5C,QAAM,MAAM,KAAK,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAE/C,UAAQ,KAAK;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAyBO,IAAM,QAAN,MAAM,OAAM;AAAA;AAAA,EAER;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAED,YACN,MACA,UACA,SACA;AACA,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,WAAW,SAAS;AACzB,SAAK,QAAQ,SAAS;AACtB,SAAK,SAAS,SAAS;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe;AACjB,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAmB;AACjB,WAAO;AAAA,MACL,MAAM,KAAK,KAAK,IAAI,EACjB,IAAI,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC,EACjC,KAAK,EAAE;AAAA,IACZ;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAoB;AAClB,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,QAAQ,KAAK,QAAQ,WAAW,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAsB;AACpB,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAsB;AACpB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,MAAM,KAAK;AAAA,MACX,UAAU,KAAK;AAAA,MACf,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,aAAa,SACX,MACA,SACgB;AAChB,UAAM,OAAO,IAAI,KAAK,IAAI;AAC1B,UAAM,SAAS,MAAM,KAAK,OAAO;AACjC,QAAI,CAAC,QAAQ;AACX,YAAM,IAAI,MAAM,iCAAiC,IAAI,EAAE;AAAA,IACzD;AAEA,QAAI;AACJ,QAAI;AACF,oBAAc,MAAM,KAAK,YAAY;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,YAAM,IAAI,MAAM,sCAAsC,IAAI,KAAK,OAAO,EAAE;AAAA,IAC1E;AAEA,QAAI,YAAY,eAAe,GAAG;AAChC,YAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAAA,IACxD;AAEA,UAAM,WAAWA,gBAAe,IAAI;AAEpC,WAAO,IAAI;AAAA,MACT,IAAI,WAAW,WAAW;AAAA,MAC1B;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,OAAO,UACL,MACA,UACA,SACO;AACP,WAAO,IAAI,OAAM,MAAM,UAAU,OAAO;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAeA,OAAO,WACL,QACA,UACA,SACO;AACP,UAAM,eAAe,KAAK,MAAM;AAChC,UAAM,QAAQ,IAAI,WAAW,aAAa,MAAM;AAChD,aAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,YAAM,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,IACtC;AACA,WAAO,IAAI,OAAM,OAAO,UAAU,OAAO;AAAA,EAC3C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,UAAU,OAA0B;AACzC,WAAO,IAAI;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,QACE,UAAU,MAAM;AAAA,QAChB,OAAO,MAAM;AAAA,QACb,QAAQ,MAAM;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AACF;;;AC1PO,IAAM,qBAAqB;AAAA;AAAA,EAEhC,UAAU;AAAA;AAAA,EAEV,OAAO;AACT;;;ACiDO,IAAM,KAAK;AAAA;AAAA,EAEhB;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AACF;","names":["newMessages","approved","text","detectMimeType","detectMimeType"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/content.ts","../src/middleware/runner.ts","../src/core/llm.ts","../src/core/embedding.ts","../src/core/image.ts","../src/core/media/document.ts","../src/core/media/Audio.ts","../src/core/media/Video.ts","../src/types/embedding.ts","../src/index.ts"],"sourcesContent":["/**\n * @fileoverview Content block types for multimodal messages.\n *\n * Defines the various content block types that can be included in\n * user and assistant messages, supporting text, images, audio, video,\n * and arbitrary binary data.\n *\n * @module types/content\n */\n\n/**\n * Content block type constants.\n *\n * Use these constants instead of raw strings for type-safe content handling:\n *\n * @example\n * ```typescript\n * import { ContentBlockType } from 'upp';\n *\n * if (block.type === ContentBlockType.Text) {\n * console.log(block.text);\n * } else if (block.type === ContentBlockType.Image) {\n * console.log(block.mimeType);\n * }\n * ```\n */\nexport const ContentBlockType = {\n /** Text content */\n Text: 'text',\n /** Reasoning/thinking content from extended thinking models */\n Reasoning: 'reasoning',\n /** Image content */\n Image: 'image',\n /** Document content (PDFs, text files) */\n Document: 'document',\n /** Audio content */\n Audio: 'audio',\n /** Video content */\n Video: 'video',\n /** Binary/arbitrary data content */\n Binary: 'binary',\n} as const;\n\n/**\n * Content block type discriminator union.\n *\n * This type is derived from {@link ContentBlockType} constants.\n */\nexport type ContentBlockType = (typeof ContentBlockType)[keyof typeof ContentBlockType];\n\n/**\n * Image source type constants.\n *\n * @example\n * ```typescript\n * import { ImageSourceType } from 'upp';\n *\n * if (source.type === ImageSourceType.Base64) {\n * // Handle base64 encoded image\n * } else if (source.type === ImageSourceType.Url) {\n * // Handle URL reference\n * }\n * ```\n */\nexport const ImageSourceType = {\n /** Base64-encoded image data */\n Base64: 'base64',\n /** URL reference to image */\n Url: 'url',\n /** Raw bytes image data */\n Bytes: 'bytes',\n} as const;\n\n/**\n * Image source type discriminator union.\n *\n * This type is derived from {@link ImageSourceType} constants.\n */\nexport type ImageSourceType = (typeof ImageSourceType)[keyof typeof ImageSourceType];\n\n/**\n * Image source variants for ImageBlock.\n *\n * Images can be provided as base64-encoded strings, URLs, or raw bytes.\n *\n * @example\n * ```typescript\n * // Base64 encoded image\n * const base64Source: ImageSource = {\n * type: 'base64',\n * data: 'iVBORw0KGgo...'\n * };\n *\n * // URL reference\n * const urlSource: ImageSource = {\n * type: 'url',\n * url: 'https://example.com/image.png'\n * };\n *\n * // Raw bytes\n * const bytesSource: ImageSource = {\n * type: 'bytes',\n * data: new Uint8Array([...])\n * };\n * ```\n */\nexport type ImageSource =\n | { type: 'base64'; data: string }\n | { type: 'url'; url: string }\n | { type: 'bytes'; data: Uint8Array };\n\n/**\n * Document source type constants.\n *\n * @example\n * ```typescript\n * import { DocumentSourceType } from 'upp';\n *\n * if (source.type === DocumentSourceType.Base64) {\n * // Handle base64 encoded document (PDF)\n * } else if (source.type === DocumentSourceType.Url) {\n * // Handle URL reference (PDF)\n * } else if (source.type === DocumentSourceType.Text) {\n * // Handle plain text document\n * }\n * ```\n */\nexport const DocumentSourceType = {\n /** Base64-encoded document data (for PDFs) */\n Base64: 'base64',\n /** URL reference to document (for PDFs) */\n Url: 'url',\n /** Plain text document content */\n Text: 'text',\n} as const;\n\n/**\n * Document source type discriminator union.\n *\n * This type is derived from {@link DocumentSourceType} constants.\n */\nexport type DocumentSourceType = (typeof DocumentSourceType)[keyof typeof DocumentSourceType];\n\n/**\n * Document source variants for DocumentBlock.\n *\n * Documents can be provided as base64-encoded data (PDFs), URLs (PDFs), or plain text.\n *\n * @example\n * ```typescript\n * // Base64 encoded PDF\n * const base64Source: DocumentSource = {\n * type: 'base64',\n * data: 'JVBERi0xLjQK...'\n * };\n *\n * // URL reference to PDF\n * const urlSource: DocumentSource = {\n * type: 'url',\n * url: 'https://example.com/document.pdf'\n * };\n *\n * // Plain text document\n * const textSource: DocumentSource = {\n * type: 'text',\n * data: 'This is the document content...'\n * };\n * ```\n */\nexport type DocumentSource =\n | { type: 'base64'; data: string }\n | { type: 'url'; url: string }\n | { type: 'text'; data: string };\n\n/**\n * Text content block.\n *\n * The most common content block type, containing plain text content.\n *\n * @example\n * ```typescript\n * const textBlock: TextBlock = {\n * type: 'text',\n * text: 'Hello, world!'\n * };\n * ```\n */\nexport interface TextBlock {\n /** Discriminator for text blocks */\n type: 'text';\n\n /** The text content */\n text: string;\n}\n\n/**\n * Reasoning content block.\n *\n * Contains model reasoning/thinking from extended thinking or chain-of-thought.\n * This content represents the model's internal reasoning process.\n *\n * @example\n * ```typescript\n * const reasoningBlock: ReasoningBlock = {\n * type: 'reasoning',\n * text: 'Let me think about this step by step...'\n * };\n * ```\n */\nexport interface ReasoningBlock {\n /** Discriminator for reasoning blocks */\n type: 'reasoning';\n\n /** The reasoning/thinking text */\n text: string;\n}\n\n/**\n * Image content block.\n *\n * Contains an image with its source data and metadata.\n *\n * @example\n * ```typescript\n * const imageBlock: ImageBlock = {\n * type: 'image',\n * source: { type: 'url', url: 'https://example.com/photo.jpg' },\n * mimeType: 'image/jpeg',\n * width: 1920,\n * height: 1080\n * };\n * ```\n */\nexport interface ImageBlock {\n /** Discriminator for image blocks */\n type: 'image';\n\n /** The image data source */\n source: ImageSource;\n\n /** MIME type of the image (e.g., 'image/png', 'image/jpeg') */\n mimeType: string;\n\n /** Image width in pixels */\n width?: number;\n\n /** Image height in pixels */\n height?: number;\n}\n\n/**\n * Document content block.\n *\n * Contains a document (PDF or plain text) with its source and metadata.\n * Supports PDF documents via base64 encoding or URL, and plain text content.\n *\n * @example\n * ```typescript\n * // PDF document from base64\n * const pdfBlock: DocumentBlock = {\n * type: 'document',\n * source: { type: 'base64', data: 'JVBERi0xLjQK...' },\n * mimeType: 'application/pdf',\n * title: 'Annual Report'\n * };\n *\n * // Plain text document\n * const textDoc: DocumentBlock = {\n * type: 'document',\n * source: { type: 'text', data: 'Document contents here...' },\n * mimeType: 'text/plain'\n * };\n * ```\n */\nexport interface DocumentBlock {\n /** Discriminator for document blocks */\n type: 'document';\n\n /** The document data source */\n source: DocumentSource;\n\n /** MIME type of the document ('application/pdf' or 'text/plain') */\n mimeType: string;\n\n /** Optional document title (used for citations) */\n title?: string;\n}\n\n/**\n * Audio content block.\n *\n * Contains audio data with its metadata.\n *\n * @example\n * ```typescript\n * const audioBlock: AudioBlock = {\n * type: 'audio',\n * data: audioBytes,\n * mimeType: 'audio/mp3',\n * duration: 120.5\n * };\n * ```\n */\nexport interface AudioBlock {\n /** Discriminator for audio blocks */\n type: 'audio';\n\n /** Raw audio data */\n data: Uint8Array;\n\n /** MIME type of the audio (e.g., 'audio/mp3', 'audio/wav') */\n mimeType: string;\n\n /** Duration in seconds */\n duration?: number;\n}\n\n/**\n * Video content block.\n *\n * Contains video data with its metadata.\n *\n * @example\n * ```typescript\n * const videoBlock: VideoBlock = {\n * type: 'video',\n * data: videoBytes,\n * mimeType: 'video/mp4',\n * duration: 30,\n * width: 1920,\n * height: 1080\n * };\n * ```\n */\nexport interface VideoBlock {\n /** Discriminator for video blocks */\n type: 'video';\n\n /** Raw video data */\n data: Uint8Array;\n\n /** MIME type of the video (e.g., 'video/mp4', 'video/webm') */\n mimeType: string;\n\n /** Duration in seconds */\n duration?: number;\n\n /** Video width in pixels */\n width?: number;\n\n /** Video height in pixels */\n height?: number;\n}\n\n/**\n * Binary content block for arbitrary data.\n *\n * A generic block type for data that doesn't fit other categories.\n *\n * @example\n * ```typescript\n * const binaryBlock: BinaryBlock = {\n * type: 'binary',\n * data: pdfBytes,\n * mimeType: 'application/pdf',\n * metadata: { filename: 'document.pdf', pages: 10 }\n * };\n * ```\n */\nexport interface BinaryBlock {\n /** Discriminator for binary blocks */\n type: 'binary';\n\n /** Raw binary data */\n data: Uint8Array;\n\n /** MIME type of the data */\n mimeType: string;\n\n /** Additional metadata about the binary content */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Union of all content block types.\n *\n * Used when a function or property can accept any type of content block.\n */\nexport type ContentBlock =\n | TextBlock\n | ReasoningBlock\n | ImageBlock\n | DocumentBlock\n | AudioBlock\n | VideoBlock\n | BinaryBlock;\n\n/**\n * Content types allowed in user messages.\n *\n * Users can send any type of content block including binary data.\n */\nexport type UserContent =\n | TextBlock\n | ImageBlock\n | DocumentBlock\n | AudioBlock\n | VideoBlock\n | BinaryBlock;\n\n/**\n * Content types allowed in assistant messages.\n *\n * Assistants can generate text and media but not arbitrary binary data.\n */\nexport type AssistantContent =\n | TextBlock\n | ReasoningBlock\n | ImageBlock\n | AudioBlock\n | VideoBlock;\n\n/**\n * Creates a text content block from a string.\n *\n * @param content - The text content\n * @returns A TextBlock containing the provided text\n *\n * @example\n * ```typescript\n * const block = text('Hello, world!');\n * // { type: 'text', text: 'Hello, world!' }\n * ```\n */\nexport function text(content: string): TextBlock {\n return { type: ContentBlockType.Text, text: content };\n}\n\n/**\n * Creates a reasoning content block from a string.\n *\n * @param content - The reasoning/thinking content\n * @returns A ReasoningBlock containing the provided text\n *\n * @example\n * ```typescript\n * const block = reasoning('Let me think step by step...');\n * // { type: 'reasoning', text: 'Let me think step by step...' }\n * ```\n */\nexport function reasoning(content: string): ReasoningBlock {\n return { type: ContentBlockType.Reasoning, text: content };\n}\n\n/**\n * Type guard for TextBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a TextBlock\n *\n * @example\n * ```typescript\n * if (isTextBlock(block)) {\n * console.log(block.text);\n * }\n * ```\n */\nexport function isTextBlock(block: ContentBlock): block is TextBlock {\n return block.type === ContentBlockType.Text;\n}\n\n/**\n * Type guard for ReasoningBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a ReasoningBlock\n *\n * @example\n * ```typescript\n * if (isReasoningBlock(block)) {\n * console.log(block.text);\n * }\n * ```\n */\nexport function isReasoningBlock(block: ContentBlock): block is ReasoningBlock {\n return block.type === ContentBlockType.Reasoning;\n}\n\n/**\n * Type guard for ImageBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is an ImageBlock\n *\n * @example\n * ```typescript\n * if (isImageBlock(block)) {\n * console.log(block.mimeType, block.width, block.height);\n * }\n * ```\n */\nexport function isImageBlock(block: ContentBlock): block is ImageBlock {\n return block.type === ContentBlockType.Image;\n}\n\n/**\n * Type guard for DocumentBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a DocumentBlock\n *\n * @example\n * ```typescript\n * if (isDocumentBlock(block)) {\n * console.log(block.mimeType, block.title);\n * }\n * ```\n */\nexport function isDocumentBlock(block: ContentBlock): block is DocumentBlock {\n return block.type === ContentBlockType.Document;\n}\n\n/**\n * Type guard for AudioBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is an AudioBlock\n *\n * @example\n * ```typescript\n * if (isAudioBlock(block)) {\n * console.log(block.mimeType, block.duration);\n * }\n * ```\n */\nexport function isAudioBlock(block: ContentBlock): block is AudioBlock {\n return block.type === ContentBlockType.Audio;\n}\n\n/**\n * Type guard for VideoBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a VideoBlock\n *\n * @example\n * ```typescript\n * if (isVideoBlock(block)) {\n * console.log(block.mimeType, block.duration);\n * }\n * ```\n */\nexport function isVideoBlock(block: ContentBlock): block is VideoBlock {\n return block.type === ContentBlockType.Video;\n}\n\n/**\n * Type guard for BinaryBlock.\n *\n * @param block - The content block to check\n * @returns True if the block is a BinaryBlock\n *\n * @example\n * ```typescript\n * if (isBinaryBlock(block)) {\n * console.log(block.mimeType, block.metadata);\n * }\n * ```\n */\nexport function isBinaryBlock(block: ContentBlock): block is BinaryBlock {\n return block.type === ContentBlockType.Binary;\n}\n","/**\n * @fileoverview Middleware execution utilities.\n *\n * Provides functions for running middleware hooks in the correct order\n * and creating stream event transformers from middleware arrays.\n *\n * @module middleware/runner\n */\n\nimport type {\n Middleware,\n MiddlewareContext,\n StreamContext,\n} from '../types/middleware.ts';\nimport type { StreamEvent } from '../types/stream.ts';\nimport type { Tool } from '../types/tool.ts';\nimport type { Turn } from '../types/turn.ts';\n\n/**\n * Lifecycle hook names that can be run in forward or reverse order.\n */\nexport type LifecycleHook = 'onStart' | 'onEnd' | 'onRequest' | 'onResponse';\n\n/**\n * Runs a lifecycle hook for all middleware in the specified order.\n *\n * Hooks are run sequentially to maintain consistent ordering.\n * If reverse is true, middleware are processed in reverse array order.\n *\n * @param middlewares - Array of middleware to process\n * @param hook - The hook name to execute\n * @param ctx - The middleware context\n * @param reverse - Whether to run in reverse order (default: false)\n */\nexport async function runHook(\n middlewares: Middleware[],\n hook: LifecycleHook,\n ctx: MiddlewareContext,\n reverse = false\n): Promise<void> {\n const ordered = reverse ? [...middlewares].reverse() : middlewares;\n\n for (const mw of ordered) {\n const fn = mw[hook];\n if (fn) {\n await fn.call(mw, ctx);\n }\n }\n}\n\n/**\n * Runs the onError hook for all middleware that have it.\n *\n * Error hooks are always run for all middleware, regardless of which\n * middleware was active when the error occurred. Errors from error\n * hooks themselves are logged but not re-thrown.\n *\n * @param middlewares - Array of middleware to process\n * @param error - The error that occurred\n * @param ctx - The middleware context\n */\nexport async function runErrorHook(\n middlewares: Middleware[],\n error: Error,\n ctx: MiddlewareContext\n): Promise<void> {\n for (const mw of middlewares) {\n if (mw.onError) {\n try {\n await mw.onError(error, ctx);\n } catch (hookError) {\n // Log but don't throw - error hooks should not cause additional failures\n console.error(`[${mw.name}] Error in onError hook:`, hookError);\n }\n }\n }\n}\n\n/**\n * Runs the onAbort hook for all middleware that have it.\n *\n * Abort hooks are run for all middleware when a request is cancelled.\n * Errors from abort hooks are logged but not re-thrown.\n *\n * @param middlewares - Array of middleware to process\n * @param error - The cancellation error\n * @param ctx - The middleware context\n */\nexport async function runAbortHook(\n middlewares: Middleware[],\n error: Error,\n ctx: MiddlewareContext\n): Promise<void> {\n for (const mw of middlewares) {\n if (mw.onAbort) {\n try {\n await mw.onAbort(error, ctx);\n } catch (hookError) {\n // Log but don't throw - abort hooks should not cause additional failures\n console.error(`[${mw.name}] Error in onAbort hook:`, hookError);\n }\n }\n }\n}\n\n/**\n * Runs tool hooks (onToolCall or onToolResult) for all middleware.\n *\n * Tool hooks are run in forward order for onToolCall and allow middleware\n * to observe or log tool interactions.\n *\n * @param middlewares - Array of middleware to process\n * @param hook - Either 'onToolCall' or 'onToolResult'\n * @param tool - The tool being called/that was called\n * @param data - Parameters (onToolCall) or result (onToolResult)\n * @param ctx - The middleware context\n */\nexport async function runToolHook(\n middlewares: Middleware[],\n hook: 'onToolCall' | 'onToolResult',\n tool: Tool,\n data: unknown,\n ctx: MiddlewareContext\n): Promise<void> {\n for (const mw of middlewares) {\n const fn = mw[hook];\n if (fn) {\n await fn.call(mw, tool, data, ctx);\n }\n }\n}\n\n/**\n * Runs the onTurn hook for all middleware that have it.\n *\n * Turn hooks are run in reverse middleware order.\n *\n * @param middlewares - Array of middleware to process\n * @param turn - The completed Turn\n * @param ctx - The middleware context\n */\nexport async function runTurnHook(\n middlewares: Middleware[],\n turn: Turn,\n ctx: MiddlewareContext\n): Promise<void> {\n const ordered = [...middlewares].reverse();\n for (const mw of ordered) {\n if (mw.onTurn) {\n await mw.onTurn.call(mw, turn, ctx);\n }\n }\n}\n\n/**\n * Creates a stream event transformer from middleware array.\n *\n * The transformer applies onStreamEvent hooks from all middleware in sequence.\n * Each middleware can transform, filter (return null), or expand (return array)\n * events.\n *\n * @param middlewares - Array of middleware to process\n * @param ctx - The stream context\n * @returns A function that transforms stream events\n *\n * @example\n * ```typescript\n * const transformer = createStreamTransformer(middlewares, streamCtx);\n *\n * for await (const event of baseStream) {\n * const result = transformer(event);\n * if (result === null) continue;\n * if (Array.isArray(result)) {\n * for (const e of result) yield e;\n * } else {\n * yield result;\n * }\n * }\n * ```\n */\nexport function createStreamTransformer(\n middlewares: Middleware[],\n ctx: StreamContext\n): (event: StreamEvent) => StreamEvent | StreamEvent[] | null {\n const streamMiddlewares = middlewares.filter((mw) => mw.onStreamEvent);\n\n if (streamMiddlewares.length === 0) {\n return (event) => event;\n }\n\n return (event: StreamEvent): StreamEvent | StreamEvent[] | null => {\n let current: StreamEvent | StreamEvent[] | null = event;\n\n for (const mw of streamMiddlewares) {\n if (current === null) {\n return null;\n }\n\n if (Array.isArray(current)) {\n // Process each event in the array through this middleware\n const results: StreamEvent[] = [];\n for (const e of current) {\n const result = mw.onStreamEvent!(e, ctx);\n if (result === null) {\n continue;\n }\n if (Array.isArray(result)) {\n results.push(...result);\n } else {\n results.push(result);\n }\n }\n current = results.length > 0 ? results : null;\n } else {\n current = mw.onStreamEvent!(current, ctx);\n }\n }\n\n return current;\n };\n}\n\n/**\n * Runs onStreamEnd hook for all middleware that have it.\n *\n * Called after all stream events have been processed.\n *\n * @param middlewares - Array of middleware to process\n * @param ctx - The stream context\n */\nexport async function runStreamEndHook(\n middlewares: Middleware[],\n ctx: StreamContext\n): Promise<void> {\n for (const mw of middlewares) {\n if (mw.onStreamEnd) {\n await mw.onStreamEnd(ctx);\n }\n }\n}\n\n/**\n * Creates a fresh MiddlewareContext for a request.\n *\n * @param modality - The modality ('llm', 'embedding', 'image')\n * @param modelId - The model ID\n * @param provider - The provider name\n * @param streaming - Whether this is a streaming request\n * @param request - The request object\n * @returns A new MiddlewareContext\n */\nexport function createMiddlewareContext(\n modality: 'llm' | 'embedding' | 'image',\n modelId: string,\n provider: string,\n streaming: boolean,\n request: MiddlewareContext['request']\n): MiddlewareContext {\n return {\n modality,\n modelId,\n provider,\n streaming,\n request,\n response: undefined,\n state: new Map(),\n startTime: Date.now(),\n endTime: undefined,\n };\n}\n\n/**\n * Creates a fresh StreamContext for streaming operations.\n *\n * @param state - Shared state map (usually from MiddlewareContext)\n * @returns A new StreamContext\n */\nexport function createStreamContext(\n state: Map<string, unknown>\n): StreamContext {\n return { state };\n}\n","/**\n * @fileoverview LLM instance factory and streaming logic for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating and managing LLM instances,\n * including support for tool execution, streaming responses, and structured output.\n *\n * @module core/llm\n */\n\nimport type {\n LLMOptions,\n LLMInstance,\n LLMRequest,\n InferenceInput,\n BoundLLMModel,\n LLMCapabilities,\n} from '../types/llm.ts';\nimport type { JSONSchema } from '../types/schema.ts';\nimport type { AssistantMessage } from '../types/messages.ts';\nimport type { ContentBlock } from '../types/content.ts';\nimport {\n isTextBlock,\n isImageBlock,\n isDocumentBlock,\n isAudioBlock,\n isVideoBlock,\n isBinaryBlock,\n} from '../types/content.ts';\nimport type { AfterCallResult, BeforeCallResult, Tool, ToolExecution, ToolResult } from '../types/tool.ts';\nimport type { Turn, TokenUsage } from '../types/turn.ts';\nimport type { StreamResult, StreamEvent } from '../types/stream.ts';\nimport type { Thread } from '../types/thread.ts';\nimport type { ProviderConfig, LLMHandler } from '../types/provider.ts';\nimport type { Middleware, MiddlewareContext } from '../types/middleware.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveLLMHandler } from './provider-handlers.ts';\nimport {\n Message,\n UserMessage as UserMessageClass,\n ToolResultMessage,\n isUserMessage,\n} from '../types/messages.ts';\nimport { createTurn, aggregateUsage } from '../types/turn.ts';\nimport {\n createStreamResult,\n toolExecutionStart,\n toolExecutionEnd,\n} from '../types/stream.ts';\nimport { toError, isCancelledError } from '../utils/error.ts';\nimport { resolveStructure, resolveTools } from '../utils/zod.ts';\nimport {\n runHook,\n runErrorHook,\n runAbortHook,\n runToolHook,\n runTurnHook,\n runStreamEndHook,\n createStreamTransformer,\n createMiddlewareContext,\n createStreamContext,\n} from '../middleware/runner.ts';\n\n/** Default maximum iterations for the tool execution loop */\nconst DEFAULT_MAX_ITERATIONS = 10;\nconst TURN_START_INDEX_KEY = 'llm:turnStartIndex';\n\n/**\n * Validates that message content is compatible with provider capabilities.\n *\n * Checks user messages for media types (image, document, video, audio) and throws\n * if the provider does not support the required input modality.\n *\n * @param messages - Messages to validate\n * @param capabilities - Provider's declared capabilities\n * @param providerName - Provider name for error messages\n * @throws {UPPError} When a message contains unsupported media type\n */\nfunction validateMediaCapabilities(\n messages: Message[],\n capabilities: LLMCapabilities,\n providerName: string\n): void {\n for (const msg of messages) {\n if (!isUserMessage(msg)) continue;\n\n for (const block of msg.content) {\n if (block.type === 'image' && !capabilities.imageInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support image input`,\n ErrorCode.InvalidRequest,\n providerName,\n ModalityType.LLM\n );\n }\n if (block.type === 'document' && !capabilities.documentInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support document input`,\n ErrorCode.InvalidRequest,\n providerName,\n ModalityType.LLM\n );\n }\n if (block.type === 'video' && !capabilities.videoInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support video input`,\n ErrorCode.InvalidRequest,\n providerName,\n ModalityType.LLM\n );\n }\n if (block.type === 'audio' && !capabilities.audioInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support audio input`,\n ErrorCode.InvalidRequest,\n providerName,\n ModalityType.LLM\n );\n }\n }\n }\n}\n\n/**\n * Type guard to check if a value is a Message instance.\n *\n * Uses `instanceof` for class instances, with a structural fallback for\n * deserialized or reconstructed Message objects that have the expected shape.\n *\n * @param value - The value to check\n * @returns `true` if the value is a Message instance\n */\nfunction isMessageInstance(value: unknown): value is Message {\n if (value instanceof Message) {\n return true;\n }\n if (typeof value === 'object' && value !== null) {\n const obj = value as Record<string, unknown>;\n const type = obj.type;\n const id = obj.id;\n const timestamp = obj.timestamp;\n const hasValidTimestamp =\n timestamp instanceof Date ||\n (typeof timestamp === 'string' && !Number.isNaN(Date.parse(timestamp)));\n\n if (typeof id !== 'string' || id.length === 0 || !hasValidTimestamp) {\n return false;\n }\n\n if (type === 'user' || type === 'assistant') {\n return Array.isArray(obj.content);\n }\n\n if (type === 'tool_result') {\n return Array.isArray(obj.results);\n }\n }\n return false;\n}\n\n/**\n * Converts an inference input to a Message instance.\n *\n * Handles string inputs, existing Message objects, and ContentBlocks,\n * wrapping non-Message inputs in a UserMessage.\n *\n * @param input - The input to convert (string, Message, or ContentBlock)\n * @returns A Message instance\n */\nfunction inputToMessage(input: InferenceInput): Message {\n if (typeof input === 'string') {\n return new UserMessageClass(input);\n }\n\n if ('type' in input && 'id' in input && 'timestamp' in input) {\n return input as Message;\n }\n\n if (typeof input !== 'object' || input === null || !('type' in input)) {\n throw new Error('Invalid inference input');\n }\n\n const block = input as ContentBlock;\n if (isTextBlock(block)) {\n return new UserMessageClass(block.text);\n }\n\n if (\n isImageBlock(block) ||\n isDocumentBlock(block) ||\n isAudioBlock(block) ||\n isVideoBlock(block) ||\n isBinaryBlock(block)\n ) {\n return new UserMessageClass([block]);\n }\n\n throw new Error('Invalid inference input');\n}\n\n/**\n * Parses flexible input arguments to separate conversation history from new messages.\n *\n * Supports multiple input patterns:\n * - No input (system-only generation)\n * - Thread object with existing messages\n * - Message array as history\n * - Direct input (string, Message, or ContentBlock) without history\n *\n * @param historyOrInput - Either conversation history, first input, or undefined for no input\n * @param inputs - Additional inputs to convert to messages\n * @returns Object containing separated history and new messages arrays\n */\nfunction parseInputs(\n historyOrInput: Message[] | Thread | InferenceInput | undefined,\n inputs: InferenceInput[]\n): { history: Message[]; messages: Message[] } {\n // Handle no-input case (system-only generation)\n if (historyOrInput === undefined && inputs.length === 0) {\n return { history: [], messages: [] };\n }\n if (\n typeof historyOrInput === 'object' &&\n historyOrInput !== null &&\n 'messages' in historyOrInput &&\n Array.isArray((historyOrInput as Thread).messages)\n ) {\n const thread = historyOrInput as Thread;\n const newMessages = inputs.map(inputToMessage);\n return { history: [...thread.messages], messages: newMessages };\n }\n\n if (Array.isArray(historyOrInput)) {\n if (historyOrInput.length === 0) {\n const newMessages = inputs.map(inputToMessage);\n return { history: [], messages: newMessages };\n }\n const first = historyOrInput[0];\n if (isMessageInstance(first)) {\n const newMessages = inputs.map(inputToMessage);\n return { history: historyOrInput as Message[], messages: newMessages };\n }\n }\n\n const allInputs = [historyOrInput as InferenceInput, ...inputs];\n const newMessages = allInputs.map(inputToMessage);\n return { history: [], messages: newMessages };\n}\n\n/**\n * Resolves the start index for the current turn within the request messages.\n *\n * Uses explicit history IDs when available, then falls back to an optional\n * middleware override, then attempts to locate new input message IDs.\n * If inputs cannot be located and no explicit history is available, defaults\n * to slicing from the start to avoid dropping expanded inputs.\n *\n * @param messages - Full request messages array after middleware\n * @param history - Explicit history messages provided by the caller\n * @param newMessages - New input messages for this request\n * @param requestMessageCount - Message count at request time (before model outputs)\n * @param overrideIndex - Optional override index provided via middleware state\n * @returns The index where the new turn begins\n */\nfunction resolveTurnStartIndex(\n messages: Message[],\n history: Message[],\n newMessages: Message[],\n requestMessageCount: number,\n overrideIndex?: number\n): number {\n if (history.length > 0) {\n const historyIds = new Set(history.map((message) => message.id));\n let lastHistoryIndex = -1;\n for (let i = 0; i < messages.length; i += 1) {\n if (historyIds.has(messages[i]!.id)) {\n lastHistoryIndex = i;\n }\n }\n if (lastHistoryIndex !== -1) {\n return lastHistoryIndex + 1;\n }\n }\n\n if (typeof overrideIndex === 'number' && Number.isFinite(overrideIndex)) {\n return Math.min(Math.max(0, overrideIndex), requestMessageCount);\n }\n\n if (newMessages.length > 0) {\n const newMessageIds = new Set(newMessages.map((message) => message.id));\n const index = messages.findIndex((message) => newMessageIds.has(message.id));\n if (index !== -1) {\n return index;\n }\n }\n\n if (history.length === 0) {\n return 0;\n }\n\n return Math.max(0, requestMessageCount - newMessages.length);\n}\n\n/**\n * Executes tool calls from an assistant message in parallel.\n *\n * Handles the complete tool execution flow including:\n * - Tool lookup and validation\n * - Strategy callbacks (onToolCall, onBeforeCall, onAfterCall, onError)\n * - Approval handlers\n * - Execution tracking and timing\n * - Stream event emission for real-time updates\n * - Middleware tool hooks\n *\n * @param assistantMessage - The assistant message containing tool calls\n * @param tools - Available tools to execute\n * @param toolStrategy - Strategy for controlling tool execution behavior\n * @param executions - Array to collect execution records (mutated in place)\n * @param onEvent - Optional callback for emitting stream events during execution\n * @param middleware - Optional middleware array for tool hooks\n * @param ctx - Optional middleware context\n * @returns Array of tool results to send back to the model\n */\nasync function executeTools(\n assistantMessage: AssistantMessage,\n tools: Tool[],\n toolStrategy: LLMOptions<unknown>['toolStrategy'],\n executions: ToolExecution[],\n onEvent?: (event: StreamEvent) => void,\n middleware: Middleware[] = [],\n ctx?: MiddlewareContext\n): Promise<ToolResult[]> {\n const toolCalls = assistantMessage.toolCalls ?? [];\n const results: ToolResult[] = [];\n\n const toolMap = new Map(tools.map((t) => [t.name, t]));\n\n const promises = toolCalls.map(async (call, index) => {\n const tool = toolMap.get(call.toolName);\n const toolName = tool?.name ?? call.toolName;\n const startTime = Date.now();\n\n onEvent?.(toolExecutionStart(call.toolCallId, toolName, startTime, index));\n\n let effectiveParams = call.arguments;\n\n const endWithError = async (errorMessage: string, approved?: boolean): Promise<ToolResult> => {\n const endTime = Date.now();\n if (tool) {\n await toolStrategy?.onError?.(tool, effectiveParams, new Error(errorMessage));\n }\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams,\n result: errorMessage,\n isError: true,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, errorMessage, true, endTime, index));\n return {\n toolCallId: call.toolCallId,\n result: errorMessage,\n isError: true,\n };\n };\n\n if (!tool) {\n return endWithError(`Tool '${call.toolName}' not found`);\n }\n\n try {\n await toolStrategy?.onToolCall?.(tool, effectiveParams);\n // Run middleware onToolCall hooks\n if (ctx) {\n await runToolHook(middleware, 'onToolCall', tool, effectiveParams, ctx);\n }\n } catch (error) {\n return endWithError(toError(error).message);\n }\n\n if (toolStrategy?.onBeforeCall) {\n let beforeResult: boolean | BeforeCallResult | undefined;\n try {\n beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);\n } catch (error) {\n return endWithError(toError(error).message);\n }\n\n const isBeforeCallResult = (value: unknown): value is BeforeCallResult =>\n typeof value === 'object' && value !== null && 'proceed' in value;\n\n if (isBeforeCallResult(beforeResult)) {\n if (!beforeResult.proceed) {\n return endWithError('Tool execution skipped');\n }\n if (beforeResult.params !== undefined) {\n effectiveParams = beforeResult.params as Record<string, unknown>;\n }\n } else if (!beforeResult) {\n return endWithError('Tool execution skipped');\n }\n }\n\n let approved = true;\n if (tool.approval) {\n try {\n approved = await tool.approval(effectiveParams);\n } catch (error) {\n return endWithError(toError(error).message);\n }\n }\n\n if (!approved) {\n const endTime = Date.now();\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams as Record<string, unknown>,\n result: 'Tool execution denied',\n isError: true,\n duration: endTime - startTime,\n approved: false,\n };\n executions.push(execution);\n\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, 'Tool execution denied by approval handler', true, endTime, index));\n\n return {\n toolCallId: call.toolCallId,\n result: 'Tool execution denied by approval handler',\n isError: true,\n };\n }\n\n try {\n let result = await tool.run(effectiveParams);\n const endTime = Date.now();\n\n if (toolStrategy?.onAfterCall) {\n const afterResult = await toolStrategy.onAfterCall(tool, effectiveParams, result);\n const isAfterCallResult = (value: unknown): value is AfterCallResult =>\n typeof value === 'object' && value !== null && 'result' in value;\n\n if (isAfterCallResult(afterResult)) {\n result = afterResult.result;\n }\n }\n\n // Run middleware onToolResult hooks\n if (ctx) {\n await runToolHook(middleware, 'onToolResult', tool, result, ctx);\n }\n\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams as Record<string, unknown>,\n result,\n isError: false,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, result, false, endTime, index));\n\n return {\n toolCallId: call.toolCallId,\n result,\n isError: false,\n };\n } catch (error) {\n const endTime = Date.now();\n const err = toError(error);\n await toolStrategy?.onError?.(tool, effectiveParams, err);\n\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams as Record<string, unknown>,\n result: err.message,\n isError: true,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, err.message, true, endTime, index));\n\n return {\n toolCallId: call.toolCallId,\n result: err.message,\n isError: true,\n };\n }\n });\n\n results.push(...(await Promise.all(promises)));\n return results;\n}\n\n/**\n * Executes a non-streaming generation request with automatic tool execution loop.\n *\n * Handles the complete lifecycle of a generation request including:\n * - Media capability validation\n * - Iterative tool execution until completion or max iterations\n * - Token usage aggregation across iterations\n * - Structured output extraction\n *\n * @typeParam TParams - Provider-specific parameter type\n * @param model - The bound LLM model to use\n * @param config - Provider configuration options\n * @param system - Optional system prompt\n * @param params - Provider-specific parameters\n * @param tools - Available tools for the model to call\n * @param toolStrategy - Strategy for tool execution behavior\n * @param structure - Schema for structured output\n * @param history - Previous conversation messages\n * @param newMessages - New messages to send\n * @returns A Turn containing all messages, tool executions, and usage\n * @throws {UPPError} When max iterations exceeded or media not supported\n */\nasync function executeGenerate<TParams>(\n model: BoundLLMModel<TParams>,\n config: ProviderConfig,\n system: string | unknown[] | undefined,\n params: TParams | undefined,\n tools: Tool[] | undefined,\n toolStrategy: LLMOptions<TParams>['toolStrategy'],\n structure: JSONSchema | undefined,\n history: Message[],\n newMessages: Message[],\n middleware: Middleware[]\n): Promise<Turn> {\n const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n let allMessages: Message[] = [...history, ...newMessages];\n const toolExecutions: ToolExecution[] = [];\n const usages: TokenUsage[] = [];\n let cycles = 0;\n\n let structuredData: unknown;\n let turnStartIndex = history.length;\n\n // Create initial request for middleware context\n const initialRequest: LLMRequest<TParams> = {\n messages: allMessages,\n system,\n params,\n tools,\n structure,\n config,\n };\n\n const ctx = createMiddlewareContext(\n 'llm',\n model.modelId,\n model.provider.name,\n false,\n initialRequest\n );\n\n try {\n // Run middleware start and request hooks\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n allMessages = (ctx.request as LLMRequest<TParams>).messages;\n const requestMessageCount = allMessages.length;\n const overrideIndex = ctx.state.get(TURN_START_INDEX_KEY);\n turnStartIndex = resolveTurnStartIndex(\n allMessages,\n history,\n newMessages,\n requestMessageCount,\n typeof overrideIndex === 'number' ? overrideIndex : undefined\n );\n validateMediaCapabilities(allMessages, model.capabilities, model.provider.name);\n\n while (cycles < maxIterations + 1) {\n cycles++;\n\n const request: LLMRequest<TParams> = {\n messages: allMessages,\n system,\n params,\n tools,\n structure,\n config,\n };\n\n const response = await model.complete(request);\n usages.push(response.usage);\n allMessages.push(response.message);\n\n if (response.data !== undefined) {\n structuredData = response.data;\n }\n\n if (response.message.hasToolCalls && tools && tools.length > 0) {\n if (response.data !== undefined) {\n break;\n }\n\n if (cycles >= maxIterations) {\n await toolStrategy?.onMaxIterations?.(maxIterations);\n throw new UPPError(\n `Tool execution exceeded maximum iterations (${maxIterations})`,\n ErrorCode.InvalidRequest,\n model.provider.name,\n ModalityType.LLM\n );\n }\n\n const results = await executeTools(\n response.message,\n tools,\n toolStrategy,\n toolExecutions,\n undefined,\n middleware,\n ctx\n );\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n\n const data = structure ? structuredData : undefined;\n\n const turn = createTurn(\n allMessages.slice(turnStartIndex),\n toolExecutions,\n aggregateUsage(usages),\n cycles,\n data\n );\n\n // Set response and run end hooks\n ctx.response = {\n message: turn.response,\n usage: turn.usage,\n stopReason: 'end_turn',\n data,\n };\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runTurnHook(middleware, turn, ctx);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return turn;\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw err;\n }\n}\n\n/**\n * Executes a streaming generation request with automatic tool execution loop.\n *\n * Creates an async generator that yields stream events while handling the complete\n * lifecycle of a streaming request. The returned StreamResult provides both the\n * event stream and a promise that resolves to the final Turn.\n *\n * @typeParam TParams - Provider-specific parameter type\n * @param model - The bound LLM model to use\n * @param config - Provider configuration options\n * @param system - Optional system prompt\n * @param params - Provider-specific parameters\n * @param tools - Available tools for the model to call\n * @param toolStrategy - Strategy for tool execution behavior\n * @param structure - Schema for structured output\n * @param history - Previous conversation messages\n * @param newMessages - New messages to send\n * @returns A StreamResult with event generator and turn promise\n * @throws {UPPError} When max iterations exceeded or media not supported\n */\nfunction executeStream<TParams>(\n model: BoundLLMModel<TParams>,\n config: ProviderConfig,\n system: string | unknown[] | undefined,\n params: TParams | undefined,\n tools: Tool[] | undefined,\n toolStrategy: LLMOptions<TParams>['toolStrategy'],\n structure: JSONSchema | undefined,\n history: Message[],\n newMessages: Message[],\n middleware: Middleware[]\n): StreamResult {\n const abortController = new AbortController();\n\n let allMessages: Message[] = [...history, ...newMessages];\n const toolExecutions: ToolExecution[] = [];\n const usages: TokenUsage[] = [];\n let cycles = 0;\n let generatorError: Error | null = null;\n let structuredData: unknown;\n let generatorCompleted = false;\n let turnStartIndex = history.length;\n\n // Create middleware contexts\n const initialRequest: LLMRequest<TParams> = {\n messages: allMessages,\n system,\n params,\n tools,\n structure,\n config,\n };\n\n const ctx = createMiddlewareContext(\n 'llm',\n model.modelId,\n model.provider.name,\n true,\n initialRequest\n );\n\n const streamCtx = createStreamContext(ctx.state);\n const transformer = createStreamTransformer(middleware, streamCtx);\n\n let resolveGenerator: () => void;\n let rejectGenerator: (error: Error) => void;\n let generatorSettled = false;\n const generatorDone = new Promise<void>((resolve, reject) => {\n resolveGenerator = () => {\n if (!generatorSettled) {\n generatorSettled = true;\n resolve();\n }\n };\n rejectGenerator = (error: Error) => {\n if (!generatorSettled) {\n generatorSettled = true;\n reject(error);\n }\n };\n });\n void generatorDone.catch((error) => {\n if (!generatorError) {\n generatorError = toError(error);\n }\n });\n\n const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n\n const onAbort = () => {\n const error = new UPPError('Stream cancelled', ErrorCode.Cancelled, model.provider.name, ModalityType.LLM);\n generatorError = error;\n rejectGenerator(error);\n };\n abortController.signal.addEventListener('abort', onAbort, { once: true });\n\n const ensureNotAborted = () => {\n if (abortController.signal.aborted) {\n throw new UPPError('Stream cancelled', ErrorCode.Cancelled, model.provider.name, ModalityType.LLM);\n }\n };\n\n async function* generateStream(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n // Check if already aborted before starting\n ensureNotAborted();\n\n // Run middleware start and request hooks\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n allMessages = (ctx.request as LLMRequest<TParams>).messages;\n const requestMessageCount = allMessages.length;\n const overrideIndex = ctx.state.get(TURN_START_INDEX_KEY);\n turnStartIndex = resolveTurnStartIndex(\n allMessages,\n history,\n newMessages,\n requestMessageCount,\n typeof overrideIndex === 'number' ? overrideIndex : undefined\n );\n validateMediaCapabilities(allMessages, model.capabilities, model.provider.name);\n\n while (cycles < maxIterations + 1) {\n cycles++;\n ensureNotAborted();\n\n const request: LLMRequest<TParams> = {\n messages: allMessages,\n system,\n params,\n tools,\n structure,\n config,\n signal: abortController.signal,\n };\n\n const streamResult = model.stream(request);\n\n for await (const event of streamResult) {\n ensureNotAborted();\n // Apply middleware stream transformer\n const transformed = transformer(event);\n if (transformed === null) continue;\n if (Array.isArray(transformed)) {\n for (const e of transformed) {\n yield e;\n }\n } else {\n yield transformed;\n }\n }\n\n const response = await streamResult.response;\n usages.push(response.usage);\n allMessages.push(response.message);\n\n if (response.data !== undefined) {\n structuredData = response.data;\n }\n\n if (response.message.hasToolCalls && tools && tools.length > 0) {\n if (response.data !== undefined) {\n break;\n }\n\n if (cycles >= maxIterations) {\n await toolStrategy?.onMaxIterations?.(maxIterations);\n throw new UPPError(\n `Tool execution exceeded maximum iterations (${maxIterations})`,\n ErrorCode.InvalidRequest,\n model.provider.name,\n ModalityType.LLM\n );\n }\n\n const toolEvents: StreamEvent[] = [];\n const results = await executeTools(\n response.message,\n tools,\n toolStrategy,\n toolExecutions,\n (event) => toolEvents.push(event),\n middleware,\n ctx\n );\n\n for (const event of toolEvents) {\n ensureNotAborted();\n // Tool events also go through transformer\n const transformed = transformer(event);\n if (transformed === null) continue;\n if (Array.isArray(transformed)) {\n for (const e of transformed) {\n yield e;\n }\n } else {\n yield transformed;\n }\n }\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n\n // Run stream end hooks\n await runStreamEndHook(middleware, streamCtx);\n\n generatorCompleted = true;\n resolveGenerator();\n } catch (error) {\n const err = toError(error);\n generatorError = err;\n if (isCancelledError(err)) {\n await runAbortHook(middleware, err, ctx);\n } else {\n await runErrorHook(middleware, err, ctx);\n }\n rejectGenerator(err);\n throw err;\n } finally {\n abortController.signal.removeEventListener('abort', onAbort);\n if (!generatorCompleted && !generatorSettled) {\n const error = new UPPError('Stream cancelled', ErrorCode.Cancelled, model.provider.name, ModalityType.LLM);\n generatorError = error;\n if (!abortController.signal.aborted) {\n abortController.abort();\n }\n await runAbortHook(middleware, error, ctx);\n rejectGenerator(error);\n }\n }\n }\n\n const createTurnPromise = async (): Promise<Turn> => {\n await generatorDone;\n\n if (generatorError) {\n throw generatorError;\n }\n\n const data = structure ? structuredData : undefined;\n\n const turn = createTurn(\n allMessages.slice(turnStartIndex),\n toolExecutions,\n aggregateUsage(usages),\n cycles,\n data\n );\n\n // Set response and run end hooks\n ctx.response = {\n message: turn.response,\n usage: turn.usage,\n stopReason: 'end_turn',\n data,\n };\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runTurnHook(middleware, turn, ctx);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return turn;\n };\n\n return createStreamResult(generateStream(), createTurnPromise, abortController);\n}\n\n/**\n * Creates an LLM instance configured with the specified options.\n *\n * This is the primary factory function for creating LLM instances. It validates\n * provider capabilities, binds the model, and returns an instance with `generate`\n * and `stream` methods for inference.\n *\n * @typeParam TParams - Provider-specific parameter type for model configuration\n * @param options - Configuration options for the LLM instance\n * @returns A configured LLM instance ready for inference\n * @throws {UPPError} When the provider does not support the LLM modality\n * @throws {UPPError} When structured output is requested but not supported\n * @throws {UPPError} When tools are provided but not supported\n *\n * @example\n * ```typescript\n * import { llm } from 'upp';\n * import { anthropic } from 'upp/providers/anthropic';\n *\n * const assistant = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * system: 'You are a helpful assistant.',\n * tools: [myTool],\n * });\n *\n * const turn = await assistant.generate('Hello, world!');\n * console.log(turn.text);\n * ```\n */\nexport function llm<TParams = unknown>(\n options: LLMOptions<TParams>\n): LLMInstance<TParams> {\n const {\n model: modelRef,\n config: explicitConfig = {},\n params,\n system,\n tools: toolsInput,\n toolStrategy,\n structure: structureInput,\n middleware = [],\n } = options;\n\n // Resolve Zod schemas to JSONSchema if needed\n const structure = structureInput ? resolveStructure(structureInput) : undefined;\n const tools = toolsInput ? resolveTools(toolsInput) : undefined;\n\n // Merge providerConfig from model reference with explicit config\n // Explicit config takes precedence, with headers being deep-merged\n const providerConfig = modelRef.providerConfig ?? {};\n const config: ProviderConfig = {\n ...providerConfig,\n ...explicitConfig,\n headers: {\n ...providerConfig.headers,\n ...explicitConfig.headers,\n },\n };\n\n // Resolve the correct LLM handler based on model reference options\n // This handles providers with multiple handlers (e.g., OpenAI responses/completions)\n // Cast is safe: ModelInput uses structural typing with unknown for variance, but the\n // actual provider at runtime is a proper Provider with LLMHandler\n const provider = modelRef.provider;\n const llmHandler = resolveLLMHandler(provider, modelRef.options) as LLMHandler<TParams> | undefined;\n\n if (!llmHandler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support LLM modality`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.LLM\n );\n }\n\n // Bind the model\n const boundModel = llmHandler.bind(modelRef.modelId);\n\n // Validate capabilities at bind time\n const capabilities = boundModel.capabilities;\n\n // Check for structured output capability\n if (structure && !capabilities.structuredOutput) {\n throw new UPPError(\n `Provider '${provider.name}' does not support structured output`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.LLM\n );\n }\n\n // Check for tools capability\n if (tools && tools.length > 0 && !capabilities.tools) {\n throw new UPPError(\n `Provider '${provider.name}' does not support tools`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.LLM\n );\n }\n\n // Build the instance\n const instance: LLMInstance<TParams> = {\n model: boundModel,\n system,\n params,\n capabilities,\n\n async generate(\n historyOrInput?: Message[] | Thread | InferenceInput,\n ...inputs: InferenceInput[]\n ): Promise<Turn> {\n const { history, messages } = parseInputs(historyOrInput, inputs);\n return executeGenerate(\n boundModel,\n config,\n system,\n params,\n tools,\n toolStrategy,\n structure,\n history,\n messages,\n middleware\n );\n },\n\n stream(\n historyOrInput?: Message[] | Thread | InferenceInput,\n ...inputs: InferenceInput[]\n ): StreamResult {\n // Check streaming capability\n if (!capabilities.streaming) {\n throw new UPPError(\n `Provider '${provider.name}' does not support streaming`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.LLM\n );\n }\n const { history, messages } = parseInputs(historyOrInput, inputs);\n return executeStream(\n boundModel,\n config,\n system,\n params,\n tools,\n toolStrategy,\n structure,\n history,\n messages,\n middleware\n );\n },\n };\n\n return instance;\n}\n","/**\n * @fileoverview Embedding instance factory for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating embedding instances\n * that generate vector embeddings from text or other content.\n *\n * @module core/embedding\n */\n\nimport type {\n EmbeddingOptions,\n EmbeddingInstance,\n EmbeddingResult,\n EmbeddingProgress,\n EmbeddingStream,\n EmbedOptions,\n Embedding,\n} from '../types/embedding.ts';\nimport type {\n EmbeddingInput,\n BoundEmbeddingModel,\n EmbeddingResponse,\n ProviderConfig,\n EmbeddingRequest,\n} from '../types/provider.ts';\nimport type { Middleware } from '../types/middleware.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveEmbeddingHandler } from './provider-handlers.ts';\nimport { toError } from '../utils/error.ts';\nimport { runHook, runErrorHook, createMiddlewareContext } from '../middleware/runner.ts';\n\n/**\n * Decode base64-encoded float32 array.\n *\n * @param b64 - Base64-encoded float32 buffer\n * @param providerName - Provider name for error reporting\n * @returns Decoded float array\n */\nfunction decodeBase64(b64: string, providerName: string): number[] {\n try {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const floats = new Float32Array(bytes.buffer);\n return Array.from(floats);\n } catch (error) {\n const cause = error instanceof Error ? error : new Error('Failed to decode base64 vector');\n throw new UPPError(\n 'Invalid base64 embedding vector',\n ErrorCode.InvalidResponse,\n providerName,\n ModalityType.Embedding,\n undefined,\n cause\n );\n }\n}\n\n/**\n * Normalize vector from floats or base64 string to number array.\n *\n * @param vector - Float vector or base64 string\n * @param providerName - Provider name for error reporting\n * @returns Normalized float array\n */\nfunction normalizeVector(vector: number[] | string, providerName: string): number[] {\n if (Array.isArray(vector)) {\n return vector;\n }\n return decodeBase64(vector, providerName);\n}\n\n/**\n * Normalize provider response to public EmbeddingResult.\n *\n * @param response - Provider response\n * @param providerName - Provider name for error reporting\n * @returns Normalized embedding result\n */\nfunction normalizeResponse(response: EmbeddingResponse, providerName: string): EmbeddingResult {\n return {\n embeddings: response.embeddings.map((vec, i) => {\n const vector = normalizeVector(vec.vector, providerName);\n return {\n vector,\n dimensions: vector.length,\n index: vec.index ?? i,\n tokens: vec.tokens,\n metadata: vec.metadata,\n };\n }),\n usage: response.usage,\n metadata: response.metadata,\n };\n}\n\n/**\n * Execute single embed request.\n *\n * @param model - Bound embedding model\n * @param inputs - Input batch\n * @param params - Provider-specific params\n * @param config - Provider configuration\n * @param signal - Abort signal\n * @param inputType - Input type hint for optimization\n * @param middleware - Middleware array\n * @returns Normalized embedding result\n */\nasync function executeEmbed<TParams>(\n model: BoundEmbeddingModel<TParams>,\n inputs: EmbeddingInput[],\n params: TParams | undefined,\n config: EmbeddingOptions<TParams>['config'],\n signal?: AbortSignal,\n inputType?: EmbedOptions['inputType'],\n middleware: Middleware[] = []\n): Promise<EmbeddingResult> {\n const request: EmbeddingRequest<TParams> = {\n inputs,\n params,\n config: config ?? {},\n signal,\n inputType,\n };\n\n const ctx = createMiddlewareContext(\n 'embedding',\n model.modelId,\n model.provider.name,\n false,\n request\n );\n\n try {\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n\n const response = await model.embed(request);\n const result = normalizeResponse(response, model.provider.name);\n\n ctx.response = response;\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return result;\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw err;\n }\n}\n\n/**\n * Create chunked stream for large input sets.\n *\n * @param model - Bound embedding model\n * @param inputs - All embedding inputs\n * @param params - Provider-specific params\n * @param config - Provider configuration\n * @param options - Chunked stream options\n * @param middleware - Middleware array\n * @returns Embedding stream with progress updates\n */\nfunction createChunkedStream<TParams>(\n model: BoundEmbeddingModel<TParams>,\n inputs: EmbeddingInput[],\n params: TParams | undefined,\n config: EmbeddingOptions<TParams>['config'],\n options: EmbedOptions,\n middleware: Middleware[] = []\n): EmbeddingStream {\n const abortController = new AbortController();\n const batchSize = options.batchSize ?? model.maxBatchSize;\n const concurrency = options.concurrency ?? 1;\n\n let resolveResult!: (result: EmbeddingResult) => void;\n let rejectResult!: (error: Error) => void;\n let settled = false;\n const resultPromise = new Promise<EmbeddingResult>((resolve, reject) => {\n resolveResult = (result) => {\n if (!settled) {\n settled = true;\n resolve(result);\n }\n };\n rejectResult = (error) => {\n if (!settled) {\n settled = true;\n reject(error);\n }\n };\n });\n\n const cancelError = () => new UPPError(\n 'Embedding cancelled',\n ErrorCode.Cancelled,\n model.provider.name,\n ModalityType.Embedding\n );\n\n const onAbort = () => {\n rejectResult(cancelError());\n };\n\n abortController.signal.addEventListener('abort', onAbort, { once: true });\n const onExternalAbort = () => abortController.abort();\n if (options.signal) {\n options.signal.addEventListener('abort', onExternalAbort, { once: true });\n }\n\n const cleanupAbortListeners = () => {\n abortController.signal.removeEventListener('abort', onAbort);\n if (options.signal) {\n options.signal.removeEventListener('abort', onExternalAbort);\n }\n };\n\n // Create middleware context for the overall chunked operation\n const request: EmbeddingRequest<TParams> = {\n inputs,\n params,\n config: config ?? {},\n signal: abortController.signal,\n inputType: options.inputType,\n };\n\n const ctx = createMiddlewareContext(\n 'embedding',\n model.modelId,\n model.provider.name,\n true,\n request\n );\n\n async function* generate(): AsyncGenerator<EmbeddingProgress> {\n const total = inputs.length;\n const allEmbeddings: Embedding[] = [];\n let totalTokens = 0;\n\n const batches: Array<{ inputs: EmbeddingInput[]; startIndex: number }> = [];\n for (let i = 0; i < inputs.length; i += batchSize) {\n batches.push({ inputs: inputs.slice(i, i + batchSize), startIndex: i });\n }\n\n try {\n // Run middleware start hooks\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n\n for (let i = 0; i < batches.length; i += concurrency) {\n if (abortController.signal.aborted || options.signal?.aborted) {\n throw cancelError();\n }\n\n const chunk = batches.slice(i, i + concurrency);\n const responses = await Promise.all(\n chunk.map((batch) =>\n model.embed({\n inputs: batch.inputs,\n params,\n config: config ?? {},\n signal: abortController.signal,\n })\n )\n );\n\n const batchEmbeddings: Embedding[] = [];\n for (let responseIndex = 0; responseIndex < responses.length; responseIndex += 1) {\n const response = responses[responseIndex]!;\n const batch = chunk[responseIndex]!;\n for (let vecIndex = 0; vecIndex < response.embeddings.length; vecIndex += 1) {\n const vec = response.embeddings[vecIndex]!;\n const vector = normalizeVector(vec.vector, model.provider.name);\n const resolvedIndex = batch.startIndex + (vec.index ?? vecIndex);\n const emb: Embedding = {\n vector,\n dimensions: vector.length,\n index: resolvedIndex,\n tokens: vec.tokens,\n metadata: vec.metadata,\n };\n batchEmbeddings.push(emb);\n }\n totalTokens += response.usage.totalTokens;\n }\n\n allEmbeddings.push(...batchEmbeddings);\n\n yield {\n embeddings: batchEmbeddings,\n completed: allEmbeddings.length,\n total,\n percent: (allEmbeddings.length / total) * 100,\n };\n }\n\n const orderedEmbeddings = [...allEmbeddings].sort(\n (left, right) => left.index - right.index\n );\n\n const result = {\n embeddings: orderedEmbeddings,\n usage: { totalTokens },\n };\n\n // Run middleware end hooks\n ctx.response = { embeddings: orderedEmbeddings.map((e) => ({ vector: e.vector, index: e.index })), usage: { totalTokens } };\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runHook(middleware, 'onEnd', ctx, true);\n\n resolveResult(result);\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n rejectResult(err);\n throw err;\n } finally {\n cleanupAbortListeners();\n }\n }\n\n const generator = generate();\n\n return {\n [Symbol.asyncIterator]: () => generator,\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n}\n\n/**\n * Creates an embedding instance configured with the specified options.\n *\n * This is the primary factory function for creating embedding instances.\n * It validates provider capabilities, binds the model, and returns an\n * instance with an `embed` method for generating embeddings.\n *\n * @typeParam TParams - Provider-specific parameter type\n * @param options - Configuration options for the embedding instance\n * @returns A configured embedding instance ready for use\n * @throws {UPPError} When the provider does not support the embedding modality\n *\n * @example\n * ```typescript\n * import { embedding } from 'upp';\n * import { openai } from 'upp/openai';\n *\n * const embedder = embedding({\n * model: openai('text-embedding-3-large'),\n * params: { dimensions: 1536 }\n * });\n *\n * // Single input\n * const result = await embedder.embed('Hello world');\n *\n * // Batch input\n * const batch = await embedder.embed(['doc1', 'doc2', 'doc3']);\n *\n * // Large-scale with progress\n * const stream = embedder.embed(documents, { chunked: true });\n * for await (const progress of stream) {\n * console.log(`${progress.percent}% complete`);\n * }\n * ```\n */\nexport function embedding<TParams = unknown>(\n options: EmbeddingOptions<TParams>\n): EmbeddingInstance<TParams> {\n const { model: modelRef, config: explicitConfig = {}, params, middleware = [] } = options;\n const providerConfig = modelRef.providerConfig ?? {};\n const config: ProviderConfig = {\n ...providerConfig,\n ...explicitConfig,\n headers: {\n ...providerConfig.headers,\n ...explicitConfig.headers,\n },\n };\n\n const provider = modelRef.provider;\n const handler = resolveEmbeddingHandler<TParams>(provider);\n if (!handler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support embedding modality`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.Embedding\n );\n }\n\n const boundModel = handler.bind(modelRef.modelId);\n\n function embed(\n input: EmbeddingInput | EmbeddingInput[],\n embedOptions?: EmbedOptions & { chunked?: false }\n ): Promise<EmbeddingResult>;\n function embed(\n input: EmbeddingInput[],\n embedOptions: EmbedOptions & { chunked: true }\n ): EmbeddingStream;\n function embed(\n input: EmbeddingInput | EmbeddingInput[],\n embedOptions?: EmbedOptions\n ): Promise<EmbeddingResult> | EmbeddingStream {\n const inputs = Array.isArray(input) ? input : [input];\n\n if (embedOptions?.chunked) {\n return createChunkedStream(boundModel, inputs, params, config, embedOptions, middleware);\n }\n\n return executeEmbed(boundModel, inputs, params, config, embedOptions?.signal, embedOptions?.inputType, middleware);\n }\n\n return {\n model: boundModel,\n params,\n embed,\n };\n}\n","/**\n * @fileoverview Image generation instance factory for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating image generation instances,\n * including support for text-to-image generation, streaming, and image editing.\n *\n * @module core/image\n */\n\nimport type {\n ImageOptions,\n ImageInstance,\n ImageInput,\n ImageEditInput,\n ImageResult,\n ImageStreamResult,\n ImageStreamEvent,\n ImageGenerateOptions,\n ImageRequest,\n} from '../types/image.ts';\nimport type { ProviderConfig } from '../types/provider.ts';\nimport type { Middleware } from '../types/middleware.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveImageHandler } from './provider-handlers.ts';\nimport { toError } from '../utils/error.ts';\nimport { runHook, runErrorHook, createMiddlewareContext } from '../middleware/runner.ts';\n\n/**\n * Normalizes ImageInput to a prompt string.\n *\n * @param input - Either a string prompt or object with prompt field\n * @returns The prompt string\n */\nfunction normalizeInput(input: ImageInput): string {\n if (typeof input === 'string') {\n return input;\n }\n return input.prompt;\n}\n\n/**\n * Creates an image generation instance configured with the specified options.\n *\n * This is the primary factory function for creating image generation instances.\n * It validates provider capabilities, binds the model, and returns an instance\n * with `generate`, `stream`, and `edit` methods.\n *\n * @typeParam TParams - Provider-specific parameter type for model configuration\n * @param options - Configuration options for the image instance\n * @returns A configured image instance ready for generation\n * @throws {UPPError} When the provider does not support the image modality\n *\n * @example\n * ```typescript\n * import { image } from 'upp';\n * import { openai } from 'upp/providers/openai';\n *\n * const dalle = image({\n * model: openai('dall-e-3'),\n * params: { size: '1024x1024', quality: 'hd' }\n * });\n *\n * const result = await dalle.generate('A sunset over mountains');\n * console.log(result.images.length);\n * ```\n */\nexport function image<TParams = unknown>(\n options: ImageOptions<TParams>\n): ImageInstance<TParams> {\n const { model: modelRef, config: explicitConfig = {}, params, middleware = [] } = options;\n const providerConfig = modelRef.providerConfig ?? {};\n const config: ProviderConfig = {\n ...providerConfig,\n ...explicitConfig,\n headers: {\n ...providerConfig.headers,\n ...explicitConfig.headers,\n },\n };\n\n const provider = modelRef.provider;\n const imageHandler = resolveImageHandler<TParams>(provider);\n if (!imageHandler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support image modality`,\n ErrorCode.InvalidRequest,\n provider.name,\n ModalityType.Image\n );\n }\n\n const boundModel = imageHandler.bind(modelRef.modelId);\n\n const capabilities = boundModel.capabilities;\n\n const normalizeImageError = (error: unknown): UPPError => {\n if (error instanceof UPPError) {\n return error;\n }\n const err = toError(error);\n return new UPPError(err.message, ErrorCode.ProviderError, provider.name, ModalityType.Image, undefined, err);\n };\n\n const instance: ImageInstance<TParams> = {\n model: boundModel,\n params,\n capabilities,\n\n async generate(input: ImageInput, generateOptions?: ImageGenerateOptions): Promise<ImageResult> {\n const prompt = normalizeInput(input);\n\n const request: ImageRequest<TParams> = {\n prompt,\n params,\n config,\n signal: generateOptions?.signal,\n };\n\n const ctx = createMiddlewareContext(\n 'image',\n boundModel.modelId,\n provider.name,\n false,\n request\n );\n\n try {\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n\n const response = await boundModel.generate(request);\n\n const result: ImageResult = {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n\n ctx.response = response;\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return result;\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw normalizeImageError(error);\n }\n },\n };\n\n if (capabilities.streaming && boundModel.stream) {\n const streamFn = boundModel.stream;\n instance.stream = function (input: ImageInput): ImageStreamResult {\n const prompt = normalizeInput(input);\n\n const abortController = new AbortController();\n const request: ImageRequest<TParams> = {\n prompt,\n params,\n config,\n signal: abortController.signal,\n };\n\n const ctx = createMiddlewareContext(\n 'image',\n boundModel.modelId,\n provider.name,\n true,\n request\n );\n\n const providerStream = streamFn(request);\n\n const resultPromise = (async () => {\n try {\n const response = await providerStream.response;\n const result = {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n\n ctx.response = response;\n ctx.endTime = Date.now();\n await runHook(middleware, 'onResponse', ctx, true);\n await runHook(middleware, 'onEnd', ctx, true);\n\n return result;\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw normalizeImageError(error);\n }\n })();\n\n async function* wrappedStream(): AsyncGenerator<ImageStreamEvent, void, unknown> {\n try {\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\n\n for await (const event of providerStream) {\n yield event;\n }\n } catch (error) {\n const err = toError(error);\n await runErrorHook(middleware, err, ctx);\n throw normalizeImageError(error);\n }\n }\n\n return {\n [Symbol.asyncIterator]: () => wrappedStream(),\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n };\n }\n\n if (capabilities.edit && boundModel.edit) {\n const edit = boundModel.edit;\n instance.edit = async function (input: ImageEditInput): Promise<ImageResult> {\n try {\n const response = await edit({\n image: input.image,\n mask: input.mask,\n prompt: input.prompt,\n params,\n config,\n });\n\n return {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n } catch (error) {\n throw normalizeImageError(error);\n }\n };\n }\n\n return instance;\n}\n\n/**\n * Creates an ImageStreamResult from an async generator.\n *\n * @param generator - The async generator of stream events\n * @param resultPromise - Promise resolving to final result\n * @param abortController - Controller for aborting the operation\n * @returns An ImageStreamResult\n */\nexport function createImageStreamResult(\n generator: AsyncGenerator<ImageStreamEvent, void, unknown>,\n resultPromise: Promise<ImageResult>,\n abortController: AbortController\n): ImageStreamResult {\n return {\n [Symbol.asyncIterator]: () => generator,\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n}\n","/**\n * @fileoverview Document content handling for the Universal Provider Protocol.\n *\n * Provides a unified Document class for working with documents across different sources\n * (file paths, URLs, raw text, base64). Supports PDF and plain text documents with\n * integration into UPP message content blocks.\n *\n * @module core/media/Document\n */\n\nimport type { DocumentSource, DocumentBlock } from '../../types/content.ts';\n\n/**\n * Detects the MIME type of a document based on its file extension.\n *\n * Supports PDF and common text file formats.\n * Returns 'application/octet-stream' for unknown extensions.\n *\n * @param path - File path or filename with extension\n * @returns The detected MIME type string\n */\nfunction detectMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n\n switch (ext) {\n case 'pdf':\n return 'application/pdf';\n case 'txt':\n case 'text':\n case 'md':\n case 'markdown':\n return 'text/plain';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Represents a document that can be used in UPP messages.\n *\n * Documents can be created from various sources (files, URLs, text, base64) and\n * converted to content blocks for provider APIs. The class provides a unified\n * interface regardless of the underlying source type.\n *\n * @example\n * ```typescript\n * // Load PDF from file\n * const pdfDoc = await Document.fromPath('./report.pdf');\n *\n * // Reference PDF by URL\n * const urlDoc = Document.fromUrl('https://example.com/document.pdf');\n *\n * // From plain text\n * const textDoc = Document.fromText('Document content here...');\n *\n * // Use in a message\n * const message = new UserMessage([document.toBlock()]);\n * ```\n */\nexport class Document {\n /** The underlying document source (base64, url, or text) */\n readonly source: DocumentSource;\n /** MIME type of the document ('application/pdf' or 'text/plain') */\n readonly mimeType: string;\n /** Optional document title (used for citations) */\n readonly title?: string;\n\n private constructor(\n source: DocumentSource,\n mimeType: string,\n title?: string\n ) {\n this.source = source;\n this.mimeType = mimeType;\n this.title = title;\n }\n\n /**\n * Whether this document has data loaded in memory.\n *\n * Returns `false` for URL-sourced documents that reference external resources.\n */\n get hasData(): boolean {\n return this.source.type !== 'url';\n }\n\n /**\n * Whether this document is a PDF.\n */\n get isPdf(): boolean {\n return this.mimeType === 'application/pdf';\n }\n\n /**\n * Whether this document is plain text.\n */\n get isText(): boolean {\n return this.mimeType === 'text/plain';\n }\n\n /**\n * Converts the document to a base64-encoded string.\n *\n * @returns The document data as a base64 string\n * @throws {Error} When the source is a URL or plain text\n */\n toBase64(): string {\n if (this.source.type === 'base64') {\n return this.source.data;\n }\n\n throw new Error('Cannot convert to base64. Only base64-sourced documents support this.');\n }\n\n /**\n * Gets the plain text content for text documents.\n *\n * @returns The document text content\n * @throws {Error} When the source is not plain text\n */\n toText(): string {\n if (this.source.type === 'text') {\n return this.source.data;\n }\n\n throw new Error('Cannot get text content. Only text-sourced documents support this.');\n }\n\n /**\n * Gets the URL for URL-sourced documents.\n *\n * @returns The document URL\n * @throws {Error} When the source is not a URL\n */\n toUrl(): string {\n if (this.source.type === 'url') {\n return this.source.url;\n }\n\n throw new Error('This document does not have a URL source.');\n }\n\n /**\n * Converts this Document to a DocumentBlock for use in UPP messages.\n *\n * @returns A DocumentBlock that can be included in message content arrays\n */\n toBlock(): DocumentBlock {\n return {\n type: 'document',\n source: this.source,\n mimeType: this.mimeType,\n title: this.title,\n };\n }\n\n /**\n * Creates a Document by reading a file from disk.\n *\n * The file is read into memory and base64-encoded. MIME type is automatically\n * detected from the file extension.\n *\n * @param path - Path to the document file\n * @param title - Optional document title\n * @returns Promise resolving to a Document with the file contents\n *\n * @example\n * ```typescript\n * const doc = await Document.fromPath('./reports/annual.pdf');\n * const docWithTitle = await Document.fromPath('./report.pdf', 'Annual Report 2024');\n * ```\n */\n static async fromPath(path: string, title?: string): Promise<Document> {\n const file = Bun.file(path);\n const exists = await file.exists();\n if (!exists) {\n throw new Error(`Document file not found at path: ${path}`);\n }\n\n let data: ArrayBuffer;\n try {\n data = await file.arrayBuffer();\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to read document file at path: ${path}. ${message}`);\n }\n\n if (data.byteLength === 0) {\n throw new Error(`Document file is empty at path: ${path}`);\n }\n const base64 = Buffer.from(data).toString('base64');\n const mimeType = detectMimeType(path);\n\n return new Document(\n { type: 'base64', data: base64 },\n mimeType,\n title\n );\n }\n\n /**\n * Creates a Document from a URL reference.\n *\n * The URL is stored as a reference and not fetched. Providers will handle\n * URL fetching if needed. Only PDF URLs are supported.\n * URLs must use the http or https protocol.\n *\n * @param url - URL pointing to the PDF document\n * @param title - Optional document title\n * @returns A Document referencing the URL\n *\n * @example\n * ```typescript\n * const doc = Document.fromUrl('https://example.com/report.pdf');\n * ```\n */\n static fromUrl(url: string, title?: string): Document {\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(url);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Invalid URL';\n throw new Error(`Invalid document URL: ${message}`);\n }\n\n if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {\n throw new Error(`Document URL must use http or https: ${url}`);\n }\n\n return new Document(\n { type: 'url', url },\n 'application/pdf',\n title\n );\n }\n\n /**\n * Creates a Document from base64-encoded data.\n *\n * @param base64 - The base64-encoded document data\n * @param mimeType - The MIME type ('application/pdf' or 'text/plain')\n * @param title - Optional document title\n * @returns A Document containing the base64 data\n *\n * @example\n * ```typescript\n * const doc = Document.fromBase64(pdfBase64, 'application/pdf', 'Contract');\n * ```\n */\n static fromBase64(base64: string, mimeType: string, title?: string): Document {\n return new Document(\n { type: 'base64', data: base64 },\n mimeType,\n title\n );\n }\n\n /**\n * Creates a Document from plain text content.\n *\n * @param text - The document text content\n * @param title - Optional document title\n * @returns A Document containing the text\n *\n * @example\n * ```typescript\n * const doc = Document.fromText('This is the document content.', 'Notes');\n * ```\n */\n static fromText(text: string, title?: string): Document {\n return new Document(\n { type: 'text', data: text },\n 'text/plain',\n title\n );\n }\n\n /**\n * Creates a Document from an existing DocumentBlock.\n *\n * Useful for converting content blocks received from providers back\n * into Document instances for further processing.\n *\n * @param block - A DocumentBlock from message content\n * @returns A Document with the block's source and metadata\n */\n static fromBlock(block: DocumentBlock): Document {\n return new Document(\n block.source,\n block.mimeType,\n block.title\n );\n }\n}\n","/**\n * @fileoverview Audio content handling for the Universal Provider Protocol.\n *\n * Provides a unified Audio class for working with audio across different sources\n * (file paths, raw bytes, base64). Supports conversion between formats and\n * integration with UPP message content blocks.\n *\n * @module core/media/Audio\n */\n\nimport type { AudioBlock } from '../../types/content.ts';\n\n/**\n * Detects the MIME type of an audio file based on its file extension.\n *\n * Supports common audio formats: MP3, WAV, OGG, FLAC, AAC, M4A, WebM.\n * Returns 'application/octet-stream' for unknown extensions.\n *\n * Note: Provider support varies. Google Gemini supports MP3, WAV, AIFF, AAC,\n * OGG Vorbis, and FLAC. Opus is NOT supported by Google.\n *\n * @param path - File path or filename with extension\n * @returns The detected MIME type string\n */\nfunction detectMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n\n switch (ext) {\n case 'mp3':\n return 'audio/mp3';\n case 'wav':\n return 'audio/wav';\n case 'ogg':\n case 'oga':\n return 'audio/ogg';\n case 'flac':\n return 'audio/flac';\n case 'aac':\n return 'audio/aac';\n case 'm4a':\n return 'audio/mp4';\n case 'webm':\n return 'audio/webm';\n case 'aiff':\n case 'aif':\n return 'audio/aiff';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Represents an audio file that can be used in UPP messages.\n *\n * Audio can be created from various sources (files, bytes, base64) and\n * converted to different formats as needed by providers. The class provides\n * a unified interface regardless of the underlying source type.\n *\n * Note: Providers have size limits for inline audio data. Google Gemini\n * limits inline data to 20MB per request. For larger files, consider using\n * provider-specific file upload APIs.\n *\n * @example\n * ```typescript\n * // Load from file\n * const fileAudio = await Audio.fromPath('./recording.mp3');\n *\n * // From raw bytes\n * const bytesAudio = Audio.fromBytes(uint8Array, 'audio/wav');\n *\n * // Use in a message\n * const message = new UserMessage([audio.toBlock()]);\n * ```\n */\nexport class Audio {\n /** The audio data as raw bytes */\n readonly data: Uint8Array;\n /** MIME type of the audio (e.g., 'audio/mp3', 'audio/wav') */\n readonly mimeType: string;\n /** Duration in seconds, if known */\n readonly duration?: number;\n\n private constructor(\n data: Uint8Array,\n mimeType: string,\n duration?: number\n ) {\n this.data = data;\n this.mimeType = mimeType;\n this.duration = duration;\n }\n\n /**\n * Gets the size of the audio data in bytes.\n */\n get size(): number {\n return this.data.length;\n }\n\n /**\n * Converts the audio to a base64-encoded string.\n *\n * @returns The audio data as a base64 string\n */\n toBase64(): string {\n return btoa(\n Array.from(this.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n }\n\n /**\n * Converts the audio to a data URL suitable for embedding.\n *\n * @returns A data URL in the format `data:{mimeType};base64,{data}`\n */\n toDataUrl(): string {\n const base64 = this.toBase64();\n return `data:${this.mimeType};base64,${base64}`;\n }\n\n /**\n * Gets the audio data as raw bytes.\n *\n * @returns The audio data as a Uint8Array\n */\n toBytes(): Uint8Array {\n return this.data;\n }\n\n /**\n * Converts this Audio to an AudioBlock for use in UPP messages.\n *\n * @returns An AudioBlock that can be included in message content arrays\n */\n toBlock(): AudioBlock {\n return {\n type: 'audio',\n data: this.data,\n mimeType: this.mimeType,\n duration: this.duration,\n };\n }\n\n /**\n * Creates an Audio by reading a file from disk.\n *\n * The file is read into memory as bytes. MIME type is automatically\n * detected from the file extension.\n *\n * @param path - Path to the audio file\n * @param duration - Optional duration in seconds\n * @returns Promise resolving to an Audio with the file contents\n *\n * @example\n * ```typescript\n * const audio = await Audio.fromPath('./recordings/interview.mp3');\n * ```\n */\n static async fromPath(path: string, duration?: number): Promise<Audio> {\n const file = Bun.file(path);\n const exists = await file.exists();\n if (!exists) {\n throw new Error(`Audio file not found at path: ${path}`);\n }\n\n let arrayBuffer: ArrayBuffer;\n try {\n arrayBuffer = await file.arrayBuffer();\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to read audio file at path: ${path}. ${message}`);\n }\n\n if (arrayBuffer.byteLength === 0) {\n throw new Error(`Audio file is empty at path: ${path}`);\n }\n\n const mimeType = detectMimeType(path);\n\n return new Audio(\n new Uint8Array(arrayBuffer),\n mimeType,\n duration\n );\n }\n\n /**\n * Creates an Audio from raw byte data.\n *\n * @param data - The audio data as a Uint8Array\n * @param mimeType - The MIME type of the audio\n * @param duration - Optional duration in seconds\n * @returns An Audio containing the byte data\n *\n * @example\n * ```typescript\n * const audio = Audio.fromBytes(wavData, 'audio/wav');\n * ```\n */\n static fromBytes(data: Uint8Array, mimeType: string, duration?: number): Audio {\n return new Audio(data, mimeType, duration);\n }\n\n /**\n * Creates an Audio from a base64-encoded string.\n *\n * @param base64 - The base64-encoded audio data (without data URL prefix)\n * @param mimeType - The MIME type of the audio\n * @param duration - Optional duration in seconds\n * @returns An Audio containing the decoded data\n *\n * @example\n * ```typescript\n * const audio = Audio.fromBase64(base64String, 'audio/mp3');\n * ```\n */\n static fromBase64(base64: string, mimeType: string, duration?: number): Audio {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return new Audio(bytes, mimeType, duration);\n }\n\n /**\n * Creates an Audio from an existing AudioBlock.\n *\n * Useful for converting content blocks received from providers back\n * into Audio instances for further processing.\n *\n * @param block - An AudioBlock from message content\n * @returns An Audio with the block's data and metadata\n */\n static fromBlock(block: AudioBlock): Audio {\n return new Audio(\n block.data,\n block.mimeType,\n block.duration\n );\n }\n}\n","/**\n * @fileoverview Video content handling for the Universal Provider Protocol.\n *\n * Provides a unified Video class for working with video across different sources\n * (file paths, raw bytes, base64). Supports conversion between formats and\n * integration with UPP message content blocks.\n *\n * @module core/media/Video\n */\n\nimport type { VideoBlock } from '../../types/content.ts';\n\n/**\n * Detects the MIME type of a video file based on its file extension.\n *\n * Supports common video formats: MP4, WebM, OGV, MOV, AVI, MPEG, WMV, 3GPP, FLV.\n * Returns 'application/octet-stream' for unknown extensions.\n *\n * Note: Provider support varies. Google Gemini supports MP4, MPEG, MOV, AVI,\n * WMV, MPEGPS, FLV, 3GPP, and WebM. MKV is NOT supported by Google.\n *\n * @param path - File path or filename with extension\n * @returns The detected MIME type string\n */\nfunction detectMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n\n switch (ext) {\n case 'mp4':\n case 'm4v':\n return 'video/mp4';\n case 'webm':\n return 'video/webm';\n case 'ogv':\n case 'ogg':\n return 'video/ogg';\n case 'mov':\n return 'video/quicktime';\n case 'avi':\n return 'video/x-msvideo';\n case 'mpeg':\n case 'mpg':\n return 'video/mpeg';\n case 'wmv':\n return 'video/x-ms-wmv';\n case '3gp':\n case '3gpp':\n return 'video/3gpp';\n case 'flv':\n return 'video/x-flv';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Represents a video file that can be used in UPP messages.\n *\n * Video can be created from various sources (files, bytes, base64) and\n * converted to different formats as needed by providers. The class provides\n * a unified interface regardless of the underlying source type.\n *\n * Note: Providers have size limits for inline video data. Google Gemini\n * limits inline data to 20MB per request. For larger files, consider using\n * provider-specific file upload APIs.\n *\n * @example\n * ```typescript\n * // Load from file\n * const fileVideo = await Video.fromPath('./clip.mp4');\n *\n * // From raw bytes\n * const bytesVideo = Video.fromBytes(uint8Array, 'video/webm');\n *\n * // Use in a message\n * const message = new UserMessage([video.toBlock()]);\n * ```\n */\nexport class Video {\n /** The video data as raw bytes */\n readonly data: Uint8Array;\n /** MIME type of the video (e.g., 'video/mp4', 'video/webm') */\n readonly mimeType: string;\n /** Duration in seconds, if known */\n readonly duration?: number;\n /** Video width in pixels, if known */\n readonly width?: number;\n /** Video height in pixels, if known */\n readonly height?: number;\n\n private constructor(\n data: Uint8Array,\n mimeType: string,\n options?: { duration?: number; width?: number; height?: number }\n ) {\n this.data = data;\n this.mimeType = mimeType;\n this.duration = options?.duration;\n this.width = options?.width;\n this.height = options?.height;\n }\n\n /**\n * Gets the size of the video data in bytes.\n */\n get size(): number {\n return this.data.length;\n }\n\n /**\n * Converts the video to a base64-encoded string.\n *\n * @returns The video data as a base64 string\n */\n toBase64(): string {\n return btoa(\n Array.from(this.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n }\n\n /**\n * Converts the video to a data URL suitable for embedding.\n *\n * @returns A data URL in the format `data:{mimeType};base64,{data}`\n */\n toDataUrl(): string {\n const base64 = this.toBase64();\n return `data:${this.mimeType};base64,${base64}`;\n }\n\n /**\n * Gets the video data as raw bytes.\n *\n * @returns The video data as a Uint8Array\n */\n toBytes(): Uint8Array {\n return this.data;\n }\n\n /**\n * Converts this Video to a VideoBlock for use in UPP messages.\n *\n * @returns A VideoBlock that can be included in message content arrays\n */\n toBlock(): VideoBlock {\n return {\n type: 'video',\n data: this.data,\n mimeType: this.mimeType,\n duration: this.duration,\n width: this.width,\n height: this.height,\n };\n }\n\n /**\n * Creates a Video by reading a file from disk.\n *\n * The file is read into memory as bytes. MIME type is automatically\n * detected from the file extension.\n *\n * @param path - Path to the video file\n * @param options - Optional metadata (duration, width, height)\n * @returns Promise resolving to a Video with the file contents\n *\n * @example\n * ```typescript\n * const video = await Video.fromPath('./clips/demo.mp4');\n * const videoWithMeta = await Video.fromPath('./clip.mp4', { duration: 30, width: 1920, height: 1080 });\n * ```\n */\n static async fromPath(\n path: string,\n options?: { duration?: number; width?: number; height?: number }\n ): Promise<Video> {\n const file = Bun.file(path);\n const exists = await file.exists();\n if (!exists) {\n throw new Error(`Video file not found at path: ${path}`);\n }\n\n let arrayBuffer: ArrayBuffer;\n try {\n arrayBuffer = await file.arrayBuffer();\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error';\n throw new Error(`Failed to read video file at path: ${path}. ${message}`);\n }\n\n if (arrayBuffer.byteLength === 0) {\n throw new Error(`Video file is empty at path: ${path}`);\n }\n\n const mimeType = detectMimeType(path);\n\n return new Video(\n new Uint8Array(arrayBuffer),\n mimeType,\n options\n );\n }\n\n /**\n * Creates a Video from raw byte data.\n *\n * @param data - The video data as a Uint8Array\n * @param mimeType - The MIME type of the video\n * @param options - Optional metadata (duration, width, height)\n * @returns A Video containing the byte data\n *\n * @example\n * ```typescript\n * const video = Video.fromBytes(mp4Data, 'video/mp4');\n * const videoWithMeta = Video.fromBytes(data, 'video/mp4', { duration: 60 });\n * ```\n */\n static fromBytes(\n data: Uint8Array,\n mimeType: string,\n options?: { duration?: number; width?: number; height?: number }\n ): Video {\n return new Video(data, mimeType, options);\n }\n\n /**\n * Creates a Video from a base64-encoded string.\n *\n * @param base64 - The base64-encoded video data (without data URL prefix)\n * @param mimeType - The MIME type of the video\n * @param options - Optional metadata (duration, width, height)\n * @returns A Video containing the decoded data\n *\n * @example\n * ```typescript\n * const video = Video.fromBase64(base64String, 'video/mp4');\n * ```\n */\n static fromBase64(\n base64: string,\n mimeType: string,\n options?: { duration?: number; width?: number; height?: number }\n ): Video {\n const binaryString = atob(base64);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return new Video(bytes, mimeType, options);\n }\n\n /**\n * Creates a Video from an existing VideoBlock.\n *\n * Useful for converting content blocks received from providers back\n * into Video instances for further processing.\n *\n * @param block - A VideoBlock from message content\n * @returns A Video with the block's data and metadata\n */\n static fromBlock(block: VideoBlock): Video {\n return new Video(\n block.data,\n block.mimeType,\n {\n duration: block.duration,\n width: block.width,\n height: block.height,\n }\n );\n }\n}\n","/**\n * @fileoverview Embedding types for vector embedding generation.\n *\n * Defines the interfaces for configuring and executing embedding operations,\n * including options, instances, requests, responses, and streaming progress.\n *\n * @module types/embedding\n */\n\nimport type {\n ProviderConfig,\n BoundEmbeddingModel,\n EmbeddingInput,\n EmbeddingUsage,\n ProviderIdentity,\n} from './provider.ts';\nimport type { Middleware } from './middleware.ts';\n\n/**\n * Input type hints for provider-specific embedding optimization.\n * Some providers optimize embeddings differently for queries vs documents.\n */\nexport const EmbeddingInputType = {\n /** Input is a document to be stored/indexed */\n Document: 'document',\n /** Input is a query for retrieval/search */\n Query: 'query',\n} as const;\n\nexport type EmbeddingInputType = (typeof EmbeddingInputType)[keyof typeof EmbeddingInputType];\n\n/**\n * Structural type for embedding model input.\n * Uses structural typing to avoid generic variance issues with Provider generics.\n *\n * @remarks\n * This type mirrors {@link ModelReference} while keeping provider options\n * structurally compatible across providers.\n *\n * @see ModelReference\n */\nexport interface EmbeddingModelInput {\n readonly modelId: string;\n readonly provider: ProviderIdentity;\n /** Optional provider configuration merged into requests */\n readonly providerConfig?: Partial<ProviderConfig>;\n}\n\n/**\n * Options for creating an embedding instance with the embedding() function.\n *\n * @typeParam TParams - Provider-specific parameter type\n *\n * @example\n * ```typescript\n * const options: EmbeddingOptions<OpenAIEmbedParams> = {\n * model: openai('text-embedding-3-large'),\n * config: { apiKey: process.env.OPENAI_API_KEY },\n * params: { dimensions: 1536 }\n * };\n * ```\n */\nexport interface EmbeddingOptions<TParams = unknown> {\n /** A model reference from a provider factory */\n model: EmbeddingModelInput;\n\n /** Provider infrastructure configuration */\n config?: ProviderConfig;\n\n /** Provider-specific parameters (passed through unchanged) */\n params?: TParams;\n\n /**\n * Middleware for intercepting and transforming requests and responses.\n *\n * Middleware are executed in array order for request/start hooks,\n * and reverse order for response/end hooks.\n */\n middleware?: Middleware[];\n}\n\n/**\n * Options for embed() calls.\n */\nexport interface EmbedOptions {\n /**\n * Enable chunked processing with progress for large input sets.\n * When true, returns EmbeddingStream instead of Promise.\n */\n chunked?: boolean;\n\n /** Inputs per batch when chunked (default: provider max) */\n batchSize?: number;\n\n /** Concurrent batch limit when chunked (default: 1) */\n concurrency?: number;\n\n /** Abort signal for cancellation */\n signal?: AbortSignal;\n\n /** Hint for embedding optimization (provider-specific) */\n inputType?: EmbeddingInputType;\n}\n\n/**\n * Single embedding vector result.\n */\nexport interface Embedding {\n /** The embedding vector */\n vector: number[];\n\n /** Vector dimensionality */\n dimensions: number;\n\n /** Index corresponding to input array position */\n index: number;\n\n /** Token count for this input (if provider reports) */\n tokens?: number;\n\n /** Provider-specific per-embedding metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Result from embed() call.\n */\nexport interface EmbeddingResult {\n /** Embeddings in same order as inputs */\n embeddings: Embedding[];\n\n /** Usage statistics */\n usage: EmbeddingUsage;\n\n /** Provider-specific response metadata */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Progress update when using chunked mode.\n */\nexport interface EmbeddingProgress {\n /** Embeddings from the latest batch */\n embeddings: Embedding[];\n\n /** Total embeddings completed so far */\n completed: number;\n\n /** Total number of inputs */\n total: number;\n\n /** Percentage complete (0-100) */\n percent: number;\n}\n\n/**\n * Async iterable stream with final result accessor.\n * Returned when embed() is called with { chunked: true }.\n */\nexport interface EmbeddingStream extends AsyncIterable<EmbeddingProgress> {\n /** Promise resolving to complete result after iteration */\n readonly result: Promise<EmbeddingResult>;\n\n /** Abort the operation */\n abort(): void;\n}\n\n/**\n * Embedding instance returned by the embedding() function.\n *\n * @typeParam TParams - Provider-specific parameter type\n *\n * @example\n * ```typescript\n * const embedder = embedding({ model: openai('text-embedding-3-large') });\n *\n * // Single input\n * const result = await embedder.embed('Hello world');\n *\n * // Batch input\n * const batch = await embedder.embed(['doc1', 'doc2', 'doc3']);\n *\n * // Large-scale with progress\n * const stream = embedder.embed(documents, { chunked: true });\n * for await (const progress of stream) {\n * console.log(`${progress.percent}% complete`);\n * }\n * ```\n */\nexport interface EmbeddingInstance<TParams = unknown> {\n /**\n * Generate embeddings for one or more inputs.\n *\n * @param input - Single input or array of inputs\n * @param options - Optional embed options\n * @returns Promise<EmbeddingResult> or EmbeddingStream if chunked\n */\n embed(\n input: EmbeddingInput | EmbeddingInput[],\n options?: EmbedOptions & { chunked?: false }\n ): Promise<EmbeddingResult>;\n embed(\n input: EmbeddingInput[],\n options: EmbedOptions & { chunked: true }\n ): EmbeddingStream;\n embed(\n input: EmbeddingInput | EmbeddingInput[],\n options?: EmbedOptions\n ): Promise<EmbeddingResult> | EmbeddingStream;\n\n /** The bound embedding model */\n readonly model: BoundEmbeddingModel<TParams>;\n\n /** Current parameters */\n readonly params: TParams | undefined;\n}\n","/**\n * @fileoverview Unified Provider Protocol (UPP) - A unified interface for AI model inference\n *\n * UPP provides a consistent API for interacting with multiple AI providers including\n * Anthropic, OpenAI, Google, Ollama, OpenRouter, and xAI. The library handles provider-specific\n * transformations, streaming, tool execution, and error handling.\n *\n * @module @providerprotocol/ai\n * @packageDocumentation\n */\n\n/**\n * LLM instance factory for creating model-bound inference functions.\n *\n * @example Basic usage\n * ```typescript\n * import { llm, anthropic } from '@providerprotocol/ai';\n *\n * const model = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * params: { max_tokens: 1000 }\n * });\n *\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Streaming\n * ```typescript\n * for await (const event of model.stream('Tell me a story')) {\n * if (event.type === 'text') {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n */\nexport { llm } from './core/llm.ts';\n\n/** Embedding instance factory for creating model-bound embedding functions */\nexport { embedding } from './core/embedding.ts';\n\n/** Image generation instance factory for creating model-bound image functions */\nexport { image } from './core/image.ts';\n\n/** Factory for creating custom providers */\nexport { createProvider } from './core/provider.ts';\n\n/** Image content wrapper for multimodal inputs */\nexport { Image } from './core/media/Image.ts';\n\n/** Document content wrapper for PDF and text documents */\nexport { Document } from './core/media/document.ts';\n\n/** Audio content wrapper for audio inputs */\nexport { Audio } from './core/media/Audio.ts';\n\n/** Video content wrapper for video inputs */\nexport { Video } from './core/media/Video.ts';\n\nimport { llm } from './core/llm.ts';\nimport { embedding } from './core/embedding.ts';\nimport { image } from './core/image.ts';\n\n/**\n * UPP namespace object providing alternative import style.\n *\n * @example\n * ```typescript\n * import { ai } from '@providerprotocol/ai';\n *\n * const model = ai.llm({\n * model: openai('gpt-4o'),\n * params: { max_tokens: 1000 }\n * });\n * ```\n */\nexport const ai = {\n /** LLM instance factory */\n llm,\n /** Embedding instance factory */\n embedding,\n /** Image generation instance factory */\n image,\n};\n\nexport * from './types/index.ts';\n\nexport {\n RoundRobinKeys,\n WeightedKeys,\n DynamicKey,\n ExponentialBackoff,\n LinearBackoff,\n NoRetry,\n TokenBucket,\n RetryAfterStrategy,\n} from './http/index.ts';\n"],"mappings":"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","names":["newMessages","approved","text","detectMimeType","detectMimeType"]}
|