@providerprotocol/ai 0.0.23 → 0.0.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ import {
32
32
  resolveEmbeddingHandler,
33
33
  resolveImageHandler,
34
34
  resolveLLMHandler
35
- } from "./chunk-MF5ETY5O.js";
35
+ } from "./chunk-6AZVUI6H.js";
36
36
  import {
37
37
  ExponentialBackoff,
38
38
  LinearBackoff,
@@ -40,7 +40,7 @@ import {
40
40
  RetryAfterStrategy,
41
41
  TokenBucket
42
42
  } from "./chunk-SBCATNHA.js";
43
- import "./chunk-NWS5IKNR.js";
43
+ import "./chunk-TOJCZMVU.js";
44
44
  import {
45
45
  DynamicKey,
46
46
  RoundRobinKeys,
@@ -57,6 +57,8 @@ import {
57
57
  var ContentBlockType = {
58
58
  /** Text content */
59
59
  Text: "text",
60
+ /** Reasoning/thinking content from extended thinking models */
61
+ Reasoning: "reasoning",
60
62
  /** Image content */
61
63
  Image: "image",
62
64
  /** Audio content */
@@ -77,9 +79,15 @@ var ImageSourceType = {
77
79
  function text(content) {
78
80
  return { type: ContentBlockType.Text, text: content };
79
81
  }
82
+ function reasoning(content) {
83
+ return { type: ContentBlockType.Reasoning, text: content };
84
+ }
80
85
  function isTextBlock(block) {
81
86
  return block.type === ContentBlockType.Text;
82
87
  }
88
+ function isReasoningBlock(block) {
89
+ return block.type === ContentBlockType.Reasoning;
90
+ }
83
91
  function isImageBlock(block) {
84
92
  return block.type === ContentBlockType.Image;
85
93
  }
@@ -1228,6 +1236,7 @@ export {
1228
1236
  isAudioBlock,
1229
1237
  isBinaryBlock,
1230
1238
  isImageBlock,
1239
+ isReasoningBlock,
1231
1240
  isTextBlock,
1232
1241
  isToolResultMessage,
1233
1242
  isUserMessage,
@@ -1235,6 +1244,7 @@ export {
1235
1244
  llm,
1236
1245
  messageStart,
1237
1246
  messageStop,
1247
+ reasoning,
1238
1248
  text,
1239
1249
  textDelta,
1240
1250
  toolCallDelta
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/content.ts","../src/core/llm.ts","../src/core/embedding.ts","../src/core/image.ts","../src/types/thread.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 /** Image content */\n Image: 'image',\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 * 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 * 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 * 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 | ImageBlock\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 | 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 | 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 * 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 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 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 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 LLMHandler,\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 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 } from '../types/provider.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';\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 { model: modelRef, config: explicitConfig = {}, params, system, tools, toolStrategy, structure } = 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 );\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 );\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 (isImageBlock(block) || isAudioBlock(block) || isVideoBlock(block) || isBinaryBlock(block)) {\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): 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 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 );\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n\n const data = structure ? structuredData : undefined;\n\n return createTurn(\n allMessages.slice(history.length),\n toolExecutions,\n aggregateUsage(usages),\n cycles,\n data\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): 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 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 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 yield event;\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 );\n\n for (const event of toolEvents) {\n ensureNotAborted();\n yield event;\n }\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n generatorCompleted = true;\n resolveGenerator();\n } catch (error) {\n const err = toError(error);\n generatorError = err;\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 return createTurn(\n allMessages.slice(history.length),\n toolExecutions,\n aggregateUsage(usages),\n cycles,\n data\n );\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 *\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 * @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): 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 } 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 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, 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 === '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} from '../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveEmbeddingHandler } from './provider-handlers.ts';\nimport { toError } from '../utils/error.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 } = 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);\n }\n\n return executeEmbed(boundModel, inputs, params, config, embedOptions?.signal);\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 * @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): Promise<EmbeddingResult> {\n const response = await model.embed({\n inputs,\n params,\n config: config ?? {},\n signal,\n });\n\n return normalizeResponse(response, model.provider.name);\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 * @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): 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 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 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 resolveResult({\n embeddings: orderedEmbeddings,\n usage: { totalTokens },\n });\n } catch (error) {\n const err = toError(error);\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} from '../types/image.ts';\nimport type { ProviderConfig } from '../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveImageHandler } from './provider-handlers.ts';\nimport { toError } from '../utils/error.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 } = 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 try {\n const response = await boundModel.generate({\n prompt,\n params,\n config,\n signal: options?.signal,\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 if (capabilities.streaming && boundModel.stream) {\n const stream = boundModel.stream;\n instance.stream = function (input: ImageInput): ImageStreamResult {\n const prompt = normalizeInput(input);\n\n const abortController = new AbortController();\n const providerStream = stream({\n prompt,\n params,\n config,\n signal: abortController.signal,\n });\n\n const resultPromise = providerStream.response\n .then((response) => ({\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n }))\n .catch((error) => {\n throw normalizeImageError(error);\n });\n\n async function* wrappedStream(): AsyncGenerator<ImageStreamEvent, void, unknown> {\n try {\n for await (const event of providerStream) {\n yield event;\n }\n } catch (error) {\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 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// Re-export for convenience\nexport type { MessageJSON };\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 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\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","message","approved","options"]}
1
+ {"version":3,"sources":["../src/types/content.ts","../src/core/llm.ts","../src/core/embedding.ts","../src/core/image.ts","../src/types/thread.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 /** 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 * 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 * 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 | 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 | 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 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 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 LLMHandler,\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 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 } from '../types/provider.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';\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 { model: modelRef, config: explicitConfig = {}, params, system, tools, toolStrategy, structure } = 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 );\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 );\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 (isImageBlock(block) || isAudioBlock(block) || isVideoBlock(block) || isBinaryBlock(block)) {\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): 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 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 );\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n\n const data = structure ? structuredData : undefined;\n\n return createTurn(\n allMessages.slice(history.length),\n toolExecutions,\n aggregateUsage(usages),\n cycles,\n data\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): 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 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 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 yield event;\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 );\n\n for (const event of toolEvents) {\n ensureNotAborted();\n yield event;\n }\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n generatorCompleted = true;\n resolveGenerator();\n } catch (error) {\n const err = toError(error);\n generatorError = err;\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 return createTurn(\n allMessages.slice(history.length),\n toolExecutions,\n aggregateUsage(usages),\n cycles,\n data\n );\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 *\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 * @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): 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 } 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 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, 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 === '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} from '../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveEmbeddingHandler } from './provider-handlers.ts';\nimport { toError } from '../utils/error.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 } = 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);\n }\n\n return executeEmbed(boundModel, inputs, params, config, embedOptions?.signal);\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 * @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): Promise<EmbeddingResult> {\n const response = await model.embed({\n inputs,\n params,\n config: config ?? {},\n signal,\n });\n\n return normalizeResponse(response, model.provider.name);\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 * @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): 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 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 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 resolveResult({\n embeddings: orderedEmbeddings,\n usage: { totalTokens },\n });\n } catch (error) {\n const err = toError(error);\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} from '../types/image.ts';\nimport type { ProviderConfig } from '../types/provider.ts';\nimport { UPPError, ErrorCode, ModalityType } from '../types/errors.ts';\nimport { resolveImageHandler } from './provider-handlers.ts';\nimport { toError } from '../utils/error.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 } = 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 try {\n const response = await boundModel.generate({\n prompt,\n params,\n config,\n signal: options?.signal,\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 if (capabilities.streaming && boundModel.stream) {\n const stream = boundModel.stream;\n instance.stream = function (input: ImageInput): ImageStreamResult {\n const prompt = normalizeInput(input);\n\n const abortController = new AbortController();\n const providerStream = stream({\n prompt,\n params,\n config,\n signal: abortController.signal,\n });\n\n const resultPromise = providerStream.response\n .then((response) => ({\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n }))\n .catch((error) => {\n throw normalizeImageError(error);\n });\n\n async function* wrappedStream(): AsyncGenerator<ImageStreamEvent, void, unknown> {\n try {\n for await (const event of providerStream) {\n yield event;\n }\n } catch (error) {\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 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// Re-export for convenience\nexport type { MessageJSON };\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 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\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","message","approved","options"]}
@@ -1,4 +1,4 @@
1
- import { g as Provider } from '../provider-DR1yins0.js';
1
+ import { g as Provider } from '../provider-x4RocsnK.js';
2
2
 
