@providerprotocol/ai 0.0.34 → 0.0.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. package/README.md +546 -3
  2. package/dist/anthropic/index.d.ts +2 -1
  3. package/dist/anthropic/index.js +151 -145
  4. package/dist/anthropic/index.js.map +1 -1
  5. package/dist/cerebras/index.d.ts +392 -0
  6. package/dist/cerebras/index.js +648 -0
  7. package/dist/cerebras/index.js.map +1 -0
  8. package/dist/chunk-2YXFLRQ6.js +49 -0
  9. package/dist/chunk-2YXFLRQ6.js.map +1 -0
  10. package/dist/chunk-4OGB7JZA.js +157 -0
  11. package/dist/chunk-4OGB7JZA.js.map +1 -0
  12. package/dist/chunk-4RX4VQCB.js +31 -0
  13. package/dist/chunk-4RX4VQCB.js.map +1 -0
  14. package/dist/chunk-5IWHCXKN.js +30 -0
  15. package/dist/chunk-5IWHCXKN.js.map +1 -0
  16. package/dist/{chunk-3C7O2RNO.js → chunk-A2IM7PGT.js} +6 -4
  17. package/dist/{chunk-3C7O2RNO.js.map → chunk-A2IM7PGT.js.map} +1 -1
  18. package/dist/{chunk-3D6XGGVG.js → chunk-ARVM24K2.js} +2 -2
  19. package/dist/{chunk-4J6OFUKX.js → chunk-AY55T37A.js} +70 -162
  20. package/dist/chunk-AY55T37A.js.map +1 -0
  21. package/dist/{chunk-ILR2D5PN.js → chunk-BRP5XJ6Q.js} +2 -86
  22. package/dist/chunk-BRP5XJ6Q.js.map +1 -0
  23. package/dist/chunk-C4JP64VW.js +298 -0
  24. package/dist/chunk-C4JP64VW.js.map +1 -0
  25. package/dist/chunk-COS4ON4G.js +111 -0
  26. package/dist/chunk-COS4ON4G.js.map +1 -0
  27. package/dist/chunk-CRP6Y7NF.js +31 -0
  28. package/dist/chunk-CRP6Y7NF.js.map +1 -0
  29. package/dist/chunk-EPB3GQNL.js +118 -0
  30. package/dist/chunk-EPB3GQNL.js.map +1 -0
  31. package/dist/chunk-ETBFOLQN.js +34 -0
  32. package/dist/chunk-ETBFOLQN.js.map +1 -0
  33. package/dist/chunk-I53CI6ZZ.js +142 -0
  34. package/dist/chunk-I53CI6ZZ.js.map +1 -0
  35. package/dist/chunk-IDZOVWP3.js +29 -0
  36. package/dist/chunk-IDZOVWP3.js.map +1 -0
  37. package/dist/chunk-JA3UZALR.js +88 -0
  38. package/dist/chunk-JA3UZALR.js.map +1 -0
  39. package/dist/{chunk-WAKD3OO5.js → chunk-N5DX5JW3.js} +31 -31
  40. package/dist/chunk-N5DX5JW3.js.map +1 -0
  41. package/dist/chunk-OIEWDFQU.js +97 -0
  42. package/dist/chunk-OIEWDFQU.js.map +1 -0
  43. package/dist/{chunk-TOJCZMVU.js → chunk-PMK5LZ5Z.js} +40 -40
  44. package/dist/chunk-PMK5LZ5Z.js.map +1 -0
  45. package/dist/{chunk-6S222DHN.js → chunk-RJGTRQ47.js} +20 -1
  46. package/dist/chunk-RJGTRQ47.js.map +1 -0
  47. package/dist/chunk-UFFJDYCE.js +94 -0
  48. package/dist/chunk-UFFJDYCE.js.map +1 -0
  49. package/dist/chunk-VGKZIGVI.js +222 -0
  50. package/dist/chunk-VGKZIGVI.js.map +1 -0
  51. package/dist/{chunk-KUPF5KHT.js → chunk-Y5H7C5J4.js} +2 -2
  52. package/dist/{embedding-D2BYIehX.d.ts → embedding-BXA72PlJ.d.ts} +1 -1
  53. package/dist/google/index.d.ts +2 -1
  54. package/dist/google/index.js +202 -199
  55. package/dist/google/index.js.map +1 -1
  56. package/dist/groq/index.d.ts +410 -0
  57. package/dist/groq/index.js +649 -0
  58. package/dist/groq/index.js.map +1 -0
  59. package/dist/http/index.d.ts +3 -2
  60. package/dist/http/index.js +5 -4
  61. package/dist/image-stream-CCgwB7ve.d.ts +11 -0
  62. package/dist/index.d.ts +8 -118
  63. package/dist/index.js +520 -769
  64. package/dist/index.js.map +1 -1
  65. package/dist/{llm-BQJZj3cD.d.ts → llm-ByUFPcFH.d.ts} +12 -1632
  66. package/dist/middleware/logging/index.d.ts +76 -0
  67. package/dist/middleware/logging/index.js +74 -0
  68. package/dist/middleware/logging/index.js.map +1 -0
  69. package/dist/middleware/parsed-object/index.d.ts +45 -0
  70. package/dist/middleware/parsed-object/index.js +73 -0
  71. package/dist/middleware/parsed-object/index.js.map +1 -0
  72. package/dist/middleware/pubsub/index.d.ts +97 -0
  73. package/dist/middleware/pubsub/index.js +160 -0
  74. package/dist/middleware/pubsub/index.js.map +1 -0
  75. package/dist/middleware/pubsub/server/express/index.d.ts +66 -0
  76. package/dist/middleware/pubsub/server/express/index.js +11 -0
  77. package/dist/middleware/pubsub/server/express/index.js.map +1 -0
  78. package/dist/middleware/pubsub/server/fastify/index.d.ts +67 -0
  79. package/dist/middleware/pubsub/server/fastify/index.js +11 -0
  80. package/dist/middleware/pubsub/server/fastify/index.js.map +1 -0
  81. package/dist/middleware/pubsub/server/h3/index.d.ts +70 -0
  82. package/dist/middleware/pubsub/server/h3/index.js +11 -0
  83. package/dist/middleware/pubsub/server/h3/index.js.map +1 -0
  84. package/dist/middleware/pubsub/server/index.d.ts +78 -0
  85. package/dist/middleware/pubsub/server/index.js +34 -0
  86. package/dist/middleware/pubsub/server/index.js.map +1 -0
  87. package/dist/middleware/pubsub/server/webapi/index.d.ts +63 -0
  88. package/dist/middleware/pubsub/server/webapi/index.js +11 -0
  89. package/dist/middleware/pubsub/server/webapi/index.js.map +1 -0
  90. package/dist/ollama/index.d.ts +2 -1
  91. package/dist/ollama/index.js +48 -45
  92. package/dist/ollama/index.js.map +1 -1
  93. package/dist/openai/index.d.ts +2 -1
  94. package/dist/openai/index.js +319 -313
  95. package/dist/openai/index.js.map +1 -1
  96. package/dist/openrouter/index.d.ts +2 -1
  97. package/dist/openrouter/index.js +381 -385
  98. package/dist/openrouter/index.js.map +1 -1
  99. package/dist/proxy/index.d.ts +10 -914
  100. package/dist/proxy/index.js +275 -1007
  101. package/dist/proxy/index.js.map +1 -1
  102. package/dist/proxy/server/express/index.d.ts +161 -0
  103. package/dist/proxy/server/express/index.js +24 -0
  104. package/dist/proxy/server/express/index.js.map +1 -0
  105. package/dist/proxy/server/fastify/index.d.ts +162 -0
  106. package/dist/proxy/server/fastify/index.js +24 -0
  107. package/dist/proxy/server/fastify/index.js.map +1 -0
  108. package/dist/proxy/server/h3/index.d.ts +189 -0
  109. package/dist/proxy/server/h3/index.js +28 -0
  110. package/dist/proxy/server/h3/index.js.map +1 -0
  111. package/dist/proxy/server/index.d.ts +151 -0
  112. package/dist/proxy/server/index.js +48 -0
  113. package/dist/proxy/server/index.js.map +1 -0
  114. package/dist/proxy/server/webapi/index.d.ts +278 -0
  115. package/dist/proxy/server/webapi/index.js +32 -0
  116. package/dist/proxy/server/webapi/index.js.map +1 -0
  117. package/dist/responses/index.d.ts +650 -0
  118. package/dist/responses/index.js +930 -0
  119. package/dist/responses/index.js.map +1 -0
  120. package/dist/{retry-8Ch-WWgX.d.ts → retry-BDMo4AVu.d.ts} +1 -1
  121. package/dist/stream-S7nwQRqM.d.ts +1643 -0
  122. package/dist/types-CE4B7pno.d.ts +96 -0
  123. package/dist/utils/index.d.ts +53 -0
  124. package/dist/utils/index.js +7 -0
  125. package/dist/utils/index.js.map +1 -0
  126. package/dist/xai/index.d.ts +2 -1
  127. package/dist/xai/index.js +310 -310
  128. package/dist/xai/index.js.map +1 -1
  129. package/package.json +82 -4
  130. package/dist/chunk-4J6OFUKX.js.map +0 -1
  131. package/dist/chunk-6S222DHN.js.map +0 -1
  132. package/dist/chunk-ILR2D5PN.js.map +0 -1
  133. package/dist/chunk-TOJCZMVU.js.map +0 -1
  134. package/dist/chunk-WAKD3OO5.js.map +0 -1
  135. /package/dist/{chunk-3D6XGGVG.js.map → chunk-ARVM24K2.js.map} +0 -0
  136. /package/dist/{chunk-KUPF5KHT.js.map → chunk-Y5H7C5J4.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/thread.ts","../src/types/embedding.ts","../src/utils/partial-json.ts","../src/middleware/parsed-object.ts","../src/middleware/logging.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 { Middleware, MiddlewareContext, StreamContext } from '../types/middleware.ts';\nimport type { StreamEvent } from '../types/stream.ts';\nimport type { Tool } from '../types/tool.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 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 * 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 LLMResponse,\n InferenceInput,\n BoundLLMModel,\n LLMCapabilities,\n} from '../types/llm.ts';\nimport type { UserMessage, 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, StreamContext } 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 isAssistantMessage,\n} from '../types/messages.ts';\nimport { createTurn, aggregateUsage, emptyUsage } from '../types/turn.ts';\nimport {\n createStreamResult,\n toolExecutionStart,\n toolExecutionEnd,\n} from '../types/stream.ts';\nimport { toError } from '../utils/error.ts';\nimport {\n runHook,\n runErrorHook,\n runToolHook,\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;\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/**\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 * 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 * 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 * 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 validateMediaCapabilities(\n [...history, ...newMessages],\n model.capabilities,\n model.provider.name\n );\n const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n const allMessages: Message[] = [...history, ...newMessages];\n const toolExecutions: ToolExecution[] = [];\n const usages: TokenUsage[] = [];\n let cycles = 0;\n\n let structuredData: unknown;\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 hooks\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\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(history.length),\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 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 validateMediaCapabilities(\n [...history, ...newMessages],\n model.capabilities,\n model.provider.name\n );\n\n const abortController = new AbortController();\n\n const 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\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 hooks\n await runHook(middleware, 'onStart', ctx);\n await runHook(middleware, 'onRequest', ctx);\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 await runErrorHook(middleware, err, ctx);\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 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(history.length),\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 runHook(middleware, 'onEnd', ctx, true);\n\n return turn;\n };\n\n return createStreamResult(generateStream(), createTurnPromise, abortController);\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 message - 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 message: 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 = message.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 (message: string, approved?: boolean): Promise<ToolResult> => {\n const endTime = Date.now();\n if (tool) {\n await toolStrategy?.onError?.(tool, effectiveParams, new Error(message));\n }\n const execution: ToolExecution = {\n toolName,\n toolCallId: call.toolCallId,\n arguments: effectiveParams,\n result: message,\n isError: true,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n onEvent?.(toolExecutionEnd(call.toolCallId, toolName, message, true, endTime, index));\n return {\n toolCallId: call.toolCallId,\n result: message,\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 * 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 * @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 * 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/**\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 * 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 * 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 * 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 * 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 * @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 ImageCapabilities,\n BoundImageModel,\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 * 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, options?: ImageGenerateOptions): Promise<ImageResult> {\n const prompt = normalizeInput(input);\n\n const request: ImageRequest<TParams> = {\n prompt,\n params,\n config,\n signal: options?.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 * 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 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 * 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/**\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 * @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 * 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/**\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 * @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 * 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/**\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 * @fileoverview Thread class for managing conversation history.\n *\n * Provides a utility class for building and manipulating conversation\n * message sequences, with support for serialization and deserialization.\n *\n * @module types/thread\n */\n\nimport { generateId } from '../utils/id.ts';\nimport {\n Message,\n UserMessage,\n AssistantMessage,\n ToolResultMessage,\n type MessageJSON,\n type MessageType,\n} from './messages.ts';\nimport type { UserContent, AssistantContent } from './content.ts';\nimport type { Turn } from './turn.ts';\n\n/**\n * Thread serialized to JSON format.\n * Picks id from Thread, converts dates to strings.\n */\nexport type ThreadJSON = Pick<Thread, 'id'> & {\n messages: MessageJSON[];\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * Thread - A utility class for managing conversation history.\n *\n * Provides methods for building, manipulating, and persisting\n * conversation message sequences. This class is optional; users\n * can also manage their own `Message[]` arrays directly.\n *\n * @example\n * ```typescript\n * // Create a new thread and add messages\n * const thread = new Thread();\n * thread.user('Hello!');\n * thread.assistant('Hi there! How can I help?');\n *\n * // Use with LLM inference\n * const turn = await instance.generate(thread, 'What is 2+2?');\n * thread.append(turn);\n *\n * // Serialize for storage\n * const json = thread.toJSON();\n * localStorage.setItem('chat', JSON.stringify(json));\n *\n * // Restore from storage\n * const restored = Thread.fromJSON(JSON.parse(localStorage.getItem('chat')));\n * ```\n */\nexport class Thread {\n /** Unique thread identifier */\n readonly id: string;\n\n /** Internal message storage */\n private _messages: Message[];\n\n /** Creation timestamp */\n private _createdAt: Date;\n\n /** Last update timestamp */\n private _updatedAt: Date;\n\n /**\n * Creates a new thread instance.\n *\n * @param messages - Optional initial messages to populate the thread\n */\n constructor(messages?: Message[]) {\n this.id = generateId();\n this._messages = messages ? [...messages] : [];\n this._createdAt = new Date();\n this._updatedAt = new Date();\n }\n\n /**\n * All messages in the thread (readonly).\n */\n get messages(): readonly Message[] {\n return this._messages;\n }\n\n /**\n * Number of messages in the thread.\n */\n get length(): number {\n return this._messages.length;\n }\n\n /**\n * Appends all messages from a Turn to the thread.\n *\n * @param turn - The Turn containing messages to append\n * @returns This thread instance for chaining\n */\n append(turn: Turn): this {\n this._messages.push(...turn.messages);\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds raw messages to the thread.\n *\n * @param messages - Messages to add\n * @returns This thread instance for chaining\n */\n push(...messages: Message[]): this {\n this._messages.push(...messages);\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds a user message to the thread.\n *\n * @param content - String or array of content blocks\n * @returns This thread instance for chaining\n *\n * @example\n * ```typescript\n * thread.user('Hello, world!');\n * thread.user([\n * { type: 'text', text: 'Describe this image:' },\n * { type: 'image', source: { type: 'url', url: '...' }, mimeType: 'image/png' }\n * ]);\n * ```\n */\n user(content: string | UserContent[]): this {\n this._messages.push(new UserMessage(content));\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds an assistant message to the thread.\n *\n * @param content - String or array of content blocks\n * @returns This thread instance for chaining\n *\n * @example\n * ```typescript\n * thread.assistant('I can help with that!');\n * ```\n */\n assistant(content: string | AssistantContent[]): this {\n this._messages.push(new AssistantMessage(content));\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Filters messages by type.\n *\n * @param type - The message type to filter by\n * @returns Array of messages matching the type\n *\n * @example\n * ```typescript\n * const userMessages = thread.filter('user');\n * const assistantMessages = thread.filter('assistant');\n * ```\n */\n filter(type: MessageType): Message[] {\n return this._messages.filter((m) => m.type === type);\n }\n\n /**\n * Returns the last N messages from the thread.\n *\n * @param count - Number of messages to return\n * @returns Array of the last N messages\n *\n * @example\n * ```typescript\n * const recent = thread.tail(5);\n * ```\n */\n tail(count: number): Message[] {\n return this._messages.slice(-count);\n }\n\n /**\n * Creates a new thread with a subset of messages.\n *\n * @param start - Start index (inclusive)\n * @param end - End index (exclusive)\n * @returns New Thread containing the sliced messages\n *\n * @example\n * ```typescript\n * const subset = thread.slice(0, 10);\n * ```\n */\n slice(start?: number, end?: number): Thread {\n return new Thread(this._messages.slice(start, end));\n }\n\n /**\n * Removes all messages from the thread.\n *\n * @returns This thread instance for chaining\n */\n clear(): this {\n this._messages = [];\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Converts the thread to a plain message array.\n *\n * @returns Copy of the internal message array\n */\n toMessages(): Message[] {\n return [...this._messages];\n }\n\n /**\n * Serializes the thread to JSON format.\n *\n * @returns JSON-serializable representation of the thread\n *\n * @example\n * ```typescript\n * const json = thread.toJSON();\n * localStorage.setItem('thread', JSON.stringify(json));\n * ```\n */\n toJSON(): ThreadJSON {\n return {\n id: this.id,\n messages: this._messages.map((m) => this.messageToJSON(m)),\n createdAt: this._createdAt.toISOString(),\n updatedAt: this._updatedAt.toISOString(),\n };\n }\n\n /**\n * Deserializes a thread from JSON format.\n *\n * @param json - The JSON representation to deserialize\n * @returns Reconstructed Thread instance\n *\n * @example\n * ```typescript\n * const json = JSON.parse(localStorage.getItem('thread'));\n * const thread = Thread.fromJSON(json);\n * ```\n */\n static fromJSON(json: ThreadJSON): Thread {\n const messages = json.messages.map((m) => Thread.messageFromJSON(m));\n const thread = new Thread(messages);\n (thread as { id: string }).id = json.id;\n thread._createdAt = new Date(json.createdAt);\n thread._updatedAt = new Date(json.updatedAt);\n return thread;\n }\n\n /**\n * Enables iteration over messages with for...of loops.\n *\n * @returns Iterator over the thread's messages\n *\n * @example\n * ```typescript\n * for (const message of thread) {\n * console.log(message.text);\n * }\n * ```\n */\n [Symbol.iterator](): Iterator<Message> {\n return this._messages[Symbol.iterator]();\n }\n\n /**\n * Converts a message to JSON format.\n */\n private messageToJSON(m: Message): MessageJSON {\n const base: MessageJSON = {\n id: m.id,\n type: m.type,\n content: [],\n metadata: m.metadata,\n timestamp: m.timestamp.toISOString(),\n };\n\n if (m instanceof UserMessage) {\n base.content = m.content;\n } else if (m instanceof AssistantMessage) {\n base.content = m.content;\n base.toolCalls = m.toolCalls;\n } else if (m instanceof ToolResultMessage) {\n base.results = m.results;\n }\n\n return base;\n }\n\n /**\n * Reconstructs a message from JSON format.\n */\n private static messageFromJSON(json: MessageJSON): Message {\n const options = {\n id: json.id,\n metadata: json.metadata,\n };\n\n switch (json.type) {\n case 'user':\n return new UserMessage(json.content as UserContent[], options);\n case 'assistant':\n return new AssistantMessage(\n json.content as AssistantContent[],\n json.toolCalls,\n options\n );\n case 'tool_result':\n return new ToolResultMessage(json.results ?? [], options);\n default:\n throw new Error(`Unknown message type: ${json.type}`);\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 Partial JSON parser for streaming LLM responses.\n *\n * Enables incremental parsing of JSON data as it streams from LLM providers,\n * allowing consumers to access usable partial objects during streaming rather\n * than waiting for complete JSON.\n *\n * @module utils/partial-json\n */\n\n/**\n * Result of parsing partial JSON.\n *\n * @typeParam T - The expected type of the parsed value\n */\nexport interface PartialParseResult<T = unknown> {\n /** The parsed value, or undefined if parsing failed */\n value: T | undefined;\n /** Whether the JSON was complete and valid */\n isComplete: boolean;\n}\n\n/**\n * Parses potentially incomplete JSON, returning as much as can be extracted.\n *\n * Handles common incomplete states during streaming:\n * - Incomplete strings: `{\"name\":\"Jo` → `{name: \"Jo\"}`\n * - Incomplete objects: `{\"a\":1,\"b\":` → `{a: 1}`\n * - Incomplete arrays: `[1,2,` → `[1, 2]`\n * - Incomplete numbers, booleans, null literals\n * - Nested structures with partial completion\n * - Unicode escape sequences\n *\n * @typeParam T - The expected type of the parsed value\n * @param json - The potentially incomplete JSON string\n * @returns A PartialParseResult with the parsed value and completion status\n *\n * @example\n * ```typescript\n * // Complete JSON\n * parsePartialJson('{\"name\":\"John\"}');\n * // => { value: { name: \"John\" }, isComplete: true }\n *\n * // Incomplete object\n * parsePartialJson('{\"user\":{\"firstName\":\"Jo');\n * // => { value: { user: { firstName: \"Jo\" } }, isComplete: false }\n *\n * // Incomplete array\n * parsePartialJson('[1, 2, 3');\n * // => { value: [1, 2, 3], isComplete: false }\n * ```\n */\nexport function parsePartialJson<T = unknown>(json: string): PartialParseResult<T> {\n const trimmed = json.trim();\n\n if (trimmed === '') {\n return { value: undefined, isComplete: false };\n }\n\n // Try parsing as complete JSON first\n try {\n const value = JSON.parse(trimmed) as T;\n return { value, isComplete: true };\n } catch {\n // Continue with partial parsing\n }\n\n // Attempt to repair and parse the incomplete JSON\n try {\n const repaired = repairJson(trimmed);\n const value = JSON.parse(repaired) as T;\n return { value, isComplete: false };\n } catch {\n return { value: undefined, isComplete: false };\n }\n}\n\n/**\n * Attempts to repair incomplete JSON by completing open structures.\n *\n * @param json - The incomplete JSON string\n * @returns A potentially valid JSON string\n */\nfunction repairJson(json: string): string {\n let result = json;\n\n // Track open structures as we scan\n const stack: Array<'{' | '['> = [];\n let inString = false;\n let escape = false;\n\n for (let i = 0; i < result.length; i++) {\n const char = result[i]!;\n\n if (escape) {\n escape = false;\n continue;\n }\n\n if (char === '\\\\' && inString) {\n escape = true;\n continue;\n }\n\n if (char === '\"' && !escape) {\n inString = !inString;\n }\n\n if (!inString) {\n if (char === '{') {\n stack.push('{');\n } else if (char === '[') {\n stack.push('[');\n } else if (char === '}') {\n if (stack.length > 0 && stack[stack.length - 1] === '{') {\n stack.pop();\n }\n } else if (char === ']') {\n if (stack.length > 0 && stack[stack.length - 1] === '[') {\n stack.pop();\n }\n }\n }\n }\n\n // If we ended inside a string, close it\n if (inString) {\n // Check if the string ends with incomplete unicode escape\n const unicodeMatch = result.match(/\\\\u[0-9a-fA-F]{0,3}$/);\n if (unicodeMatch) {\n // Remove incomplete unicode escape\n result = result.slice(0, -unicodeMatch[0].length);\n }\n // Check if string ends with incomplete escape sequence\n if (result.endsWith('\\\\')) {\n result = result.slice(0, -1);\n }\n result += '\"';\n inString = false;\n }\n\n // Handle trailing incomplete structures\n result = cleanupTrailingIncomplete(result);\n\n // Close any open structures\n while (stack.length > 0) {\n const open = stack.pop();\n if (open === '{') {\n result += '}';\n } else {\n result += ']';\n }\n }\n\n return result;\n}\n\n/**\n * Cleans up trailing incomplete elements from JSON.\n * Iteratively handles chained incomplete elements (e.g., trailing colon followed by comma).\n */\nfunction cleanupTrailingIncomplete(json: string): string {\n let result = json.trim();\n let changed = true;\n\n // Keep cleaning until no more changes\n while (changed) {\n changed = false;\n const trimmed = result.trim();\n\n // Handle trailing comma - remove it\n if (trimmed.endsWith(',')) {\n result = trimmed.slice(0, -1);\n changed = true;\n continue;\n }\n\n // Handle trailing colon - remove the incomplete key-value pair\n if (trimmed.endsWith(':')) {\n // Find the start of the key (the opening quote before the colon)\n const colonIndex = trimmed.length - 1;\n let keyStart = colonIndex - 1;\n while (keyStart >= 0 && /\\s/.test(trimmed[keyStart]!)) {\n keyStart--;\n }\n // Should now be at closing quote of key\n if (keyStart >= 0 && trimmed[keyStart] === '\"') {\n // Find opening quote of key\n keyStart--;\n while (keyStart >= 0 && trimmed[keyStart] !== '\"') {\n keyStart--;\n }\n // Now find what's before the key (comma or opening brace)\n keyStart--;\n while (keyStart >= 0 && /\\s/.test(trimmed[keyStart]!)) {\n keyStart--;\n }\n if (keyStart >= 0 && trimmed[keyStart] === ',') {\n result = trimmed.slice(0, keyStart);\n } else {\n result = trimmed.slice(0, keyStart + 1);\n }\n changed = true;\n continue;\n }\n }\n\n // Handle incomplete literals (true, false, null)\n const literalMatch = trimmed.match(/(,?\\s*)(t(?:r(?:ue?)?)?|f(?:a(?:l(?:se?)?)?)?|n(?:u(?:ll?)?)?)$/i);\n if (literalMatch && literalMatch[2]) {\n const partial = literalMatch[2].toLowerCase();\n const literals = ['true', 'false', 'null'];\n const match = literals.find((lit) => lit.startsWith(partial) && partial !== lit);\n if (match) {\n result = trimmed.slice(0, -literalMatch[2].length) + match;\n changed = true;\n continue;\n }\n }\n\n // Handle incomplete numbers at end (e.g., \"123.\" or \"1e\" or \"1e+\" or \"-\")\n const numberMatch = trimmed.match(/(,?\\s*)(-?(?:\\d+\\.|\\d*\\.?\\d+[eE][+-]?|\\d+[eE]|-))$/);\n if (numberMatch && numberMatch[2]) {\n const partial = numberMatch[2];\n if (/[.eE+-]$/.test(partial)) {\n if (partial === '-') {\n // Just a minus sign - remove it and any preceding whitespace/comma\n result = trimmed.slice(0, -(numberMatch[0]?.length ?? 0)).trimEnd();\n // If we now end with a colon, the loop will clean that up next iteration\n } else {\n result = trimmed.slice(0, -1);\n }\n changed = true;\n continue;\n }\n }\n }\n\n return result;\n}\n","/**\n * @fileoverview Parsed object middleware for incremental JSON parsing.\n *\n * This middleware parses partial JSON from ObjectDelta and ToolCallDelta\n * stream events, providing incremental structured data during streaming.\n *\n * @module middleware/parsed-object\n */\n\nimport type { Middleware, StreamContext } from '../types/middleware.ts';\nimport type { EventDelta, StreamEvent } from '../types/stream.ts';\nimport { StreamEventType } from '../types/stream.ts';\nimport { parsePartialJson } from '../utils/partial-json.ts';\n\n/**\n * Event delta with parsed JSON data.\n * Extended by parsedObjectMiddleware when parsing is enabled.\n */\nexport interface ParsedEventDelta extends EventDelta {\n /** Incrementally parsed JSON value */\n parsed?: unknown;\n}\n\n/**\n * Stream event with parsed JSON data.\n * Returned by parsedObjectMiddleware for ObjectDelta and ToolCallDelta events.\n */\nexport interface ParsedStreamEvent extends Omit<StreamEvent, 'delta'> {\n delta: ParsedEventDelta;\n}\n\n/**\n * Options for parsed object middleware.\n */\nexport interface ParsedObjectOptions {\n /**\n * Parse ObjectDelta events (structured output responses).\n * @default true\n */\n parseObjects?: boolean;\n\n /**\n * Parse ToolCallDelta events (tool call arguments).\n * @default true\n */\n parseToolCalls?: boolean;\n}\n\n/**\n * Creates a middleware that parses partial JSON from stream events.\n *\n * This middleware accumulates text from ObjectDelta events and tool\n * argument JSON from ToolCallDelta events, then parses them incrementally\n * using partial JSON parsing. The parsed result is added to the event's\n * `parsed` field.\n *\n * @param options - Configuration options\n * @returns A middleware that adds parsed JSON to stream events\n *\n * @example\n * ```typescript\n * import { llm, parsedObjectMiddleware } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n *\n * const model = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * structure: mySchema,\n * middleware: [parsedObjectMiddleware()],\n * });\n *\n * for await (const event of model.stream('Extract data from this text')) {\n * if (event.type === 'object_delta') {\n * // event.delta.parsed contains incrementally parsed object\n * console.log(event.delta.parsed);\n * }\n * }\n * ```\n */\n/** State key for accumulated object text */\nconst ACCUMULATED_TEXT_KEY = 'parsedObject:text';\n/** State key for accumulated tool arguments */\nconst ACCUMULATED_ARGS_KEY = 'parsedObject:args';\n\n/**\n * Gets or creates the accumulated text map from state.\n */\nfunction getAccumulatedText(state: Map<string, unknown>): Map<number, string> {\n let map = state.get(ACCUMULATED_TEXT_KEY) as Map<number, string> | undefined;\n if (!map) {\n map = new Map();\n state.set(ACCUMULATED_TEXT_KEY, map);\n }\n return map;\n}\n\n/**\n * Gets or creates the accumulated args map from state.\n */\nfunction getAccumulatedArgs(state: Map<string, unknown>): Map<number, string> {\n let map = state.get(ACCUMULATED_ARGS_KEY) as Map<number, string> | undefined;\n if (!map) {\n map = new Map();\n state.set(ACCUMULATED_ARGS_KEY, map);\n }\n return map;\n}\n\nexport function parsedObjectMiddleware(options: ParsedObjectOptions = {}): Middleware {\n const { parseObjects = true, parseToolCalls = true } = options;\n\n return {\n name: 'parsed-object',\n\n onStreamEvent(event: StreamEvent, ctx: StreamContext): StreamEvent | StreamEvent[] | null {\n if (parseObjects && event.type === StreamEventType.ObjectDelta) {\n const accumulatedText = getAccumulatedText(ctx.state);\n const current = accumulatedText.get(event.index) ?? '';\n const newText = current + (event.delta.text ?? '');\n accumulatedText.set(event.index, newText);\n\n const parseResult = parsePartialJson(newText);\n\n const parsedEvent: ParsedStreamEvent = {\n ...event,\n delta: {\n ...event.delta,\n parsed: parseResult.value,\n },\n };\n return parsedEvent as StreamEvent;\n }\n\n if (parseToolCalls && event.type === StreamEventType.ToolCallDelta) {\n const accumulatedArgs = getAccumulatedArgs(ctx.state);\n const current = accumulatedArgs.get(event.index) ?? '';\n const newJson = current + (event.delta.argumentsJson ?? '');\n accumulatedArgs.set(event.index, newJson);\n\n const parseResult = parsePartialJson(newJson);\n\n const parsedEvent: ParsedStreamEvent = {\n ...event,\n delta: {\n ...event.delta,\n parsed: parseResult.value,\n },\n };\n return parsedEvent as StreamEvent;\n }\n\n return event;\n },\n\n onStreamEnd(ctx: StreamContext): void {\n // Clean up accumulated state to prevent memory buildup in long sessions\n ctx.state.delete(ACCUMULATED_TEXT_KEY);\n ctx.state.delete(ACCUMULATED_ARGS_KEY);\n },\n };\n}\n","/**\n * @fileoverview Logging middleware for request/response visibility.\n *\n * Provides configurable logging for LLM, embedding, and image operations,\n * including timing, error tracking, and optional event logging.\n *\n * @module middleware/logging\n */\n\nimport type { Middleware, MiddlewareContext, StreamContext } from '../types/middleware.ts';\nimport type { StreamEvent } from '../types/stream.ts';\n\n/**\n * Log levels for filtering output.\n */\nexport type LogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * Options for logging middleware.\n */\nexport interface LoggingOptions {\n /**\n * Minimum log level to output.\n * @default 'info'\n */\n level?: LogLevel;\n\n /**\n * Log individual stream events.\n * @default false\n */\n logStreamEvents?: boolean;\n\n /**\n * Log tool calls and results.\n * @default true\n */\n logToolCalls?: boolean;\n\n /**\n * Custom logger function. If not provided, uses console.log.\n * @param level - The log level\n * @param message - The log message\n * @param data - Optional additional data\n */\n logger?(level: LogLevel, message: string, data?: Record<string, unknown>): void;\n\n /**\n * Prefix for all log messages.\n * @default '[PP]'\n */\n prefix?: string;\n}\n\nconst LOG_LEVELS: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\n/**\n * Creates a logging middleware for visibility into request lifecycle.\n *\n * This middleware logs the start, end, and errors of requests,\n * with optional logging of stream events and tool calls.\n *\n * @param options - Configuration options\n * @returns A middleware that logs request lifecycle events\n *\n * @example\n * ```typescript\n * import { llm, loggingMiddleware } from '@providerprotocol/ai';\n * import { anthropic } from '@providerprotocol/ai/anthropic';\n *\n * const model = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * middleware: [loggingMiddleware({ level: 'debug' })],\n * });\n *\n * // Logs: [PP] [anthropic] Starting llm request (streaming)\n * // Logs: [PP] [anthropic] Completed in 1234ms\n * const result = await model.generate('Hello');\n * ```\n */\nexport function loggingMiddleware(options: LoggingOptions = {}): Middleware {\n const {\n level = 'info',\n logStreamEvents = false,\n logToolCalls = true,\n logger,\n prefix = '[PP]',\n } = options;\n\n const minLevel = LOG_LEVELS[level];\n\n const log = (logLevel: LogLevel, message: string, data?: Record<string, unknown>) => {\n if (LOG_LEVELS[logLevel] < minLevel) {\n return;\n }\n\n const fullMessage = `${prefix} ${message}`;\n\n if (logger) {\n logger(logLevel, fullMessage, data);\n } else {\n const consoleMethod = logLevel === 'error' ? console.error : logLevel === 'warn' ? console.warn : console.log;\n if (data) {\n consoleMethod(fullMessage, data);\n } else {\n consoleMethod(fullMessage);\n }\n }\n };\n\n return {\n name: 'logging',\n\n onStart(ctx: MiddlewareContext): void {\n const streamingLabel = ctx.streaming ? '(streaming)' : '';\n log('info', `[${ctx.provider}] Starting ${ctx.modality} request ${streamingLabel}`.trim());\n log('debug', `[${ctx.provider}] Model: ${ctx.modelId}`);\n },\n\n onEnd(ctx: MiddlewareContext): void {\n const duration = ctx.endTime ? ctx.endTime - ctx.startTime : 0;\n log('info', `[${ctx.provider}] Completed in ${duration}ms`);\n },\n\n onError(error: Error, ctx: MiddlewareContext): void {\n const duration = Date.now() - ctx.startTime;\n log('error', `[${ctx.provider}] Error after ${duration}ms: ${error.message}`);\n },\n\n onStreamEvent(event: StreamEvent, ctx: StreamContext): StreamEvent {\n if (logStreamEvents) {\n log('debug', `Stream event: ${event.type}`, { index: event.index });\n }\n return event;\n },\n\n onToolCall(tool, params, ctx: MiddlewareContext): void {\n if (logToolCalls) {\n log('info', `[${ctx.provider}] Tool call: ${tool.name}`);\n log('debug', `[${ctx.provider}] Tool params:`, { params });\n }\n },\n\n onToolResult(tool, result, ctx: MiddlewareContext): void {\n if (logToolCalls) {\n log('debug', `[${ctx.provider}] Tool result: ${tool.name}`, { result });\n }\n },\n };\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\n/**\n * Middleware exports for composable request/response/stream transformations.\n *\n * @example\n * ```typescript\n * import { llm, parsedObjectMiddleware, loggingMiddleware } from '@providerprotocol/ai';\n *\n * const model = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * structure: mySchema,\n * middleware: [\n * loggingMiddleware(),\n * parsedObjectMiddleware(),\n * ],\n * });\n * ```\n */\nexport {\n parsedObjectMiddleware,\n loggingMiddleware,\n type ParsedObjectOptions,\n type ParsedEventDelta,\n type ParsedStreamEvent,\n type LoggingOptions,\n type LogLevel,\n} from './middleware/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","message","approved","options","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/thread.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';\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 * 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 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;\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 * 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 validateMediaCapabilities(\n [...history, ...newMessages],\n model.capabilities,\n model.provider.name\n );\n const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n const allMessages: Message[] = [...history, ...newMessages];\n const toolExecutions: ToolExecution[] = [];\n const usages: TokenUsage[] = [];\n let cycles = 0;\n\n let structuredData: unknown;\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\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(history.length),\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 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 validateMediaCapabilities(\n [...history, ...newMessages],\n model.capabilities,\n model.provider.name\n );\n\n const abortController = new AbortController();\n\n const 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\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\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(history.length),\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 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 Thread class for managing conversation history.\n *\n * Provides a utility class for building and manipulating conversation\n * message sequences, with support for serialization and deserialization.\n *\n * @module types/thread\n */\n\nimport { generateId } from '../utils/id.ts';\nimport {\n Message,\n UserMessage,\n AssistantMessage,\n ToolResultMessage,\n type MessageJSON,\n type MessageType,\n} from './messages.ts';\nimport type { UserContent, AssistantContent } from './content.ts';\nimport type { Turn } from './turn.ts';\n\n/**\n * Thread serialized to JSON format.\n * Picks id from Thread, converts dates to strings.\n */\nexport type ThreadJSON = Pick<Thread, 'id'> & {\n messages: MessageJSON[];\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * Thread - A utility class for managing conversation history.\n *\n * Provides methods for building, manipulating, and persisting\n * conversation message sequences. This class is optional; users\n * can also manage their own `Message[]` arrays directly.\n *\n * @example\n * ```typescript\n * // Create a new thread and add messages\n * const thread = new Thread();\n * thread.user('Hello!');\n * thread.assistant('Hi there! How can I help?');\n *\n * // Use with LLM inference\n * const turn = await instance.generate(thread, 'What is 2+2?');\n * thread.append(turn);\n *\n * // Serialize for storage\n * const json = thread.toJSON();\n * localStorage.setItem('chat', JSON.stringify(json));\n *\n * // Restore from storage\n * const restored = Thread.fromJSON(JSON.parse(localStorage.getItem('chat')));\n * ```\n */\nexport class Thread {\n /** Unique thread identifier */\n readonly id: string;\n\n /** Internal message storage */\n private _messages: Message[];\n\n /** Creation timestamp */\n private _createdAt: Date;\n\n /** Last update timestamp */\n private _updatedAt: Date;\n\n /**\n * Creates a new thread instance.\n *\n * @param messages - Optional initial messages to populate the thread\n */\n constructor(messages?: Message[]) {\n this.id = generateId();\n this._messages = messages ? [...messages] : [];\n this._createdAt = new Date();\n this._updatedAt = new Date();\n }\n\n /**\n * All messages in the thread (readonly).\n */\n get messages(): readonly Message[] {\n return this._messages;\n }\n\n /**\n * Number of messages in the thread.\n */\n get length(): number {\n return this._messages.length;\n }\n\n /**\n * Appends all messages from a Turn to the thread.\n *\n * @param turn - The Turn containing messages to append\n * @returns This thread instance for chaining\n */\n append(turn: Turn): this {\n this._messages.push(...turn.messages);\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds raw messages to the thread.\n *\n * @param messages - Messages to add\n * @returns This thread instance for chaining\n */\n push(...messages: Message[]): this {\n this._messages.push(...messages);\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds a user message to the thread.\n *\n * @param content - String or array of content blocks\n * @returns This thread instance for chaining\n *\n * @example\n * ```typescript\n * thread.user('Hello, world!');\n * thread.user([\n * { type: 'text', text: 'Describe this image:' },\n * { type: 'image', source: { type: 'url', url: '...' }, mimeType: 'image/png' }\n * ]);\n * ```\n */\n user(content: string | UserContent[]): this {\n this._messages.push(new UserMessage(content));\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds an assistant message to the thread.\n *\n * @param content - String or array of content blocks\n * @returns This thread instance for chaining\n *\n * @example\n * ```typescript\n * thread.assistant('I can help with that!');\n * ```\n */\n assistant(content: string | AssistantContent[]): this {\n this._messages.push(new AssistantMessage(content));\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Filters messages by type.\n *\n * @param type - The message type to filter by\n * @returns Array of messages matching the type\n *\n * @example\n * ```typescript\n * const userMessages = thread.filter('user');\n * const assistantMessages = thread.filter('assistant');\n * ```\n */\n filter(type: MessageType): Message[] {\n return this._messages.filter((m) => m.type === type);\n }\n\n /**\n * Returns the last N messages from the thread.\n *\n * @param count - Number of messages to return\n * @returns Array of the last N messages\n *\n * @example\n * ```typescript\n * const recent = thread.tail(5);\n * ```\n */\n tail(count: number): Message[] {\n return this._messages.slice(-count);\n }\n\n /**\n * Creates a new thread with a subset of messages.\n *\n * @param start - Start index (inclusive)\n * @param end - End index (exclusive)\n * @returns New Thread containing the sliced messages\n *\n * @example\n * ```typescript\n * const subset = thread.slice(0, 10);\n * ```\n */\n slice(start?: number, end?: number): Thread {\n return new Thread(this._messages.slice(start, end));\n }\n\n /**\n * Removes all messages from the thread.\n *\n * @returns This thread instance for chaining\n */\n clear(): this {\n this._messages = [];\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Converts the thread to a plain message array.\n *\n * @returns Copy of the internal message array\n */\n toMessages(): Message[] {\n return [...this._messages];\n }\n\n /**\n * Serializes the thread to JSON format.\n *\n * @returns JSON-serializable representation of the thread\n *\n * @example\n * ```typescript\n * const json = thread.toJSON();\n * localStorage.setItem('thread', JSON.stringify(json));\n * ```\n */\n toJSON(): ThreadJSON {\n return {\n id: this.id,\n messages: this._messages.map((m) => this.messageToJSON(m)),\n createdAt: this._createdAt.toISOString(),\n updatedAt: this._updatedAt.toISOString(),\n };\n }\n\n /**\n * Deserializes a thread from JSON format.\n *\n * @param json - The JSON representation to deserialize\n * @returns Reconstructed Thread instance\n *\n * @example\n * ```typescript\n * const json = JSON.parse(localStorage.getItem('thread'));\n * const thread = Thread.fromJSON(json);\n * ```\n */\n static fromJSON(json: ThreadJSON): Thread {\n const messages = json.messages.map((m) => Thread.messageFromJSON(m));\n const thread = new Thread(messages);\n (thread as { id: string }).id = json.id;\n thread._createdAt = new Date(json.createdAt);\n thread._updatedAt = new Date(json.updatedAt);\n return thread;\n }\n\n /**\n * Enables iteration over messages with for...of loops.\n *\n * @returns Iterator over the thread's messages\n *\n * @example\n * ```typescript\n * for (const message of thread) {\n * console.log(message.text);\n * }\n * ```\n */\n [Symbol.iterator](): Iterator<Message> {\n return this._messages[Symbol.iterator]();\n }\n\n /**\n * Converts a message to JSON format.\n */\n private messageToJSON(m: Message): MessageJSON {\n const base: MessageJSON = {\n id: m.id,\n type: m.type,\n content: [],\n metadata: m.metadata,\n timestamp: m.timestamp.toISOString(),\n };\n\n if (m instanceof UserMessage) {\n base.content = m.content;\n } else if (m instanceof AssistantMessage) {\n base.content = m.content;\n base.toolCalls = m.toolCalls;\n } else if (m instanceof ToolResultMessage) {\n base.results = m.results;\n }\n\n return base;\n }\n\n /**\n * Reconstructs a message from JSON format.\n */\n private static messageFromJSON(json: MessageJSON): Message {\n const options = {\n id: json.id,\n metadata: json.metadata,\n };\n\n switch (json.type) {\n case 'user':\n return new UserMessage(json.content as UserContent[], options);\n case 'assistant':\n return new AssistantMessage(\n json.content as AssistantContent[],\n json.toolCalls,\n options\n );\n case 'tool_result':\n return new ToolResultMessage(json.results ?? [], options);\n default:\n throw new Error(`Unknown message type: ${json.type}`);\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"]}