@providerprotocol/ai 0.0.20 → 0.0.21
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 +184 -14
- package/dist/anthropic/index.js +210 -82
- package/dist/anthropic/index.js.map +1 -1
- package/dist/{chunk-U3FZWV4U.js → chunk-EDENPF3E.js} +5 -2
- package/dist/{chunk-U3FZWV4U.js.map → chunk-EDENPF3E.js.map} +1 -1
- package/dist/{chunk-UMKWXGO3.js → chunk-M4BMM5IB.js} +86 -2
- package/dist/chunk-M4BMM5IB.js.map +1 -0
- package/dist/{chunk-P5IRTEM5.js → chunk-Y3GBJNA2.js} +2 -2
- package/dist/{chunk-U4JJC2YX.js → chunk-Z4ILICF5.js} +2 -2
- package/dist/chunk-Z4ILICF5.js.map +1 -0
- package/dist/google/index.d.ts +16 -19
- package/dist/google/index.js +14 -36
- package/dist/google/index.js.map +1 -1
- package/dist/http/index.d.ts +2 -2
- package/dist/http/index.js +3 -3
- package/dist/index.d.ts +101 -38
- package/dist/index.js +69 -43
- package/dist/index.js.map +1 -1
- package/dist/ollama/index.d.ts +14 -16
- package/dist/ollama/index.js +5 -7
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +25 -133
- package/dist/openai/index.js +27 -81
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +28 -53
- package/dist/openrouter/index.js +20 -43
- package/dist/openrouter/index.js.map +1 -1
- package/dist/provider-DGQHYE6I.d.ts +1319 -0
- package/dist/proxy/index.d.ts +2 -3
- package/dist/proxy/index.js +5 -7
- package/dist/proxy/index.js.map +1 -1
- package/dist/{retry-DR7YRJDz.d.ts → retry-Pcs3hnbu.d.ts} +2 -2
- package/dist/{stream-DRHy6q1a.d.ts → stream-Di9acos2.d.ts} +1 -1
- package/dist/xai/index.d.ts +16 -88
- package/dist/xai/index.js +30 -58
- package/dist/xai/index.js.map +1 -1
- package/package.json +4 -1
- package/dist/chunk-MSR5P65T.js +0 -39
- package/dist/chunk-MSR5P65T.js.map +0 -1
- package/dist/chunk-U4JJC2YX.js.map +0 -1
- package/dist/chunk-UMKWXGO3.js.map +0 -1
- package/dist/content-DEl3z_W2.d.ts +0 -276
- package/dist/image-Dhq-Yuq4.d.ts +0 -456
- package/dist/provider-BBMBZuGn.d.ts +0 -570
- /package/dist/{chunk-P5IRTEM5.js.map → chunk-Y3GBJNA2.js.map} +0 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/types/stream.ts","../src/core/llm.ts","../src/core/embedding.ts","../src/core/image.ts","../src/types/content.ts","../src/types/thread.ts","../src/index.ts"],"sourcesContent":["/**\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 Embedding instance factory for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating embedding instances\n * that generate vector embeddings from text or other content.\n *\n * @module core/embedding\n */\n\nimport type {\n EmbeddingOptions,\n EmbeddingInstance,\n EmbeddingResult,\n EmbeddingProgress,\n EmbeddingStream,\n EmbedOptions,\n Embedding,\n} from '../types/embedding.ts';\nimport type {\n EmbeddingInput,\n BoundEmbeddingModel,\n EmbeddingHandler,\n EmbeddingResponse,\n} from '../types/provider.ts';\nimport { UPPError } from '../types/errors.ts';\n\n/**\n * Creates an embedding instance configured with the specified options.\n *\n * This is the primary factory function for creating embedding instances.\n * It validates provider capabilities, binds the model, and returns an\n * instance with an `embed` method for generating embeddings.\n *\n * @typeParam TParams - Provider-specific parameter type\n * @param options - Configuration options for the embedding instance\n * @returns A configured embedding instance ready for use\n * @throws {UPPError} When the provider does not support the embedding modality\n *\n * @example\n * ```typescript\n * import { embedding } from 'upp';\n * import { openai } from 'upp/openai';\n *\n * const embedder = embedding({\n * model: openai('text-embedding-3-large'),\n * params: { dimensions: 1536 }\n * });\n *\n * // Single input\n * const result = await embedder.embed('Hello world');\n *\n * // Batch input\n * const batch = await embedder.embed(['doc1', 'doc2', 'doc3']);\n *\n * // Large-scale with progress\n * const stream = embedder.embed(documents, { chunked: true });\n * for await (const progress of stream) {\n * console.log(`${progress.percent}% complete`);\n * }\n * ```\n */\nexport function embedding<TParams = unknown>(\n options: EmbeddingOptions<TParams>\n): EmbeddingInstance<TParams> {\n const { model: modelRef, config = {}, params } = options;\n\n const provider = modelRef.provider;\n if (!provider.modalities.embedding) {\n throw new UPPError(\n `Provider '${provider.name}' does not support embedding modality`,\n 'INVALID_REQUEST',\n provider.name,\n 'embedding'\n );\n }\n\n const handler = provider.modalities.embedding as EmbeddingHandler<TParams>;\n const boundModel = handler.bind(modelRef.modelId);\n\n const instance: EmbeddingInstance<TParams> = {\n model: boundModel,\n params,\n\n embed(\n input: EmbeddingInput | EmbeddingInput[],\n embedOptions?: EmbedOptions\n ): Promise<EmbeddingResult> | EmbeddingStream {\n const inputs = Array.isArray(input) ? input : [input];\n\n if (embedOptions?.chunked) {\n return createChunkedStream(boundModel, inputs, params, config, embedOptions);\n }\n\n return executeEmbed(boundModel, inputs, params, config, embedOptions?.signal);\n },\n } as EmbeddingInstance<TParams>;\n\n return instance;\n}\n\n/**\n * Execute single embed request.\n */\nasync function executeEmbed<TParams>(\n model: BoundEmbeddingModel<TParams>,\n inputs: EmbeddingInput[],\n params: TParams | undefined,\n config: EmbeddingOptions<TParams>['config'],\n signal?: AbortSignal\n): Promise<EmbeddingResult> {\n const response = await model.embed({\n inputs,\n params,\n config: config ?? {},\n signal,\n });\n\n return normalizeResponse(response);\n}\n\n/**\n * Normalize provider response to public EmbeddingResult.\n */\nfunction normalizeResponse(response: EmbeddingResponse): EmbeddingResult {\n return {\n embeddings: response.embeddings.map((vec, i) => {\n const vector = normalizeVector(vec.vector);\n return {\n vector,\n dimensions: vector.length,\n index: vec.index ?? i,\n tokens: vec.tokens,\n metadata: vec.metadata,\n };\n }),\n usage: response.usage,\n metadata: response.metadata,\n };\n}\n\n/**\n * Normalize vector from floats or base64 string to number array.\n */\nfunction normalizeVector(vector: number[] | string): number[] {\n if (Array.isArray(vector)) {\n return vector;\n }\n return decodeBase64(vector);\n}\n\n/**\n * Decode base64-encoded float32 array.\n */\nfunction decodeBase64(b64: string): number[] {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const floats = new Float32Array(bytes.buffer);\n return Array.from(floats);\n}\n\n/**\n * Create chunked stream for large input sets.\n */\nfunction createChunkedStream<TParams>(\n model: BoundEmbeddingModel<TParams>,\n inputs: EmbeddingInput[],\n params: TParams | undefined,\n config: EmbeddingOptions<TParams>['config'],\n options: EmbedOptions\n): EmbeddingStream {\n const abortController = new AbortController();\n const batchSize = options.batchSize ?? model.maxBatchSize;\n const concurrency = options.concurrency ?? 1;\n\n let resolveResult: (result: EmbeddingResult) => void;\n let rejectResult: (error: Error) => void;\n const resultPromise = new Promise<EmbeddingResult>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n\n async function* generate(): AsyncGenerator<EmbeddingProgress> {\n const total = inputs.length;\n const allEmbeddings: Embedding[] = [];\n let totalTokens = 0;\n\n const batches: EmbeddingInput[][] = [];\n for (let i = 0; i < inputs.length; i += batchSize) {\n batches.push(inputs.slice(i, i + batchSize));\n }\n\n try {\n for (let i = 0; i < batches.length; i += concurrency) {\n if (abortController.signal.aborted || options.signal?.aborted) {\n throw new UPPError(\n 'Embedding cancelled',\n 'CANCELLED',\n model.provider.name,\n 'embedding'\n );\n }\n\n const chunk = batches.slice(i, i + concurrency);\n const responses = await Promise.all(\n chunk.map((batch) =>\n model.embed({\n inputs: batch,\n params,\n config: config ?? {},\n signal: abortController.signal,\n })\n )\n );\n\n const batchEmbeddings: Embedding[] = [];\n for (const response of responses) {\n for (const vec of response.embeddings) {\n const vector = normalizeVector(vec.vector);\n const emb: Embedding = {\n vector,\n dimensions: vector.length,\n index: allEmbeddings.length + batchEmbeddings.length,\n tokens: vec.tokens,\n metadata: vec.metadata,\n };\n batchEmbeddings.push(emb);\n }\n totalTokens += response.usage.totalTokens;\n }\n\n allEmbeddings.push(...batchEmbeddings);\n\n yield {\n embeddings: batchEmbeddings,\n completed: allEmbeddings.length,\n total,\n percent: (allEmbeddings.length / total) * 100,\n };\n }\n\n resolveResult({\n embeddings: allEmbeddings,\n usage: { totalTokens },\n });\n } catch (error) {\n rejectResult(error as Error);\n throw error;\n }\n }\n\n const generator = generate();\n\n return {\n [Symbol.asyncIterator]: () => generator,\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n}\n","/**\n * @fileoverview Image generation instance factory for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating image generation instances,\n * including support for text-to-image generation, streaming, and image editing.\n *\n * @module core/image\n */\n\nimport type {\n ImageOptions,\n ImageInstance,\n ImageInput,\n ImageEditInput,\n ImageResult,\n ImageStreamResult,\n ImageStreamEvent,\n ImageCapabilities,\n BoundImageModel,\n ImageHandler,\n} from '../types/image.ts';\nimport type { ProviderConfig } from '../types/provider.ts';\nimport { UPPError } from '../types/errors.ts';\n\n/**\n * Creates an image generation instance configured with the specified options.\n *\n * This is the primary factory function for creating image generation instances.\n * It validates provider capabilities, binds the model, and returns an instance\n * with `generate`, `stream`, and `edit` methods.\n *\n * @typeParam TParams - Provider-specific parameter type for model configuration\n * @param options - Configuration options for the image instance\n * @returns A configured image instance ready for generation\n * @throws {UPPError} When the provider does not support the image modality\n *\n * @example\n * ```typescript\n * import { image } from 'upp';\n * import { openai } from 'upp/providers/openai';\n *\n * const dalle = image({\n * model: openai('dall-e-3'),\n * params: { size: '1024x1024', quality: 'hd' }\n * });\n *\n * const result = await dalle.generate('A sunset over mountains');\n * console.log(result.images.length);\n * ```\n */\nexport function image<TParams = unknown>(\n options: ImageOptions<TParams>\n): ImageInstance<TParams> {\n const { model: modelRef, config = {}, params } = options;\n\n const provider = modelRef.provider;\n if (!provider.modalities.image) {\n throw new UPPError(\n `Provider '${provider.name}' does not support image modality`,\n 'INVALID_REQUEST',\n provider.name,\n 'image'\n );\n }\n\n const imageHandler = provider.modalities.image as ImageHandler<TParams>;\n const boundModel = imageHandler.bind(modelRef.modelId);\n\n const capabilities = boundModel.capabilities;\n\n const instance: ImageInstance<TParams> = {\n model: boundModel,\n params,\n capabilities,\n\n async generate(input: ImageInput): Promise<ImageResult> {\n const prompt = normalizeInput(input);\n\n const response = await boundModel.generate({\n prompt,\n params,\n config,\n });\n\n return {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n },\n };\n\n if (capabilities.streaming && boundModel.stream) {\n const boundModelWithStream = boundModel;\n instance.stream = function (input: ImageInput): ImageStreamResult {\n const prompt = normalizeInput(input);\n\n const abortController = new AbortController();\n const providerStream = boundModelWithStream.stream!({\n prompt,\n params,\n config,\n signal: abortController.signal,\n });\n\n const resultPromise = providerStream.response.then((response) => ({\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n }));\n\n return {\n [Symbol.asyncIterator]: () => providerStream[Symbol.asyncIterator](),\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n };\n }\n\n if (capabilities.edit && boundModel.edit) {\n const boundModelWithEdit = boundModel;\n instance.edit = async function (input: ImageEditInput): Promise<ImageResult> {\n const response = await boundModelWithEdit.edit!({\n image: input.image,\n mask: input.mask,\n prompt: input.prompt,\n params,\n config,\n });\n\n return {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n };\n }\n\n return instance;\n}\n\n/**\n * Normalizes ImageInput to a prompt string.\n *\n * @param input - Either a string prompt or object with prompt field\n * @returns The prompt string\n */\nfunction normalizeInput(input: ImageInput): string {\n if (typeof input === 'string') {\n return input;\n }\n return input.prompt;\n}\n\n/**\n * Creates an ImageStreamResult from an async generator.\n *\n * @param generator - The async generator of stream events\n * @param resultPromise - Promise resolving to final result\n * @param abortController - Controller for aborting the operation\n * @returns An ImageStreamResult\n */\nexport function createImageStreamResult(\n generator: AsyncGenerator<ImageStreamEvent, void, unknown>,\n resultPromise: Promise<ImageResult>,\n abortController: AbortController\n): ImageStreamResult {\n return {\n [Symbol.asyncIterator]: () => generator,\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n}\n","/**\n * @fileoverview 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 type MessageJSON,\n type MessageType,\n} from './messages.ts';\nimport type { UserContent, AssistantContent } from './content.ts';\nimport type { Turn } from './turn.ts';\n\n// Re-export for convenience\nexport type { MessageJSON };\n\n/**\n * Thread serialized to JSON format.\n * Picks id from Thread, converts dates to strings.\n */\nexport type ThreadJSON = Pick<Thread, 'id'> & {\n messages: MessageJSON[];\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * Thread - A utility class for managing conversation history.\n *\n * Provides methods for building, manipulating, and persisting\n * conversation message sequences. This class is optional; users\n * can also manage their own `Message[]` arrays directly.\n *\n * @example\n * ```typescript\n * // Create a new thread and add messages\n * const thread = new Thread();\n * thread.user('Hello!');\n * thread.assistant('Hi there! How can I help?');\n *\n * // Use with LLM inference\n * const turn = await instance.generate(thread, 'What is 2+2?');\n * thread.append(turn);\n *\n * // Serialize for storage\n * const json = thread.toJSON();\n * localStorage.setItem('chat', JSON.stringify(json));\n *\n * // Restore from storage\n * const restored = Thread.fromJSON(JSON.parse(localStorage.getItem('chat')));\n * ```\n */\nexport class Thread {\n /** Unique thread identifier */\n readonly id: string;\n\n /** Internal message storage */\n private _messages: Message[];\n\n /** Creation timestamp */\n private _createdAt: Date;\n\n /** Last update timestamp */\n private _updatedAt: Date;\n\n /**\n * Creates a new thread instance.\n *\n * @param messages - Optional initial messages to populate the thread\n */\n constructor(messages?: Message[]) {\n this.id = generateId();\n this._messages = messages ? [...messages] : [];\n this._createdAt = new Date();\n this._updatedAt = new Date();\n }\n\n /**\n * All messages in the thread (readonly).\n */\n get messages(): readonly Message[] {\n return this._messages;\n }\n\n /**\n * Number of messages in the thread.\n */\n get length(): number {\n return this._messages.length;\n }\n\n /**\n * Appends all messages from a Turn to the thread.\n *\n * @param turn - The Turn containing messages to append\n * @returns This thread instance for chaining\n */\n append(turn: Turn): this {\n this._messages.push(...turn.messages);\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds raw messages to the thread.\n *\n * @param messages - Messages to add\n * @returns This thread instance for chaining\n */\n push(...messages: Message[]): this {\n this._messages.push(...messages);\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds a user message to the thread.\n *\n * @param content - String or array of content blocks\n * @returns This thread instance for chaining\n *\n * @example\n * ```typescript\n * thread.user('Hello, world!');\n * thread.user([\n * { type: 'text', text: 'Describe this image:' },\n * { type: 'image', source: { type: 'url', url: '...' }, mimeType: 'image/png' }\n * ]);\n * ```\n */\n user(content: string | UserContent[]): this {\n this._messages.push(new UserMessage(content));\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds an assistant message to the thread.\n *\n * @param content - String or array of content blocks\n * @returns This thread instance for chaining\n *\n * @example\n * ```typescript\n * thread.assistant('I can help with that!');\n * ```\n */\n assistant(content: string | AssistantContent[]): this {\n this._messages.push(new AssistantMessage(content));\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Filters messages by type.\n *\n * @param type - The message type to filter by\n * @returns Array of messages matching the type\n *\n * @example\n * ```typescript\n * const userMessages = thread.filter('user');\n * const assistantMessages = thread.filter('assistant');\n * ```\n */\n filter(type: MessageType): Message[] {\n return this._messages.filter((m) => m.type === type);\n }\n\n /**\n * Returns the last N messages from the thread.\n *\n * @param count - Number of messages to return\n * @returns Array of the last N messages\n *\n * @example\n * ```typescript\n * const recent = thread.tail(5);\n * ```\n */\n tail(count: number): Message[] {\n return this._messages.slice(-count);\n }\n\n /**\n * Creates a new thread with a subset of messages.\n *\n * @param start - Start index (inclusive)\n * @param end - End index (exclusive)\n * @returns New Thread containing the sliced messages\n *\n * @example\n * ```typescript\n * const subset = thread.slice(0, 10);\n * ```\n */\n slice(start?: number, end?: number): Thread {\n return new Thread(this._messages.slice(start, end));\n }\n\n /**\n * Removes all messages from the thread.\n *\n * @returns This thread instance for chaining\n */\n clear(): this {\n this._messages = [];\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Converts the thread to a plain message array.\n *\n * @returns Copy of the internal message array\n */\n toMessages(): Message[] {\n return [...this._messages];\n }\n\n /**\n * Serializes the thread to JSON format.\n *\n * @returns JSON-serializable representation of the thread\n *\n * @example\n * ```typescript\n * const json = thread.toJSON();\n * localStorage.setItem('thread', JSON.stringify(json));\n * ```\n */\n toJSON(): ThreadJSON {\n return {\n id: this.id,\n messages: this._messages.map((m) => this.messageToJSON(m)),\n createdAt: this._createdAt.toISOString(),\n updatedAt: this._updatedAt.toISOString(),\n };\n }\n\n /**\n * Deserializes a thread from JSON format.\n *\n * @param json - The JSON representation to deserialize\n * @returns Reconstructed Thread instance\n *\n * @example\n * ```typescript\n * const json = JSON.parse(localStorage.getItem('thread'));\n * const thread = Thread.fromJSON(json);\n * ```\n */\n static fromJSON(json: ThreadJSON): Thread {\n const messages = json.messages.map((m) => Thread.messageFromJSON(m));\n const thread = new Thread(messages);\n (thread as { id: string }).id = json.id;\n thread._createdAt = new Date(json.createdAt);\n thread._updatedAt = new Date(json.updatedAt);\n return thread;\n }\n\n /**\n * Enables iteration over messages with for...of loops.\n *\n * @returns Iterator over the thread's messages\n *\n * @example\n * ```typescript\n * for (const message of thread) {\n * console.log(message.text);\n * }\n * ```\n */\n [Symbol.iterator](): Iterator<Message> {\n return this._messages[Symbol.iterator]();\n }\n\n /**\n * Converts a message to JSON format.\n */\n private messageToJSON(m: Message): MessageJSON {\n const base: MessageJSON = {\n id: m.id,\n type: m.type,\n content: [],\n metadata: m.metadata,\n timestamp: m.timestamp.toISOString(),\n };\n\n if (m instanceof UserMessage) {\n base.content = m.content;\n } else if (m instanceof AssistantMessage) {\n base.content = m.content;\n base.toolCalls = m.toolCalls;\n } else if (m instanceof ToolResultMessage) {\n base.results = m.results;\n }\n\n return base;\n }\n\n /**\n * Reconstructs a message from JSON format.\n */\n private static messageFromJSON(json: MessageJSON): Message {\n const options = {\n id: json.id,\n metadata: json.metadata,\n };\n\n switch (json.type) {\n case 'user':\n return new UserMessage(json.content as UserContent[], options);\n case 'assistant':\n return new AssistantMessage(\n json.content as AssistantContent[],\n json.toolCalls,\n options\n );\n case 'tool_result':\n return new ToolResultMessage(json.results ?? [], options);\n default:\n throw new Error(`Unknown message type: ${json.type}`);\n }\n }\n}\n","/**\n * @fileoverview Unified Provider Protocol (UPP) - A unified interface for AI model inference\n *\n * UPP provides a consistent API for interacting with multiple AI providers including\n * Anthropic, OpenAI, Google, Ollama, OpenRouter, and xAI. The library handles provider-specific\n * transformations, streaming, tool execution, and error handling.\n *\n * @module @providerprotocol/ai\n * @packageDocumentation\n */\n\n/**\n * LLM instance factory for creating model-bound inference functions.\n *\n * @example Basic usage\n * ```typescript\n * import { llm, anthropic } from '@providerprotocol/ai';\n *\n * const model = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * params: { max_tokens: 1000 }\n * });\n *\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Streaming\n * ```typescript\n * for await (const event of model.stream('Tell me a story')) {\n * if (event.type === 'text') {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n */\nexport { llm } from './core/llm.ts';\n\n/** Embedding instance factory for creating model-bound embedding functions */\nexport { embedding } from './core/embedding.ts';\n\n/** Image generation instance factory for creating model-bound image functions */\nexport { image } from './core/image.ts';\n\n/** Factory for creating custom providers */\nexport { createProvider } from './core/provider.ts';\n\n/** Image content wrapper for multimodal inputs */\nexport { Image } from './core/media/Image.ts';\n\nimport { llm } from './core/llm.ts';\nimport { embedding } from './core/embedding.ts';\nimport { image } from './core/image.ts';\n\n/**\n * UPP namespace object providing alternative import style.\n *\n * @example\n * ```typescript\n * import { ai } from '@providerprotocol/ai';\n *\n * const model = ai.llm({\n * model: openai('gpt-4o'),\n * params: { max_tokens: 1000 }\n * });\n * ```\n */\nexport const ai = {\n /** LLM instance factory */\n llm,\n /** Embedding instance factory */\n embedding,\n /** Image generation instance factory */\n image,\n};\n\nexport * from './types/index.ts';\n\nexport {\n RoundRobinKeys,\n WeightedKeys,\n DynamicKey,\n ExponentialBackoff,\n LinearBackoff,\n NoRetry,\n TokenBucket,\n RetryAfterStrategy,\n} from './http/index.ts';\n"],"mappings":"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","names":["text","newMessages"]}
|
|
1
|
+
{"version":3,"sources":["../src/types/stream.ts","../src/core/llm.ts","../src/core/embedding.ts","../src/core/image.ts","../src/types/content.ts","../src/types/thread.ts","../src/index.ts"],"sourcesContent":["/**\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 { resolveLLMHandler } from './provider-handlers.ts';\nimport {\n Message,\n UserMessage as UserMessageClass,\n ToolResultMessage,\n isUserMessage,\n isAssistantMessage,\n} from '../types/messages.ts';\nimport { createTurn, aggregateUsage, emptyUsage } from '../types/turn.ts';\nimport {\n createStreamResult,\n toolExecutionStart,\n toolExecutionEnd,\n} from '../types/stream.ts';\nimport { 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: explicitConfig = {}, params, system, tools, toolStrategy, structure } = options;\n\n // Merge providerConfig from model reference with explicit config\n // Explicit config takes precedence, with headers being deep-merged\n const providerConfig = modelRef.providerConfig ?? {};\n const config: ProviderConfig = {\n ...providerConfig,\n ...explicitConfig,\n headers: {\n ...providerConfig.headers,\n ...explicitConfig.headers,\n },\n };\n\n // Resolve the correct LLM handler based on model reference options\n // This handles providers with multiple handlers (e.g., OpenAI responses/completions)\n // Cast is safe: ModelInput uses structural typing with unknown for variance, but the\n // actual provider at runtime is a proper Provider with LLMHandler\n const provider = modelRef.provider;\n const llmHandler = resolveLLMHandler(provider, modelRef.options) as LLMHandler<TParams> | undefined;\n\n if (!llmHandler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support LLM modality`,\n 'INVALID_REQUEST',\n provider.name,\n 'llm'\n );\n }\n\n // Bind the model\n const boundModel = llmHandler.bind(modelRef.modelId);\n\n // Validate capabilities at bind time\n const capabilities = boundModel.capabilities;\n\n // Check for structured output capability\n if (structure && !capabilities.structuredOutput) {\n throw new UPPError(\n `Provider '${provider.name}' does not support structured output`,\n '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]);\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 // Check if already aborted before starting\n if (abortController.signal.aborted) {\n throw new UPPError('Stream cancelled', 'CANCELLED', model.provider.name, 'llm');\n }\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 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 Embedding instance factory for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating embedding instances\n * that generate vector embeddings from text or other content.\n *\n * @module core/embedding\n */\n\nimport type {\n EmbeddingOptions,\n EmbeddingInstance,\n EmbeddingResult,\n EmbeddingProgress,\n EmbeddingStream,\n EmbedOptions,\n Embedding,\n} from '../types/embedding.ts';\nimport type {\n EmbeddingInput,\n BoundEmbeddingModel,\n EmbeddingResponse,\n} from '../types/provider.ts';\nimport { UPPError } from '../types/errors.ts';\nimport { resolveEmbeddingHandler } from './provider-handlers.ts';\n\n/**\n * Creates an embedding instance configured with the specified options.\n *\n * This is the primary factory function for creating embedding instances.\n * It validates provider capabilities, binds the model, and returns an\n * instance with an `embed` method for generating embeddings.\n *\n * @typeParam TParams - Provider-specific parameter type\n * @param options - Configuration options for the embedding instance\n * @returns A configured embedding instance ready for use\n * @throws {UPPError} When the provider does not support the embedding modality\n *\n * @example\n * ```typescript\n * import { embedding } from 'upp';\n * import { openai } from 'upp/openai';\n *\n * const embedder = embedding({\n * model: openai('text-embedding-3-large'),\n * params: { dimensions: 1536 }\n * });\n *\n * // Single input\n * const result = await embedder.embed('Hello world');\n *\n * // Batch input\n * const batch = await embedder.embed(['doc1', 'doc2', 'doc3']);\n *\n * // Large-scale with progress\n * const stream = embedder.embed(documents, { chunked: true });\n * for await (const progress of stream) {\n * console.log(`${progress.percent}% complete`);\n * }\n * ```\n */\nexport function embedding<TParams = unknown>(\n options: EmbeddingOptions<TParams>\n): EmbeddingInstance<TParams> {\n const { model: modelRef, config = {}, params } = options;\n\n const provider = modelRef.provider;\n const handler = resolveEmbeddingHandler<TParams>(provider);\n if (!handler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support embedding modality`,\n 'INVALID_REQUEST',\n provider.name,\n 'embedding'\n );\n }\n\n const boundModel = handler.bind(modelRef.modelId);\n\n function embed(\n input: EmbeddingInput | EmbeddingInput[],\n embedOptions?: EmbedOptions & { chunked?: false }\n ): Promise<EmbeddingResult>;\n function embed(\n input: EmbeddingInput[],\n embedOptions: EmbedOptions & { chunked: true }\n ): EmbeddingStream;\n function embed(\n input: EmbeddingInput | EmbeddingInput[],\n embedOptions?: EmbedOptions\n ): Promise<EmbeddingResult> | EmbeddingStream {\n const inputs = Array.isArray(input) ? input : [input];\n\n if (embedOptions?.chunked) {\n return createChunkedStream(boundModel, inputs, params, config, embedOptions);\n }\n\n return executeEmbed(boundModel, inputs, params, config, embedOptions?.signal);\n }\n\n return {\n model: boundModel,\n params,\n embed,\n };\n}\n\n/**\n * Execute single embed request.\n *\n * @param model - Bound embedding model\n * @param inputs - Input batch\n * @param params - Provider-specific params\n * @param config - Provider configuration\n * @param signal - Abort signal\n * @returns Normalized embedding result\n */\nasync function executeEmbed<TParams>(\n model: BoundEmbeddingModel<TParams>,\n inputs: EmbeddingInput[],\n params: TParams | undefined,\n config: EmbeddingOptions<TParams>['config'],\n signal?: AbortSignal\n): Promise<EmbeddingResult> {\n const response = await model.embed({\n inputs,\n params,\n config: config ?? {},\n signal,\n });\n\n return normalizeResponse(response, model.provider.name);\n}\n\n/**\n * Normalize provider response to public EmbeddingResult.\n *\n * @param response - Provider response\n * @param providerName - Provider name for error reporting\n * @returns Normalized embedding result\n */\nfunction normalizeResponse(response: EmbeddingResponse, providerName: string): EmbeddingResult {\n return {\n embeddings: response.embeddings.map((vec, i) => {\n const vector = normalizeVector(vec.vector, providerName);\n return {\n vector,\n dimensions: vector.length,\n index: vec.index ?? i,\n tokens: vec.tokens,\n metadata: vec.metadata,\n };\n }),\n usage: response.usage,\n metadata: response.metadata,\n };\n}\n\n/**\n * Normalize vector from floats or base64 string to number array.\n *\n * @param vector - Float vector or base64 string\n * @param providerName - Provider name for error reporting\n * @returns Normalized float array\n */\nfunction normalizeVector(vector: number[] | string, providerName: string): number[] {\n if (Array.isArray(vector)) {\n return vector;\n }\n return decodeBase64(vector, providerName);\n}\n\n/**\n * Decode base64-encoded float32 array.\n *\n * @param b64 - Base64-encoded float32 buffer\n * @param providerName - Provider name for error reporting\n * @returns Decoded float array\n */\nfunction decodeBase64(b64: string, providerName: string): number[] {\n try {\n const binary = atob(b64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n const floats = new Float32Array(bytes.buffer);\n return Array.from(floats);\n } catch (error) {\n const cause = error instanceof Error ? error : new Error('Failed to decode base64 vector');\n throw new UPPError(\n 'Invalid base64 embedding vector',\n 'INVALID_RESPONSE',\n providerName,\n 'embedding',\n undefined,\n cause\n );\n }\n}\n\n/**\n * Create chunked stream for large input sets.\n *\n * @param model - Bound embedding model\n * @param inputs - All embedding inputs\n * @param params - Provider-specific params\n * @param config - Provider configuration\n * @param options - Chunked stream options\n * @returns Embedding stream with progress updates\n */\nfunction createChunkedStream<TParams>(\n model: BoundEmbeddingModel<TParams>,\n inputs: EmbeddingInput[],\n params: TParams | undefined,\n config: EmbeddingOptions<TParams>['config'],\n options: EmbedOptions\n): EmbeddingStream {\n const abortController = new AbortController();\n const batchSize = options.batchSize ?? model.maxBatchSize;\n const concurrency = options.concurrency ?? 1;\n\n let resolveResult: (result: EmbeddingResult) => void;\n let rejectResult: (error: Error) => void;\n const resultPromise = new Promise<EmbeddingResult>((resolve, reject) => {\n resolveResult = resolve;\n rejectResult = reject;\n });\n\n async function* generate(): AsyncGenerator<EmbeddingProgress> {\n const total = inputs.length;\n const allEmbeddings: Embedding[] = [];\n let totalTokens = 0;\n\n const batches: EmbeddingInput[][] = [];\n for (let i = 0; i < inputs.length; i += batchSize) {\n batches.push(inputs.slice(i, i + batchSize));\n }\n\n try {\n for (let i = 0; i < batches.length; i += concurrency) {\n if (abortController.signal.aborted || options.signal?.aborted) {\n throw new UPPError(\n 'Embedding cancelled',\n 'CANCELLED',\n model.provider.name,\n 'embedding'\n );\n }\n\n const chunk = batches.slice(i, i + concurrency);\n const responses = await Promise.all(\n chunk.map((batch) =>\n model.embed({\n inputs: batch,\n params,\n config: config ?? {},\n signal: abortController.signal,\n })\n )\n );\n\n const batchEmbeddings: Embedding[] = [];\n for (const response of responses) {\n for (const vec of response.embeddings) {\n const vector = normalizeVector(vec.vector, model.provider.name);\n const emb: Embedding = {\n vector,\n dimensions: vector.length,\n index: allEmbeddings.length + batchEmbeddings.length,\n tokens: vec.tokens,\n metadata: vec.metadata,\n };\n batchEmbeddings.push(emb);\n }\n totalTokens += response.usage.totalTokens;\n }\n\n allEmbeddings.push(...batchEmbeddings);\n\n yield {\n embeddings: batchEmbeddings,\n completed: allEmbeddings.length,\n total,\n percent: (allEmbeddings.length / total) * 100,\n };\n }\n\n resolveResult({\n embeddings: allEmbeddings,\n usage: { totalTokens },\n });\n } catch (error) {\n rejectResult(error as Error);\n throw error;\n }\n }\n\n const generator = generate();\n\n return {\n [Symbol.asyncIterator]: () => generator,\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n}\n","/**\n * @fileoverview Image generation instance factory for the Universal Provider Protocol.\n *\n * This module provides the core functionality for creating image generation instances,\n * including support for text-to-image generation, streaming, and image editing.\n *\n * @module core/image\n */\n\nimport type {\n ImageOptions,\n ImageInstance,\n ImageInput,\n ImageEditInput,\n ImageResult,\n ImageStreamResult,\n ImageStreamEvent,\n ImageCapabilities,\n BoundImageModel,\n ImageGenerateOptions,\n} from '../types/image.ts';\nimport { UPPError } from '../types/errors.ts';\nimport { resolveImageHandler } from './provider-handlers.ts';\n\n/**\n * Creates an image generation instance configured with the specified options.\n *\n * This is the primary factory function for creating image generation instances.\n * It validates provider capabilities, binds the model, and returns an instance\n * with `generate`, `stream`, and `edit` methods.\n *\n * @typeParam TParams - Provider-specific parameter type for model configuration\n * @param options - Configuration options for the image instance\n * @returns A configured image instance ready for generation\n * @throws {UPPError} When the provider does not support the image modality\n *\n * @example\n * ```typescript\n * import { image } from 'upp';\n * import { openai } from 'upp/providers/openai';\n *\n * const dalle = image({\n * model: openai('dall-e-3'),\n * params: { size: '1024x1024', quality: 'hd' }\n * });\n *\n * const result = await dalle.generate('A sunset over mountains');\n * console.log(result.images.length);\n * ```\n */\nexport function image<TParams = unknown>(\n options: ImageOptions<TParams>\n): ImageInstance<TParams> {\n const { model: modelRef, config = {}, params } = options;\n\n const provider = modelRef.provider;\n const imageHandler = resolveImageHandler<TParams>(provider);\n if (!imageHandler) {\n throw new UPPError(\n `Provider '${provider.name}' does not support image modality`,\n 'INVALID_REQUEST',\n provider.name,\n 'image'\n );\n }\n\n const boundModel = imageHandler.bind(modelRef.modelId);\n\n const capabilities = boundModel.capabilities;\n\n const instance: ImageInstance<TParams> = {\n model: boundModel,\n params,\n capabilities,\n\n async generate(input: ImageInput, options?: ImageGenerateOptions): Promise<ImageResult> {\n const prompt = normalizeInput(input);\n\n const response = await boundModel.generate({\n prompt,\n params,\n config,\n signal: options?.signal,\n });\n\n return {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n },\n };\n\n if (capabilities.streaming && boundModel.stream) {\n const stream = boundModel.stream;\n instance.stream = function (input: ImageInput): ImageStreamResult {\n const prompt = normalizeInput(input);\n\n const abortController = new AbortController();\n const providerStream = stream({\n prompt,\n params,\n config,\n signal: abortController.signal,\n });\n\n const resultPromise = providerStream.response.then((response) => ({\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n }));\n\n return {\n [Symbol.asyncIterator]: () => providerStream[Symbol.asyncIterator](),\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n };\n }\n\n if (capabilities.edit && boundModel.edit) {\n const edit = boundModel.edit;\n instance.edit = async function (input: ImageEditInput): Promise<ImageResult> {\n const response = await edit({\n image: input.image,\n mask: input.mask,\n prompt: input.prompt,\n params,\n config,\n });\n\n return {\n images: response.images,\n metadata: response.metadata,\n usage: response.usage,\n };\n };\n }\n\n return instance;\n}\n\n/**\n * Normalizes ImageInput to a prompt string.\n *\n * @param input - Either a string prompt or object with prompt field\n * @returns The prompt string\n */\nfunction normalizeInput(input: ImageInput): string {\n if (typeof input === 'string') {\n return input;\n }\n return input.prompt;\n}\n\n/**\n * Creates an ImageStreamResult from an async generator.\n *\n * @param generator - The async generator of stream events\n * @param resultPromise - Promise resolving to final result\n * @param abortController - Controller for aborting the operation\n * @returns An ImageStreamResult\n */\nexport function createImageStreamResult(\n generator: AsyncGenerator<ImageStreamEvent, void, unknown>,\n resultPromise: Promise<ImageResult>,\n abortController: AbortController\n): ImageStreamResult {\n return {\n [Symbol.asyncIterator]: () => generator,\n result: resultPromise,\n abort: () => abortController.abort(),\n };\n}\n","/**\n * @fileoverview 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 type MessageJSON,\n type MessageType,\n} from './messages.ts';\nimport type { UserContent, AssistantContent } from './content.ts';\nimport type { Turn } from './turn.ts';\n\n// Re-export for convenience\nexport type { MessageJSON };\n\n/**\n * Thread serialized to JSON format.\n * Picks id from Thread, converts dates to strings.\n */\nexport type ThreadJSON = Pick<Thread, 'id'> & {\n messages: MessageJSON[];\n createdAt: string;\n updatedAt: string;\n};\n\n/**\n * Thread - A utility class for managing conversation history.\n *\n * Provides methods for building, manipulating, and persisting\n * conversation message sequences. This class is optional; users\n * can also manage their own `Message[]` arrays directly.\n *\n * @example\n * ```typescript\n * // Create a new thread and add messages\n * const thread = new Thread();\n * thread.user('Hello!');\n * thread.assistant('Hi there! How can I help?');\n *\n * // Use with LLM inference\n * const turn = await instance.generate(thread, 'What is 2+2?');\n * thread.append(turn);\n *\n * // Serialize for storage\n * const json = thread.toJSON();\n * localStorage.setItem('chat', JSON.stringify(json));\n *\n * // Restore from storage\n * const restored = Thread.fromJSON(JSON.parse(localStorage.getItem('chat')));\n * ```\n */\nexport class Thread {\n /** Unique thread identifier */\n readonly id: string;\n\n /** Internal message storage */\n private _messages: Message[];\n\n /** Creation timestamp */\n private _createdAt: Date;\n\n /** Last update timestamp */\n private _updatedAt: Date;\n\n /**\n * Creates a new thread instance.\n *\n * @param messages - Optional initial messages to populate the thread\n */\n constructor(messages?: Message[]) {\n this.id = generateId();\n this._messages = messages ? [...messages] : [];\n this._createdAt = new Date();\n this._updatedAt = new Date();\n }\n\n /**\n * All messages in the thread (readonly).\n */\n get messages(): readonly Message[] {\n return this._messages;\n }\n\n /**\n * Number of messages in the thread.\n */\n get length(): number {\n return this._messages.length;\n }\n\n /**\n * Appends all messages from a Turn to the thread.\n *\n * @param turn - The Turn containing messages to append\n * @returns This thread instance for chaining\n */\n append(turn: Turn): this {\n this._messages.push(...turn.messages);\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds raw messages to the thread.\n *\n * @param messages - Messages to add\n * @returns This thread instance for chaining\n */\n push(...messages: Message[]): this {\n this._messages.push(...messages);\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds a user message to the thread.\n *\n * @param content - String or array of content blocks\n * @returns This thread instance for chaining\n *\n * @example\n * ```typescript\n * thread.user('Hello, world!');\n * thread.user([\n * { type: 'text', text: 'Describe this image:' },\n * { type: 'image', source: { type: 'url', url: '...' }, mimeType: 'image/png' }\n * ]);\n * ```\n */\n user(content: string | UserContent[]): this {\n this._messages.push(new UserMessage(content));\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Adds an assistant message to the thread.\n *\n * @param content - String or array of content blocks\n * @returns This thread instance for chaining\n *\n * @example\n * ```typescript\n * thread.assistant('I can help with that!');\n * ```\n */\n assistant(content: string | AssistantContent[]): this {\n this._messages.push(new AssistantMessage(content));\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Filters messages by type.\n *\n * @param type - The message type to filter by\n * @returns Array of messages matching the type\n *\n * @example\n * ```typescript\n * const userMessages = thread.filter('user');\n * const assistantMessages = thread.filter('assistant');\n * ```\n */\n filter(type: MessageType): Message[] {\n return this._messages.filter((m) => m.type === type);\n }\n\n /**\n * Returns the last N messages from the thread.\n *\n * @param count - Number of messages to return\n * @returns Array of the last N messages\n *\n * @example\n * ```typescript\n * const recent = thread.tail(5);\n * ```\n */\n tail(count: number): Message[] {\n return this._messages.slice(-count);\n }\n\n /**\n * Creates a new thread with a subset of messages.\n *\n * @param start - Start index (inclusive)\n * @param end - End index (exclusive)\n * @returns New Thread containing the sliced messages\n *\n * @example\n * ```typescript\n * const subset = thread.slice(0, 10);\n * ```\n */\n slice(start?: number, end?: number): Thread {\n return new Thread(this._messages.slice(start, end));\n }\n\n /**\n * Removes all messages from the thread.\n *\n * @returns This thread instance for chaining\n */\n clear(): this {\n this._messages = [];\n this._updatedAt = new Date();\n return this;\n }\n\n /**\n * Converts the thread to a plain message array.\n *\n * @returns Copy of the internal message array\n */\n toMessages(): Message[] {\n return [...this._messages];\n }\n\n /**\n * Serializes the thread to JSON format.\n *\n * @returns JSON-serializable representation of the thread\n *\n * @example\n * ```typescript\n * const json = thread.toJSON();\n * localStorage.setItem('thread', JSON.stringify(json));\n * ```\n */\n toJSON(): ThreadJSON {\n return {\n id: this.id,\n messages: this._messages.map((m) => this.messageToJSON(m)),\n createdAt: this._createdAt.toISOString(),\n updatedAt: this._updatedAt.toISOString(),\n };\n }\n\n /**\n * Deserializes a thread from JSON format.\n *\n * @param json - The JSON representation to deserialize\n * @returns Reconstructed Thread instance\n *\n * @example\n * ```typescript\n * const json = JSON.parse(localStorage.getItem('thread'));\n * const thread = Thread.fromJSON(json);\n * ```\n */\n static fromJSON(json: ThreadJSON): Thread {\n const messages = json.messages.map((m) => Thread.messageFromJSON(m));\n const thread = new Thread(messages);\n (thread as { id: string }).id = json.id;\n thread._createdAt = new Date(json.createdAt);\n thread._updatedAt = new Date(json.updatedAt);\n return thread;\n }\n\n /**\n * Enables iteration over messages with for...of loops.\n *\n * @returns Iterator over the thread's messages\n *\n * @example\n * ```typescript\n * for (const message of thread) {\n * console.log(message.text);\n * }\n * ```\n */\n [Symbol.iterator](): Iterator<Message> {\n return this._messages[Symbol.iterator]();\n }\n\n /**\n * Converts a message to JSON format.\n */\n private messageToJSON(m: Message): MessageJSON {\n const base: MessageJSON = {\n id: m.id,\n type: m.type,\n content: [],\n metadata: m.metadata,\n timestamp: m.timestamp.toISOString(),\n };\n\n if (m instanceof UserMessage) {\n base.content = m.content;\n } else if (m instanceof AssistantMessage) {\n base.content = m.content;\n base.toolCalls = m.toolCalls;\n } else if (m instanceof ToolResultMessage) {\n base.results = m.results;\n }\n\n return base;\n }\n\n /**\n * Reconstructs a message from JSON format.\n */\n private static messageFromJSON(json: MessageJSON): Message {\n const options = {\n id: json.id,\n metadata: json.metadata,\n };\n\n switch (json.type) {\n case 'user':\n return new UserMessage(json.content as UserContent[], options);\n case 'assistant':\n return new AssistantMessage(\n json.content as AssistantContent[],\n json.toolCalls,\n options\n );\n case 'tool_result':\n return new ToolResultMessage(json.results ?? [], options);\n default:\n throw new Error(`Unknown message type: ${json.type}`);\n }\n }\n}\n","/**\n * @fileoverview Unified Provider Protocol (UPP) - A unified interface for AI model inference\n *\n * UPP provides a consistent API for interacting with multiple AI providers including\n * Anthropic, OpenAI, Google, Ollama, OpenRouter, and xAI. The library handles provider-specific\n * transformations, streaming, tool execution, and error handling.\n *\n * @module @providerprotocol/ai\n * @packageDocumentation\n */\n\n/**\n * LLM instance factory for creating model-bound inference functions.\n *\n * @example Basic usage\n * ```typescript\n * import { llm, anthropic } from '@providerprotocol/ai';\n *\n * const model = llm({\n * model: anthropic('claude-sonnet-4-20250514'),\n * params: { max_tokens: 1000 }\n * });\n *\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Streaming\n * ```typescript\n * for await (const event of model.stream('Tell me a story')) {\n * if (event.type === 'text') {\n * process.stdout.write(event.delta.text);\n * }\n * }\n * ```\n */\nexport { llm } from './core/llm.ts';\n\n/** Embedding instance factory for creating model-bound embedding functions */\nexport { embedding } from './core/embedding.ts';\n\n/** Image generation instance factory for creating model-bound image functions */\nexport { image } from './core/image.ts';\n\n/** Factory for creating custom providers */\nexport { createProvider } from './core/provider.ts';\n\n/** Image content wrapper for multimodal inputs */\nexport { Image } from './core/media/Image.ts';\n\nimport { llm } from './core/llm.ts';\nimport { embedding } from './core/embedding.ts';\nimport { image } from './core/image.ts';\n\n/**\n * UPP namespace object providing alternative import style.\n *\n * @example\n * ```typescript\n * import { ai } from '@providerprotocol/ai';\n *\n * const model = ai.llm({\n * model: openai('gpt-4o'),\n * params: { max_tokens: 1000 }\n * });\n * ```\n */\nexport const ai = {\n /** LLM instance factory */\n llm,\n /** Embedding instance factory */\n embedding,\n /** Image generation instance factory */\n image,\n};\n\nexport * from './types/index.ts';\n\nexport {\n RoundRobinKeys,\n WeightedKeys,\n DynamicKey,\n ExponentialBackoff,\n LinearBackoff,\n NoRetry,\n TokenBucket,\n RetryAfterStrategy,\n} from './http/index.ts';\n"],"mappings":"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","names":["text","newMessages","options"]}
|
package/dist/ollama/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { g as Provider } from '../provider-DGQHYE6I.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* @fileoverview Type definitions for the Ollama provider.
|
|
@@ -154,10 +154,9 @@ interface OllamaEmbedParams {
|
|
|
154
154
|
* import { llm } from 'provider-protocol';
|
|
155
155
|
* import { ollama } from 'provider-protocol/ollama';
|
|
156
156
|
*
|
|
157
|
-
* const model = llm(ollama('llama3.2'));
|
|
158
|
-
* const
|
|
159
|
-
*
|
|
160
|
-
* });
|
|
157
|
+
* const model = llm({ model: ollama('llama3.2') });
|
|
158
|
+
* const turn = await model.generate('Hello!');
|
|
159
|
+
* console.log(turn.response.text);
|
|
161
160
|
* ```
|
|
162
161
|
*
|
|
163
162
|
* @example Custom Ollama server URL
|
|
@@ -165,17 +164,16 @@ interface OllamaEmbedParams {
|
|
|
165
164
|
* import { llm } from 'provider-protocol';
|
|
166
165
|
* import { ollama } from 'provider-protocol/ollama';
|
|
167
166
|
*
|
|
168
|
-
* const model = llm(
|
|
169
|
-
*
|
|
167
|
+
* const model = llm({
|
|
168
|
+
* model: ollama('llama3.2'),
|
|
169
|
+
* config: { baseUrl: 'http://my-ollama-server:11434' },
|
|
170
170
|
* });
|
|
171
171
|
* ```
|
|
172
172
|
*
|
|
173
173
|
* @example Streaming responses
|
|
174
174
|
* ```typescript
|
|
175
|
-
* const model = llm(ollama('llama3.2'));
|
|
176
|
-
* const stream = model.stream(
|
|
177
|
-
* messages: [{ role: 'user', content: 'Write a poem' }]
|
|
178
|
-
* });
|
|
175
|
+
* const model = llm({ model: ollama('llama3.2') });
|
|
176
|
+
* const stream = model.stream('Write a poem');
|
|
179
177
|
*
|
|
180
178
|
* for await (const event of stream) {
|
|
181
179
|
* if (event.type === 'text_delta') {
|
|
@@ -186,15 +184,15 @@ interface OllamaEmbedParams {
|
|
|
186
184
|
*
|
|
187
185
|
* @example Using model parameters
|
|
188
186
|
* ```typescript
|
|
189
|
-
* const model = llm(
|
|
190
|
-
*
|
|
191
|
-
* messages: [{ role: 'user', content: 'Be creative!' }],
|
|
187
|
+
* const model = llm({
|
|
188
|
+
* model: ollama('llama3.2'),
|
|
192
189
|
* params: {
|
|
193
190
|
* temperature: 0.9,
|
|
194
191
|
* top_p: 0.95,
|
|
195
|
-
* num_predict: 500
|
|
196
|
-
* }
|
|
192
|
+
* num_predict: 500,
|
|
193
|
+
* },
|
|
197
194
|
* });
|
|
195
|
+
* const result = await model.generate('Be creative!');
|
|
198
196
|
* ```
|
|
199
197
|
*
|
|
200
198
|
* @see {@link OllamaLLMParams} for available model parameters
|
package/dist/ollama/index.js
CHANGED
|
@@ -1,21 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
createProvider
|
|
3
|
-
} from "../chunk-MSR5P65T.js";
|
|
4
1
|
import {
|
|
5
2
|
AssistantMessage,
|
|
3
|
+
createProvider,
|
|
6
4
|
isAssistantMessage,
|
|
7
5
|
isToolResultMessage,
|
|
8
6
|
isUserMessage
|
|
9
|
-
} from "../chunk-
|
|
7
|
+
} from "../chunk-M4BMM5IB.js";
|
|
10
8
|
import {
|
|
11
9
|
resolveApiKey
|
|
12
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-Y3GBJNA2.js";
|
|
13
11
|
import {
|
|
14
12
|
UPPError,
|
|
15
13
|
doFetch,
|
|
16
14
|
doStreamFetch,
|
|
17
15
|
normalizeHttpError
|
|
18
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-EDENPF3E.js";
|
|
19
17
|
|
|
20
18
|
// src/providers/ollama/transform.ts
|
|
21
19
|
function transformRequest(request, modelId) {
|
|
@@ -616,7 +614,7 @@ function createEmbeddingHandler() {
|
|
|
616
614
|
var ollama = createProvider({
|
|
617
615
|
name: "ollama",
|
|
618
616
|
version: "1.0.0",
|
|
619
|
-
|
|
617
|
+
handlers: {
|
|
620
618
|
llm: createLLMHandler(),
|
|
621
619
|
embedding: createEmbeddingHandler()
|
|
622
620
|
}
|