3
3
  /**
4
4
  * @fileoverview Type definitions for the Ollama provider.
@@ -10,7 +10,7 @@ import {
10
10
  isAssistantMessage,
11
11
  isToolResultMessage,
12
12
  isUserMessage
13
- } from "../chunk-MF5ETY5O.js";
13
+ } from "../chunk-6AZVUI6H.js";
14
14
  import {
15
15
  resolveApiKey
16
16
  } from "../chunk-55X3W2MN.js";
@@ -128,7 +128,7 @@ function transformMessages(messages, system) {
128
128
  }
129
129
  ollamaMessages.push(message);
130
130
  } else if (isAssistantMessage(msg)) {
131
- const textContent = msg.content.filter((block) => block.type === "text").map((block) => block.text).join("\n");
131
+ const textContent = msg.content.filter((block) => block.type === "text").map((block) => block.text).join("\n").replace(/<think>[\s\S]*?<\/think>/g, "").trim();
132
132
  const message = {
133
133
  role: "assistant",
134
134
  content: textContent
@@ -171,11 +171,14 @@ function transformTool(tool) {
171
171
  };
172
172
  }
173
173
  function transformResponse(data) {
174
- const textContent = [];
174
+ const content = [];
175
175
  const toolCalls = [];
176
176
  let structuredData;
177
+ if (data.message.thinking) {
178
+ content.push({ type: "reasoning", text: data.message.thinking });
179
+ }
177
180
  if (data.message.content) {
178
- textContent.push({ type: "text", text: data.message.content });
181
+ content.push({ type: "text", text: data.message.content });
179
182
  try {
180
183
  structuredData = JSON.parse(data.message.content);
181
184
  } catch {
@@ -192,7 +195,7 @@ function transformResponse(data) {
192
195
  }
193
196
  }
194
197
  const message = new AssistantMessage(
195
- textContent,
198
+ content,
196
199
  toolCalls.length > 0 ? toolCalls : void 0,
197
200
  {
198
201
  metadata: {
@@ -299,11 +302,14 @@ function transformStreamChunk(chunk, state) {
299
302
  return events;
300
303
  }
301
304
  function buildResponseFromState(state) {
302
- const textContent = [];
305
+ const content = [];
303
306
  const toolCalls = [];
304
307
  let structuredData;
308
+ if (state.thinking) {
309
+ content.push({ type: "reasoning", text: state.thinking });
310
+ }
305
311
  if (state.content) {
306
- textContent.push({ type: "text", text: state.content });
312
+ content.push({ type: "text", text: state.content });
307
313
  try {
308
314
  structuredData = JSON.parse(state.content);
309
315
  } catch {
@@ -317,7 +323,7 @@ function buildResponseFromState(state) {
317
323
  });
318
324
  }
319
325
  const message = new AssistantMessage(
320
- textContent,
326
+ content,
321
327
  toolCalls.length > 0 ? toolCalls : void 0,
322
328
  {
323
329
  metadata: {