@providerprotocol/ai 0.0.15 → 0.0.16
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/anthropic/index.d.ts +1 -1
- package/dist/google/index.d.ts +1 -1
- package/dist/http/index.d.ts +2 -2
- package/dist/index.d.ts +22 -5
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/ollama/index.d.ts +1 -1
- package/dist/openai/index.d.ts +2 -1
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +46 -1
- package/dist/openrouter/index.js +78 -17
- package/dist/openrouter/index.js.map +1 -1
- package/dist/{provider-Bi0nyNhA.d.ts → provider-vTZ74u-w.d.ts} +1 -1
- package/dist/{retry-BatS2hjD.d.ts → retry-CMdT0kD8.d.ts} +1 -1
- package/dist/xai/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/google/index.d.ts
CHANGED
package/dist/http/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { D as DynamicKey, E as ExponentialBackoff, L as LinearBackoff, N as NoRetry, a as RetryAfterStrategy, R as RoundRobinKeys, T as TokenBucket, W as WeightedKeys, r as resolveApiKey } from '../retry-
|
|
2
|
-
import { P as ProviderConfig,
|
|
1
|
+
export { D as DynamicKey, E as ExponentialBackoff, L as LinearBackoff, N as NoRetry, a as RetryAfterStrategy, R as RoundRobinKeys, T as TokenBucket, W as WeightedKeys, r as resolveApiKey } from '../retry-CMdT0kD8.js';
|
|
2
|
+
import { P as ProviderConfig, M as Modality, U as UPPError, c as ErrorCode } from '../provider-vTZ74u-w.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* HTTP fetch utilities with retry, timeout, and error normalization.
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { B as BoundEmbeddingModel, g as BoundImageModel, e as EmbeddingProvider, c as ErrorCode, f as ImageProvider, K as KeyStrategy,
|
|
3
|
-
export { D as DynamicKey, E as ExponentialBackoff, L as LinearBackoff, N as NoRetry, a as RetryAfterStrategy, R as RoundRobinKeys, T as TokenBucket, W as WeightedKeys } from './retry-
|
|
1
|
+
import { P as ProviderConfig, L as LLMProvider, a as LLMHandler$1, E as EmbeddingHandler, I as ImageHandler, b as Provider } from './provider-vTZ74u-w.js';
|
|
2
|
+
export { B as BoundEmbeddingModel, g as BoundImageModel, e as EmbeddingProvider, c as ErrorCode, f as ImageProvider, K as KeyStrategy, M as Modality, d as ModelReference, R as RetryStrategy, U as UPPError } from './provider-vTZ74u-w.js';
|
|
3
|
+
export { D as DynamicKey, E as ExponentialBackoff, L as LinearBackoff, N as NoRetry, a as RetryAfterStrategy, R as RoundRobinKeys, T as TokenBucket, W as WeightedKeys } from './retry-CMdT0kD8.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* @fileoverview Content block types for multimodal messages.
|
|
@@ -1513,6 +1513,21 @@ declare class Thread {
|
|
|
1513
1513
|
* @module types/llm
|
|
1514
1514
|
*/
|
|
1515
1515
|
|
|
1516
|
+
/**
|
|
1517
|
+
* Structural type for model input that accepts any ModelReference.
|
|
1518
|
+
* Uses structural typing to avoid generic variance issues with Provider generics.
|
|
1519
|
+
* The nested types use `unknown` to accept any provider parameter types.
|
|
1520
|
+
*/
|
|
1521
|
+
type ModelInput = {
|
|
1522
|
+
readonly modelId: string;
|
|
1523
|
+
readonly provider: {
|
|
1524
|
+
readonly name: string;
|
|
1525
|
+
readonly version: string;
|
|
1526
|
+
readonly modalities: {
|
|
1527
|
+
llm?: unknown;
|
|
1528
|
+
};
|
|
1529
|
+
};
|
|
1530
|
+
};
|
|
1516
1531
|
/**
|
|
1517
1532
|
* LLM capabilities declare what a provider's API supports.
|
|
1518
1533
|
*
|
|
@@ -1547,6 +1562,8 @@ interface LLMCapabilities {
|
|
|
1547
1562
|
videoInput: boolean;
|
|
1548
1563
|
/** Provider API supports audio input in messages */
|
|
1549
1564
|
audioInput: boolean;
|
|
1565
|
+
/** Provider API supports image generation output (via modalities or built-in tools) */
|
|
1566
|
+
imageOutput?: boolean;
|
|
1550
1567
|
}
|
|
1551
1568
|
/**
|
|
1552
1569
|
* Valid input types for inference.
|
|
@@ -1575,7 +1592,7 @@ type InferenceInput = string | Message | ContentBlock;
|
|
|
1575
1592
|
*/
|
|
1576
1593
|
interface LLMOptions<TParams = unknown> {
|
|
1577
1594
|
/** A model reference from a provider factory */
|
|
1578
|
-
model:
|
|
1595
|
+
model: ModelInput;
|
|
1579
1596
|
/** Provider infrastructure configuration (optional - uses env vars if omitted) */
|
|
1580
1597
|
config?: ProviderConfig;
|
|
1581
1598
|
/** Model-specific parameters (temperature, max_tokens, etc.) */
|
|
@@ -2093,4 +2110,4 @@ declare const ai: {
|
|
|
2093
2110
|
llm: typeof llm;
|
|
2094
2111
|
};
|
|
2095
2112
|
|
|
2096
|
-
export { type AfterCallResult, type AssistantContent, AssistantMessage, type AudioBlock, type BeforeCallResult, type BinaryBlock, type BoundLLMModel, type ContentBlock, EmbeddingHandler, type EventDelta, Image, type ImageBlock, ImageHandler, type ImageSource, type InferenceInput, type JSONSchema, type JSONSchemaProperty, type JSONSchemaPropertyType, type LLMCapabilities, type LLMHandler, type LLMInstance, type LLMOptions, LLMProvider, type LLMRequest, type LLMResponse, type LLMStreamResult, Message, type MessageJSON, type MessageMetadata, type MessageOptions, type MessageType,
|
|
2113
|
+
export { type AfterCallResult, type AssistantContent, AssistantMessage, type AudioBlock, type BeforeCallResult, type BinaryBlock, type BoundLLMModel, type ContentBlock, EmbeddingHandler, type EventDelta, Image, type ImageBlock, ImageHandler, type ImageSource, type InferenceInput, type JSONSchema, type JSONSchemaProperty, type JSONSchemaPropertyType, type LLMCapabilities, type LLMHandler, type LLMInstance, type LLMOptions, LLMProvider, type LLMRequest, type LLMResponse, type LLMStreamResult, Message, type MessageJSON, type MessageMetadata, type MessageOptions, type MessageType, Provider, ProviderConfig, type StreamEvent, type StreamEventType, type StreamResult, type TextBlock, Thread, type ThreadJSON, type TokenUsage, type Tool, type ToolCall, type ToolExecution, type ToolMetadata, type ToolResult, ToolResultMessage, type ToolUseStrategy, type Turn, type UserContent, UserMessage, type VideoBlock, aggregateUsage, ai, contentBlockStart, contentBlockStop, createProvider, createStreamResult, createTurn, emptyUsage, isAssistantMessage, isAudioBlock, isBinaryBlock, isImageBlock, isTextBlock, isToolResultMessage, isUserMessage, isVideoBlock, llm, messageStart, messageStop, text, textDelta, toolCallDelta };
|
package/dist/index.js
CHANGED
|
@@ -161,7 +161,8 @@ function llm(options) {
|
|
|
161
161
|
"llm"
|
|
162
162
|
);
|
|
163
163
|
}
|
|
164
|
-
const
|
|
164
|
+
const llmHandler = provider.modalities.llm;
|
|
165
|
+
const boundModel = llmHandler.bind(modelRef.modelId);
|
|
165
166
|
const capabilities = boundModel.capabilities;
|
|
166
167
|
if (structure && !capabilities.structuredOutput) {
|
|
167
168
|
throw new UPPError(
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/turn.ts","../src/types/stream.ts","../src/core/llm.ts","../src/core/image.ts","../src/types/content.ts","../src/types/thread.ts","../src/index.ts"],"sourcesContent":["/**\n * @fileoverview Turn types for inference results.\n *\n * A Turn represents the complete result of one inference call, including\n * all messages produced during tool execution loops, token usage, and\n * optional structured output data.\n *\n * @module types/turn\n */\n\nimport type { Message, AssistantMessage } from './messages.ts';\nimport type { ToolExecution } from './tool.ts';\n\n/**\n * Token usage information for an inference request.\n *\n * Tracks input and output tokens across all inference cycles,\n * with optional per-cycle breakdown and cache metrics.\n *\n * @example\n * ```typescript\n * const usage: TokenUsage = {\n * inputTokens: 150,\n * outputTokens: 50,\n * totalTokens: 200,\n * cacheReadTokens: 100,\n * cacheWriteTokens: 50,\n * cycles: [\n * { inputTokens: 100, outputTokens: 30, cacheReadTokens: 0, cacheWriteTokens: 50 },\n * { inputTokens: 50, outputTokens: 20, cacheReadTokens: 100, cacheWriteTokens: 0 }\n * ]\n * };\n * ```\n */\nexport interface TokenUsage {\n /** Total input tokens across all cycles */\n inputTokens: number;\n\n /** Total output tokens across all cycles */\n outputTokens: number;\n\n /** Sum of input and output tokens */\n totalTokens: number;\n\n /**\n * Tokens read from cache (cache hits).\n * Returns 0 for providers that don't support or report cache metrics.\n */\n cacheReadTokens: number;\n\n /**\n * Tokens written to cache (cache misses that were cached).\n * Only Anthropic reports this metric; returns 0 for other providers.\n */\n cacheWriteTokens: number;\n\n /** Per-cycle token breakdown (if multiple cycles occurred) */\n cycles?: Array<{\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n }>;\n}\n\n/**\n * A Turn represents the complete result of one inference call.\n *\n * Includes all messages produced during tool execution loops,\n * the final assistant response, token usage, and optional\n * structured output data.\n *\n * @typeParam TData - Type of the structured output data\n *\n * @example\n * ```typescript\n * const turn = await instance.generate('Hello');\n * console.log(turn.response.text);\n * console.log(`Used ${turn.usage.totalTokens} tokens in ${turn.cycles} cycles`);\n *\n * // With structured output\n * interface WeatherData { temperature: number; conditions: string; }\n * const turn = await instance.generate<WeatherData>('Get weather');\n * console.log(turn.data?.temperature);\n * ```\n */\nexport interface Turn<TData = unknown> {\n /**\n * All messages produced during this inference, in chronological order.\n * Includes UserMessage, AssistantMessage (may include toolCalls), and ToolResultMessage.\n */\n readonly messages: Message[];\n\n /** The final assistant response (last AssistantMessage in the turn) */\n readonly response: AssistantMessage;\n\n /** Tool executions that occurred during this turn */\n readonly toolExecutions: ToolExecution[];\n\n /** Aggregate token usage for the entire turn */\n readonly usage: TokenUsage;\n\n /** Total number of inference cycles (1 + number of tool rounds) */\n readonly cycles: number;\n\n /**\n * Structured output data (if a structure schema was provided).\n * Type is inferred from the schema when using TypeScript.\n */\n readonly data?: TData;\n}\n\n/**\n * Creates a Turn from accumulated inference data.\n *\n * @typeParam TData - Type of the structured output data\n * @param messages - All messages produced during the inference\n * @param toolExecutions - Record of all tool executions\n * @param usage - Aggregate token usage\n * @param cycles - Number of inference cycles\n * @param data - Optional structured output data\n * @returns A complete Turn object\n * @throws Error if no assistant message is found in the messages\n *\n * @example\n * ```typescript\n * const turn = createTurn(\n * [userMsg, assistantMsg],\n * [],\n * { inputTokens: 100, outputTokens: 50, totalTokens: 150 },\n * 1\n * );\n * ```\n */\nexport function createTurn<TData = unknown>(\n messages: Message[],\n toolExecutions: ToolExecution[],\n usage: TokenUsage,\n cycles: number,\n data?: TData\n): Turn<TData> {\n const response = messages\n .filter((m): m is AssistantMessage => m.type === 'assistant')\n .pop();\n\n if (!response) {\n throw new Error('Turn must contain at least one assistant message');\n }\n\n return {\n messages,\n response,\n toolExecutions,\n usage,\n cycles,\n data,\n };\n}\n\n/**\n * Creates an empty TokenUsage object.\n *\n * @returns A TokenUsage with all values set to zero\n *\n * @example\n * ```typescript\n * const usage = emptyUsage();\n * // { inputTokens: 0, outputTokens: 0, totalTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, cycles: [] }\n * ```\n */\nexport function emptyUsage(): TokenUsage {\n return {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n cycles: [],\n };\n}\n\n/**\n * Aggregates token usage from multiple inference cycles.\n *\n * @param usages - Array of TokenUsage objects to aggregate\n * @returns Combined TokenUsage with per-cycle breakdown\n *\n * @example\n * ```typescript\n * const cycle1 = { inputTokens: 100, outputTokens: 30, totalTokens: 130, cacheReadTokens: 50, cacheWriteTokens: 0 };\n * const cycle2 = { inputTokens: 150, outputTokens: 40, totalTokens: 190, cacheReadTokens: 100, cacheWriteTokens: 0 };\n * const total = aggregateUsage([cycle1, cycle2]);\n * // { inputTokens: 250, outputTokens: 70, totalTokens: 320, cacheReadTokens: 150, cacheWriteTokens: 0, cycles: [...] }\n * ```\n */\nexport function aggregateUsage(usages: TokenUsage[]): TokenUsage {\n const cycles: TokenUsage['cycles'] = [];\n let inputTokens = 0;\n let outputTokens = 0;\n let cacheReadTokens = 0;\n let cacheWriteTokens = 0;\n\n for (const usage of usages) {\n inputTokens += usage.inputTokens;\n outputTokens += usage.outputTokens;\n cacheReadTokens += usage.cacheReadTokens;\n cacheWriteTokens += usage.cacheWriteTokens;\n cycles.push({\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheReadTokens: usage.cacheReadTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n });\n }\n\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n cacheReadTokens,\n cacheWriteTokens,\n cycles,\n };\n}\n","/**\n * @fileoverview Streaming types for real-time LLM responses.\n *\n * Defines the event types and interfaces for streaming LLM inference,\n * including text deltas, tool call deltas, and control events.\n *\n * @module types/stream\n */\n\nimport type { Turn } from './turn.ts';\n\n/**\n * Stream event type discriminators.\n *\n * Each event type represents a different kind of streaming update\n * from the LLM provider.\n */\nexport type StreamEventType =\n /** Incremental text output */\n | 'text_delta'\n /** Incremental reasoning/thinking output */\n | 'reasoning_delta'\n /** Incremental image data */\n | 'image_delta'\n /** Incremental audio data */\n | 'audio_delta'\n /** Incremental video data */\n | 'video_delta'\n /** Incremental tool call data (arguments being streamed) */\n | 'tool_call_delta'\n /** Tool execution has started */\n | 'tool_execution_start'\n /** Tool execution has completed */\n | 'tool_execution_end'\n /** Beginning of a message */\n | 'message_start'\n /** End of a message */\n | 'message_stop'\n /** Beginning of a content block */\n | 'content_block_start'\n /** End of a content block */\n | 'content_block_stop';\n\n/**\n * Event delta data payload.\n *\n * Contains the type-specific data for a streaming event.\n * Different fields are populated depending on the event type.\n */\nexport interface EventDelta {\n /** Incremental text content (for text_delta, reasoning_delta) */\n text?: string;\n\n /** Incremental binary data (for image_delta, audio_delta, video_delta) */\n data?: Uint8Array;\n\n /** Tool call identifier (for tool_call_delta, tool_execution_start/end) */\n toolCallId?: string;\n\n /** Tool name (for tool_call_delta, tool_execution_start/end) */\n toolName?: string;\n\n /** Incremental JSON arguments string (for tool_call_delta) */\n argumentsJson?: string;\n\n /** Tool execution result (for tool_execution_end) */\n result?: unknown;\n\n /** Whether tool execution resulted in an error (for tool_execution_end) */\n isError?: boolean;\n\n /** Timestamp in milliseconds (for tool_execution_start/end) */\n timestamp?: number;\n}\n\n/**\n * A single streaming event from the LLM.\n *\n * Events are emitted in order as the model generates output,\n * allowing for real-time display of responses.\n *\n * @example\n * ```typescript\n * for await (const event of stream) {\n * if (event.type === 'text_delta') {\n * process.stdout.write(event.delta.text ?? '');\n * } else if (event.type === 'tool_call_delta') {\n * console.log('Tool:', event.delta.toolName);\n * }\n * }\n * ```\n */\nexport interface StreamEvent {\n /** Event type discriminator */\n type: StreamEventType;\n\n /** Index of the content block this event belongs to */\n index: number;\n\n /** Event-specific data payload */\n delta: EventDelta;\n}\n\n/**\n * Stream result - an async iterable that also provides the final turn.\n *\n * Allows consuming streaming events while also awaiting the complete\n * Turn result after streaming finishes.\n *\n * @typeParam TData - Type of the structured output data\n *\n * @example\n * ```typescript\n * const stream = instance.stream('Tell me a story');\n *\n * // Consume streaming events\n * for await (const event of stream) {\n * if (event.type === 'text_delta') {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n *\n * // Get the complete turn after streaming\n * const turn = await stream.turn;\n * console.log('\\n\\nTokens used:', turn.usage.totalTokens);\n * ```\n */\nexport interface StreamResult<TData = unknown>\n extends AsyncIterable<StreamEvent> {\n /**\n * Promise that resolves to the complete Turn after streaming finishes.\n */\n readonly turn: Promise<Turn<TData>>;\n\n /**\n * Aborts the stream, stopping further events and cancelling the request.\n */\n abort(): void;\n}\n\n/**\n * Creates a StreamResult from an async generator and completion promise.\n *\n * @typeParam TData - Type of the structured output data\n * @param generator - Async generator that yields stream events\n * @param turnPromise - Promise that resolves to the complete Turn\n * @param abortController - Controller for aborting the stream\n * @returns A StreamResult that can be iterated and awaited\n *\n * @example\n * ```typescript\n * const abortController = new AbortController();\n * const stream = createStreamResult(\n * eventGenerator(),\n * turnPromise,\n * abortController\n * );\n * ```\n */\nexport function createStreamResult<TData = unknown>(\n generator: AsyncGenerator<StreamEvent, void, unknown>,\n turnPromise: Promise<Turn<TData>>,\n abortController: AbortController\n): StreamResult<TData> {\n return {\n [Symbol.asyncIterator]() {\n return generator;\n },\n turn: turnPromise,\n abort() {\n abortController.abort();\n },\n };\n}\n\n/**\n * Creates a text delta stream event.\n *\n * @param text - The incremental text content\n * @param index - Content block index (default: 0)\n * @returns A text_delta StreamEvent\n */\nexport function textDelta(text: string, index = 0): StreamEvent {\n return {\n type: 'text_delta',\n index,\n delta: { text },\n };\n}\n\n/**\n * Creates a tool call delta stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being called\n * @param argumentsJson - Incremental JSON arguments string\n * @param index - Content block index (default: 0)\n * @returns A tool_call_delta StreamEvent\n */\nexport function toolCallDelta(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n index = 0\n): StreamEvent {\n return {\n type: 'tool_call_delta',\n index,\n delta: { toolCallId, toolName, argumentsJson },\n };\n}\n\n/**\n * Creates a message start stream event.\n *\n * @returns A message_start StreamEvent\n */\nexport function messageStart(): StreamEvent {\n return {\n type: 'message_start',\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a message stop stream event.\n *\n * @returns A message_stop StreamEvent\n */\nexport function messageStop(): StreamEvent {\n return {\n type: 'message_stop',\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a content block start stream event.\n *\n * @param index - The content block index starting\n * @returns A content_block_start StreamEvent\n */\nexport function contentBlockStart(index: number): StreamEvent {\n return {\n type: 'content_block_start',\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a content block stop stream event.\n *\n * @param index - The content block index stopping\n * @returns A content_block_stop StreamEvent\n */\nexport function contentBlockStop(index: number): StreamEvent {\n return {\n type: 'content_block_stop',\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a tool execution start stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being executed\n * @param timestamp - Start timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_start StreamEvent\n */\nexport function toolExecutionStart(\n toolCallId: string,\n toolName: string,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: 'tool_execution_start',\n index,\n delta: { toolCallId, toolName, timestamp },\n };\n}\n\n/**\n * Creates a tool execution end stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool that was executed\n * @param result - The result from the tool execution\n * @param isError - Whether the execution resulted in an error\n * @param timestamp - End timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_end StreamEvent\n */\nexport function toolExecutionEnd(\n toolCallId: string,\n toolName: string,\n result: unknown,\n isError: boolean,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: 'tool_execution_end',\n index,\n delta: { toolCallId, toolName, result, isError, timestamp },\n };\n}\n","/**\n * @fileoverview LLM instance factory and streaming logic for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating and managing LLM instances,\n * including support for tool execution, streaming responses, and structured output.\n *\n * @module core/llm\n */\n\nimport type {\n LLMOptions,\n LLMInstance,\n LLMRequest,\n LLMResponse,\n InferenceInput,\n BoundLLMModel,\n LLMCapabilities,\n} from '../types/llm.ts';\nimport type { UserMessage, AssistantMessage } from '../types/messages.ts';\nimport type { ContentBlock, TextBlock } 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 } from '../types/errors.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 { generateShortId } from '../utils/id.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 = {}, params, system, tools, toolStrategy, structure } = options;\n\n // Validate that the provider supports LLM\n const provider = modelRef.provider;\n if (!provider.modalities.llm) {\n throw new UPPError(\n `Provider '${provider.name}' does not support LLM modality`,\n 'INVALID_REQUEST',\n provider.name,\n 'llm'\n );\n }\n\n // Bind the model\n const boundModel = provider.modalities.llm.bind(modelRef.modelId) as BoundLLMModel<TParams>;\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 'INVALID_REQUEST',\n provider.name,\n '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 'INVALID_REQUEST',\n provider.name,\n '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 'INVALID_REQUEST',\n provider.name,\n '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 (\n typeof value === 'object' &&\n value !== null &&\n 'timestamp' in value &&\n 'type' in value &&\n 'id' in value\n ) {\n const obj = value as Record<string, unknown>;\n const messageTypes = ['user', 'assistant', 'tool_result'];\n return messageTypes.includes(obj.type as string);\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 const block = input as ContentBlock;\n if (block.type === 'text') {\n return new UserMessageClass((block as TextBlock).text);\n }\n\n return new UserMessageClass([block as any]);\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 'INVALID_REQUEST',\n model.provider.name,\n '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\n let resolveGenerator: () => void;\n let rejectGenerator: (error: Error) => void;\n const generatorDone = new Promise<void>((resolve, reject) => {\n resolveGenerator = resolve;\n rejectGenerator = reject;\n });\n\n const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n\n async function* generateStream(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\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 signal: abortController.signal,\n };\n\n const streamResult = model.stream(request);\n\n for await (const event of streamResult) {\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 'INVALID_REQUEST',\n model.provider.name,\n '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 yield event;\n }\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n resolveGenerator();\n } catch (error) {\n generatorError = error as Error;\n rejectGenerator(error as Error);\n throw error;\n }\n }\n\n const turnPromise = (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(), turnPromise, 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 if (!tool) {\n return {\n toolCallId: call.toolCallId,\n result: `Tool '${call.toolName}' not found`,\n isError: true,\n };\n }\n\n const startTime = Date.now();\n\n onEvent?.(toolExecutionStart(call.toolCallId, tool.name, startTime, index));\n\n let effectiveParams = call.arguments;\n\n await toolStrategy?.onToolCall?.(tool, effectiveParams);\n\n if (toolStrategy?.onBeforeCall) {\n const beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);\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 const endTime = Date.now();\n onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, 'Tool execution skipped', true, endTime, index));\n return {\n toolCallId: call.toolCallId,\n result: 'Tool execution skipped',\n isError: true,\n };\n }\n if (beforeResult.params !== undefined) {\n effectiveParams = beforeResult.params as Record<string, unknown>;\n }\n } else if (!beforeResult) {\n const endTime = Date.now();\n onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, 'Tool execution skipped', true, endTime, index));\n return {\n toolCallId: call.toolCallId,\n result: 'Tool execution skipped',\n isError: true,\n };\n }\n }\n\n let approved = true;\n if (tool.approval) {\n try {\n approved = await tool.approval(effectiveParams);\n } catch (error) {\n throw error;\n }\n }\n\n if (!approved) {\n const endTime = Date.now();\n const execution: ToolExecution = {\n toolName: tool.name,\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, tool.name, '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: tool.name,\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, tool.name, 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 await toolStrategy?.onError?.(tool, effectiveParams, error as Error);\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n const execution: ToolExecution = {\n toolName: tool.name,\n toolCallId: call.toolCallId,\n arguments: effectiveParams as Record<string, unknown>,\n result: errorMessage,\n isError: true,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n\n onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, errorMessage, true, endTime, index));\n\n return {\n toolCallId: call.toolCallId,\n result: errorMessage,\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 'INVALID_REQUEST',\n providerName,\n 'llm'\n );\n }\n if (block.type === 'video' && !capabilities.videoInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support video input`,\n 'INVALID_REQUEST',\n providerName,\n 'llm'\n );\n }\n if (block.type === 'audio' && !capabilities.audioInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support audio input`,\n 'INVALID_REQUEST',\n providerName,\n 'llm'\n );\n }\n }\n }\n}\n","/**\n * @fileoverview Image content handling for the Universal Provider Protocol.\n *\n * Provides a unified Image class for working with images across different sources\n * (file paths, URLs, raw bytes, base64). Supports conversion between formats and\n * integration with UPP message content blocks.\n *\n * @module core/image\n */\n\nimport { readFile } from 'node:fs/promises';\nimport type { ImageSource, ImageBlock } from '../types/content.ts';\n\n/**\n * Represents an image that can be used in UPP messages.\n *\n * Images can be created from various sources (files, URLs, bytes, base64) and\n * converted to different formats as needed by providers. The class provides\n * a unified interface regardless of the underlying source type.\n *\n * @example\n * ```typescript\n * // Load from file\n * const fileImage = await Image.fromPath('./photo.jpg');\n *\n * // Reference by URL\n * const urlImage = Image.fromUrl('https://example.com/image.png');\n *\n * // From raw bytes\n * const bytesImage = Image.fromBytes(uint8Array, 'image/png');\n *\n * // Use in a message\n * const message = new UserMessage([image.toBlock()]);\n * ```\n */\nexport class Image {\n /** The underlying image source (bytes, base64, or URL) */\n readonly source: ImageSource;\n /** MIME type of the image (e.g., 'image/jpeg', 'image/png') */\n readonly mimeType: string;\n /** Image width in pixels, if known */\n readonly width?: number;\n /** Image height in pixels, if known */\n readonly height?: number;\n\n private constructor(\n source: ImageSource,\n mimeType: string,\n width?: number,\n height?: number\n ) {\n this.source = source;\n this.mimeType = mimeType;\n this.width = width;\n this.height = height;\n }\n\n /**\n * Whether this image has data loaded in memory.\n *\n * Returns `false` for URL-sourced images that reference external resources.\n * These must be fetched before their data can be accessed.\n */\n get hasData(): boolean {\n return this.source.type !== 'url';\n }\n\n /**\n * Converts the image to a base64-encoded string.\n *\n * @returns The image data as a base64 string\n * @throws {Error} When the source is a URL (data must be fetched first)\n */\n toBase64(): string {\n if (this.source.type === 'base64') {\n return this.source.data;\n }\n\n if (this.source.type === 'bytes') {\n return btoa(\n Array.from(this.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n }\n\n throw new Error('Cannot convert URL image to base64. Fetch the image first.');\n }\n\n /**\n * Converts the image to a data URL suitable for embedding in HTML or CSS.\n *\n * @returns A data URL in the format `data:{mimeType};base64,{data}`\n * @throws {Error} When the source is a URL (data must be fetched first)\n */\n toDataUrl(): string {\n const base64 = this.toBase64();\n return `data:${this.mimeType};base64,${base64}`;\n }\n\n /**\n * Gets the image data as raw bytes.\n *\n * @returns The image data as a Uint8Array\n * @throws {Error} When the source is a URL (data must be fetched first)\n */\n toBytes(): Uint8Array {\n if (this.source.type === 'bytes') {\n return this.source.data;\n }\n\n if (this.source.type === 'base64') {\n const binaryString = atob(this.source.data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n }\n\n throw new Error('Cannot get bytes from URL image. Fetch the image first.');\n }\n\n /**\n * Gets the URL for URL-sourced images.\n *\n * @returns The image URL\n * @throws {Error} When the source is not a URL\n */\n toUrl(): string {\n if (this.source.type === 'url') {\n return this.source.url;\n }\n\n throw new Error('This image does not have a URL source.');\n }\n\n /**\n * Converts this Image to an ImageBlock for use in UPP messages.\n *\n * @returns An ImageBlock that can be included in message content arrays\n */\n toBlock(): ImageBlock {\n return {\n type: 'image',\n source: this.source,\n mimeType: this.mimeType,\n width: this.width,\n height: this.height,\n };\n }\n\n /**\n * Creates an Image by reading a file from disk.\n *\n * The file is read into memory as bytes. MIME type is automatically\n * detected from the file extension.\n *\n * @param path - Path to the image file\n * @returns Promise resolving to an Image with the file contents\n *\n * @example\n * ```typescript\n * const image = await Image.fromPath('./photos/vacation.jpg');\n * ```\n */\n static async fromPath(path: string): Promise<Image> {\n const data = await readFile(path);\n const mimeType = detectMimeType(path);\n\n return new Image(\n { type: 'bytes', data: new Uint8Array(data) },\n mimeType\n );\n }\n\n /**\n * Creates an Image from a URL reference.\n *\n * The URL is stored as a reference and not fetched. Providers will handle\n * URL-to-data conversion if needed. MIME type is detected from the URL\n * path if not provided.\n *\n * @param url - URL pointing to the image\n * @param mimeType - Optional MIME type override\n * @returns An Image referencing the URL\n *\n * @example\n * ```typescript\n * const image = Image.fromUrl('https://example.com/logo.png');\n * ```\n */\n static fromUrl(url: string, mimeType?: string): Image {\n const detected = mimeType || detectMimeTypeFromUrl(url);\n return new Image({ type: 'url', url }, detected);\n }\n\n /**\n * Creates an Image from raw byte data.\n *\n * @param data - The image data as a Uint8Array\n * @param mimeType - The MIME type of the image\n * @returns An Image containing the byte data\n *\n * @example\n * ```typescript\n * const image = Image.fromBytes(pngData, 'image/png');\n * ```\n */\n static fromBytes(data: Uint8Array, mimeType: string): Image {\n return new Image({ type: 'bytes', data }, mimeType);\n }\n\n /**\n * Creates an Image from a base64-encoded string.\n *\n * @param base64 - The base64-encoded image data (without data URL prefix)\n * @param mimeType - The MIME type of the image\n * @returns An Image containing the base64 data\n *\n * @example\n * ```typescript\n * const image = Image.fromBase64(base64String, 'image/jpeg');\n * ```\n */\n static fromBase64(base64: string, mimeType: string): Image {\n return new Image({ type: 'base64', data: base64 }, mimeType);\n }\n\n /**\n * Creates an Image from an existing ImageBlock.\n *\n * Useful for converting content blocks received from providers back\n * into Image instances for further processing.\n *\n * @param block - An ImageBlock from message content\n * @returns An Image with the block's source and metadata\n */\n static fromBlock(block: ImageBlock): Image {\n return new Image(\n block.source,\n block.mimeType,\n block.width,\n block.height\n );\n }\n}\n\n/**\n * Detects the MIME type of an image based on its file extension.\n *\n * Supports common web image formats: JPEG, PNG, GIF, WebP, SVG, BMP, ICO.\n * Returns 'application/octet-stream' for unknown extensions.\n *\n * @param path - File path or filename with extension\n * @returns The detected MIME type string\n */\nfunction detectMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n\n switch (ext) {\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg';\n case 'png':\n return 'image/png';\n case 'gif':\n return 'image/gif';\n case 'webp':\n return 'image/webp';\n case 'svg':\n return 'image/svg+xml';\n case 'bmp':\n return 'image/bmp';\n case 'ico':\n return 'image/x-icon';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Detects the MIME type of an image from its URL.\n *\n * Extracts the pathname from the URL and delegates to `detectMimeType`.\n * Returns 'application/octet-stream' if the URL cannot be parsed.\n *\n * @param url - Full URL pointing to an image\n * @returns The detected MIME type string\n */\nfunction detectMimeTypeFromUrl(url: string): string {\n try {\n const pathname = new URL(url).pathname;\n return detectMimeType(pathname);\n } catch {\n return 'application/octet-stream';\n }\n}\n","/**\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 * 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: '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 === '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 === '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 === '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 === '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 === 'binary';\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} from './messages.ts';\nimport type { MessageType, MessageMetadata } from './messages.ts';\nimport type { ContentBlock, UserContent, AssistantContent } from './content.ts';\nimport type { Turn } from './turn.ts';\nimport type { ToolCall, ToolResult } from './tool.ts';\n\n/**\n * Serialized message format for JSON storage.\n *\n * Used when persisting messages to storage or transmitting over the network.\n */\nexport interface MessageJSON {\n /** Unique message identifier */\n id: string;\n\n /** Message type discriminator */\n type: MessageType;\n\n /** Content blocks in the message */\n content: ContentBlock[];\n\n /** Tool calls (for assistant messages) */\n toolCalls?: ToolCall[];\n\n /** Tool results (for tool result messages) */\n results?: ToolResult[];\n\n /** Provider-specific metadata */\n metadata?: MessageMetadata;\n\n /** ISO timestamp string */\n timestamp: string;\n}\n\n/**\n * Serialized thread format for JSON storage.\n *\n * Contains all data needed to reconstruct a Thread instance.\n */\nexport interface ThreadJSON {\n /** Unique thread identifier */\n id: string;\n\n /** Serialized messages */\n messages: MessageJSON[];\n\n /** ISO timestamp of thread creation */\n createdAt: string;\n\n /** ISO timestamp of last update */\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 * @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 *\n * @module @providerprotocol/ai\n * @packageDocumentation\n */\n\n/** LLM instance factory for creating model-bound inference functions */\nexport { llm } from './core/llm.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/image.ts';\n\nimport { llm } from './core/llm.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};\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":["text","newMessages"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/turn.ts","../src/types/stream.ts","../src/core/llm.ts","../src/core/image.ts","../src/types/content.ts","../src/types/thread.ts","../src/index.ts"],"sourcesContent":["/**\n * @fileoverview Turn types for inference results.\n *\n * A Turn represents the complete result of one inference call, including\n * all messages produced during tool execution loops, token usage, and\n * optional structured output data.\n *\n * @module types/turn\n */\n\nimport type { Message, AssistantMessage } from './messages.ts';\nimport type { ToolExecution } from './tool.ts';\n\n/**\n * Token usage information for an inference request.\n *\n * Tracks input and output tokens across all inference cycles,\n * with optional per-cycle breakdown and cache metrics.\n *\n * @example\n * ```typescript\n * const usage: TokenUsage = {\n * inputTokens: 150,\n * outputTokens: 50,\n * totalTokens: 200,\n * cacheReadTokens: 100,\n * cacheWriteTokens: 50,\n * cycles: [\n * { inputTokens: 100, outputTokens: 30, cacheReadTokens: 0, cacheWriteTokens: 50 },\n * { inputTokens: 50, outputTokens: 20, cacheReadTokens: 100, cacheWriteTokens: 0 }\n * ]\n * };\n * ```\n */\nexport interface TokenUsage {\n /** Total input tokens across all cycles */\n inputTokens: number;\n\n /** Total output tokens across all cycles */\n outputTokens: number;\n\n /** Sum of input and output tokens */\n totalTokens: number;\n\n /**\n * Tokens read from cache (cache hits).\n * Returns 0 for providers that don't support or report cache metrics.\n */\n cacheReadTokens: number;\n\n /**\n * Tokens written to cache (cache misses that were cached).\n * Only Anthropic reports this metric; returns 0 for other providers.\n */\n cacheWriteTokens: number;\n\n /** Per-cycle token breakdown (if multiple cycles occurred) */\n cycles?: Array<{\n inputTokens: number;\n outputTokens: number;\n cacheReadTokens: number;\n cacheWriteTokens: number;\n }>;\n}\n\n/**\n * A Turn represents the complete result of one inference call.\n *\n * Includes all messages produced during tool execution loops,\n * the final assistant response, token usage, and optional\n * structured output data.\n *\n * @typeParam TData - Type of the structured output data\n *\n * @example\n * ```typescript\n * const turn = await instance.generate('Hello');\n * console.log(turn.response.text);\n * console.log(`Used ${turn.usage.totalTokens} tokens in ${turn.cycles} cycles`);\n *\n * // With structured output\n * interface WeatherData { temperature: number; conditions: string; }\n * const turn = await instance.generate<WeatherData>('Get weather');\n * console.log(turn.data?.temperature);\n * ```\n */\nexport interface Turn<TData = unknown> {\n /**\n * All messages produced during this inference, in chronological order.\n * Includes UserMessage, AssistantMessage (may include toolCalls), and ToolResultMessage.\n */\n readonly messages: Message[];\n\n /** The final assistant response (last AssistantMessage in the turn) */\n readonly response: AssistantMessage;\n\n /** Tool executions that occurred during this turn */\n readonly toolExecutions: ToolExecution[];\n\n /** Aggregate token usage for the entire turn */\n readonly usage: TokenUsage;\n\n /** Total number of inference cycles (1 + number of tool rounds) */\n readonly cycles: number;\n\n /**\n * Structured output data (if a structure schema was provided).\n * Type is inferred from the schema when using TypeScript.\n */\n readonly data?: TData;\n}\n\n/**\n * Creates a Turn from accumulated inference data.\n *\n * @typeParam TData - Type of the structured output data\n * @param messages - All messages produced during the inference\n * @param toolExecutions - Record of all tool executions\n * @param usage - Aggregate token usage\n * @param cycles - Number of inference cycles\n * @param data - Optional structured output data\n * @returns A complete Turn object\n * @throws Error if no assistant message is found in the messages\n *\n * @example\n * ```typescript\n * const turn = createTurn(\n * [userMsg, assistantMsg],\n * [],\n * { inputTokens: 100, outputTokens: 50, totalTokens: 150 },\n * 1\n * );\n * ```\n */\nexport function createTurn<TData = unknown>(\n messages: Message[],\n toolExecutions: ToolExecution[],\n usage: TokenUsage,\n cycles: number,\n data?: TData\n): Turn<TData> {\n const response = messages\n .filter((m): m is AssistantMessage => m.type === 'assistant')\n .pop();\n\n if (!response) {\n throw new Error('Turn must contain at least one assistant message');\n }\n\n return {\n messages,\n response,\n toolExecutions,\n usage,\n cycles,\n data,\n };\n}\n\n/**\n * Creates an empty TokenUsage object.\n *\n * @returns A TokenUsage with all values set to zero\n *\n * @example\n * ```typescript\n * const usage = emptyUsage();\n * // { inputTokens: 0, outputTokens: 0, totalTokens: 0, cacheReadTokens: 0, cacheWriteTokens: 0, cycles: [] }\n * ```\n */\nexport function emptyUsage(): TokenUsage {\n return {\n inputTokens: 0,\n outputTokens: 0,\n totalTokens: 0,\n cacheReadTokens: 0,\n cacheWriteTokens: 0,\n cycles: [],\n };\n}\n\n/**\n * Aggregates token usage from multiple inference cycles.\n *\n * @param usages - Array of TokenUsage objects to aggregate\n * @returns Combined TokenUsage with per-cycle breakdown\n *\n * @example\n * ```typescript\n * const cycle1 = { inputTokens: 100, outputTokens: 30, totalTokens: 130, cacheReadTokens: 50, cacheWriteTokens: 0 };\n * const cycle2 = { inputTokens: 150, outputTokens: 40, totalTokens: 190, cacheReadTokens: 100, cacheWriteTokens: 0 };\n * const total = aggregateUsage([cycle1, cycle2]);\n * // { inputTokens: 250, outputTokens: 70, totalTokens: 320, cacheReadTokens: 150, cacheWriteTokens: 0, cycles: [...] }\n * ```\n */\nexport function aggregateUsage(usages: TokenUsage[]): TokenUsage {\n const cycles: TokenUsage['cycles'] = [];\n let inputTokens = 0;\n let outputTokens = 0;\n let cacheReadTokens = 0;\n let cacheWriteTokens = 0;\n\n for (const usage of usages) {\n inputTokens += usage.inputTokens;\n outputTokens += usage.outputTokens;\n cacheReadTokens += usage.cacheReadTokens;\n cacheWriteTokens += usage.cacheWriteTokens;\n cycles.push({\n inputTokens: usage.inputTokens,\n outputTokens: usage.outputTokens,\n cacheReadTokens: usage.cacheReadTokens,\n cacheWriteTokens: usage.cacheWriteTokens,\n });\n }\n\n return {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n cacheReadTokens,\n cacheWriteTokens,\n cycles,\n };\n}\n","/**\n * @fileoverview Streaming types for real-time LLM responses.\n *\n * Defines the event types and interfaces for streaming LLM inference,\n * including text deltas, tool call deltas, and control events.\n *\n * @module types/stream\n */\n\nimport type { Turn } from './turn.ts';\n\n/**\n * Stream event type discriminators.\n *\n * Each event type represents a different kind of streaming update\n * from the LLM provider.\n */\nexport type StreamEventType =\n /** Incremental text output */\n | 'text_delta'\n /** Incremental reasoning/thinking output */\n | 'reasoning_delta'\n /** Incremental image data */\n | 'image_delta'\n /** Incremental audio data */\n | 'audio_delta'\n /** Incremental video data */\n | 'video_delta'\n /** Incremental tool call data (arguments being streamed) */\n | 'tool_call_delta'\n /** Tool execution has started */\n | 'tool_execution_start'\n /** Tool execution has completed */\n | 'tool_execution_end'\n /** Beginning of a message */\n | 'message_start'\n /** End of a message */\n | 'message_stop'\n /** Beginning of a content block */\n | 'content_block_start'\n /** End of a content block */\n | 'content_block_stop';\n\n/**\n * Event delta data payload.\n *\n * Contains the type-specific data for a streaming event.\n * Different fields are populated depending on the event type.\n */\nexport interface EventDelta {\n /** Incremental text content (for text_delta, reasoning_delta) */\n text?: string;\n\n /** Incremental binary data (for image_delta, audio_delta, video_delta) */\n data?: Uint8Array;\n\n /** Tool call identifier (for tool_call_delta, tool_execution_start/end) */\n toolCallId?: string;\n\n /** Tool name (for tool_call_delta, tool_execution_start/end) */\n toolName?: string;\n\n /** Incremental JSON arguments string (for tool_call_delta) */\n argumentsJson?: string;\n\n /** Tool execution result (for tool_execution_end) */\n result?: unknown;\n\n /** Whether tool execution resulted in an error (for tool_execution_end) */\n isError?: boolean;\n\n /** Timestamp in milliseconds (for tool_execution_start/end) */\n timestamp?: number;\n}\n\n/**\n * A single streaming event from the LLM.\n *\n * Events are emitted in order as the model generates output,\n * allowing for real-time display of responses.\n *\n * @example\n * ```typescript\n * for await (const event of stream) {\n * if (event.type === 'text_delta') {\n * process.stdout.write(event.delta.text ?? '');\n * } else if (event.type === 'tool_call_delta') {\n * console.log('Tool:', event.delta.toolName);\n * }\n * }\n * ```\n */\nexport interface StreamEvent {\n /** Event type discriminator */\n type: StreamEventType;\n\n /** Index of the content block this event belongs to */\n index: number;\n\n /** Event-specific data payload */\n delta: EventDelta;\n}\n\n/**\n * Stream result - an async iterable that also provides the final turn.\n *\n * Allows consuming streaming events while also awaiting the complete\n * Turn result after streaming finishes.\n *\n * @typeParam TData - Type of the structured output data\n *\n * @example\n * ```typescript\n * const stream = instance.stream('Tell me a story');\n *\n * // Consume streaming events\n * for await (const event of stream) {\n * if (event.type === 'text_delta') {\n * process.stdout.write(event.delta.text ?? '');\n * }\n * }\n *\n * // Get the complete turn after streaming\n * const turn = await stream.turn;\n * console.log('\\n\\nTokens used:', turn.usage.totalTokens);\n * ```\n */\nexport interface StreamResult<TData = unknown>\n extends AsyncIterable<StreamEvent> {\n /**\n * Promise that resolves to the complete Turn after streaming finishes.\n */\n readonly turn: Promise<Turn<TData>>;\n\n /**\n * Aborts the stream, stopping further events and cancelling the request.\n */\n abort(): void;\n}\n\n/**\n * Creates a StreamResult from an async generator and completion promise.\n *\n * @typeParam TData - Type of the structured output data\n * @param generator - Async generator that yields stream events\n * @param turnPromise - Promise that resolves to the complete Turn\n * @param abortController - Controller for aborting the stream\n * @returns A StreamResult that can be iterated and awaited\n *\n * @example\n * ```typescript\n * const abortController = new AbortController();\n * const stream = createStreamResult(\n * eventGenerator(),\n * turnPromise,\n * abortController\n * );\n * ```\n */\nexport function createStreamResult<TData = unknown>(\n generator: AsyncGenerator<StreamEvent, void, unknown>,\n turnPromise: Promise<Turn<TData>>,\n abortController: AbortController\n): StreamResult<TData> {\n return {\n [Symbol.asyncIterator]() {\n return generator;\n },\n turn: turnPromise,\n abort() {\n abortController.abort();\n },\n };\n}\n\n/**\n * Creates a text delta stream event.\n *\n * @param text - The incremental text content\n * @param index - Content block index (default: 0)\n * @returns A text_delta StreamEvent\n */\nexport function textDelta(text: string, index = 0): StreamEvent {\n return {\n type: 'text_delta',\n index,\n delta: { text },\n };\n}\n\n/**\n * Creates a tool call delta stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being called\n * @param argumentsJson - Incremental JSON arguments string\n * @param index - Content block index (default: 0)\n * @returns A tool_call_delta StreamEvent\n */\nexport function toolCallDelta(\n toolCallId: string,\n toolName: string,\n argumentsJson: string,\n index = 0\n): StreamEvent {\n return {\n type: 'tool_call_delta',\n index,\n delta: { toolCallId, toolName, argumentsJson },\n };\n}\n\n/**\n * Creates a message start stream event.\n *\n * @returns A message_start StreamEvent\n */\nexport function messageStart(): StreamEvent {\n return {\n type: 'message_start',\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a message stop stream event.\n *\n * @returns A message_stop StreamEvent\n */\nexport function messageStop(): StreamEvent {\n return {\n type: 'message_stop',\n index: 0,\n delta: {},\n };\n}\n\n/**\n * Creates a content block start stream event.\n *\n * @param index - The content block index starting\n * @returns A content_block_start StreamEvent\n */\nexport function contentBlockStart(index: number): StreamEvent {\n return {\n type: 'content_block_start',\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a content block stop stream event.\n *\n * @param index - The content block index stopping\n * @returns A content_block_stop StreamEvent\n */\nexport function contentBlockStop(index: number): StreamEvent {\n return {\n type: 'content_block_stop',\n index,\n delta: {},\n };\n}\n\n/**\n * Creates a tool execution start stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool being executed\n * @param timestamp - Start timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_start StreamEvent\n */\nexport function toolExecutionStart(\n toolCallId: string,\n toolName: string,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: 'tool_execution_start',\n index,\n delta: { toolCallId, toolName, timestamp },\n };\n}\n\n/**\n * Creates a tool execution end stream event.\n *\n * @param toolCallId - Unique identifier for the tool call\n * @param toolName - Name of the tool that was executed\n * @param result - The result from the tool execution\n * @param isError - Whether the execution resulted in an error\n * @param timestamp - End timestamp in milliseconds\n * @param index - Content block index (default: 0)\n * @returns A tool_execution_end StreamEvent\n */\nexport function toolExecutionEnd(\n toolCallId: string,\n toolName: string,\n result: unknown,\n isError: boolean,\n timestamp: number,\n index = 0\n): StreamEvent {\n return {\n type: 'tool_execution_end',\n index,\n delta: { toolCallId, toolName, result, isError, timestamp },\n };\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, TextBlock } 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 } from '../types/errors.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 { generateShortId } from '../utils/id.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 = {}, params, system, tools, toolStrategy, structure } = options;\n\n // Validate that the provider supports LLM\n const provider = modelRef.provider;\n if (!provider.modalities.llm) {\n throw new UPPError(\n `Provider '${provider.name}' does not support LLM modality`,\n 'INVALID_REQUEST',\n provider.name,\n 'llm'\n );\n }\n\n // Bind the model (cast through LLMHandler since ModelInput uses unknown for variance)\n const llmHandler = provider.modalities.llm as LLMHandler<TParams>;\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 'INVALID_REQUEST',\n provider.name,\n '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 'INVALID_REQUEST',\n provider.name,\n '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 'INVALID_REQUEST',\n provider.name,\n '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 (\n typeof value === 'object' &&\n value !== null &&\n 'timestamp' in value &&\n 'type' in value &&\n 'id' in value\n ) {\n const obj = value as Record<string, unknown>;\n const messageTypes = ['user', 'assistant', 'tool_result'];\n return messageTypes.includes(obj.type as string);\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 const block = input as ContentBlock;\n if (block.type === 'text') {\n return new UserMessageClass((block as TextBlock).text);\n }\n\n return new UserMessageClass([block as any]);\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 'INVALID_REQUEST',\n model.provider.name,\n '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\n let resolveGenerator: () => void;\n let rejectGenerator: (error: Error) => void;\n const generatorDone = new Promise<void>((resolve, reject) => {\n resolveGenerator = resolve;\n rejectGenerator = reject;\n });\n\n const maxIterations = toolStrategy?.maxIterations ?? DEFAULT_MAX_ITERATIONS;\n\n async function* generateStream(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\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 signal: abortController.signal,\n };\n\n const streamResult = model.stream(request);\n\n for await (const event of streamResult) {\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 'INVALID_REQUEST',\n model.provider.name,\n '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 yield event;\n }\n\n allMessages.push(new ToolResultMessage(results));\n\n continue;\n }\n\n break;\n }\n resolveGenerator();\n } catch (error) {\n generatorError = error as Error;\n rejectGenerator(error as Error);\n throw error;\n }\n }\n\n const turnPromise = (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(), turnPromise, 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 if (!tool) {\n return {\n toolCallId: call.toolCallId,\n result: `Tool '${call.toolName}' not found`,\n isError: true,\n };\n }\n\n const startTime = Date.now();\n\n onEvent?.(toolExecutionStart(call.toolCallId, tool.name, startTime, index));\n\n let effectiveParams = call.arguments;\n\n await toolStrategy?.onToolCall?.(tool, effectiveParams);\n\n if (toolStrategy?.onBeforeCall) {\n const beforeResult = await toolStrategy.onBeforeCall(tool, effectiveParams);\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 const endTime = Date.now();\n onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, 'Tool execution skipped', true, endTime, index));\n return {\n toolCallId: call.toolCallId,\n result: 'Tool execution skipped',\n isError: true,\n };\n }\n if (beforeResult.params !== undefined) {\n effectiveParams = beforeResult.params as Record<string, unknown>;\n }\n } else if (!beforeResult) {\n const endTime = Date.now();\n onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, 'Tool execution skipped', true, endTime, index));\n return {\n toolCallId: call.toolCallId,\n result: 'Tool execution skipped',\n isError: true,\n };\n }\n }\n\n let approved = true;\n if (tool.approval) {\n try {\n approved = await tool.approval(effectiveParams);\n } catch (error) {\n throw error;\n }\n }\n\n if (!approved) {\n const endTime = Date.now();\n const execution: ToolExecution = {\n toolName: tool.name,\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, tool.name, '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: tool.name,\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, tool.name, 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 await toolStrategy?.onError?.(tool, effectiveParams, error as Error);\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n const execution: ToolExecution = {\n toolName: tool.name,\n toolCallId: call.toolCallId,\n arguments: effectiveParams as Record<string, unknown>,\n result: errorMessage,\n isError: true,\n duration: endTime - startTime,\n approved,\n };\n executions.push(execution);\n\n onEvent?.(toolExecutionEnd(call.toolCallId, tool.name, errorMessage, true, endTime, index));\n\n return {\n toolCallId: call.toolCallId,\n result: errorMessage,\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 'INVALID_REQUEST',\n providerName,\n 'llm'\n );\n }\n if (block.type === 'video' && !capabilities.videoInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support video input`,\n 'INVALID_REQUEST',\n providerName,\n 'llm'\n );\n }\n if (block.type === 'audio' && !capabilities.audioInput) {\n throw new UPPError(\n `Provider '${providerName}' does not support audio input`,\n 'INVALID_REQUEST',\n providerName,\n 'llm'\n );\n }\n }\n }\n}\n","/**\n * @fileoverview Image content handling for the Universal Provider Protocol.\n *\n * Provides a unified Image class for working with images across different sources\n * (file paths, URLs, raw bytes, base64). Supports conversion between formats and\n * integration with UPP message content blocks.\n *\n * @module core/image\n */\n\nimport { readFile } from 'node:fs/promises';\nimport type { ImageSource, ImageBlock } from '../types/content.ts';\n\n/**\n * Represents an image that can be used in UPP messages.\n *\n * Images can be created from various sources (files, URLs, bytes, base64) and\n * converted to different formats as needed by providers. The class provides\n * a unified interface regardless of the underlying source type.\n *\n * @example\n * ```typescript\n * // Load from file\n * const fileImage = await Image.fromPath('./photo.jpg');\n *\n * // Reference by URL\n * const urlImage = Image.fromUrl('https://example.com/image.png');\n *\n * // From raw bytes\n * const bytesImage = Image.fromBytes(uint8Array, 'image/png');\n *\n * // Use in a message\n * const message = new UserMessage([image.toBlock()]);\n * ```\n */\nexport class Image {\n /** The underlying image source (bytes, base64, or URL) */\n readonly source: ImageSource;\n /** MIME type of the image (e.g., 'image/jpeg', 'image/png') */\n readonly mimeType: string;\n /** Image width in pixels, if known */\n readonly width?: number;\n /** Image height in pixels, if known */\n readonly height?: number;\n\n private constructor(\n source: ImageSource,\n mimeType: string,\n width?: number,\n height?: number\n ) {\n this.source = source;\n this.mimeType = mimeType;\n this.width = width;\n this.height = height;\n }\n\n /**\n * Whether this image has data loaded in memory.\n *\n * Returns `false` for URL-sourced images that reference external resources.\n * These must be fetched before their data can be accessed.\n */\n get hasData(): boolean {\n return this.source.type !== 'url';\n }\n\n /**\n * Converts the image to a base64-encoded string.\n *\n * @returns The image data as a base64 string\n * @throws {Error} When the source is a URL (data must be fetched first)\n */\n toBase64(): string {\n if (this.source.type === 'base64') {\n return this.source.data;\n }\n\n if (this.source.type === 'bytes') {\n return btoa(\n Array.from(this.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n }\n\n throw new Error('Cannot convert URL image to base64. Fetch the image first.');\n }\n\n /**\n * Converts the image to a data URL suitable for embedding in HTML or CSS.\n *\n * @returns A data URL in the format `data:{mimeType};base64,{data}`\n * @throws {Error} When the source is a URL (data must be fetched first)\n */\n toDataUrl(): string {\n const base64 = this.toBase64();\n return `data:${this.mimeType};base64,${base64}`;\n }\n\n /**\n * Gets the image data as raw bytes.\n *\n * @returns The image data as a Uint8Array\n * @throws {Error} When the source is a URL (data must be fetched first)\n */\n toBytes(): Uint8Array {\n if (this.source.type === 'bytes') {\n return this.source.data;\n }\n\n if (this.source.type === 'base64') {\n const binaryString = atob(this.source.data);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes;\n }\n\n throw new Error('Cannot get bytes from URL image. Fetch the image first.');\n }\n\n /**\n * Gets the URL for URL-sourced images.\n *\n * @returns The image URL\n * @throws {Error} When the source is not a URL\n */\n toUrl(): string {\n if (this.source.type === 'url') {\n return this.source.url;\n }\n\n throw new Error('This image does not have a URL source.');\n }\n\n /**\n * Converts this Image to an ImageBlock for use in UPP messages.\n *\n * @returns An ImageBlock that can be included in message content arrays\n */\n toBlock(): ImageBlock {\n return {\n type: 'image',\n source: this.source,\n mimeType: this.mimeType,\n width: this.width,\n height: this.height,\n };\n }\n\n /**\n * Creates an Image by reading a file from disk.\n *\n * The file is read into memory as bytes. MIME type is automatically\n * detected from the file extension.\n *\n * @param path - Path to the image file\n * @returns Promise resolving to an Image with the file contents\n *\n * @example\n * ```typescript\n * const image = await Image.fromPath('./photos/vacation.jpg');\n * ```\n */\n static async fromPath(path: string): Promise<Image> {\n const data = await readFile(path);\n const mimeType = detectMimeType(path);\n\n return new Image(\n { type: 'bytes', data: new Uint8Array(data) },\n mimeType\n );\n }\n\n /**\n * Creates an Image from a URL reference.\n *\n * The URL is stored as a reference and not fetched. Providers will handle\n * URL-to-data conversion if needed. MIME type is detected from the URL\n * path if not provided.\n *\n * @param url - URL pointing to the image\n * @param mimeType - Optional MIME type override\n * @returns An Image referencing the URL\n *\n * @example\n * ```typescript\n * const image = Image.fromUrl('https://example.com/logo.png');\n * ```\n */\n static fromUrl(url: string, mimeType?: string): Image {\n const detected = mimeType || detectMimeTypeFromUrl(url);\n return new Image({ type: 'url', url }, detected);\n }\n\n /**\n * Creates an Image from raw byte data.\n *\n * @param data - The image data as a Uint8Array\n * @param mimeType - The MIME type of the image\n * @returns An Image containing the byte data\n *\n * @example\n * ```typescript\n * const image = Image.fromBytes(pngData, 'image/png');\n * ```\n */\n static fromBytes(data: Uint8Array, mimeType: string): Image {\n return new Image({ type: 'bytes', data }, mimeType);\n }\n\n /**\n * Creates an Image from a base64-encoded string.\n *\n * @param base64 - The base64-encoded image data (without data URL prefix)\n * @param mimeType - The MIME type of the image\n * @returns An Image containing the base64 data\n *\n * @example\n * ```typescript\n * const image = Image.fromBase64(base64String, 'image/jpeg');\n * ```\n */\n static fromBase64(base64: string, mimeType: string): Image {\n return new Image({ type: 'base64', data: base64 }, mimeType);\n }\n\n /**\n * Creates an Image from an existing ImageBlock.\n *\n * Useful for converting content blocks received from providers back\n * into Image instances for further processing.\n *\n * @param block - An ImageBlock from message content\n * @returns An Image with the block's source and metadata\n */\n static fromBlock(block: ImageBlock): Image {\n return new Image(\n block.source,\n block.mimeType,\n block.width,\n block.height\n );\n }\n}\n\n/**\n * Detects the MIME type of an image based on its file extension.\n *\n * Supports common web image formats: JPEG, PNG, GIF, WebP, SVG, BMP, ICO.\n * Returns 'application/octet-stream' for unknown extensions.\n *\n * @param path - File path or filename with extension\n * @returns The detected MIME type string\n */\nfunction detectMimeType(path: string): string {\n const ext = path.split('.').pop()?.toLowerCase();\n\n switch (ext) {\n case 'jpg':\n case 'jpeg':\n return 'image/jpeg';\n case 'png':\n return 'image/png';\n case 'gif':\n return 'image/gif';\n case 'webp':\n return 'image/webp';\n case 'svg':\n return 'image/svg+xml';\n case 'bmp':\n return 'image/bmp';\n case 'ico':\n return 'image/x-icon';\n default:\n return 'application/octet-stream';\n }\n}\n\n/**\n * Detects the MIME type of an image from its URL.\n *\n * Extracts the pathname from the URL and delegates to `detectMimeType`.\n * Returns 'application/octet-stream' if the URL cannot be parsed.\n *\n * @param url - Full URL pointing to an image\n * @returns The detected MIME type string\n */\nfunction detectMimeTypeFromUrl(url: string): string {\n try {\n const pathname = new URL(url).pathname;\n return detectMimeType(pathname);\n } catch {\n return 'application/octet-stream';\n }\n}\n","/**\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 * 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: '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 === '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 === '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 === '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 === '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 === 'binary';\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} from './messages.ts';\nimport type { MessageType, MessageMetadata } from './messages.ts';\nimport type { ContentBlock, UserContent, AssistantContent } from './content.ts';\nimport type { Turn } from './turn.ts';\nimport type { ToolCall, ToolResult } from './tool.ts';\n\n/**\n * Serialized message format for JSON storage.\n *\n * Used when persisting messages to storage or transmitting over the network.\n */\nexport interface MessageJSON {\n /** Unique message identifier */\n id: string;\n\n /** Message type discriminator */\n type: MessageType;\n\n /** Content blocks in the message */\n content: ContentBlock[];\n\n /** Tool calls (for assistant messages) */\n toolCalls?: ToolCall[];\n\n /** Tool results (for tool result messages) */\n results?: ToolResult[];\n\n /** Provider-specific metadata */\n metadata?: MessageMetadata;\n\n /** ISO timestamp string */\n timestamp: string;\n}\n\n/**\n * Serialized thread format for JSON storage.\n *\n * Contains all data needed to reconstruct a Thread instance.\n */\nexport interface ThreadJSON {\n /** Unique thread identifier */\n id: string;\n\n /** Serialized messages */\n messages: MessageJSON[];\n\n /** ISO timestamp of thread creation */\n createdAt: string;\n\n /** ISO timestamp of last update */\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 * @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 *\n * @module @providerprotocol/ai\n * @packageDocumentation\n */\n\n/** LLM instance factory for creating model-bound inference functions */\nexport { llm } from './core/llm.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/image.ts';\n\nimport { llm } from './core/llm.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};\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsIO,SAAS,WACd,UACA,gBACA,OACA,QACA,MACa;AACb,QAAM,WAAW,SACd,OAAO,CAAC,MAA6B,EAAE,SAAS,WAAW,EAC3D,IAAI;AAEP,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,kDAAkD;AAAA,EACpE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAaO,SAAS,aAAyB;AACvC,SAAO;AAAA,IACL,aAAa;AAAA,IACb,cAAc;AAAA,IACd,aAAa;AAAA,IACb,iBAAiB;AAAA,IACjB,kBAAkB;AAAA,IAClB,QAAQ,CAAC;AAAA,EACX;AACF;AAgBO,SAAS,eAAe,QAAkC;AAC/D,QAAM,SAA+B,CAAC;AACtC,MAAI,cAAc;AAClB,MAAI,eAAe;AACnB,MAAI,kBAAkB;AACtB,MAAI,mBAAmB;AAEvB,aAAW,SAAS,QAAQ;AAC1B,mBAAe,MAAM;AACrB,oBAAgB,MAAM;AACtB,uBAAmB,MAAM;AACzB,wBAAoB,MAAM;AAC1B,WAAO,KAAK;AAAA,MACV,aAAa,MAAM;AAAA,MACnB,cAAc,MAAM;AAAA,MACpB,iBAAiB,MAAM;AAAA,MACvB,kBAAkB,MAAM;AAAA,IAC1B,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,aAAa,cAAc;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AChEO,SAAS,mBACd,WACA,aACA,iBACqB;AACrB,SAAO;AAAA,IACL,CAAC,OAAO,aAAa,IAAI;AACvB,aAAO;AAAA,IACT;AAAA,IACA,MAAM;AAAA,IACN,QAAQ;AACN,sBAAgB,MAAM;AAAA,IACxB;AAAA,EACF;AACF;AASO,SAAS,UAAUA,OAAc,QAAQ,GAAgB;AAC9D,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,OAAO,EAAE,MAAAA,MAAK;AAAA,EAChB;AACF;AAWO,SAAS,cACd,YACA,UACA,eACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,cAAc;AAAA,EAC/C;AACF;AAOO,SAAS,eAA4B;AAC1C,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC;AAAA,EACV;AACF;AAOO,SAAS,cAA2B;AACzC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,IACP,OAAO,CAAC;AAAA,EACV;AACF;AAQO,SAAS,kBAAkB,OAA4B;AAC5D,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,OAAO,CAAC;AAAA,EACV;AACF;AAQO,SAAS,iBAAiB,OAA4B;AAC3D,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,OAAO,CAAC;AAAA,EACV;AACF;AAWO,SAAS,mBACd,YACA,UACA,WACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,UAAU;AAAA,EAC3C;AACF;AAaO,SAAS,iBACd,YACA,UACA,QACA,SACA,WACA,QAAQ,GACK;AACb,SAAO;AAAA,IACL,MAAM;AAAA,IACN;AAAA,IACA,OAAO,EAAE,YAAY,UAAU,QAAQ,SAAS,UAAU;AAAA,EAC5D;AACF;;;AC7QA,IAAM,yBAAyB;AA+BxB,SAAS,IACd,SACsB;AACtB,QAAM,EAAE,OAAO,UAAU,SAAS,CAAC,GAAG,QAAQ,QAAQ,OAAO,cAAc,UAAU,IAAI;AAGzF,QAAM,WAAW,SAAS;AAC1B,MAAI,CAAC,SAAS,WAAW,KAAK;AAC5B,UAAM,IAAI;AAAA,MACR,aAAa,SAAS,IAAI;AAAA,MAC1B;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGA,QAAM,aAAa,SAAS,WAAW;AACvC,QAAM,aAAa,WAAW,KAAK,SAAS,OAAO;AAGnD,QAAM,eAAe,WAAW;AAGhC,MAAI,aAAa,CAAC,aAAa,kBAAkB;AAC/C,UAAM,IAAI;AAAA,MACR,aAAa,SAAS,IAAI;AAAA,MAC1B;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGA,MAAI,SAAS,MAAM,SAAS,KAAK,CAAC,aAAa,OAAO;AACpD,UAAM,IAAI;AAAA,MACR,aAAa,SAAS,IAAI;AAAA,MAC1B;AAAA,MACA,SAAS;AAAA,MACT;AAAA,IACF;AAAA,EACF;AAGA,QAAM,WAAiC;AAAA,IACrC,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA;AAAA,IAEA,MAAM,SACJ,mBACG,QACY;AACf,YAAM,EAAE,SAAS,SAAS,IAAI,YAAY,gBAAgB,MAAM;AAChE,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IAEA,OACE,mBACG,QACW;AAEd,UAAI,CAAC,aAAa,WAAW;AAC3B,cAAM,IAAI;AAAA,UACR,aAAa,SAAS,IAAI;AAAA,UAC1B;AAAA,UACA,SAAS;AAAA,UACT;AAAA,QACF;AAAA,MACF;AACA,YAAM,EAAE,SAAS,SAAS,IAAI,YAAY,gBAAgB,MAAM;AAChE,aAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;AAWA,SAAS,kBAAkB,OAAkC;AAC3D,MAAI,iBAAiB,SAAS;AAC5B,WAAO;AAAA,EACT;AACA,MACE,OAAO,UAAU,YACjB,UAAU,QACV,eAAe,SACf,UAAU,SACV,QAAQ,OACR;AACA,UAAM,MAAM;AACZ,UAAM,eAAe,CAAC,QAAQ,aAAa,aAAa;AACxD,WAAO,aAAa,SAAS,IAAI,IAAc;AAAA,EACjD;AACA,SAAO;AACT;AAcA,SAAS,YACP,gBACA,QAC6C;AAC7C,MACE,OAAO,mBAAmB,YAC1B,mBAAmB,QACnB,cAAc,kBACd,MAAM,QAAS,eAA0B,QAAQ,GACjD;AACA,UAAM,SAAS;AACf,UAAMC,eAAc,OAAO,IAAI,cAAc;AAC7C,WAAO,EAAE,SAAS,CAAC,GAAG,OAAO,QAAQ,GAAG,UAAUA,aAAY;AAAA,EAChE;AAEA,MAAI,MAAM,QAAQ,cAAc,GAAG;AACjC,QAAI,eAAe,WAAW,GAAG;AAC/B,YAAMA,eAAc,OAAO,IAAI,cAAc;AAC7C,aAAO,EAAE,SAAS,CAAC,GAAG,UAAUA,aAAY;AAAA,IAC9C;AACA,UAAM,QAAQ,eAAe,CAAC;AAC9B,QAAI,kBAAkB,KAAK,GAAG;AAC5B,YAAMA,eAAc,OAAO,IAAI,cAAc;AAC7C,aAAO,EAAE,SAAS,gBAA6B,UAAUA,aAAY;AAAA,IACvE;AAAA,EACF;AAEA,QAAM,YAAY,CAAC,gBAAkC,GAAG,MAAM;AAC9D,QAAM,cAAc,UAAU,IAAI,cAAc;AAChD,SAAO,EAAE,SAAS,CAAC,GAAG,UAAU,YAAY;AAC9C;AAWA,SAAS,eAAe,OAAgC;AACtD,MAAI,OAAO,UAAU,UAAU;AAC7B,WAAO,IAAI,YAAiB,KAAK;AAAA,EACnC;AAEA,MAAI,UAAU,SAAS,QAAQ,SAAS,eAAe,OAAO;AAC5D,WAAO;AAAA,EACT;AAEA,QAAM,QAAQ;AACd,MAAI,MAAM,SAAS,QAAQ;AACzB,WAAO,IAAI,YAAkB,MAAoB,IAAI;AAAA,EACvD;AAEA,SAAO,IAAI,YAAiB,CAAC,KAAY,CAAC;AAC5C;AAwBA,eAAe,gBACb,OACA,QACA,QACA,QACA,OACA,cACA,WACA,SACA,aACe;AACf;AAAA,IACE,CAAC,GAAG,SAAS,GAAG,WAAW;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM,SAAS;AAAA,EACjB;AACA,QAAM,gBAAgB,cAAc,iBAAiB;AACrD,QAAM,cAAyB,CAAC,GAAG,SAAS,GAAG,WAAW;AAC1D,QAAM,iBAAkC,CAAC;AACzC,QAAM,SAAuB,CAAC;AAC9B,MAAI,SAAS;AAEb,MAAI;AAEJ,SAAO,SAAS,gBAAgB,GAAG;AACjC;AAEA,UAAM,UAA+B;AAAA,MACnC,UAAU;AAAA,MACV;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,UAAM,WAAW,MAAM,MAAM,SAAS,OAAO;AAC7C,WAAO,KAAK,SAAS,KAAK;AAC1B,gBAAY,KAAK,SAAS,OAAO;AAEjC,QAAI,SAAS,SAAS,QAAW;AAC/B,uBAAiB,SAAS;AAAA,IAC5B;AAEA,QAAI,SAAS,QAAQ,gBAAgB,SAAS,MAAM,SAAS,GAAG;AAC9D,UAAI,SAAS,SAAS,QAAW;AAC/B;AAAA,MACF;AAEA,UAAI,UAAU,eAAe;AAC3B,cAAM,cAAc,kBAAkB,aAAa;AACnD,cAAM,IAAI;AAAA,UACR,+CAA+C,aAAa;AAAA,UAC5D;AAAA,UACA,MAAM,SAAS;AAAA,UACf;AAAA,QACF;AAAA,MACF;AAEA,YAAM,UAAU,MAAM;AAAA,QACpB,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAEA,kBAAY,KAAK,IAAI,kBAAkB,OAAO,CAAC;AAE/C;AAAA,IACF;AAEA;AAAA,EACF;AAEA,QAAM,OAAO,YAAY,iBAAiB;AAE1C,SAAO;AAAA,IACL,YAAY,MAAM,QAAQ,MAAM;AAAA,IAChC;AAAA,IACA,eAAe,MAAM;AAAA,IACrB;AAAA,IACA;AAAA,EACF;AACF;AAsBA,SAAS,cACP,OACA,QACA,QACA,QACA,OACA,cACA,WACA,SACA,aACc;AACd;AAAA,IACE,CAAC,GAAG,SAAS,GAAG,WAAW;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM,SAAS;AAAA,EACjB;AAEA,QAAM,kBAAkB,IAAI,gBAAgB;AAE5C,QAAM,cAAyB,CAAC,GAAG,SAAS,GAAG,WAAW;AAC1D,QAAM,iBAAkC,CAAC;AACzC,QAAM,SAAuB,CAAC;AAC9B,MAAI,SAAS;AACb,MAAI,iBAA+B;AACnC,MAAI;AAEJ,MAAI;AACJ,MAAI;AACJ,QAAM,gBAAgB,IAAI,QAAc,CAAC,SAAS,WAAW;AAC3D,uBAAmB;AACnB,sBAAkB;AAAA,EACpB,CAAC;AAED,QAAM,gBAAgB,cAAc,iBAAiB;AAErD,kBAAgB,iBAA6D;AAC3E,QAAI;AACF,aAAO,SAAS,gBAAgB,GAAG;AACjC;AAEA,cAAM,UAA+B;AAAA,UACnC,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ,gBAAgB;AAAA,QAC1B;AAEA,cAAM,eAAe,MAAM,OAAO,OAAO;AAEzC,yBAAiB,SAAS,cAAc;AACtC,gBAAM;AAAA,QACR;AAEA,cAAM,WAAW,MAAM,aAAa;AACpC,eAAO,KAAK,SAAS,KAAK;AAC1B,oBAAY,KAAK,SAAS,OAAO;AAEjC,YAAI,SAAS,SAAS,QAAW;AAC/B,2BAAiB,SAAS;AAAA,QAC5B;AAEA,YAAI,SAAS,QAAQ,gBAAgB,SAAS,MAAM,SAAS,GAAG;AAC9D,cAAI,SAAS,SAAS,QAAW;AAC/B;AAAA,UACF;AAEA,cAAI,UAAU,eAAe;AAC3B,kBAAM,cAAc,kBAAkB,aAAa;AACnD,kBAAM,IAAI;AAAA,cACR,+CAA+C,aAAa;AAAA,cAC5D;AAAA,cACA,MAAM,SAAS;AAAA,cACf;AAAA,YACF;AAAA,UACF;AAEA,gBAAM,aAA4B,CAAC;AACnC,gBAAM,UAAU,MAAM;AAAA,YACpB,SAAS;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA,CAAC,UAAU,WAAW,KAAK,KAAK;AAAA,UAClC;AAEA,qBAAW,SAAS,YAAY;AAC9B,kBAAM;AAAA,UACR;AAEA,sBAAY,KAAK,IAAI,kBAAkB,OAAO,CAAC;AAE/C;AAAA,QACF;AAEA;AAAA,MACF;AACA,uBAAiB;AAAA,IACnB,SAAS,OAAO;AACd,uBAAiB;AACjB,sBAAgB,KAAc;AAC9B,YAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,eAAe,YAA2B;AAC9C,UAAM;AAEN,QAAI,gBAAgB;AAClB,YAAM;AAAA,IACR;AAEA,UAAM,OAAO,YAAY,iBAAiB;AAE1C,WAAO;AAAA,MACL,YAAY,MAAM,QAAQ,MAAM;AAAA,MAChC;AAAA,MACA,eAAe,MAAM;AAAA,MACrB;AAAA,MACA;AAAA,IACF;AAAA,EACF,GAAG;AAEH,SAAO,mBAAmB,eAAe,GAAG,aAAa,eAAe;AAC1E;AAmBA,eAAe,aACb,SACA,OACA,cACA,YACA,SACuB;AACvB,QAAM,YAAY,QAAQ,aAAa,CAAC;AACxC,QAAM,UAAwB,CAAC;AAE/B,QAAM,UAAU,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AAErD,QAAM,WAAW,UAAU,IAAI,OAAO,MAAM,UAAU;AACpD,UAAM,OAAO,QAAQ,IAAI,KAAK,QAAQ;AACtC,QAAI,CAAC,MAAM;AACT,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,QAAQ,SAAS,KAAK,QAAQ;AAAA,QAC9B,SAAS;AAAA,MACX;AAAA,IACF;AAEA,UAAM,YAAY,KAAK,IAAI;AAE3B,cAAU,mBAAmB,KAAK,YAAY,KAAK,MAAM,WAAW,KAAK,CAAC;AAE1E,QAAI,kBAAkB,KAAK;AAE3B,UAAM,cAAc,aAAa,MAAM,eAAe;AAEtD,QAAI,cAAc,cAAc;AAC9B,YAAM,eAAe,MAAM,aAAa,aAAa,MAAM,eAAe;AAC1E,YAAM,qBAAqB,CAAC,UAC1B,OAAO,UAAU,YAAY,UAAU,QAAQ,aAAa;AAE9D,UAAI,mBAAmB,YAAY,GAAG;AACpC,YAAI,CAAC,aAAa,SAAS;AACzB,gBAAM,UAAU,KAAK,IAAI;AACzB,oBAAU,iBAAiB,KAAK,YAAY,KAAK,MAAM,0BAA0B,MAAM,SAAS,KAAK,CAAC;AACtG,iBAAO;AAAA,YACL,YAAY,KAAK;AAAA,YACjB,QAAQ;AAAA,YACR,SAAS;AAAA,UACX;AAAA,QACF;AACA,YAAI,aAAa,WAAW,QAAW;AACrC,4BAAkB,aAAa;AAAA,QACjC;AAAA,MACF,WAAW,CAAC,cAAc;AACxB,cAAM,UAAU,KAAK,IAAI;AACzB,kBAAU,iBAAiB,KAAK,YAAY,KAAK,MAAM,0BAA0B,MAAM,SAAS,KAAK,CAAC;AACtG,eAAO;AAAA,UACL,YAAY,KAAK;AAAA,UACjB,QAAQ;AAAA,UACR,SAAS;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAEA,QAAI,WAAW;AACf,QAAI,KAAK,UAAU;AACjB,UAAI;AACF,mBAAW,MAAM,KAAK,SAAS,eAAe;AAAA,MAChD,SAAS,OAAO;AACd,cAAM;AAAA,MACR;AAAA,IACF;AAEA,QAAI,CAAC,UAAU;AACb,YAAM,UAAU,KAAK,IAAI;AACzB,YAAM,YAA2B;AAAA,QAC/B,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU,UAAU;AAAA,QACpB,UAAU;AAAA,MACZ;AACA,iBAAW,KAAK,SAAS;AAEzB,gBAAU,iBAAiB,KAAK,YAAY,KAAK,MAAM,6CAA6C,MAAM,SAAS,KAAK,CAAC;AAEzH,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAEA,QAAI;AACF,UAAI,SAAS,MAAM,KAAK,IAAI,eAAe;AAC3C,YAAM,UAAU,KAAK,IAAI;AAEzB,UAAI,cAAc,aAAa;AAC7B,cAAM,cAAc,MAAM,aAAa,YAAY,MAAM,iBAAiB,MAAM;AAChF,cAAM,oBAAoB,CAAC,UACzB,OAAO,UAAU,YAAY,UAAU,QAAQ,YAAY;AAE7D,YAAI,kBAAkB,WAAW,GAAG;AAClC,mBAAS,YAAY;AAAA,QACvB;AAAA,MACF;AAEA,YAAM,YAA2B;AAAA,QAC/B,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX;AAAA,QACA,SAAS;AAAA,QACT,UAAU,UAAU;AAAA,QACpB;AAAA,MACF;AACA,iBAAW,KAAK,SAAS;AAEzB,gBAAU,iBAAiB,KAAK,YAAY,KAAK,MAAM,QAAQ,OAAO,SAAS,KAAK,CAAC;AAErF,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF,SAAS,OAAO;AACd,YAAM,UAAU,KAAK,IAAI;AACzB,YAAM,cAAc,UAAU,MAAM,iBAAiB,KAAc;AAEnE,YAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAE1E,YAAM,YAA2B;AAAA,QAC/B,UAAU,KAAK;AAAA,QACf,YAAY,KAAK;AAAA,QACjB,WAAW;AAAA,QACX,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU,UAAU;AAAA,QACpB;AAAA,MACF;AACA,iBAAW,KAAK,SAAS;AAEzB,gBAAU,iBAAiB,KAAK,YAAY,KAAK,MAAM,cAAc,MAAM,SAAS,KAAK,CAAC;AAE1F,aAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF,CAAC;AAED,UAAQ,KAAK,GAAI,MAAM,QAAQ,IAAI,QAAQ,CAAE;AAC7C,SAAO;AACT;AAaA,SAAS,0BACP,UACA,cACA,cACM;AACN,aAAW,OAAO,UAAU;AAC1B,QAAI,CAAC,cAAc,GAAG,EAAG;AAEzB,eAAW,SAAS,IAAI,SAAS;AAC/B,UAAI,MAAM,SAAS,WAAW,CAAC,aAAa,YAAY;AACtD,cAAM,IAAI;AAAA,UACR,aAAa,YAAY;AAAA,UACzB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,UAAI,MAAM,SAAS,WAAW,CAAC,aAAa,YAAY;AACtD,cAAM,IAAI;AAAA,UACR,aAAa,YAAY;AAAA,UACzB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,UAAI,MAAM,SAAS,WAAW,CAAC,aAAa,YAAY;AACtD,cAAM,IAAI;AAAA,UACR,aAAa,YAAY;AAAA,UACzB;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;;;AC3tBA,SAAS,gBAAgB;AAyBlB,IAAM,QAAN,MAAM,OAAM;AAAA;AAAA,EAER;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA;AAAA,EAED,YACN,QACA,UACA,OACA,QACA;AACA,SAAK,SAAS;AACd,SAAK,WAAW;AAChB,SAAK,QAAQ;AACb,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAI,UAAmB;AACrB,WAAO,KAAK,OAAO,SAAS;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,WAAmB;AACjB,QAAI,KAAK,OAAO,SAAS,UAAU;AACjC,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,QAAI,KAAK,OAAO,SAAS,SAAS;AAChC,aAAO;AAAA,QACL,MAAM,KAAK,KAAK,OAAO,IAAI,EACxB,IAAI,CAAC,MAAM,OAAO,aAAa,CAAC,CAAC,EACjC,KAAK,EAAE;AAAA,MACZ;AAAA,IACF;AAEA,UAAM,IAAI,MAAM,4DAA4D;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,YAAoB;AAClB,UAAM,SAAS,KAAK,SAAS;AAC7B,WAAO,QAAQ,KAAK,QAAQ,WAAW,MAAM;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAsB;AACpB,QAAI,KAAK,OAAO,SAAS,SAAS;AAChC,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,QAAI,KAAK,OAAO,SAAS,UAAU;AACjC,YAAM,eAAe,KAAK,KAAK,OAAO,IAAI;AAC1C,YAAM,QAAQ,IAAI,WAAW,aAAa,MAAM;AAChD,eAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,cAAM,CAAC,IAAI,aAAa,WAAW,CAAC;AAAA,MACtC;AACA,aAAO;AAAA,IACT;AAEA,UAAM,IAAI,MAAM,yDAAyD;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAgB;AACd,QAAI,KAAK,OAAO,SAAS,OAAO;AAC9B,aAAO,KAAK,OAAO;AAAA,IACrB;AAEA,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAsB;AACpB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,KAAK;AAAA,MACb,UAAU,KAAK;AAAA,MACf,OAAO,KAAK;AAAA,MACZ,QAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAgBA,aAAa,SAAS,MAA8B;AAClD,UAAM,OAAO,MAAM,SAAS,IAAI;AAChC,UAAM,WAAW,eAAe,IAAI;AAEpC,WAAO,IAAI;AAAA,MACT,EAAE,MAAM,SAAS,MAAM,IAAI,WAAW,IAAI,EAAE;AAAA,MAC5C;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBA,OAAO,QAAQ,KAAa,UAA0B;AACpD,UAAM,WAAW,YAAY,sBAAsB,GAAG;AACtD,WAAO,IAAI,OAAM,EAAE,MAAM,OAAO,IAAI,GAAG,QAAQ;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAAO,UAAU,MAAkB,UAAyB;AAC1D,WAAO,IAAI,OAAM,EAAE,MAAM,SAAS,KAAK,GAAG,QAAQ;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAAO,WAAW,QAAgB,UAAyB;AACzD,WAAO,IAAI,OAAM,EAAE,MAAM,UAAU,MAAM,OAAO,GAAG,QAAQ;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,OAAO,UAAU,OAA0B;AACzC,WAAO,IAAI;AAAA,MACT,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAAA,EACF;AACF;AAWA,SAAS,eAAe,MAAsB;AAC5C,QAAM,MAAM,KAAK,MAAM,GAAG,EAAE,IAAI,GAAG,YAAY;AAE/C,UAAQ,KAAK;AAAA,IACX,KAAK;AAAA,IACL,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAWA,SAAS,sBAAsB,KAAqB;AAClD,MAAI;AACF,UAAM,WAAW,IAAI,IAAI,GAAG,EAAE;AAC9B,WAAO,eAAe,QAAQ;AAAA,EAChC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;;;AC5DO,SAAS,KAAK,SAA4B;AAC/C,SAAO,EAAE,MAAM,QAAQ,MAAM,QAAQ;AACvC;AAeO,SAAS,YAAY,OAAyC;AACnE,SAAO,MAAM,SAAS;AACxB;AAeO,SAAS,aAAa,OAA0C;AACrE,SAAO,MAAM,SAAS;AACxB;AAeO,SAAS,aAAa,OAA0C;AACrE,SAAO,MAAM,SAAS;AACxB;AAeO,SAAS,aAAa,OAA0C;AACrE,SAAO,MAAM,SAAS;AACxB;AAeO,SAAS,cAAc,OAA2C;AACvE,SAAO,MAAM,SAAS;AACxB;;;ACtOO,IAAM,SAAN,MAAM,QAAO;AAAA;AAAA,EAET;AAAA;AAAA,EAGD;AAAA;AAAA,EAGA;AAAA;AAAA,EAGA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOR,YAAY,UAAsB;AAChC,SAAK,KAAK,WAAW;AACrB,SAAK,YAAY,WAAW,CAAC,GAAG,QAAQ,IAAI,CAAC;AAC7C,SAAK,aAAa,oBAAI,KAAK;AAC3B,SAAK,aAAa,oBAAI,KAAK;AAAA,EAC7B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,WAA+B;AACjC,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAiB;AACnB,WAAO,KAAK,UAAU;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAO,MAAkB;AACvB,SAAK,UAAU,KAAK,GAAG,KAAK,QAAQ;AACpC,SAAK,aAAa,oBAAI,KAAK;AAC3B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,QAAQ,UAA2B;AACjC,SAAK,UAAU,KAAK,GAAG,QAAQ;AAC/B,SAAK,aAAa,oBAAI,KAAK;AAC3B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,KAAK,SAAuC;AAC1C,SAAK,UAAU,KAAK,IAAI,YAAY,OAAO,CAAC;AAC5C,SAAK,aAAa,oBAAI,KAAK;AAC3B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,UAAU,SAA4C;AACpD,SAAK,UAAU,KAAK,IAAI,iBAAiB,OAAO,CAAC;AACjD,SAAK,aAAa,oBAAI,KAAK;AAC3B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAAO,MAA8B;AACnC,WAAO,KAAK,UAAU,OAAO,CAAC,MAAM,EAAE,SAAS,IAAI;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,KAAK,OAA0B;AAC7B,WAAO,KAAK,UAAU,MAAM,CAAC,KAAK;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,MAAM,OAAgB,KAAsB;AAC1C,WAAO,IAAI,QAAO,KAAK,UAAU,MAAM,OAAO,GAAG,CAAC;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,QAAc;AACZ,SAAK,YAAY,CAAC;AAClB,SAAK,aAAa,oBAAI,KAAK;AAC3B,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,aAAwB;AACtB,WAAO,CAAC,GAAG,KAAK,SAAS;AAAA,EAC3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAaA,SAAqB;AACnB,WAAO;AAAA,MACL,IAAI,KAAK;AAAA,MACT,UAAU,KAAK,UAAU,IAAI,CAAC,MAAM,KAAK,cAAc,CAAC,CAAC;AAAA,MACzD,WAAW,KAAK,WAAW,YAAY;AAAA,MACvC,WAAW,KAAK,WAAW,YAAY;AAAA,IACzC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAAO,SAAS,MAA0B;AACxC,UAAM,WAAW,KAAK,SAAS,IAAI,CAAC,MAAM,QAAO,gBAAgB,CAAC,CAAC;AACnE,UAAM,SAAS,IAAI,QAAO,QAAQ;AAClC,IAAC,OAA0B,KAAK,KAAK;AACrC,WAAO,aAAa,IAAI,KAAK,KAAK,SAAS;AAC3C,WAAO,aAAa,IAAI,KAAK,KAAK,SAAS;AAC3C,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,CAAC,OAAO,QAAQ,IAAuB;AACrC,WAAO,KAAK,UAAU,OAAO,QAAQ,EAAE;AAAA,EACzC;AAAA;AAAA;AAAA;AAAA,EAKQ,cAAc,GAAyB;AAC7C,UAAM,OAAoB;AAAA,MACxB,IAAI,EAAE;AAAA,MACN,MAAM,EAAE;AAAA,MACR,SAAS,CAAC;AAAA,MACV,UAAU,EAAE;AAAA,MACZ,WAAW,EAAE,UAAU,YAAY;AAAA,IACrC;AAEA,QAAI,aAAa,aAAa;AAC5B,WAAK,UAAU,EAAE;AAAA,IACnB,WAAW,aAAa,kBAAkB;AACxC,WAAK,UAAU,EAAE;AACjB,WAAK,YAAY,EAAE;AAAA,IACrB,WAAW,aAAa,mBAAmB;AACzC,WAAK,UAAU,EAAE;AAAA,IACnB;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAe,gBAAgB,MAA4B;AACzD,UAAM,UAAU;AAAA,MACd,IAAI,KAAK;AAAA,MACT,UAAU,KAAK;AAAA,IACjB;AAEA,YAAQ,KAAK,MAAM;AAAA,MACjB,KAAK;AACH,eAAO,IAAI,YAAY,KAAK,SAA0B,OAAO;AAAA,MAC/D,KAAK;AACH,eAAO,IAAI;AAAA,UACT,KAAK;AAAA,UACL,KAAK;AAAA,UACL;AAAA,QACF;AAAA,MACF,KAAK;AACH,eAAO,IAAI,kBAAkB,KAAK,WAAW,CAAC,GAAG,OAAO;AAAA,MAC1D;AACE,cAAM,IAAI,MAAM,yBAAyB,KAAK,IAAI,EAAE;AAAA,IACxD;AAAA,EACF;AACF;;;ACtTO,IAAM,KAAK;AAAA;AAAA,EAEhB;AACF;","names":["text","newMessages"]}
|
package/dist/ollama/index.d.ts
CHANGED
package/dist/openai/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { b as Provider,
|
|
1
|
+
import { b as Provider, d as ModelReference, a as LLMHandler } from '../provider-vTZ74u-w.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @fileoverview OpenAI Provider Type Definitions
|
|
@@ -672,6 +672,7 @@ declare function computerTool(options: {
|
|
|
672
672
|
declare function imageGenerationTool(options?: {
|
|
673
673
|
background?: 'transparent' | 'opaque' | 'auto';
|
|
674
674
|
model?: string;
|
|
675
|
+
partial_images?: number;
|
|
675
676
|
quality?: 'auto' | 'high' | 'medium' | 'low';
|
|
676
677
|
size?: 'auto' | '1024x1024' | '1024x1536' | '1536x1024';
|
|
677
678
|
output_format?: 'png' | 'jpeg' | 'webp';
|