@providerprotocol/ai 0.0.20 → 0.0.22
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 +306 -107
- package/dist/anthropic/index.js.map +1 -1
- package/dist/{chunk-P5IRTEM5.js → chunk-7WYBJPJJ.js} +2 -2
- package/dist/chunk-I2VHCGQE.js +49 -0
- package/dist/chunk-I2VHCGQE.js.map +1 -0
- package/dist/{chunk-UMKWXGO3.js → chunk-M4BMM5IB.js} +86 -2
- package/dist/chunk-M4BMM5IB.js.map +1 -0
- package/dist/{chunk-SKY2JLA7.js → chunk-MKDLXV4O.js} +1 -1
- package/dist/chunk-MKDLXV4O.js.map +1 -0
- package/dist/{chunk-Z7RBRCRN.js → chunk-NWS5IKNR.js} +37 -11
- package/dist/chunk-NWS5IKNR.js.map +1 -0
- package/dist/{chunk-U3FZWV4U.js → chunk-RFWLEFAB.js} +100 -43
- package/dist/chunk-RFWLEFAB.js.map +1 -0
- package/dist/{chunk-U4JJC2YX.js → chunk-RS7C25LS.js} +36 -11
- package/dist/chunk-RS7C25LS.js.map +1 -0
- package/dist/google/index.d.ts +35 -24
- package/dist/google/index.js +273 -99
- package/dist/google/index.js.map +1 -1
- package/dist/http/index.d.ts +3 -3
- package/dist/http/index.js +4 -4
- package/dist/index.d.ts +103 -38
- package/dist/index.js +346 -153
- package/dist/index.js.map +1 -1
- package/dist/ollama/index.d.ts +14 -16
- package/dist/ollama/index.js +68 -16
- package/dist/ollama/index.js.map +1 -1
- package/dist/openai/index.d.ts +25 -133
- package/dist/openai/index.js +208 -122
- package/dist/openai/index.js.map +1 -1
- package/dist/openrouter/index.d.ts +28 -53
- package/dist/openrouter/index.js +179 -72
- package/dist/openrouter/index.js.map +1 -1
- package/dist/provider-DWEAzeM5.d.ts +1329 -0
- package/dist/proxy/index.d.ts +2 -3
- package/dist/proxy/index.js +174 -17
- package/dist/proxy/index.js.map +1 -1
- package/dist/{retry-DR7YRJDz.d.ts → retry-DmPmqZL6.d.ts} +12 -3
- package/dist/{stream-DRHy6q1a.d.ts → stream-DbkLOIbJ.d.ts} +15 -5
- package/dist/xai/index.d.ts +16 -88
- package/dist/xai/index.js +167 -86
- 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-SKY2JLA7.js.map +0 -1
- package/dist/chunk-U3FZWV4U.js.map +0 -1
- package/dist/chunk-U4JJC2YX.js.map +0 -1
- package/dist/chunk-UMKWXGO3.js.map +0 -1
- package/dist/chunk-Z7RBRCRN.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-7WYBJPJJ.js.map} +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/providers/openrouter/transform.completions.ts","../../src/providers/openrouter/llm.completions.ts","../../src/providers/openrouter/transform.responses.ts","../../src/providers/openrouter/llm.responses.ts","../../src/providers/openrouter/embed.ts","../../src/providers/openrouter/index.ts"],"sourcesContent":["/**\n * Transform utilities for OpenRouter Chat Completions API.\n *\n * This module handles bidirectional conversion between UPP (Unified Provider Protocol)\n * request/response formats and OpenRouter's Chat Completions API format, which is\n * compatible with the OpenAI Chat Completions API.\n *\n * @module transform.completions\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock, AssistantContent } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport type {\n OpenRouterCompletionsParams,\n OpenRouterCompletionsRequest,\n OpenRouterCompletionsMessage,\n OpenRouterUserContent,\n OpenRouterCompletionsTool,\n OpenRouterCompletionsResponse,\n OpenRouterCompletionsStreamChunk,\n OpenRouterToolCall,\n OpenRouterCacheControl,\n} from './types.ts';\n\n/**\n * Transforms a UPP LLMRequest into an OpenRouter Chat Completions API request body.\n *\n * Parameters are spread directly to enable pass-through of any OpenRouter API fields,\n * even those not explicitly defined in our types. This allows developers to use new\n * API features without waiting for library updates.\n *\n * @param request - The UPP LLM request containing messages, tools, and parameters\n * @param modelId - The OpenRouter model identifier (e.g., 'openai/gpt-4o')\n * @returns A fully formed OpenRouter Chat Completions request body\n */\nexport function transformRequest(\n request: LLMRequest<OpenRouterCompletionsParams>,\n modelId: string\n): OpenRouterCompletionsRequest {\n const params = request.params ?? ({} as OpenRouterCompletionsParams);\n\n const openrouterRequest: OpenRouterCompletionsRequest = {\n ...params,\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n if (request.tools && request.tools.length > 0) {\n openrouterRequest.tools = request.tools.map(transformTool);\n }\n\n if (request.structure) {\n const schema: Record<string, unknown> = {\n type: 'object',\n properties: request.structure.properties,\n required: request.structure.required,\n ...(request.structure.additionalProperties !== undefined\n ? { additionalProperties: request.structure.additionalProperties }\n : { additionalProperties: false }),\n };\n if (request.structure.description) {\n schema.description = request.structure.description;\n }\n\n openrouterRequest.response_format = {\n type: 'json_schema',\n json_schema: {\n name: 'json_response',\n description: request.structure.description,\n schema,\n strict: true,\n },\n };\n }\n\n return openrouterRequest;\n}\n\n/**\n * Transforms UPP messages into OpenRouter Chat Completions message format.\n *\n * Handles system prompts, user messages, assistant messages, and tool results.\n * Tool result messages are expanded into individual tool messages.\n *\n * System prompts support both string and array formats:\n * - String: Simple text system prompt\n * - Array: Content blocks with optional cache_control for Anthropic/Gemini models\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt (string or array with cache_control)\n * @returns Array of OpenRouter-formatted messages\n */\nfunction transformMessages(\n messages: Message[],\n system?: string | unknown[]\n): OpenRouterCompletionsMessage[] {\n const result: OpenRouterCompletionsMessage[] = [];\n\n if (system) {\n // Pass through directly - OpenRouter supports both string and array formats\n result.push({\n role: 'system',\n content: system as string | Array<{type: 'text'; text: string; cache_control?: {type: 'ephemeral'; ttl?: '1h'}}>,\n });\n }\n\n for (const message of messages) {\n if (isToolResultMessage(message)) {\n const toolMessages = transformToolResults(message);\n result.push(...toolMessages);\n } else {\n const transformed = transformMessage(message);\n if (transformed) {\n result.push(transformed);\n }\n }\n }\n\n return result;\n}\n\n/**\n * Filters content blocks to only those with a valid type property.\n *\n * @param content - Array of content blocks to filter\n * @returns Filtered array containing only blocks with string type properties\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Extracts cache control configuration from message metadata.\n *\n * @param message - The message to extract cache control from\n * @returns The cache control configuration if present, undefined otherwise\n */\nfunction extractCacheControl(message: Message): OpenRouterCacheControl | undefined {\n const openrouterMeta = message.metadata?.openrouter as\n | { cache_control?: OpenRouterCacheControl }\n | undefined;\n return openrouterMeta?.cache_control;\n}\n\n/**\n * Transforms a single UPP message to OpenRouter Chat Completions format.\n *\n * Cache control can be specified via message metadata:\n * ```typescript\n * new UserMessage(content, {\n * metadata: { openrouter: { cache_control: { type: \"ephemeral\" } } }\n * })\n * ```\n *\n * @param message - The UPP message to transform\n * @returns The transformed OpenRouter message, or null if the message type is unsupported\n */\nfunction transformMessage(message: Message): OpenRouterCompletionsMessage | null {\n if (isUserMessage(message)) {\n const validContent = filterValidContent(message.content);\n const cacheControl = extractCacheControl(message);\n\n // If cache_control is present, always use array format to attach it\n if (cacheControl) {\n const content = validContent.map(transformContentBlock);\n // Apply cache_control to the last text content block\n for (let i = content.length - 1; i >= 0; i--) {\n const block = content[i];\n if (block?.type === 'text') {\n content[i] = { type: 'text', text: block.text, cache_control: cacheControl };\n break;\n }\n }\n return { role: 'user', content };\n }\n\n // No cache_control: use string shortcut for single text block\n if (validContent.length === 1 && validContent[0]?.type === 'text') {\n return {\n role: 'user',\n content: (validContent[0] as TextBlock).text,\n };\n }\n return {\n role: 'user',\n content: validContent.map(transformContentBlock),\n };\n }\n\n if (isAssistantMessage(message)) {\n const validContent = filterValidContent(message.content);\n const textContent = validContent\n .filter((c): c is TextBlock => c.type === 'text')\n .map((c) => c.text)\n .join('');\n\n const assistantMessage: OpenRouterCompletionsMessage = {\n role: 'assistant',\n content: textContent || null,\n };\n\n if (message.toolCalls && message.toolCalls.length > 0) {\n (assistantMessage as { tool_calls?: OpenRouterToolCall[] }).tool_calls =\n message.toolCalls.map((call) => ({\n id: call.toolCallId,\n type: 'function' as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.arguments),\n },\n }));\n }\n\n return assistantMessage;\n }\n\n if (isToolResultMessage(message)) {\n const results = message.results.map((result) => ({\n role: 'tool' as const,\n tool_call_id: result.toolCallId,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n\n return results[0] ?? null;\n }\n\n return null;\n}\n\n/**\n * Transforms a tool result message into multiple OpenRouter tool messages.\n *\n * Each tool result in the UPP ToolResultMessage becomes a separate OpenRouter\n * tool message with the corresponding tool_call_id.\n *\n * @param message - The UPP message (expected to be a ToolResultMessage)\n * @returns Array of OpenRouter tool messages\n */\nexport function transformToolResults(\n message: Message\n): OpenRouterCompletionsMessage[] {\n if (!isToolResultMessage(message)) {\n const single = transformMessage(message);\n return single ? [single] : [];\n }\n\n return message.results.map((result) => ({\n role: 'tool' as const,\n tool_call_id: result.toolCallId,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n}\n\n/**\n * Transforms a UPP content block to OpenRouter user content format.\n *\n * Supports text and image content types. Images are converted to data URLs\n * or passed through as URL references.\n *\n * @param block - The UPP content block to transform\n * @returns OpenRouter user content part\n * @throws Error if the content type is unsupported\n */\nfunction transformContentBlock(block: ContentBlock): OpenRouterUserContent {\n switch (block.type) {\n case 'text':\n return { type: 'text', text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n let url: string;\n\n if (imageBlock.source.type === 'base64') {\n url = `data:${imageBlock.mimeType};base64,${imageBlock.source.data}`;\n } else if (imageBlock.source.type === 'url') {\n url = imageBlock.source.url;\n } else if (imageBlock.source.type === 'bytes') {\n // Convert bytes to base64\n const base64 = btoa(\n Array.from(imageBlock.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n url = `data:${imageBlock.mimeType};base64,${base64}`;\n } else {\n throw new Error('Unknown image source type');\n }\n\n return {\n type: 'image_url',\n image_url: { url },\n };\n }\n\n default:\n throw new Error(`Unsupported content type: ${block.type}`);\n }\n}\n\n/**\n * Transforms a UPP Tool definition to OpenRouter function tool format.\n *\n * @param tool - The UPP tool definition\n * @returns OpenRouter function tool definition\n */\nfunction transformTool(tool: Tool): OpenRouterCompletionsTool {\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n },\n };\n}\n\n/**\n * Transforms an OpenRouter Chat Completions API response to UPP LLMResponse format.\n *\n * Extracts text content, tool calls, usage statistics, and stop reason from\n * the OpenRouter response. Attempts to parse JSON content for structured output.\n *\n * @param data - The raw OpenRouter Chat Completions response\n * @returns UPP-formatted LLM response\n * @throws Error if no choices are present in the response\n */\nexport function transformResponse(data: OpenRouterCompletionsResponse): LLMResponse {\n const choice = data.choices[0];\n if (!choice) {\n throw new Error('No choices in OpenRouter response');\n }\n\n const content: AssistantContent[] = [];\n let structuredData: unknown;\n if (choice.message.content) {\n content.push({ type: 'text', text: choice.message.content });\n try {\n structuredData = JSON.parse(choice.message.content);\n } catch {\n // Content is not JSON - acceptable for non-structured responses\n }\n }\n\n if (choice.message.images && choice.message.images.length > 0) {\n for (const image of choice.message.images) {\n const imageBlock = parseGeneratedImage(image.image_url.url);\n if (imageBlock) {\n content.push(imageBlock);\n }\n }\n }\n\n const toolCalls: ToolCall[] = [];\n if (choice.message.tool_calls) {\n for (const call of choice.message.tool_calls) {\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(call.function.arguments);\n } catch {\n // Invalid JSON arguments - use empty object as fallback\n }\n toolCalls.push({\n toolCallId: call.id,\n toolName: call.function.name,\n arguments: args,\n });\n }\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: data.id,\n metadata: {\n openrouter: {\n model: data.model,\n finish_reason: choice.finish_reason,\n system_fingerprint: data.system_fingerprint,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usage.prompt_tokens,\n outputTokens: data.usage.completion_tokens,\n totalTokens: data.usage.total_tokens,\n cacheReadTokens: data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n switch (choice.finish_reason) {\n case 'stop':\n stopReason = 'end_turn';\n break;\n case 'length':\n stopReason = 'max_tokens';\n break;\n case 'tool_calls':\n stopReason = 'tool_use';\n break;\n case 'content_filter':\n stopReason = 'content_filter';\n break;\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Parses a generated image data URL into an ImageBlock.\n *\n * @param dataUrl - The data URL from the image generation response\n * @returns An ImageBlock or null if parsing fails\n */\nfunction parseGeneratedImage(dataUrl: string): ImageBlock | null {\n const match = dataUrl.match(/^data:(image\\/[^;]+);base64,(.+)$/);\n if (!match) {\n return null;\n }\n const [, mimeType, data] = match;\n if (!mimeType || !data) {\n return null;\n }\n return {\n type: 'image',\n mimeType,\n source: { type: 'base64', data },\n };\n}\n\n/**\n * Mutable state object for accumulating streaming response data.\n *\n * Used during streaming to collect text deltas, tool call fragments,\n * and usage statistics before building the final LLMResponse.\n */\nexport interface CompletionsStreamState {\n /** Response ID from the first chunk */\n id: string;\n /** Model identifier from the response */\n model: string;\n /** Accumulated text content */\n text: string;\n /** Map of tool call index to accumulated tool call data */\n toolCalls: Map<number, { id: string; name: string; arguments: string }>;\n /** Generated image data URLs from image generation models */\n images: string[];\n /** Final finish reason from the stream */\n finishReason: string | null;\n /** Input token count from usage */\n inputTokens: number;\n /** Output token count from usage */\n outputTokens: number;\n /** Number of tokens read from cache */\n cacheReadTokens: number;\n}\n\n/**\n * Creates an empty stream state object for accumulating streaming data.\n *\n * @returns A new CompletionsStreamState with all fields initialized\n */\nexport function createStreamState(): CompletionsStreamState {\n return {\n id: '',\n model: '',\n text: '',\n toolCalls: new Map(),\n images: [],\n finishReason: null,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n };\n}\n\n/**\n * Transforms an OpenRouter streaming chunk into UPP StreamEvents.\n *\n * Processes the chunk to extract text deltas, tool call updates, and finish signals.\n * Updates the provided state object with accumulated data. Returns an array because\n * a single chunk may produce multiple events (e.g., text delta and tool call delta).\n *\n * @param chunk - The OpenRouter streaming chunk to process\n * @param state - The mutable state object to update with chunk data\n * @returns Array of UPP StreamEvents generated from this chunk\n */\nexport function transformStreamEvent(\n chunk: OpenRouterCompletionsStreamChunk,\n state: CompletionsStreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n if (chunk.id && !state.id) {\n state.id = chunk.id;\n events.push({ type: 'message_start', index: 0, delta: {} });\n }\n if (chunk.model) {\n state.model = chunk.model;\n }\n\n const choice = chunk.choices[0];\n if (choice) {\n if (choice.delta.content) {\n state.text += choice.delta.content;\n events.push({\n type: 'text_delta',\n index: 0,\n delta: { text: choice.delta.content },\n });\n }\n\n if (choice.delta.tool_calls) {\n for (const toolCallDelta of choice.delta.tool_calls) {\n const index = toolCallDelta.index;\n let toolCall = state.toolCalls.get(index);\n\n if (!toolCall) {\n toolCall = { id: '', name: '', arguments: '' };\n state.toolCalls.set(index, toolCall);\n }\n\n if (toolCallDelta.id) {\n toolCall.id = toolCallDelta.id;\n }\n if (toolCallDelta.function?.name) {\n toolCall.name = toolCallDelta.function.name;\n }\n if (toolCallDelta.function?.arguments) {\n toolCall.arguments += toolCallDelta.function.arguments;\n events.push({\n type: 'tool_call_delta',\n index: index,\n delta: {\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n argumentsJson: toolCallDelta.function.arguments,\n },\n });\n }\n }\n }\n\n if (choice.delta.images) {\n for (const image of choice.delta.images) {\n state.images.push(image.image_url.url);\n }\n }\n\n if (choice.finish_reason) {\n state.finishReason = choice.finish_reason;\n events.push({ type: 'message_stop', index: 0, delta: {} });\n }\n }\n\n if (chunk.usage) {\n state.inputTokens = chunk.usage.prompt_tokens;\n state.outputTokens = chunk.usage.completion_tokens;\n state.cacheReadTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;\n }\n\n return events;\n}\n\n/**\n * Builds the final LLMResponse from accumulated streaming state.\n *\n * Constructs the complete response after streaming has finished, including\n * the assistant message, tool calls, usage statistics, and stop reason.\n *\n * @param state - The accumulated stream state\n * @returns Complete UPP LLMResponse\n */\nexport function buildResponseFromState(state: CompletionsStreamState): LLMResponse {\n const content: AssistantContent[] = [];\n let structuredData: unknown;\n if (state.text) {\n content.push({ type: 'text', text: state.text });\n try {\n structuredData = JSON.parse(state.text);\n } catch {\n // Content is not JSON - acceptable for non-structured responses\n }\n }\n\n for (const imageUrl of state.images) {\n const imageBlock = parseGeneratedImage(imageUrl);\n if (imageBlock) {\n content.push(imageBlock);\n }\n }\n\n const toolCalls: ToolCall[] = [];\n for (const [, toolCall] of state.toolCalls) {\n let args: Record<string, unknown> = {};\n if (toolCall.arguments) {\n try {\n args = JSON.parse(toolCall.arguments);\n } catch {\n // Invalid JSON arguments - use empty object as fallback\n }\n }\n toolCalls.push({\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n arguments: args,\n });\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: state.id,\n metadata: {\n openrouter: {\n model: state.model,\n finish_reason: state.finishReason,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n cacheReadTokens: state.cacheReadTokens,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n switch (state.finishReason) {\n case 'stop':\n stopReason = 'end_turn';\n break;\n case 'length':\n stopReason = 'max_tokens';\n break;\n case 'tool_calls':\n stopReason = 'tool_use';\n break;\n case 'content_filter':\n stopReason = 'content_filter';\n break;\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * OpenRouter Chat Completions API LLM handler.\n *\n * This module implements the LLMHandler interface for OpenRouter's Chat Completions API,\n * which is compatible with the OpenAI Chat Completions API format.\n *\n * @module llm.completions\n */\n\nimport type { LLMHandler, BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport type { OpenRouterCompletionsParams, OpenRouterCompletionsResponse, OpenRouterCompletionsStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.completions.ts';\n\n/** Base URL for OpenRouter's Chat Completions API endpoint. */\nconst OPENROUTER_API_URL = 'https://openrouter.ai/api/v1/chat/completions';\n\n/**\n * Capability flags for the OpenRouter Chat Completions API.\n *\n * OpenRouter supports streaming, function calling (tools), structured JSON output,\n * and image inputs. Video and audio inputs are not currently supported.\n */\nconst OPENROUTER_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n imageOutput: true,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Creates an LLM handler for OpenRouter's Chat Completions API.\n *\n * This handler implements the UPP LLMHandler interface and provides\n * both synchronous completion and streaming capabilities.\n *\n * @returns An LLMHandler configured for OpenRouter Chat Completions\n *\n * @example\n * ```typescript\n * const handler = createCompletionsLLMHandler();\n * handler._setProvider(provider);\n * const model = handler.bind('openai/gpt-4o');\n * const response = await model.complete(request);\n * ```\n */\nexport function createCompletionsLLMHandler(): LLMHandler<OpenRouterCompletionsParams> {\n let providerRef: LLMProvider<OpenRouterCompletionsParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<OpenRouterCompletionsParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<OpenRouterCompletionsParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider() or have _setProvider called.',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n\n const model: BoundLLMModel<OpenRouterCompletionsParams> = {\n modelId,\n capabilities: OPENROUTER_CAPABILITIES,\n\n get provider(): LLMProvider<OpenRouterCompletionsParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<OpenRouterCompletionsParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_API_URL;\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'openrouter',\n 'llm'\n );\n\n const data = (await response.json()) as OpenRouterCompletionsResponse;\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<OpenRouterCompletionsParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_API_URL;\n const body = transformRequest(request, modelId);\n body.stream = true;\n body.stream_options = { include_usage: true };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'openrouter',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'openrouter', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n // Skip [DONE] marker\n if (data === '[DONE]') {\n continue;\n }\n\n // Check for OpenRouter error event\n if (typeof data === 'object' && data !== null) {\n const chunk = data as OpenRouterCompletionsStreamChunk;\n\n // Check for error in chunk\n if ('error' in chunk && chunk.error) {\n const errorData = chunk.error as { message?: string; type?: string };\n const error = new UPPError(\n errorData.message ?? 'Unknown error',\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n const uppEvents = transformStreamEvent(chunk, state);\n for (const event of uppEvents) {\n yield event;\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n responseReject(error as Error);\n throw error;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * Transform utilities for OpenRouter Responses API (beta).\n *\n * This module handles bidirectional conversion between UPP (Unified Provider Protocol)\n * request/response formats and OpenRouter's Responses API format. The Responses API\n * uses a different structure than Chat Completions, with input items and output items.\n *\n * @module transform.responses\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock, AssistantContent } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport type {\n OpenRouterResponsesParams,\n OpenRouterResponsesRequest,\n OpenRouterResponsesInputItem,\n OpenRouterResponsesContentPart,\n OpenRouterResponsesTool,\n OpenRouterResponsesResponse,\n OpenRouterResponsesStreamEvent,\n OpenRouterResponsesOutputItem,\n OpenRouterResponsesMessageOutput,\n OpenRouterResponsesFunctionCallOutput,\n OpenRouterResponsesImageGenerationOutput,\n} from './types.ts';\n\n/**\n * Transforms a UPP LLMRequest into an OpenRouter Responses API request body.\n *\n * Parameters are spread directly to enable pass-through of any OpenRouter API fields,\n * even those not explicitly defined in our types. This allows developers to use new\n * API features without waiting for library updates.\n *\n * @param request - The UPP LLM request containing messages, tools, and parameters\n * @param modelId - The OpenRouter model identifier (e.g., 'openai/gpt-4o')\n * @returns A fully formed OpenRouter Responses API request body\n */\nexport function transformRequest(\n request: LLMRequest<OpenRouterResponsesParams>,\n modelId: string\n): OpenRouterResponsesRequest {\n const params = request.params ?? ({} as OpenRouterResponsesParams);\n\n const openrouterRequest: OpenRouterResponsesRequest = {\n ...params,\n model: modelId,\n input: transformInputItems(request.messages, request.system),\n };\n\n if (request.tools && request.tools.length > 0) {\n openrouterRequest.tools = request.tools.map(transformTool);\n }\n\n if (request.structure) {\n const schema: Record<string, unknown> = {\n type: 'object',\n properties: request.structure.properties,\n required: request.structure.required,\n ...(request.structure.additionalProperties !== undefined\n ? { additionalProperties: request.structure.additionalProperties }\n : { additionalProperties: false }),\n };\n if (request.structure.description) {\n schema.description = request.structure.description;\n }\n\n openrouterRequest.text = {\n format: {\n type: 'json_schema',\n name: 'json_response',\n description: request.structure.description,\n schema,\n strict: true,\n },\n };\n }\n\n return openrouterRequest;\n}\n\n/**\n * Transforms UPP messages into Responses API input items.\n *\n * Handles system prompts, user messages, assistant messages, function calls,\n * and tool results. Returns a string for simple single-message requests.\n *\n * System prompts support both string and array formats for cache_control.\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt (string or array with cache_control)\n * @returns Array of input items, or a simple string for single-message requests\n */\nfunction transformInputItems(\n messages: Message[],\n system?: string | unknown[]\n): OpenRouterResponsesInputItem[] | string {\n const result: OpenRouterResponsesInputItem[] = [];\n\n if (system) {\n // Pass through directly - OpenRouter supports both string and array formats\n // Array format enables cache_control for Anthropic/Gemini models\n result.push({\n type: 'message',\n role: 'system',\n content: system,\n } as OpenRouterResponsesInputItem);\n }\n\n for (const message of messages) {\n const items = transformMessage(message);\n result.push(...items);\n }\n\n if (result.length === 1 && result[0]?.type === 'message') {\n const item = result[0] as { role?: string; content?: string | unknown[] };\n if (item.role === 'user' && typeof item.content === 'string') {\n return item.content;\n }\n }\n\n return result;\n}\n\n/**\n * Filters content blocks to only those with a valid type property.\n *\n * @param content - Array of content blocks to filter\n * @returns Filtered array containing only blocks with string type properties\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Transforms a single UPP message to Responses API input items.\n *\n * May return multiple input items for messages containing tool calls,\n * as function_call items must be separate from message items.\n *\n * @param message - The UPP message to transform\n * @returns Array of Responses API input items\n */\nfunction transformMessage(message: Message): OpenRouterResponsesInputItem[] {\n if (isUserMessage(message)) {\n const validContent = filterValidContent(message.content);\n if (validContent.length === 1 && validContent[0]?.type === 'text') {\n return [\n {\n type: 'message',\n role: 'user',\n content: (validContent[0] as TextBlock).text,\n },\n ];\n }\n return [\n {\n type: 'message',\n role: 'user',\n content: validContent.map(transformContentPart),\n },\n ];\n }\n\n if (isAssistantMessage(message)) {\n const validContent = filterValidContent(message.content);\n const items: OpenRouterResponsesInputItem[] = [];\n\n const contentParts: OpenRouterResponsesContentPart[] = validContent\n .filter((c): c is TextBlock => c.type === 'text')\n .map((c): OpenRouterResponsesContentPart => ({\n type: 'output_text',\n text: c.text,\n annotations: [],\n }));\n\n const messageId = message.id ?? `msg_${Date.now()}`;\n\n if (contentParts.length > 0) {\n items.push({\n type: 'message',\n role: 'assistant',\n id: messageId,\n status: 'completed',\n content: contentParts,\n });\n }\n\n const openrouterMeta = message.metadata?.openrouter as\n | { functionCallItems?: Array<{ id: string; call_id: string; name: string; arguments: string }> }\n | undefined;\n const functionCallItems = openrouterMeta?.functionCallItems;\n\n if (functionCallItems && functionCallItems.length > 0) {\n for (const fc of functionCallItems) {\n items.push({\n type: 'function_call',\n id: fc.id,\n call_id: fc.call_id,\n name: fc.name,\n arguments: fc.arguments,\n });\n }\n } else if (message.toolCalls && message.toolCalls.length > 0) {\n for (const call of message.toolCalls) {\n items.push({\n type: 'function_call',\n id: `fc_${call.toolCallId}`,\n call_id: call.toolCallId,\n name: call.toolName,\n arguments: JSON.stringify(call.arguments),\n });\n }\n }\n\n return items;\n }\n\n if (isToolResultMessage(message)) {\n return message.results.map((result, index) => ({\n type: 'function_call_output' as const,\n id: `fco_${result.toolCallId}_${index}`,\n call_id: result.toolCallId,\n output:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n }\n\n return [];\n}\n\n/**\n * Transforms a UPP content block to Responses API content part format.\n *\n * Supports text and image content types. Images are converted to data URLs\n * or passed through as URL references.\n *\n * @param block - The UPP content block to transform\n * @returns Responses API content part\n * @throws Error if the content type is unsupported\n */\nfunction transformContentPart(block: ContentBlock): OpenRouterResponsesContentPart {\n switch (block.type) {\n case 'text':\n return { type: 'input_text', text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n if (imageBlock.source.type === 'base64') {\n return {\n type: 'input_image',\n image_url: `data:${imageBlock.mimeType};base64,${imageBlock.source.data}`,\n detail: 'auto',\n };\n }\n\n if (imageBlock.source.type === 'url') {\n return {\n type: 'input_image',\n image_url: imageBlock.source.url,\n detail: 'auto',\n };\n }\n\n if (imageBlock.source.type === 'bytes') {\n // Convert bytes to base64\n const base64 = btoa(\n Array.from(imageBlock.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n return {\n type: 'input_image',\n image_url: `data:${imageBlock.mimeType};base64,${base64}`,\n detail: 'auto',\n };\n }\n\n throw new Error('Unknown image source type');\n }\n\n default:\n throw new Error(`Unsupported content type: ${block.type}`);\n }\n}\n\n/**\n * Transforms a UPP Tool definition to Responses API function tool format.\n *\n * @param tool - The UPP tool definition\n * @returns Responses API function tool definition\n */\nfunction transformTool(tool: Tool): OpenRouterResponsesTool {\n return {\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n };\n}\n\n/**\n * Transforms an OpenRouter Responses API response to UPP LLMResponse format.\n *\n * Extracts text content, tool calls, usage statistics, and stop reason from\n * the Responses API output items. Handles refusals and structured output parsing.\n *\n * @param data - The raw OpenRouter Responses API response\n * @returns UPP-formatted LLM response\n */\nexport function transformResponse(data: OpenRouterResponsesResponse): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n const functionCallItems: Array<{\n id: string;\n call_id: string;\n name: string;\n arguments: string;\n }> = [];\n let hadRefusal = false;\n let structuredData: unknown;\n\n for (const item of data.output) {\n if (item.type === 'message') {\n const messageItem = item as OpenRouterResponsesMessageOutput;\n for (const part of messageItem.content) {\n if (part.type === 'output_text') {\n content.push({ type: 'text', text: part.text });\n if (structuredData === undefined) {\n try {\n structuredData = JSON.parse(part.text);\n } catch {\n // Content is not JSON - acceptable for non-structured responses\n }\n }\n } else if (part.type === 'refusal') {\n content.push({ type: 'text', text: part.refusal });\n hadRefusal = true;\n }\n }\n } else if (item.type === 'function_call') {\n const functionCall = item as OpenRouterResponsesFunctionCallOutput;\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(functionCall.arguments);\n } catch {\n // Invalid JSON arguments - use empty object as fallback\n }\n toolCalls.push({\n toolCallId: functionCall.call_id,\n toolName: functionCall.name,\n arguments: args,\n });\n functionCallItems.push({\n id: functionCall.id,\n call_id: functionCall.call_id,\n name: functionCall.name,\n arguments: functionCall.arguments,\n });\n } else if (item.type === 'image_generation_call') {\n const imageGen = item as OpenRouterResponsesImageGenerationOutput;\n if (imageGen.result) {\n content.push({\n type: 'image',\n mimeType: 'image/png',\n source: { type: 'base64', data: imageGen.result },\n } as ImageBlock);\n }\n }\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: data.id,\n metadata: {\n openrouter: {\n model: data.model,\n status: data.status,\n // Store response_id for multi-turn tool calling\n response_id: data.id,\n functionCallItems:\n functionCallItems.length > 0 ? functionCallItems : undefined,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usage.input_tokens,\n outputTokens: data.usage.output_tokens,\n totalTokens: data.usage.total_tokens,\n cacheReadTokens: data.usage.input_tokens_details?.cached_tokens ?? 0,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n if (data.status === 'completed') {\n stopReason = toolCalls.length > 0 ? 'tool_use' : 'end_turn';\n } else if (data.status === 'incomplete') {\n stopReason = data.incomplete_details?.reason === 'max_output_tokens'\n ? 'max_tokens'\n : 'end_turn';\n } else if (data.status === 'failed') {\n stopReason = 'error';\n }\n if (hadRefusal && stopReason !== 'error') {\n stopReason = 'content_filter';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Mutable state object for accumulating Responses API streaming data.\n *\n * Used during streaming to collect text deltas, tool call fragments,\n * and usage statistics before building the final LLMResponse.\n */\nexport interface ResponsesStreamState {\n /** Response ID from the created event */\n id: string;\n /** Model identifier from the response */\n model: string;\n /** Map of output index to accumulated text content */\n textByIndex: Map<number, string>;\n /** Map of output index to accumulated tool call data */\n toolCalls: Map<\n number,\n { itemId?: string; callId?: string; name?: string; arguments: string }\n >;\n /** Map of output index to generated image data (base64) */\n images: Map<number, string>;\n /** Current response status */\n status: string;\n /** Input token count from usage */\n inputTokens: number;\n /** Output token count from usage */\n outputTokens: number;\n /** Number of tokens read from cache */\n cacheReadTokens: number;\n /** Whether a refusal was encountered */\n hadRefusal: boolean;\n}\n\n/**\n * Creates an empty stream state object for accumulating Responses API streaming data.\n *\n * @returns A new ResponsesStreamState with all fields initialized\n */\nexport function createStreamState(): ResponsesStreamState {\n return {\n id: '',\n model: '',\n textByIndex: new Map(),\n toolCalls: new Map(),\n images: new Map(),\n status: 'in_progress',\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n hadRefusal: false,\n };\n}\n\n/**\n * Transforms an OpenRouter Responses API streaming event into UPP StreamEvents.\n *\n * Handles the various Responses API event types including response lifecycle events,\n * output item events, content deltas, function call arguments, and reasoning deltas.\n * Updates the provided state object with accumulated data.\n *\n * @param event - The OpenRouter Responses API streaming event to process\n * @param state - The mutable state object to update with event data\n * @returns Array of UPP StreamEvents generated from this event\n */\nexport function transformStreamEvent(\n event: OpenRouterResponsesStreamEvent,\n state: ResponsesStreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n switch (event.type) {\n case 'response.created':\n state.id = event.response.id;\n state.model = event.response.model;\n events.push({ type: 'message_start', index: 0, delta: {} });\n break;\n\n case 'response.in_progress':\n state.status = 'in_progress';\n break;\n\n case 'response.completed':\n case 'response.done':\n state.status = 'completed';\n if (event.response?.usage) {\n state.inputTokens = event.response.usage.input_tokens;\n state.outputTokens = event.response.usage.output_tokens;\n state.cacheReadTokens = event.response.usage.input_tokens_details?.cached_tokens ?? 0;\n }\n if (event.response?.output) {\n for (let i = 0; i < event.response.output.length; i++) {\n const item = event.response.output[i];\n if (item && item.type === 'function_call') {\n const functionCall = item as OpenRouterResponsesFunctionCallOutput;\n const existing = state.toolCalls.get(i) ?? { arguments: '' };\n existing.itemId = functionCall.id ?? existing.itemId;\n existing.callId = functionCall.call_id ?? existing.callId;\n existing.name = functionCall.name ?? existing.name;\n if (functionCall.arguments) {\n existing.arguments = functionCall.arguments;\n }\n state.toolCalls.set(i, existing);\n }\n }\n }\n events.push({ type: 'message_stop', index: 0, delta: {} });\n break;\n\n case 'response.failed':\n state.status = 'failed';\n events.push({ type: 'message_stop', index: 0, delta: {} });\n break;\n\n case 'response.output_item.added':\n if (event.item.type === 'function_call') {\n const functionCall = event.item as OpenRouterResponsesFunctionCallOutput;\n const existing = state.toolCalls.get(event.output_index) ?? {\n arguments: '',\n };\n existing.itemId = functionCall.id;\n existing.callId = functionCall.call_id;\n existing.name = functionCall.name;\n if (functionCall.arguments) {\n existing.arguments = functionCall.arguments;\n }\n state.toolCalls.set(event.output_index, existing);\n }\n events.push({\n type: 'content_block_start',\n index: event.output_index,\n delta: {},\n });\n break;\n\n case 'response.output_item.done':\n if (event.item.type === 'function_call') {\n const functionCall = event.item as OpenRouterResponsesFunctionCallOutput;\n const existing = state.toolCalls.get(event.output_index) ?? {\n arguments: '',\n };\n existing.itemId = functionCall.id;\n existing.callId = functionCall.call_id;\n existing.name = functionCall.name;\n if (functionCall.arguments) {\n existing.arguments = functionCall.arguments;\n }\n state.toolCalls.set(event.output_index, existing);\n } else if (event.item.type === 'message') {\n // Extract text from completed message item (may not have incremental deltas)\n const messageItem = event.item as OpenRouterResponsesMessageOutput;\n for (const content of messageItem.content || []) {\n if (content.type === 'output_text') {\n const existingText = state.textByIndex.get(event.output_index) ?? '';\n if (!existingText && content.text) {\n // Only use done text if we didn't get incremental deltas\n state.textByIndex.set(event.output_index, content.text);\n events.push({\n type: 'text_delta',\n index: event.output_index,\n delta: { text: content.text },\n });\n }\n }\n }\n } else if (event.item.type === 'image_generation_call') {\n const imageGen = event.item as OpenRouterResponsesImageGenerationOutput;\n if (imageGen.result) {\n state.images.set(event.output_index, imageGen.result);\n }\n }\n events.push({\n type: 'content_block_stop',\n index: event.output_index,\n delta: {},\n });\n break;\n\n case 'response.content_part.delta':\n case 'response.output_text.delta': {\n const textDelta = (event as { delta: string }).delta;\n const currentText = state.textByIndex.get(event.output_index) ?? '';\n state.textByIndex.set(event.output_index, currentText + textDelta);\n events.push({\n type: 'text_delta',\n index: event.output_index,\n delta: { text: textDelta },\n });\n break;\n }\n\n case 'response.output_text.done':\n case 'response.content_part.done':\n if ('text' in event) {\n state.textByIndex.set(event.output_index, (event as { text: string }).text);\n }\n break;\n\n case 'response.refusal.delta': {\n state.hadRefusal = true;\n const currentRefusal = state.textByIndex.get(event.output_index) ?? '';\n state.textByIndex.set(event.output_index, currentRefusal + event.delta);\n events.push({\n type: 'text_delta',\n index: event.output_index,\n delta: { text: event.delta },\n });\n break;\n }\n\n case 'response.refusal.done':\n state.hadRefusal = true;\n state.textByIndex.set(event.output_index, event.refusal);\n break;\n\n case 'response.function_call_arguments.delta': {\n let toolCall = state.toolCalls.get(event.output_index);\n if (!toolCall) {\n toolCall = { arguments: '' };\n state.toolCalls.set(event.output_index, toolCall);\n }\n if (event.item_id && !toolCall.itemId) {\n toolCall.itemId = event.item_id;\n }\n if (event.call_id && !toolCall.callId) {\n toolCall.callId = event.call_id;\n }\n toolCall.arguments += event.delta;\n events.push({\n type: 'tool_call_delta',\n index: event.output_index,\n delta: {\n toolCallId: toolCall.callId ?? toolCall.itemId ?? '',\n toolName: toolCall.name,\n argumentsJson: event.delta,\n },\n });\n break;\n }\n\n case 'response.function_call_arguments.done': {\n let toolCall = state.toolCalls.get(event.output_index);\n if (!toolCall) {\n toolCall = { arguments: '' };\n state.toolCalls.set(event.output_index, toolCall);\n }\n if (event.item_id) {\n toolCall.itemId = event.item_id;\n }\n if (event.call_id) {\n toolCall.callId = event.call_id;\n }\n toolCall.name = event.name;\n toolCall.arguments = event.arguments;\n break;\n }\n\n case 'response.reasoning.delta':\n // Emit reasoning as a reasoning_delta event\n events.push({\n type: 'reasoning_delta',\n index: 0,\n delta: { text: event.delta },\n });\n break;\n\n case 'error':\n break;\n\n default:\n break;\n }\n\n return events;\n}\n\n/**\n * Builds the final LLMResponse from accumulated Responses API streaming state.\n *\n * Constructs the complete response after streaming has finished, including\n * the assistant message, tool calls, usage statistics, and stop reason.\n *\n * @param state - The accumulated stream state\n * @returns Complete UPP LLMResponse\n */\nexport function buildResponseFromState(state: ResponsesStreamState): LLMResponse {\n const content: AssistantContent[] = [];\n let structuredData: unknown;\n\n for (const [, text] of state.textByIndex) {\n if (text) {\n content.push({ type: 'text', text });\n if (structuredData === undefined) {\n try {\n structuredData = JSON.parse(text);\n } catch {\n // Content is not JSON - acceptable for non-structured responses\n }\n }\n }\n }\n\n for (const [, imageData] of state.images) {\n if (imageData) {\n content.push({\n type: 'image',\n mimeType: 'image/png',\n source: { type: 'base64', data: imageData },\n } as ImageBlock);\n }\n }\n\n const toolCalls: ToolCall[] = [];\n const functionCallItems: Array<{\n id: string;\n call_id: string;\n name: string;\n arguments: string;\n }> = [];\n for (const [, toolCall] of state.toolCalls) {\n let args: Record<string, unknown> = {};\n if (toolCall.arguments) {\n try {\n args = JSON.parse(toolCall.arguments);\n } catch {\n // Invalid JSON arguments - use empty object as fallback\n }\n }\n const itemId = toolCall.itemId ?? '';\n const callId = toolCall.callId ?? toolCall.itemId ?? '';\n const name = toolCall.name ?? '';\n toolCalls.push({\n toolCallId: callId,\n toolName: name,\n arguments: args,\n });\n\n if (itemId && callId && name) {\n functionCallItems.push({\n id: itemId,\n call_id: callId,\n name,\n arguments: toolCall.arguments,\n });\n }\n }\n\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: state.id,\n metadata: {\n openrouter: {\n model: state.model,\n status: state.status,\n // Store response_id for multi-turn tool calling\n response_id: state.id,\n functionCallItems:\n functionCallItems.length > 0 ? functionCallItems : undefined,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n cacheReadTokens: state.cacheReadTokens,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n if (state.status === 'completed') {\n stopReason = toolCalls.length > 0 ? 'tool_use' : 'end_turn';\n } else if (state.status === 'failed') {\n stopReason = 'error';\n }\n if (state.hadRefusal && stopReason !== 'error') {\n stopReason = 'content_filter';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * OpenRouter Responses API LLM handler.\n *\n * This module implements the LLMHandler interface for OpenRouter's Responses API,\n * which is currently in beta and provides additional features like reasoning support.\n *\n * @module llm.responses\n */\n\nimport type { LLMHandler, BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport type { OpenRouterResponsesParams, OpenRouterResponsesResponse, OpenRouterResponsesStreamEvent, OpenRouterResponseErrorEvent } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.responses.ts';\n\n/** Base URL for OpenRouter's Responses API endpoint (beta). */\nconst OPENROUTER_RESPONSES_API_URL = 'https://openrouter.ai/api/v1/responses';\n\n/**\n * Capability flags for the OpenRouter Responses API.\n *\n * The Responses API shares the same capabilities as the Completions API,\n * with additional support for reasoning models.\n */\nconst OPENROUTER_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n imageOutput: true,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Creates an LLM handler for OpenRouter's Responses API (beta).\n *\n * The Responses API provides a different interface than Chat Completions,\n * with features like reasoning effort configuration and different output formats.\n *\n * @returns An LLMHandler configured for OpenRouter Responses API\n *\n * @example\n * ```typescript\n * const handler = createResponsesLLMHandler();\n * handler._setProvider(provider);\n * const model = handler.bind('openai/gpt-4o');\n * const response = await model.complete(request);\n * ```\n */\nexport function createResponsesLLMHandler(): LLMHandler<OpenRouterResponsesParams> {\n let providerRef: LLMProvider<OpenRouterResponsesParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<OpenRouterResponsesParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<OpenRouterResponsesParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider() or have _setProvider called.',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n\n const model: BoundLLMModel<OpenRouterResponsesParams> = {\n modelId,\n capabilities: OPENROUTER_CAPABILITIES,\n\n get provider(): LLMProvider<OpenRouterResponsesParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<OpenRouterResponsesParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_RESPONSES_API_URL;\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'openrouter',\n 'llm'\n );\n\n const data = (await response.json()) as OpenRouterResponsesResponse;\n\n // Check for error in response\n if (data.status === 'failed' && data.error) {\n throw new UPPError(\n data.error.message,\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n }\n\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<OpenRouterResponsesParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_RESPONSES_API_URL;\n const body = transformRequest(request, modelId);\n body.stream = true;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'openrouter',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'openrouter', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n // Skip [DONE] marker\n if (data === '[DONE]') {\n continue;\n }\n\n // Check for OpenRouter error event\n if (typeof data === 'object' && data !== null) {\n const event = data as OpenRouterResponsesStreamEvent;\n\n // Check for error event\n if (event.type === 'error') {\n const errorEvent = event as OpenRouterResponseErrorEvent;\n const error = new UPPError(\n errorEvent.error.message,\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n const uppEvents = transformStreamEvent(event, state);\n for (const uppEvent of uppEvents) {\n yield uppEvent;\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n responseReject(error as Error);\n throw error;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview OpenRouter Embeddings API Handler\n *\n * This module implements the embedding handler for OpenRouter's embeddings API.\n * OpenRouter provides access to multiple embedding providers through an OpenAI-compatible endpoint.\n *\n * @see {@link https://openrouter.ai/docs/api/reference/embeddings OpenRouter Embeddings API Reference}\n * @module providers/openrouter/embed\n */\n\nimport type {\n EmbeddingHandler,\n BoundEmbeddingModel,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch } from '../../http/fetch.ts';\n\n/** Base URL for OpenRouter's Embeddings API endpoint */\nconst OPENROUTER_EMBEDDINGS_API_URL = 'https://openrouter.ai/api/v1/embeddings';\n\n/**\n * OpenRouter embedding parameters.\n * Passed through unchanged to the API.\n */\nexport interface OpenRouterEmbedParams {\n /** Output dimensions (model-dependent) */\n dimensions?: number;\n /** Encoding format: 'float' or 'base64' */\n encoding_format?: 'float' | 'base64';\n /** A unique identifier representing your end-user */\n user?: string;\n /** Input type hint for some models */\n input_type?: string;\n}\n\n/**\n * OpenRouter embeddings API response structure (OpenAI-compatible).\n */\ninterface OpenRouterEmbeddingsResponse {\n id: string;\n object: 'list';\n data: Array<{\n index: number;\n embedding: number[] | string;\n type: 'embedding';\n }>;\n model: string;\n usage: {\n prompt_tokens: number;\n total_tokens: number;\n cost?: number;\n };\n}\n\n/**\n * Get default dimensions for a model.\n */\nfunction getDefaultDimensions(modelId: string): number {\n if (modelId.includes('text-embedding-3-large')) {\n return 3072;\n }\n if (modelId.includes('text-embedding-3-small') || modelId.includes('ada-002')) {\n return 1536;\n }\n if (modelId.includes('gemini-embedding')) {\n return 3072;\n }\n return 1536;\n}\n\n/**\n * Creates an embedding handler for OpenRouter's Embeddings API.\n *\n * @returns An embedding handler configured for OpenRouter\n *\n * @example\n * ```typescript\n * const handler = createEmbeddingHandler();\n * const model = handler.bind('openai/text-embedding-3-large');\n *\n * const response = await model.embed({\n * inputs: ['Hello world'],\n * config: { apiKey: 'sk-or-...' }\n * });\n * ```\n */\nexport function createEmbeddingHandler(): EmbeddingHandler<OpenRouterEmbedParams> {\n let providerRef: EmbeddingProvider<OpenRouterEmbedParams> | null = null;\n\n return {\n supportedInputs: ['text'],\n\n _setProvider(provider: EmbeddingProvider<OpenRouterEmbedParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundEmbeddingModel<OpenRouterEmbedParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n 'INVALID_REQUEST',\n 'openrouter',\n 'embedding'\n );\n }\n\n const model: BoundEmbeddingModel<OpenRouterEmbedParams> = {\n modelId,\n maxBatchSize: 2048,\n maxInputLength: 8191,\n dimensions: getDefaultDimensions(modelId),\n\n get provider(): EmbeddingProvider<OpenRouterEmbedParams> {\n return providerRef!;\n },\n\n async embed(request: EmbeddingRequest<OpenRouterEmbedParams>): Promise<EmbeddingResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'embedding'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_EMBEDDINGS_API_URL;\n\n // Transform inputs to strings\n const inputTexts = request.inputs.map((input) => {\n if (typeof input === 'string') {\n return input;\n }\n if ('text' in input) {\n return input.text;\n }\n throw new UPPError(\n 'OpenRouter embeddings only support text input',\n 'INVALID_REQUEST',\n 'openrouter',\n 'embedding'\n );\n });\n\n // Build request body - params pass through unchanged\n const body: Record<string, unknown> = {\n model: modelId,\n input: inputTexts,\n };\n\n // Pass through OpenRouter-specific params\n if (request.params?.dimensions !== undefined) {\n body.dimensions = request.params.dimensions;\n }\n if (request.params?.encoding_format !== undefined) {\n body.encoding_format = request.params.encoding_format;\n }\n if (request.params?.user !== undefined) {\n body.user = request.params.user;\n }\n if (request.params?.input_type !== undefined) {\n body.input_type = request.params.input_type;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n // Merge custom headers\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(baseUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n }, request.config, 'openrouter', 'embedding');\n\n const data = await response.json() as OpenRouterEmbeddingsResponse;\n\n // Return EmbeddingResponse - vector is floats or base64 string\n return {\n embeddings: data.data.map((d) => ({\n vector: d.embedding,\n index: d.index,\n })),\n usage: { totalTokens: data.usage.total_tokens },\n metadata: data.usage.cost !== undefined ? { cost: data.usage.cost } : undefined,\n };\n },\n };\n\n return model;\n },\n };\n}\n","import type {\n Provider,\n ModelReference,\n LLMHandler,\n LLMProvider,\n EmbeddingHandler,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { createCompletionsLLMHandler } from './llm.completions.ts';\nimport { createResponsesLLMHandler } from './llm.responses.ts';\nimport { createEmbeddingHandler, type OpenRouterEmbedParams } from './embed.ts';\nimport type { OpenRouterCompletionsParams, OpenRouterResponsesParams } from './types.ts';\n\n/**\n * Union type for both Completions and Responses API parameter types.\n * Used internally to type the modalities handler.\n */\ntype OpenRouterLLMParamsUnion = OpenRouterCompletionsParams | OpenRouterResponsesParams;\n\n/**\n * Configuration options for creating an OpenRouter model reference.\n *\n * OpenRouter supports two distinct APIs:\n * - Chat Completions API: Stable, production-ready, supports most models\n * - Responses API: Beta, supports advanced features like reasoning\n */\nexport interface OpenRouterProviderOptions {\n /**\n * Which OpenRouter API to use.\n *\n * - `'completions'`: Chat Completions API (default, recommended for production)\n * - `'responses'`: Responses API (beta, supports reasoning models)\n */\n api?: 'completions' | 'responses';\n}\n\n/**\n * OpenRouter provider interface with configurable API mode.\n *\n * OpenRouter is a unified API that provides access to hundreds of AI models\n * through a single endpoint, including models from OpenAI, Anthropic, Google,\n * Meta, Mistral, and many others.\n *\n * @example Using the Chat Completions API (default)\n * ```typescript\n * const model = openrouter('openai/gpt-4o');\n * ```\n *\n * @example Using the Responses API (beta)\n * ```typescript\n * const model = openrouter('openai/gpt-4o', { api: 'responses' });\n * ```\n *\n * @example Using Anthropic models\n * ```typescript\n * const model = openrouter('anthropic/claude-3.5-sonnet', { api: 'completions' });\n * ```\n */\nexport interface OpenRouterProvider extends Provider<OpenRouterProviderOptions> {\n /**\n * Creates a model reference for the specified model ID.\n *\n * @param modelId - The OpenRouter model identifier in `provider/model` format\n * (e.g., 'openai/gpt-4o', 'anthropic/claude-3.5-sonnet',\n * 'meta-llama/llama-3.1-70b-instruct')\n * @param options - Optional configuration including API selection\n * @returns A model reference that can be passed to llm()\n */\n (modelId: string, options?: OpenRouterProviderOptions): ModelReference<OpenRouterProviderOptions>;\n\n /** Provider identifier. Always 'openrouter'. */\n readonly name: 'openrouter';\n\n /** Semantic version of this provider implementation. */\n readonly version: string;\n\n /**\n * Supported modalities for this provider.\n * OpenRouter supports LLM (text generation) and Embedding.\n */\n readonly modalities: {\n llm: LLMHandler<OpenRouterLLMParamsUnion>;\n embedding: EmbeddingHandler<OpenRouterEmbedParams>;\n };\n}\n\n/**\n * Factory function to create the OpenRouter provider singleton.\n *\n * Creates both Completions and Responses API handlers and manages\n * API mode switching based on the options passed when creating model references.\n *\n * @returns A fully configured OpenRouter provider instance\n * @internal\n */\nfunction createOpenRouterProvider(): OpenRouterProvider {\n let currentApiMode: 'completions' | 'responses' = 'completions';\n\n const completionsHandler = createCompletionsLLMHandler();\n const responsesHandler = createResponsesLLMHandler();\n const embeddingHandler = createEmbeddingHandler();\n\n const fn = function (\n modelId: string,\n options?: OpenRouterProviderOptions\n ): ModelReference<OpenRouterProviderOptions> {\n const apiMode = options?.api ?? 'completions';\n currentApiMode = apiMode;\n return { modelId, provider };\n };\n\n const modalities = {\n get llm(): LLMHandler<OpenRouterLLMParamsUnion> {\n return currentApiMode === 'responses'\n ? (responsesHandler as unknown as LLMHandler<OpenRouterLLMParamsUnion>)\n : (completionsHandler as unknown as LLMHandler<OpenRouterLLMParamsUnion>);\n },\n embedding: embeddingHandler,\n };\n\n Object.defineProperties(fn, {\n name: {\n value: 'openrouter',\n writable: false,\n configurable: true,\n },\n version: {\n value: '1.0.0',\n writable: false,\n configurable: true,\n },\n modalities: {\n value: modalities,\n writable: false,\n configurable: true,\n },\n });\n\n const provider = fn as OpenRouterProvider;\n\n completionsHandler._setProvider?.(provider as unknown as LLMProvider<OpenRouterCompletionsParams>);\n responsesHandler._setProvider?.(provider as unknown as LLMProvider<OpenRouterResponsesParams>);\n embeddingHandler._setProvider?.(provider as unknown as EmbeddingProvider<OpenRouterEmbedParams>);\n\n return provider;\n}\n\n/**\n * OpenRouter provider singleton.\n *\n * OpenRouter is a unified API that provides access to hundreds of AI models\n * through a single endpoint, including models from OpenAI, Anthropic, Google,\n * Meta, Mistral, and many others.\n *\n * Supports both the Chat Completions API (default) and Responses API (beta).\n *\n * @example Basic usage with Chat Completions API\n * ```typescript\n * import { openrouter } from './providers/openrouter';\n * import { llm } from './core/llm';\n *\n * const model = llm({\n * model: openrouter('openai/gpt-4o'),\n * params: { max_tokens: 1000 }\n * });\n *\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Using the Responses API (beta)\n * ```typescript\n * const betaModel = llm({\n * model: openrouter('openai/gpt-4o', { api: 'responses' }),\n * params: { max_output_tokens: 1000 }\n * });\n * ```\n *\n * @example Model routing and fallback configuration\n * ```typescript\n * const routedModel = llm({\n * model: openrouter('openai/gpt-4o'),\n * params: {\n * max_tokens: 1000,\n * models: ['openai/gpt-4o', 'anthropic/claude-3.5-sonnet'],\n * route: 'fallback',\n * provider: {\n * allow_fallbacks: true,\n * require_parameters: true,\n * },\n * }\n * });\n * ```\n *\n * @see {@link https://openrouter.ai/docs | OpenRouter Documentation}\n */\nexport const openrouter = createOpenRouterProvider();\n\nexport type {\n OpenRouterCompletionsParams,\n OpenRouterResponsesParams,\n OpenRouterConfig,\n OpenRouterAPIMode,\n OpenRouterModelOptions,\n OpenRouterModelReference,\n OpenRouterProviderPreferences,\n OpenRouterImageConfig,\n OpenRouterHeaders,\n} from './types.ts';\n\nexport type { OpenRouterEmbedParams } from './embed.ts';\n"],"mappings":"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","names":["transformRequest","transformTool","transformMessage","filterValidContent","transformResponse","createStreamState","transformStreamEvent","buildResponseFromState","OPENROUTER_CAPABILITIES","transformRequest","transformResponse","createStreamState","transformStreamEvent","buildResponseFromState"]}
|
|
1
|
+
{"version":3,"sources":["../../src/providers/openrouter/transform.completions.ts","../../src/providers/openrouter/llm.completions.ts","../../src/providers/openrouter/transform.responses.ts","../../src/providers/openrouter/llm.responses.ts","../../src/providers/openrouter/embed.ts","../../src/providers/openrouter/index.ts"],"sourcesContent":["/**\n * Transform utilities for OpenRouter Chat Completions API.\n *\n * This module handles bidirectional conversion between UPP (Unified Provider Protocol)\n * request/response formats and OpenRouter's Chat Completions API format, which is\n * compatible with the OpenAI Chat Completions API.\n *\n * @module transform.completions\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock, AssistantContent } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { generateId } from '../../utils/id.ts';\nimport type {\n OpenRouterCompletionsParams,\n OpenRouterCompletionsRequest,\n OpenRouterCompletionsMessage,\n OpenRouterSystemContent,\n OpenRouterUserContent,\n OpenRouterCompletionsTool,\n OpenRouterCompletionsResponse,\n OpenRouterCompletionsStreamChunk,\n OpenRouterToolCall,\n OpenRouterCacheControl,\n} from './types.ts';\n\n/**\n * Transforms a UPP LLMRequest into an OpenRouter Chat Completions API request body.\n *\n * Parameters are spread directly to enable pass-through of any OpenRouter API fields,\n * even those not explicitly defined in our types. This allows developers to use new\n * API features without waiting for library updates.\n *\n * @param request - The UPP LLM request containing messages, tools, and parameters\n * @param modelId - The OpenRouter model identifier (e.g., 'openai/gpt-4o')\n * @returns A fully formed OpenRouter Chat Completions request body\n */\nexport function transformRequest(\n request: LLMRequest<OpenRouterCompletionsParams>,\n modelId: string\n): OpenRouterCompletionsRequest {\n const params = request.params ?? ({} as OpenRouterCompletionsParams);\n\n const openrouterRequest: OpenRouterCompletionsRequest = {\n ...params,\n model: modelId,\n messages: transformMessages(request.messages, request.system),\n };\n\n if (request.tools && request.tools.length > 0) {\n openrouterRequest.tools = request.tools.map(transformTool);\n }\n\n if (request.structure) {\n const schema: Record<string, unknown> = {\n type: 'object',\n properties: request.structure.properties,\n required: request.structure.required,\n ...(request.structure.additionalProperties !== undefined\n ? { additionalProperties: request.structure.additionalProperties }\n : { additionalProperties: false }),\n };\n if (request.structure.description) {\n schema.description = request.structure.description;\n }\n\n openrouterRequest.response_format = {\n type: 'json_schema',\n json_schema: {\n name: 'json_response',\n description: request.structure.description,\n schema,\n strict: true,\n },\n };\n }\n\n return openrouterRequest;\n}\n\n/**\n * Transforms UPP messages into OpenRouter Chat Completions message format.\n *\n * Handles system prompts, user messages, assistant messages, and tool results.\n * Tool result messages are expanded into individual tool messages.\n *\n * System prompts support both string and array formats:\n * - String: Simple text system prompt\n * - Array: Content blocks with optional cache_control for Anthropic/Gemini models\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt (string or array with cache_control)\n * @returns Array of OpenRouter-formatted messages\n */\nfunction transformMessages(\n messages: Message[],\n system?: string | unknown[]\n): OpenRouterCompletionsMessage[] {\n const result: OpenRouterCompletionsMessage[] = [];\n\n if (system !== undefined && system !== null) {\n const normalizedSystem = normalizeSystem(system);\n if (typeof normalizedSystem === 'string') {\n if (normalizedSystem.length > 0) {\n result.push({\n role: 'system',\n content: normalizedSystem,\n });\n }\n } else if (normalizedSystem.length > 0) {\n result.push({\n role: 'system',\n content: normalizedSystem,\n });\n }\n }\n\n for (const message of messages) {\n if (isToolResultMessage(message)) {\n const toolMessages = transformToolResults(message);\n result.push(...toolMessages);\n } else {\n const transformed = transformMessage(message);\n if (transformed) {\n result.push(transformed);\n }\n }\n }\n\n return result;\n}\n\nfunction normalizeSystem(system: string | unknown[]): string | OpenRouterSystemContent[] {\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text blocks',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n\n const blocks: OpenRouterSystemContent[] = [];\n for (const block of system) {\n if (!block || typeof block !== 'object') {\n throw new UPPError(\n 'System prompt array must contain objects with type \"text\"',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n const candidate = block as { type?: unknown; text?: unknown; cache_control?: unknown };\n if (candidate.type !== 'text' || typeof candidate.text !== 'string') {\n throw new UPPError(\n 'OpenRouter system blocks must be of type \"text\" with a string text field',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n if (candidate.cache_control !== undefined && !isValidCacheControl(candidate.cache_control)) {\n throw new UPPError(\n 'Invalid cache_control for OpenRouter system prompt',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n blocks.push(block as OpenRouterSystemContent);\n }\n\n return blocks;\n}\n\nfunction isValidCacheControl(value: unknown): value is OpenRouterCacheControl {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as { type?: unknown; ttl?: unknown };\n if (candidate.type !== 'ephemeral') return false;\n if (candidate.ttl !== undefined && candidate.ttl !== '1h') return false;\n return true;\n}\n\n/**\n * Filters content blocks to only those with a valid type property.\n *\n * @param content - Array of content blocks to filter\n * @returns Filtered array containing only blocks with string type properties\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Extracts cache control configuration from message metadata.\n *\n * @param message - The message to extract cache control from\n * @returns The cache control configuration if present, undefined otherwise\n */\nfunction extractCacheControl(message: Message): OpenRouterCacheControl | undefined {\n const openrouterMeta = message.metadata?.openrouter as\n | { cache_control?: OpenRouterCacheControl }\n | undefined;\n return openrouterMeta?.cache_control;\n}\n\n/**\n * Transforms a single UPP message to OpenRouter Chat Completions format.\n *\n * Cache control can be specified via message metadata:\n * ```typescript\n * new UserMessage(content, {\n * metadata: { openrouter: { cache_control: { type: \"ephemeral\" } } }\n * })\n * ```\n *\n * @param message - The UPP message to transform\n * @returns The transformed OpenRouter message, or null if the message type is unsupported\n */\nfunction transformMessage(message: Message): OpenRouterCompletionsMessage | null {\n if (isUserMessage(message)) {\n const validContent = filterValidContent(message.content);\n const cacheControl = extractCacheControl(message);\n\n // If cache_control is present, always use array format to attach it\n if (cacheControl) {\n const content = validContent.map(transformContentBlock);\n // Apply cache_control to the last text content block\n for (let i = content.length - 1; i >= 0; i--) {\n const block = content[i];\n if (block?.type === 'text') {\n content[i] = { type: 'text', text: block.text, cache_control: cacheControl };\n break;\n }\n }\n return { role: 'user', content };\n }\n\n // No cache_control: use string shortcut for single text block\n if (validContent.length === 1 && validContent[0]?.type === 'text') {\n return {\n role: 'user',\n content: (validContent[0] as TextBlock).text,\n };\n }\n return {\n role: 'user',\n content: validContent.map(transformContentBlock),\n };\n }\n\n if (isAssistantMessage(message)) {\n const validContent = filterValidContent(message.content);\n const textContent = validContent\n .filter((c): c is TextBlock => c.type === 'text')\n .map((c) => c.text)\n .join('');\n\n const assistantMessage: OpenRouterCompletionsMessage = {\n role: 'assistant',\n content: textContent || null,\n };\n\n if (message.toolCalls && message.toolCalls.length > 0) {\n (assistantMessage as { tool_calls?: OpenRouterToolCall[] }).tool_calls =\n message.toolCalls.map((call) => ({\n id: call.toolCallId,\n type: 'function' as const,\n function: {\n name: call.toolName,\n arguments: JSON.stringify(call.arguments),\n },\n }));\n }\n\n return assistantMessage;\n }\n\n if (isToolResultMessage(message)) {\n const results = message.results.map((result) => ({\n role: 'tool' as const,\n tool_call_id: result.toolCallId,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n\n return results[0] ?? null;\n }\n\n return null;\n}\n\n/**\n * Transforms a tool result message into multiple OpenRouter tool messages.\n *\n * Each tool result in the UPP ToolResultMessage becomes a separate OpenRouter\n * tool message with the corresponding tool_call_id.\n *\n * @param message - The UPP message (expected to be a ToolResultMessage)\n * @returns Array of OpenRouter tool messages\n */\nexport function transformToolResults(\n message: Message\n): OpenRouterCompletionsMessage[] {\n if (!isToolResultMessage(message)) {\n const single = transformMessage(message);\n return single ? [single] : [];\n }\n\n return message.results.map((result) => ({\n role: 'tool' as const,\n tool_call_id: result.toolCallId,\n content:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n}\n\n/**\n * Transforms a UPP content block to OpenRouter user content format.\n *\n * Supports text and image content types. Images are converted to data URLs\n * or passed through as URL references.\n *\n * @param block - The UPP content block to transform\n * @returns OpenRouter user content part\n * @throws Error if the content type is unsupported\n */\nfunction transformContentBlock(block: ContentBlock): OpenRouterUserContent {\n switch (block.type) {\n case 'text':\n return { type: 'text', text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n let url: string;\n\n if (imageBlock.source.type === 'base64') {\n url = `data:${imageBlock.mimeType};base64,${imageBlock.source.data}`;\n } else if (imageBlock.source.type === 'url') {\n url = imageBlock.source.url;\n } else if (imageBlock.source.type === 'bytes') {\n // Convert bytes to base64\n const base64 = btoa(\n Array.from(imageBlock.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n url = `data:${imageBlock.mimeType};base64,${base64}`;\n } else {\n throw new Error('Unknown image source type');\n }\n\n return {\n type: 'image_url',\n image_url: { url },\n };\n }\n\n default:\n throw new Error(`Unsupported content type: ${block.type}`);\n }\n}\n\n/**\n * Transforms a UPP Tool definition to OpenRouter function tool format.\n *\n * @param tool - The UPP tool definition\n * @returns OpenRouter function tool definition\n */\nfunction transformTool(tool: Tool): OpenRouterCompletionsTool {\n return {\n type: 'function',\n function: {\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n },\n };\n}\n\n/**\n * Transforms an OpenRouter Chat Completions API response to UPP LLMResponse format.\n *\n * Extracts text content, tool calls, usage statistics, and stop reason from\n * the OpenRouter response. Attempts to parse JSON content for structured output.\n *\n * @param data - The raw OpenRouter Chat Completions response\n * @returns UPP-formatted LLM response\n * @throws Error if no choices are present in the response\n */\nexport function transformResponse(data: OpenRouterCompletionsResponse): LLMResponse {\n const choice = data.choices[0];\n if (!choice) {\n throw new Error('No choices in OpenRouter response');\n }\n\n const content: AssistantContent[] = [];\n let structuredData: unknown;\n if (choice.message.content) {\n content.push({ type: 'text', text: choice.message.content });\n try {\n structuredData = JSON.parse(choice.message.content);\n } catch {\n // Content is not JSON - acceptable for non-structured responses\n }\n }\n\n if (choice.message.images && choice.message.images.length > 0) {\n for (const image of choice.message.images) {\n const imageBlock = parseGeneratedImage(image.image_url.url);\n if (imageBlock) {\n content.push(imageBlock);\n }\n }\n }\n\n const toolCalls: ToolCall[] = [];\n if (choice.message.tool_calls) {\n for (const call of choice.message.tool_calls) {\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(call.function.arguments);\n } catch {\n // Invalid JSON arguments - use empty object as fallback\n }\n toolCalls.push({\n toolCallId: call.id,\n toolName: call.function.name,\n arguments: args,\n });\n }\n }\n\n const responseId = data.id || generateId();\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: responseId,\n metadata: {\n openrouter: {\n model: data.model,\n finish_reason: choice.finish_reason,\n system_fingerprint: data.system_fingerprint,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usage.prompt_tokens,\n outputTokens: data.usage.completion_tokens,\n totalTokens: data.usage.total_tokens,\n cacheReadTokens: data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n switch (choice.finish_reason) {\n case 'stop':\n stopReason = 'end_turn';\n break;\n case 'length':\n stopReason = 'max_tokens';\n break;\n case 'tool_calls':\n stopReason = 'tool_use';\n break;\n case 'content_filter':\n stopReason = 'content_filter';\n break;\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Parses a generated image data URL into an ImageBlock.\n *\n * @param dataUrl - The data URL from the image generation response\n * @returns An ImageBlock or null if parsing fails\n */\nfunction parseGeneratedImage(dataUrl: string): ImageBlock | null {\n const match = dataUrl.match(/^data:(image\\/[^;]+);base64,(.+)$/);\n if (!match) {\n return null;\n }\n const [, mimeType, data] = match;\n if (!mimeType || !data) {\n return null;\n }\n return {\n type: 'image',\n mimeType,\n source: { type: 'base64', data },\n };\n}\n\n/**\n * Mutable state object for accumulating streaming response data.\n *\n * Used during streaming to collect text deltas, tool call fragments,\n * and usage statistics before building the final LLMResponse.\n */\nexport interface CompletionsStreamState {\n /** Response ID from the first chunk */\n id: string;\n /** Model identifier from the response */\n model: string;\n /** Accumulated text content */\n text: string;\n /** Map of tool call index to accumulated tool call data */\n toolCalls: Map<number, { id: string; name: string; arguments: string }>;\n /** Generated image data URLs from image generation models */\n images: string[];\n /** Final finish reason from the stream */\n finishReason: string | null;\n /** Input token count from usage */\n inputTokens: number;\n /** Output token count from usage */\n outputTokens: number;\n /** Number of tokens read from cache */\n cacheReadTokens: number;\n}\n\n/**\n * Creates an empty stream state object for accumulating streaming data.\n *\n * @returns A new CompletionsStreamState with all fields initialized\n */\nexport function createStreamState(): CompletionsStreamState {\n return {\n id: '',\n model: '',\n text: '',\n toolCalls: new Map(),\n images: [],\n finishReason: null,\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n };\n}\n\n/**\n * Transforms an OpenRouter streaming chunk into UPP StreamEvents.\n *\n * Processes the chunk to extract text deltas, tool call updates, and finish signals.\n * Updates the provided state object with accumulated data. Returns an array because\n * a single chunk may produce multiple events (e.g., text delta and tool call delta).\n *\n * @param chunk - The OpenRouter streaming chunk to process\n * @param state - The mutable state object to update with chunk data\n * @returns Array of UPP StreamEvents generated from this chunk\n */\nexport function transformStreamEvent(\n chunk: OpenRouterCompletionsStreamChunk,\n state: CompletionsStreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n if (chunk.id && !state.id) {\n state.id = chunk.id;\n events.push({ type: 'message_start', index: 0, delta: {} });\n }\n if (chunk.model) {\n state.model = chunk.model;\n }\n\n const choice = chunk.choices[0];\n if (choice) {\n if (choice.delta.content) {\n state.text += choice.delta.content;\n events.push({\n type: 'text_delta',\n index: 0,\n delta: { text: choice.delta.content },\n });\n }\n\n if (choice.delta.tool_calls) {\n for (const toolCallDelta of choice.delta.tool_calls) {\n const index = toolCallDelta.index;\n let toolCall = state.toolCalls.get(index);\n\n if (!toolCall) {\n toolCall = { id: '', name: '', arguments: '' };\n state.toolCalls.set(index, toolCall);\n }\n\n if (toolCallDelta.id) {\n toolCall.id = toolCallDelta.id;\n }\n if (toolCallDelta.function?.name) {\n toolCall.name = toolCallDelta.function.name;\n }\n if (toolCallDelta.function?.arguments) {\n toolCall.arguments += toolCallDelta.function.arguments;\n events.push({\n type: 'tool_call_delta',\n index: index,\n delta: {\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n argumentsJson: toolCallDelta.function.arguments,\n },\n });\n }\n }\n }\n\n if (choice.delta.images) {\n for (const image of choice.delta.images) {\n state.images.push(image.image_url.url);\n }\n }\n\n if (choice.finish_reason) {\n state.finishReason = choice.finish_reason;\n events.push({ type: 'message_stop', index: 0, delta: {} });\n }\n }\n\n if (chunk.usage) {\n state.inputTokens = chunk.usage.prompt_tokens;\n state.outputTokens = chunk.usage.completion_tokens;\n state.cacheReadTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? 0;\n }\n\n return events;\n}\n\n/**\n * Builds the final LLMResponse from accumulated streaming state.\n *\n * Constructs the complete response after streaming has finished, including\n * the assistant message, tool calls, usage statistics, and stop reason.\n *\n * @param state - The accumulated stream state\n * @returns Complete UPP LLMResponse\n */\nexport function buildResponseFromState(state: CompletionsStreamState): LLMResponse {\n const content: AssistantContent[] = [];\n let structuredData: unknown;\n if (state.text) {\n content.push({ type: 'text', text: state.text });\n try {\n structuredData = JSON.parse(state.text);\n } catch {\n // Content is not JSON - acceptable for non-structured responses\n }\n }\n\n for (const imageUrl of state.images) {\n const imageBlock = parseGeneratedImage(imageUrl);\n if (imageBlock) {\n content.push(imageBlock);\n }\n }\n\n const toolCalls: ToolCall[] = [];\n for (const [, toolCall] of state.toolCalls) {\n let args: Record<string, unknown> = {};\n if (toolCall.arguments) {\n try {\n args = JSON.parse(toolCall.arguments);\n } catch {\n // Invalid JSON arguments - use empty object as fallback\n }\n }\n toolCalls.push({\n toolCallId: toolCall.id,\n toolName: toolCall.name,\n arguments: args,\n });\n }\n\n const messageId = state.id || generateId();\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: messageId,\n metadata: {\n openrouter: {\n model: state.model,\n finish_reason: state.finishReason,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n cacheReadTokens: state.cacheReadTokens,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n switch (state.finishReason) {\n case 'stop':\n stopReason = 'end_turn';\n break;\n case 'length':\n stopReason = 'max_tokens';\n break;\n case 'tool_calls':\n stopReason = 'tool_use';\n break;\n case 'content_filter':\n stopReason = 'content_filter';\n break;\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * OpenRouter Chat Completions API LLM handler.\n *\n * This module implements the LLMHandler interface for OpenRouter's Chat Completions API,\n * which is compatible with the OpenAI Chat Completions API format.\n *\n * @module llm.completions\n */\n\nimport type { LLMHandler, BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { OpenRouterCompletionsParams, OpenRouterCompletionsResponse, OpenRouterCompletionsStreamChunk } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.completions.ts';\n\n/** Base URL for OpenRouter's Chat Completions API endpoint. */\nconst OPENROUTER_API_URL = 'https://openrouter.ai/api/v1/chat/completions';\n\n/**\n * Capability flags for the OpenRouter Chat Completions API.\n *\n * OpenRouter supports streaming, function calling (tools), structured JSON output,\n * and image inputs. Video and audio inputs are not currently supported.\n */\nconst OPENROUTER_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n imageOutput: true,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Creates an LLM handler for OpenRouter's Chat Completions API.\n *\n * This handler implements the UPP LLMHandler interface and provides\n * both synchronous completion and streaming capabilities.\n *\n * @returns An LLMHandler configured for OpenRouter Chat Completions\n *\n * @example\n * ```typescript\n * const handler = createCompletionsLLMHandler();\n * handler._setProvider(provider);\n * const model = handler.bind('openai/gpt-4o');\n * const response = await model.complete(request);\n * ```\n */\nexport function createCompletionsLLMHandler(): LLMHandler<OpenRouterCompletionsParams> {\n let providerRef: LLMProvider<OpenRouterCompletionsParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<OpenRouterCompletionsParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<OpenRouterCompletionsParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider() or have _setProvider called.',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n\n const model: BoundLLMModel<OpenRouterCompletionsParams> = {\n modelId,\n capabilities: OPENROUTER_CAPABILITIES,\n\n get provider(): LLMProvider<OpenRouterCompletionsParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<OpenRouterCompletionsParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_API_URL;\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'openrouter',\n 'llm'\n );\n\n const data = await parseJsonResponse<OpenRouterCompletionsResponse>(response, 'openrouter', 'llm');\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<OpenRouterCompletionsParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_API_URL;\n const body = transformRequest(request, modelId);\n body.stream = true;\n body.stream_options = { include_usage: true };\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n Accept: 'text/event-stream',\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'openrouter',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'openrouter', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n // Skip [DONE] marker\n if (data === '[DONE]') {\n continue;\n }\n\n // Check for OpenRouter error event\n if (typeof data === 'object' && data !== null) {\n const chunk = data as OpenRouterCompletionsStreamChunk;\n\n // Check for error in chunk\n if ('error' in chunk && chunk.error) {\n const errorData = chunk.error as { message?: string; type?: string };\n const error = new UPPError(\n errorData.message ?? 'Unknown error',\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n const uppEvents = transformStreamEvent(chunk, state);\n for (const event of uppEvents) {\n yield event;\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * Transform utilities for OpenRouter Responses API (beta).\n *\n * This module handles bidirectional conversion between UPP (Unified Provider Protocol)\n * request/response formats and OpenRouter's Responses API format. The Responses API\n * uses a different structure than Chat Completions, with input items and output items.\n *\n * @module transform.responses\n */\n\nimport type { LLMRequest, LLMResponse } from '../../types/llm.ts';\nimport type { Message } from '../../types/messages.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { Tool, ToolCall } from '../../types/tool.ts';\nimport type { TokenUsage } from '../../types/turn.ts';\nimport type { ContentBlock, TextBlock, ImageBlock, AssistantContent } from '../../types/content.ts';\nimport {\n AssistantMessage,\n isUserMessage,\n isAssistantMessage,\n isToolResultMessage,\n} from '../../types/messages.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { generateId } from '../../utils/id.ts';\nimport type {\n OpenRouterResponsesParams,\n OpenRouterResponsesRequest,\n OpenRouterResponsesInputItem,\n OpenRouterResponsesContentPart,\n OpenRouterResponsesTool,\n OpenRouterResponsesResponse,\n OpenRouterResponsesStreamEvent,\n OpenRouterSystemContent,\n OpenRouterCacheControl,\n} from './types.ts';\n\n/**\n * Transforms a UPP LLMRequest into an OpenRouter Responses API request body.\n *\n * Parameters are spread directly to enable pass-through of any OpenRouter API fields,\n * even those not explicitly defined in our types. This allows developers to use new\n * API features without waiting for library updates.\n *\n * @param request - The UPP LLM request containing messages, tools, and parameters\n * @param modelId - The OpenRouter model identifier (e.g., 'openai/gpt-4o')\n * @returns A fully formed OpenRouter Responses API request body\n */\nexport function transformRequest(\n request: LLMRequest<OpenRouterResponsesParams>,\n modelId: string\n): OpenRouterResponsesRequest {\n const params = request.params ?? ({} as OpenRouterResponsesParams);\n\n const openrouterRequest: OpenRouterResponsesRequest = {\n ...params,\n model: modelId,\n input: transformInputItems(request.messages, request.system),\n };\n\n if (request.tools && request.tools.length > 0) {\n openrouterRequest.tools = request.tools.map(transformTool);\n }\n\n if (request.structure) {\n const schema: Record<string, unknown> = {\n type: 'object',\n properties: request.structure.properties,\n required: request.structure.required,\n ...(request.structure.additionalProperties !== undefined\n ? { additionalProperties: request.structure.additionalProperties }\n : { additionalProperties: false }),\n };\n if (request.structure.description) {\n schema.description = request.structure.description;\n }\n\n openrouterRequest.text = {\n format: {\n type: 'json_schema',\n name: 'json_response',\n description: request.structure.description,\n schema,\n strict: true,\n },\n };\n }\n\n return openrouterRequest;\n}\n\n/**\n * Transforms UPP messages into Responses API input items.\n *\n * Handles system prompts, user messages, assistant messages, function calls,\n * and tool results. Returns a string for simple single-message requests.\n *\n * System prompts support both string and array formats for cache_control.\n *\n * @param messages - Array of UPP messages to transform\n * @param system - Optional system prompt (string or array with cache_control)\n * @returns Array of input items, or a simple string for single-message requests\n */\nfunction transformInputItems(\n messages: Message[],\n system?: string | unknown[]\n): OpenRouterResponsesInputItem[] | string {\n const result: OpenRouterResponsesInputItem[] = [];\n\n if (system !== undefined && system !== null) {\n const normalizedSystem = normalizeSystem(system);\n if (typeof normalizedSystem === 'string') {\n if (normalizedSystem.length > 0) {\n result.push({\n type: 'message',\n role: 'system',\n content: normalizedSystem,\n } as OpenRouterResponsesInputItem);\n }\n } else if (normalizedSystem.length > 0) {\n result.push({\n type: 'message',\n role: 'system',\n content: normalizedSystem,\n } as OpenRouterResponsesInputItem);\n }\n }\n\n for (const message of messages) {\n const items = transformMessage(message);\n result.push(...items);\n }\n\n if (result.length === 1 && result[0]?.type === 'message') {\n const item = result[0] as { role?: string; content?: string | unknown[] };\n if (item.role === 'user' && typeof item.content === 'string') {\n return item.content;\n }\n }\n\n return result;\n}\n\nfunction normalizeSystem(system: string | unknown[]): string | OpenRouterSystemContent[] {\n if (typeof system === 'string') return system;\n if (!Array.isArray(system)) {\n throw new UPPError(\n 'System prompt must be a string or an array of text blocks',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n\n const blocks: OpenRouterSystemContent[] = [];\n for (const block of system) {\n if (!block || typeof block !== 'object') {\n throw new UPPError(\n 'System prompt array must contain objects with type \"text\"',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n const candidate = block as { type?: unknown; text?: unknown; cache_control?: unknown };\n if (candidate.type !== 'text' || typeof candidate.text !== 'string') {\n throw new UPPError(\n 'OpenRouter system blocks must be of type \"text\" with a string text field',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n if (candidate.cache_control !== undefined && !isValidCacheControl(candidate.cache_control)) {\n throw new UPPError(\n 'Invalid cache_control for OpenRouter system prompt',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n blocks.push(block as OpenRouterSystemContent);\n }\n\n return blocks;\n}\n\nfunction isValidCacheControl(value: unknown): value is OpenRouterCacheControl {\n if (!value || typeof value !== 'object') return false;\n const candidate = value as { type?: unknown; ttl?: unknown };\n if (candidate.type !== 'ephemeral') return false;\n if (candidate.ttl !== undefined && candidate.ttl !== '1h') return false;\n return true;\n}\n\n/**\n * Filters content blocks to only those with a valid type property.\n *\n * @param content - Array of content blocks to filter\n * @returns Filtered array containing only blocks with string type properties\n */\nfunction filterValidContent<T extends { type?: string }>(content: T[]): T[] {\n return content.filter((c) => c && typeof c.type === 'string');\n}\n\n/**\n * Transforms a single UPP message to Responses API input items.\n *\n * May return multiple input items for messages containing tool calls,\n * as function_call items must be separate from message items.\n *\n * @param message - The UPP message to transform\n * @returns Array of Responses API input items\n */\nfunction transformMessage(message: Message): OpenRouterResponsesInputItem[] {\n if (isUserMessage(message)) {\n const validContent = filterValidContent(message.content);\n if (validContent.length === 1 && validContent[0]?.type === 'text') {\n return [\n {\n type: 'message',\n role: 'user',\n content: (validContent[0] as TextBlock).text,\n },\n ];\n }\n return [\n {\n type: 'message',\n role: 'user',\n content: validContent.map(transformContentPart),\n },\n ];\n }\n\n if (isAssistantMessage(message)) {\n const validContent = filterValidContent(message.content);\n const items: OpenRouterResponsesInputItem[] = [];\n\n const contentParts: OpenRouterResponsesContentPart[] = validContent\n .filter((c): c is TextBlock => c.type === 'text')\n .map((c): OpenRouterResponsesContentPart => ({\n type: 'output_text',\n text: c.text,\n annotations: [],\n }));\n\n const messageId = message.id || generateId();\n\n if (contentParts.length > 0) {\n items.push({\n type: 'message',\n role: 'assistant',\n id: messageId,\n status: 'completed',\n content: contentParts,\n });\n }\n\n const openrouterMeta = message.metadata?.openrouter as\n | { functionCallItems?: Array<{ id: string; call_id: string; name: string; arguments: string }> }\n | undefined;\n const functionCallItems = openrouterMeta?.functionCallItems;\n\n if (functionCallItems && functionCallItems.length > 0) {\n for (const fc of functionCallItems) {\n items.push({\n type: 'function_call',\n id: fc.id,\n call_id: fc.call_id,\n name: fc.name,\n arguments: fc.arguments,\n });\n }\n } else if (message.toolCalls && message.toolCalls.length > 0) {\n for (const call of message.toolCalls) {\n items.push({\n type: 'function_call',\n id: `fc_${call.toolCallId}`,\n call_id: call.toolCallId,\n name: call.toolName,\n arguments: JSON.stringify(call.arguments),\n });\n }\n }\n\n return items;\n }\n\n if (isToolResultMessage(message)) {\n return message.results.map((result, index) => ({\n type: 'function_call_output' as const,\n id: `fco_${result.toolCallId}_${index}`,\n call_id: result.toolCallId,\n output:\n typeof result.result === 'string'\n ? result.result\n : JSON.stringify(result.result),\n }));\n }\n\n return [];\n}\n\n/**\n * Transforms a UPP content block to Responses API content part format.\n *\n * Supports text and image content types. Images are converted to data URLs\n * or passed through as URL references.\n *\n * @param block - The UPP content block to transform\n * @returns Responses API content part\n * @throws Error if the content type is unsupported\n */\nfunction transformContentPart(block: ContentBlock): OpenRouterResponsesContentPart {\n switch (block.type) {\n case 'text':\n return { type: 'input_text', text: block.text };\n\n case 'image': {\n const imageBlock = block as ImageBlock;\n if (imageBlock.source.type === 'base64') {\n return {\n type: 'input_image',\n image_url: `data:${imageBlock.mimeType};base64,${imageBlock.source.data}`,\n detail: 'auto',\n };\n }\n\n if (imageBlock.source.type === 'url') {\n return {\n type: 'input_image',\n image_url: imageBlock.source.url,\n detail: 'auto',\n };\n }\n\n if (imageBlock.source.type === 'bytes') {\n // Convert bytes to base64\n const base64 = btoa(\n Array.from(imageBlock.source.data)\n .map((b) => String.fromCharCode(b))\n .join('')\n );\n return {\n type: 'input_image',\n image_url: `data:${imageBlock.mimeType};base64,${base64}`,\n detail: 'auto',\n };\n }\n\n throw new Error('Unknown image source type');\n }\n\n default:\n throw new Error(`Unsupported content type: ${block.type}`);\n }\n}\n\n/**\n * Transforms a UPP Tool definition to Responses API function tool format.\n *\n * @param tool - The UPP tool definition\n * @returns Responses API function tool definition\n */\nfunction transformTool(tool: Tool): OpenRouterResponsesTool {\n return {\n type: 'function',\n name: tool.name,\n description: tool.description,\n parameters: {\n type: 'object',\n properties: tool.parameters.properties,\n required: tool.parameters.required,\n ...(tool.parameters.additionalProperties !== undefined\n ? { additionalProperties: tool.parameters.additionalProperties }\n : {}),\n },\n };\n}\n\n/**\n * Transforms an OpenRouter Responses API response to UPP LLMResponse format.\n *\n * Extracts text content, tool calls, usage statistics, and stop reason from\n * the Responses API output items. Handles refusals and structured output parsing.\n *\n * @param data - The raw OpenRouter Responses API response\n * @returns UPP-formatted LLM response\n */\nexport function transformResponse(data: OpenRouterResponsesResponse): LLMResponse {\n const content: AssistantContent[] = [];\n const toolCalls: ToolCall[] = [];\n const functionCallItems: Array<{\n id: string;\n call_id: string;\n name: string;\n arguments: string;\n }> = [];\n let hadRefusal = false;\n let structuredData: unknown;\n\n for (const item of data.output) {\n if (item.type === 'message') {\n const messageItem = item;\n for (const part of messageItem.content) {\n if (part.type === 'output_text') {\n content.push({ type: 'text', text: part.text });\n if (structuredData === undefined) {\n try {\n structuredData = JSON.parse(part.text);\n } catch {\n // Content is not JSON - acceptable for non-structured responses\n }\n }\n } else if (part.type === 'refusal') {\n content.push({ type: 'text', text: part.refusal });\n hadRefusal = true;\n }\n }\n } else if (item.type === 'function_call') {\n const functionCall = item;\n let args: Record<string, unknown> = {};\n try {\n args = JSON.parse(functionCall.arguments);\n } catch {\n // Invalid JSON arguments - use empty object as fallback\n }\n toolCalls.push({\n toolCallId: functionCall.call_id,\n toolName: functionCall.name,\n arguments: args,\n });\n functionCallItems.push({\n id: functionCall.id,\n call_id: functionCall.call_id,\n name: functionCall.name,\n arguments: functionCall.arguments,\n });\n } else if (item.type === 'image_generation_call') {\n const imageGen = item;\n if (imageGen.result) {\n content.push({\n type: 'image',\n mimeType: 'image/png',\n source: { type: 'base64', data: imageGen.result },\n } as ImageBlock);\n }\n }\n }\n\n const responseId = data.id || generateId();\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: responseId,\n metadata: {\n openrouter: {\n model: data.model,\n status: data.status,\n // Store response_id for multi-turn tool calling\n response_id: responseId,\n functionCallItems:\n functionCallItems.length > 0 ? functionCallItems : undefined,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: data.usage.input_tokens,\n outputTokens: data.usage.output_tokens,\n totalTokens: data.usage.total_tokens,\n cacheReadTokens: data.usage.input_tokens_details?.cached_tokens ?? 0,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n if (data.status === 'completed') {\n stopReason = toolCalls.length > 0 ? 'tool_use' : 'end_turn';\n } else if (data.status === 'incomplete') {\n stopReason = data.incomplete_details?.reason === 'max_output_tokens'\n ? 'max_tokens'\n : 'end_turn';\n } else if (data.status === 'failed') {\n stopReason = 'error';\n }\n if (hadRefusal && stopReason !== 'error') {\n stopReason = 'content_filter';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n\n/**\n * Mutable state object for accumulating Responses API streaming data.\n *\n * Used during streaming to collect text deltas, tool call fragments,\n * and usage statistics before building the final LLMResponse.\n */\nexport interface ResponsesStreamState {\n /** Response ID from the created event */\n id: string;\n /** Model identifier from the response */\n model: string;\n /** Map of output index to accumulated text content */\n textByIndex: Map<number, string>;\n /** Map of output index to accumulated tool call data */\n toolCalls: Map<\n number,\n { itemId?: string; callId?: string; name?: string; arguments: string }\n >;\n /** Map of output index to generated image data (base64) */\n images: Map<number, string>;\n /** Current response status */\n status: string;\n /** Input token count from usage */\n inputTokens: number;\n /** Output token count from usage */\n outputTokens: number;\n /** Number of tokens read from cache */\n cacheReadTokens: number;\n /** Whether a refusal was encountered */\n hadRefusal: boolean;\n}\n\n/**\n * Creates an empty stream state object for accumulating Responses API streaming data.\n *\n * @returns A new ResponsesStreamState with all fields initialized\n */\nexport function createStreamState(): ResponsesStreamState {\n return {\n id: '',\n model: '',\n textByIndex: new Map(),\n toolCalls: new Map(),\n images: new Map(),\n status: 'in_progress',\n inputTokens: 0,\n outputTokens: 0,\n cacheReadTokens: 0,\n hadRefusal: false,\n };\n}\n\n/**\n * Transforms an OpenRouter Responses API streaming event into UPP StreamEvents.\n *\n * Handles the various Responses API event types including response lifecycle events,\n * output item events, content deltas, function call arguments, and reasoning deltas.\n * Updates the provided state object with accumulated data.\n *\n * @param event - The OpenRouter Responses API streaming event to process\n * @param state - The mutable state object to update with event data\n * @returns Array of UPP StreamEvents generated from this event\n */\nexport function transformStreamEvent(\n event: OpenRouterResponsesStreamEvent,\n state: ResponsesStreamState\n): StreamEvent[] {\n const events: StreamEvent[] = [];\n\n switch (event.type) {\n case 'response.created':\n state.id = event.response.id;\n state.model = event.response.model;\n events.push({ type: 'message_start', index: 0, delta: {} });\n break;\n\n case 'response.in_progress':\n state.status = 'in_progress';\n break;\n\n case 'response.completed':\n case 'response.done':\n state.status = 'completed';\n if (event.response?.usage) {\n state.inputTokens = event.response.usage.input_tokens;\n state.outputTokens = event.response.usage.output_tokens;\n state.cacheReadTokens = event.response.usage.input_tokens_details?.cached_tokens ?? 0;\n }\n if (event.response?.output) {\n for (let i = 0; i < event.response.output.length; i++) {\n const item = event.response.output[i];\n if (item && item.type === 'function_call') {\n const functionCall = item;\n const existing = state.toolCalls.get(i) ?? { arguments: '' };\n existing.itemId = functionCall.id ?? existing.itemId;\n existing.callId = functionCall.call_id ?? existing.callId;\n existing.name = functionCall.name ?? existing.name;\n if (functionCall.arguments) {\n existing.arguments = functionCall.arguments;\n }\n state.toolCalls.set(i, existing);\n }\n }\n }\n events.push({ type: 'message_stop', index: 0, delta: {} });\n break;\n\n case 'response.failed':\n state.status = 'failed';\n events.push({ type: 'message_stop', index: 0, delta: {} });\n break;\n\n case 'response.output_item.added':\n if (event.item.type === 'function_call') {\n const functionCall = event.item;\n const existing = state.toolCalls.get(event.output_index) ?? {\n arguments: '',\n };\n existing.itemId = functionCall.id;\n existing.callId = functionCall.call_id;\n existing.name = functionCall.name;\n if (functionCall.arguments) {\n existing.arguments = functionCall.arguments;\n }\n state.toolCalls.set(event.output_index, existing);\n }\n events.push({\n type: 'content_block_start',\n index: event.output_index,\n delta: {},\n });\n break;\n\n case 'response.output_item.done':\n if (event.item.type === 'function_call') {\n const functionCall = event.item;\n const existing = state.toolCalls.get(event.output_index) ?? {\n arguments: '',\n };\n existing.itemId = functionCall.id;\n existing.callId = functionCall.call_id;\n existing.name = functionCall.name;\n if (functionCall.arguments) {\n existing.arguments = functionCall.arguments;\n }\n state.toolCalls.set(event.output_index, existing);\n } else if (event.item.type === 'message') {\n // Extract text from completed message item (may not have incremental deltas)\n const messageItem = event.item;\n for (const content of messageItem.content || []) {\n if (content.type === 'output_text') {\n const existingText = state.textByIndex.get(event.output_index) ?? '';\n if (!existingText && content.text) {\n // Only use done text if we didn't get incremental deltas\n state.textByIndex.set(event.output_index, content.text);\n events.push({\n type: 'text_delta',\n index: event.output_index,\n delta: { text: content.text },\n });\n }\n }\n }\n } else if (event.item.type === 'image_generation_call') {\n const imageGen = event.item;\n if (imageGen.result) {\n state.images.set(event.output_index, imageGen.result);\n }\n }\n events.push({\n type: 'content_block_stop',\n index: event.output_index,\n delta: {},\n });\n break;\n\n case 'response.content_part.delta':\n case 'response.output_text.delta': {\n const textDelta = (event as { delta: string }).delta;\n const currentText = state.textByIndex.get(event.output_index) ?? '';\n state.textByIndex.set(event.output_index, currentText + textDelta);\n events.push({\n type: 'text_delta',\n index: event.output_index,\n delta: { text: textDelta },\n });\n break;\n }\n\n case 'response.output_text.done':\n case 'response.content_part.done':\n if ('text' in event) {\n state.textByIndex.set(event.output_index, (event as { text: string }).text);\n }\n break;\n\n case 'response.refusal.delta': {\n state.hadRefusal = true;\n const currentRefusal = state.textByIndex.get(event.output_index) ?? '';\n state.textByIndex.set(event.output_index, currentRefusal + event.delta);\n events.push({\n type: 'text_delta',\n index: event.output_index,\n delta: { text: event.delta },\n });\n break;\n }\n\n case 'response.refusal.done':\n state.hadRefusal = true;\n state.textByIndex.set(event.output_index, event.refusal);\n break;\n\n case 'response.function_call_arguments.delta': {\n let toolCall = state.toolCalls.get(event.output_index);\n if (!toolCall) {\n toolCall = { arguments: '' };\n state.toolCalls.set(event.output_index, toolCall);\n }\n if (event.item_id && !toolCall.itemId) {\n toolCall.itemId = event.item_id;\n }\n if (event.call_id && !toolCall.callId) {\n toolCall.callId = event.call_id;\n }\n toolCall.arguments += event.delta;\n events.push({\n type: 'tool_call_delta',\n index: event.output_index,\n delta: {\n toolCallId: toolCall.callId ?? toolCall.itemId ?? '',\n toolName: toolCall.name,\n argumentsJson: event.delta,\n },\n });\n break;\n }\n\n case 'response.function_call_arguments.done': {\n let toolCall = state.toolCalls.get(event.output_index);\n if (!toolCall) {\n toolCall = { arguments: '' };\n state.toolCalls.set(event.output_index, toolCall);\n }\n if (event.item_id) {\n toolCall.itemId = event.item_id;\n }\n if (event.call_id) {\n toolCall.callId = event.call_id;\n }\n toolCall.name = event.name;\n toolCall.arguments = event.arguments;\n break;\n }\n\n case 'response.reasoning.delta':\n // Emit reasoning as a reasoning_delta event\n events.push({\n type: 'reasoning_delta',\n index: 0,\n delta: { text: event.delta },\n });\n break;\n\n case 'error':\n break;\n\n default:\n break;\n }\n\n return events;\n}\n\n/**\n * Builds the final LLMResponse from accumulated Responses API streaming state.\n *\n * Constructs the complete response after streaming has finished, including\n * the assistant message, tool calls, usage statistics, and stop reason.\n *\n * @param state - The accumulated stream state\n * @returns Complete UPP LLMResponse\n */\nexport function buildResponseFromState(state: ResponsesStreamState): LLMResponse {\n const content: AssistantContent[] = [];\n let structuredData: unknown;\n\n for (const [, text] of state.textByIndex) {\n if (text) {\n content.push({ type: 'text', text });\n if (structuredData === undefined) {\n try {\n structuredData = JSON.parse(text);\n } catch {\n // Content is not JSON - acceptable for non-structured responses\n }\n }\n }\n }\n\n for (const [, imageData] of state.images) {\n if (imageData) {\n content.push({\n type: 'image',\n mimeType: 'image/png',\n source: { type: 'base64', data: imageData },\n } as ImageBlock);\n }\n }\n\n const toolCalls: ToolCall[] = [];\n const functionCallItems: Array<{\n id: string;\n call_id: string;\n name: string;\n arguments: string;\n }> = [];\n for (const [, toolCall] of state.toolCalls) {\n let args: Record<string, unknown> = {};\n if (toolCall.arguments) {\n try {\n args = JSON.parse(toolCall.arguments);\n } catch {\n // Invalid JSON arguments - use empty object as fallback\n }\n }\n const itemId = toolCall.itemId ?? '';\n const callId = toolCall.callId ?? toolCall.itemId ?? '';\n const name = toolCall.name ?? '';\n toolCalls.push({\n toolCallId: callId,\n toolName: name,\n arguments: args,\n });\n\n if (itemId && callId && name) {\n functionCallItems.push({\n id: itemId,\n call_id: callId,\n name,\n arguments: toolCall.arguments,\n });\n }\n }\n\n const responseId = state.id || generateId();\n const message = new AssistantMessage(\n content,\n toolCalls.length > 0 ? toolCalls : undefined,\n {\n id: responseId,\n metadata: {\n openrouter: {\n model: state.model,\n status: state.status,\n // Store response_id for multi-turn tool calling\n response_id: responseId,\n functionCallItems:\n functionCallItems.length > 0 ? functionCallItems : undefined,\n },\n },\n }\n );\n\n const usage: TokenUsage = {\n inputTokens: state.inputTokens,\n outputTokens: state.outputTokens,\n totalTokens: state.inputTokens + state.outputTokens,\n cacheReadTokens: state.cacheReadTokens,\n cacheWriteTokens: 0,\n };\n\n let stopReason = 'end_turn';\n if (state.status === 'completed') {\n stopReason = toolCalls.length > 0 ? 'tool_use' : 'end_turn';\n } else if (state.status === 'failed') {\n stopReason = 'error';\n }\n if (state.hadRefusal && stopReason !== 'error') {\n stopReason = 'content_filter';\n }\n\n return {\n message,\n usage,\n stopReason,\n data: structuredData,\n };\n}\n","/**\n * OpenRouter Responses API LLM handler.\n *\n * This module implements the LLMHandler interface for OpenRouter's Responses API,\n * which is currently in beta and provides additional features like reasoning support.\n *\n * @module llm.responses\n */\n\nimport type { LLMHandler, BoundLLMModel, LLMRequest, LLMResponse, LLMStreamResult, LLMCapabilities } from '../../types/llm.ts';\nimport type { StreamEvent } from '../../types/stream.ts';\nimport type { LLMProvider } from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch, doStreamFetch } from '../../http/fetch.ts';\nimport { parseSSEStream } from '../../http/sse.ts';\nimport { normalizeHttpError } from '../../http/errors.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\nimport { toError } from '../../utils/error.ts';\nimport type { OpenRouterResponsesParams, OpenRouterResponsesResponse, OpenRouterResponsesStreamEvent, OpenRouterResponseErrorEvent } from './types.ts';\nimport {\n transformRequest,\n transformResponse,\n transformStreamEvent,\n createStreamState,\n buildResponseFromState,\n} from './transform.responses.ts';\n\n/** Base URL for OpenRouter's Responses API endpoint (beta). */\nconst OPENROUTER_RESPONSES_API_URL = 'https://openrouter.ai/api/v1/responses';\n\n/**\n * Capability flags for the OpenRouter Responses API.\n *\n * The Responses API shares the same capabilities as the Completions API,\n * with additional support for reasoning models.\n */\nconst OPENROUTER_CAPABILITIES: LLMCapabilities = {\n streaming: true,\n tools: true,\n structuredOutput: true,\n imageInput: true,\n imageOutput: true,\n videoInput: false,\n audioInput: false,\n};\n\n/**\n * Creates an LLM handler for OpenRouter's Responses API (beta).\n *\n * The Responses API provides a different interface than Chat Completions,\n * with features like reasoning effort configuration and different output formats.\n *\n * @returns An LLMHandler configured for OpenRouter Responses API\n *\n * @example\n * ```typescript\n * const handler = createResponsesLLMHandler();\n * handler._setProvider(provider);\n * const model = handler.bind('openai/gpt-4o');\n * const response = await model.complete(request);\n * ```\n */\nexport function createResponsesLLMHandler(): LLMHandler<OpenRouterResponsesParams> {\n let providerRef: LLMProvider<OpenRouterResponsesParams> | null = null;\n\n return {\n _setProvider(provider: LLMProvider<OpenRouterResponsesParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundLLMModel<OpenRouterResponsesParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider() or have _setProvider called.',\n 'INVALID_REQUEST',\n 'openrouter',\n 'llm'\n );\n }\n\n const model: BoundLLMModel<OpenRouterResponsesParams> = {\n modelId,\n capabilities: OPENROUTER_CAPABILITIES,\n\n get provider(): LLMProvider<OpenRouterResponsesParams> {\n return providerRef!;\n },\n\n async complete(request: LLMRequest<OpenRouterResponsesParams>): Promise<LLMResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_RESPONSES_API_URL;\n const body = transformRequest(request, modelId);\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'openrouter',\n 'llm'\n );\n\n const data = await parseJsonResponse<OpenRouterResponsesResponse>(response, 'openrouter', 'llm');\n\n // Check for error in response\n if (data.status === 'failed' && data.error) {\n throw new UPPError(\n data.error.message,\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n }\n\n return transformResponse(data);\n },\n\n stream(request: LLMRequest<OpenRouterResponsesParams>): LLMStreamResult {\n const state = createStreamState();\n let responseResolve: (value: LLMResponse) => void;\n let responseReject: (error: Error) => void;\n\n const responsePromise = new Promise<LLMResponse>((resolve, reject) => {\n responseResolve = resolve;\n responseReject = reject;\n });\n\n async function* generateEvents(): AsyncGenerator<StreamEvent, void, unknown> {\n try {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'llm'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_RESPONSES_API_URL;\n const body = transformRequest(request, modelId);\n body.stream = true;\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n Accept: 'text/event-stream',\n };\n\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doStreamFetch(\n baseUrl,\n {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n },\n request.config,\n 'openrouter',\n 'llm'\n );\n\n if (!response.ok) {\n const error = await normalizeHttpError(response, 'openrouter', 'llm');\n responseReject(error);\n throw error;\n }\n\n if (!response.body) {\n const error = new UPPError(\n 'No response body for streaming request',\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n for await (const data of parseSSEStream(response.body)) {\n // Skip [DONE] marker\n if (data === '[DONE]') {\n continue;\n }\n\n // Check for OpenRouter error event\n if (typeof data === 'object' && data !== null) {\n const event = data as OpenRouterResponsesStreamEvent;\n\n // Check for error event\n if (event.type === 'error') {\n const errorEvent = event as OpenRouterResponseErrorEvent;\n const error = new UPPError(\n errorEvent.error.message,\n 'PROVIDER_ERROR',\n 'openrouter',\n 'llm'\n );\n responseReject(error);\n throw error;\n }\n\n const uppEvents = transformStreamEvent(event, state);\n for (const uppEvent of uppEvents) {\n yield uppEvent;\n }\n }\n }\n\n // Build final response\n responseResolve(buildResponseFromState(state));\n } catch (error) {\n const err = toError(error);\n responseReject(err);\n throw err;\n }\n }\n\n return {\n [Symbol.asyncIterator]() {\n return generateEvents();\n },\n response: responsePromise,\n };\n },\n };\n\n return model;\n },\n };\n}\n","/**\n * @fileoverview OpenRouter Embeddings API Handler\n *\n * This module implements the embedding handler for OpenRouter's embeddings API.\n * OpenRouter provides access to multiple embedding providers through an OpenAI-compatible endpoint.\n *\n * @see {@link https://openrouter.ai/docs/api/reference/embeddings OpenRouter Embeddings API Reference}\n * @module providers/openrouter/embed\n */\n\nimport type {\n EmbeddingHandler,\n BoundEmbeddingModel,\n EmbeddingRequest,\n EmbeddingResponse,\n EmbeddingProvider,\n} from '../../types/provider.ts';\nimport { UPPError } from '../../types/errors.ts';\nimport { resolveApiKey } from '../../http/keys.ts';\nimport { doFetch } from '../../http/fetch.ts';\nimport { parseJsonResponse } from '../../http/json.ts';\n\n/** Base URL for OpenRouter's Embeddings API endpoint */\nconst OPENROUTER_EMBEDDINGS_API_URL = 'https://openrouter.ai/api/v1/embeddings';\n\n/**\n * OpenRouter embedding parameters.\n * Passed through unchanged to the API.\n */\nexport interface OpenRouterEmbedParams {\n /** Output dimensions (model-dependent) */\n dimensions?: number;\n /** Encoding format: 'float' or 'base64' */\n encoding_format?: 'float' | 'base64';\n /** A unique identifier representing your end-user */\n user?: string;\n /** Input type hint for some models */\n input_type?: string;\n}\n\n/**\n * OpenRouter embeddings API response structure (OpenAI-compatible).\n */\ninterface OpenRouterEmbeddingsResponse {\n id: string;\n object: 'list';\n data: Array<{\n index: number;\n embedding: number[] | string;\n type: 'embedding';\n }>;\n model: string;\n usage: {\n prompt_tokens: number;\n total_tokens: number;\n cost?: number;\n };\n}\n\n/**\n * Get default dimensions for a model.\n */\nfunction getDefaultDimensions(modelId: string): number {\n if (modelId.includes('text-embedding-3-large')) {\n return 3072;\n }\n if (modelId.includes('text-embedding-3-small') || modelId.includes('ada-002')) {\n return 1536;\n }\n if (modelId.includes('gemini-embedding')) {\n return 3072;\n }\n return 1536;\n}\n\n/**\n * Creates an embedding handler for OpenRouter's Embeddings API.\n *\n * @returns An embedding handler configured for OpenRouter\n *\n * @example\n * ```typescript\n * const handler = createEmbeddingHandler();\n * const model = handler.bind('openai/text-embedding-3-large');\n *\n * const response = await model.embed({\n * inputs: ['Hello world'],\n * config: { apiKey: 'sk-or-...' }\n * });\n * ```\n */\nexport function createEmbeddingHandler(): EmbeddingHandler<OpenRouterEmbedParams> {\n let providerRef: EmbeddingProvider<OpenRouterEmbedParams> | null = null;\n\n return {\n supportedInputs: ['text'],\n\n _setProvider(provider: EmbeddingProvider<OpenRouterEmbedParams>) {\n providerRef = provider;\n },\n\n bind(modelId: string): BoundEmbeddingModel<OpenRouterEmbedParams> {\n if (!providerRef) {\n throw new UPPError(\n 'Provider reference not set. Handler must be used with createProvider().',\n 'INVALID_REQUEST',\n 'openrouter',\n 'embedding'\n );\n }\n\n const model: BoundEmbeddingModel<OpenRouterEmbedParams> = {\n modelId,\n maxBatchSize: 2048,\n maxInputLength: 8191,\n dimensions: getDefaultDimensions(modelId),\n\n get provider(): EmbeddingProvider<OpenRouterEmbedParams> {\n return providerRef!;\n },\n\n async embed(request: EmbeddingRequest<OpenRouterEmbedParams>): Promise<EmbeddingResponse> {\n const apiKey = await resolveApiKey(\n request.config,\n 'OPENROUTER_API_KEY',\n 'openrouter',\n 'embedding'\n );\n\n const baseUrl = request.config.baseUrl ?? OPENROUTER_EMBEDDINGS_API_URL;\n\n // Transform inputs to strings\n const inputTexts = request.inputs.map((input) => {\n if (typeof input === 'string') {\n return input;\n }\n if ('text' in input) {\n return input.text;\n }\n throw new UPPError(\n 'OpenRouter embeddings only support text input',\n 'INVALID_REQUEST',\n 'openrouter',\n 'embedding'\n );\n });\n\n // Build request body - params pass through unchanged\n const body: Record<string, unknown> = {\n model: modelId,\n input: inputTexts,\n };\n\n // Pass through OpenRouter-specific params\n if (request.params?.dimensions !== undefined) {\n body.dimensions = request.params.dimensions;\n }\n if (request.params?.encoding_format !== undefined) {\n body.encoding_format = request.params.encoding_format;\n }\n if (request.params?.user !== undefined) {\n body.user = request.params.user;\n }\n if (request.params?.input_type !== undefined) {\n body.input_type = request.params.input_type;\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${apiKey}`,\n };\n\n // Merge custom headers\n if (request.config.headers) {\n for (const [key, value] of Object.entries(request.config.headers)) {\n if (value !== undefined) {\n headers[key] = value;\n }\n }\n }\n\n const response = await doFetch(baseUrl, {\n method: 'POST',\n headers,\n body: JSON.stringify(body),\n signal: request.signal,\n }, request.config, 'openrouter', 'embedding');\n\n const data = await parseJsonResponse<OpenRouterEmbeddingsResponse>(response, 'openrouter', 'embedding');\n\n // Return EmbeddingResponse - vector is floats or base64 string\n return {\n embeddings: data.data.map((d) => ({\n vector: d.embedding,\n index: d.index,\n })),\n usage: { totalTokens: data.usage.total_tokens },\n metadata: data.usage.cost !== undefined ? { cost: data.usage.cost } : undefined,\n };\n },\n };\n\n return model;\n },\n };\n}\n","import type { Provider } from '../../types/provider.ts';\nimport { createProvider } from '../../core/provider.ts';\nimport type { LLMHandlerResolver } from '../../core/provider-handlers.ts';\nimport { createCompletionsLLMHandler } from './llm.completions.ts';\nimport { createResponsesLLMHandler } from './llm.responses.ts';\nimport { createEmbeddingHandler } from './embed.ts';\n\n/**\n * Configuration options for creating an OpenRouter model reference.\n *\n * OpenRouter supports two distinct APIs:\n * - Chat Completions API: Stable, production-ready, supports most models\n * - Responses API: Beta, supports advanced features like reasoning\n */\nexport interface OpenRouterProviderOptions {\n /**\n * Which OpenRouter API to use.\n *\n * - `'completions'`: Chat Completions API (default, recommended for production)\n * - `'responses'`: Responses API (beta, supports reasoning models)\n */\n api?: 'completions' | 'responses';\n}\n\n/**\n * OpenRouter provider interface with configurable API mode.\n *\n * OpenRouter is a unified API that provides access to hundreds of AI models\n * through a single endpoint, including models from OpenAI, Anthropic, Google,\n * Meta, Mistral, and many others.\n *\n * @example Using the Chat Completions API (default)\n * ```typescript\n * const model = openrouter('openai/gpt-4o');\n * ```\n *\n * @example Using the Responses API (beta)\n * ```typescript\n * const model = openrouter('openai/gpt-4o', { api: 'responses' });\n * ```\n *\n * @example Using Anthropic models\n * ```typescript\n * const model = openrouter('anthropic/claude-3.5-sonnet', { api: 'completions' });\n * ```\n */\n/**\n * Type alias for the OpenRouter provider with its options.\n */\nexport type OpenRouterProvider = Provider<OpenRouterProviderOptions>;\n\n/**\n * LLM handler resolver for OpenRouter's dual API support.\n *\n * Dynamically selects between Completions and Responses API handlers\n * based on the options stored on the ModelReference. This eliminates\n * race conditions from shared mutable state.\n */\nconst llmResolver: LLMHandlerResolver<OpenRouterProviderOptions> = {\n handlers: {\n completions: createCompletionsLLMHandler(),\n responses: createResponsesLLMHandler(),\n },\n defaultMode: 'completions',\n getMode: (options) => options?.api ?? 'completions',\n};\n\n/**\n * OpenRouter provider singleton.\n *\n * OpenRouter is a unified API that provides access to hundreds of AI models\n * through a single endpoint, including models from OpenAI, Anthropic, Google,\n * Meta, Mistral, and many others.\n *\n * Supports both the Chat Completions API (default) and Responses API (beta).\n *\n * @example Basic usage with Chat Completions API\n * ```typescript\n * import { openrouter } from './providers/openrouter';\n * import { llm } from './core/llm';\n *\n * const model = llm({\n * model: openrouter('openai/gpt-4o'),\n * params: { max_tokens: 1000 }\n * });\n *\n * const turn = await model.generate('Hello!');\n * console.log(turn.response.text);\n * ```\n *\n * @example Using the Responses API (beta)\n * ```typescript\n * const betaModel = llm({\n * model: openrouter('openai/gpt-4o', { api: 'responses' }),\n * params: { max_output_tokens: 1000 }\n * });\n * ```\n *\n * @example Model routing and fallback configuration\n * ```typescript\n * const routedModel = llm({\n * model: openrouter('openai/gpt-4o'),\n * params: {\n * max_tokens: 1000,\n * models: ['openai/gpt-4o', 'anthropic/claude-3.5-sonnet'],\n * route: 'fallback',\n * provider: {\n * allow_fallbacks: true,\n * require_parameters: true,\n * },\n * }\n * });\n * ```\n *\n * @see {@link https://openrouter.ai/docs | OpenRouter Documentation}\n */\nexport const openrouter = createProvider<OpenRouterProviderOptions>({\n name: 'openrouter',\n version: '1.0.0',\n handlers: {\n llm: llmResolver,\n embedding: createEmbeddingHandler(),\n },\n}) as OpenRouterProvider;\n\nexport type {\n OpenRouterCompletionsParams,\n OpenRouterResponsesParams,\n OpenRouterConfig,\n OpenRouterAPIMode,\n OpenRouterModelOptions,\n OpenRouterModelReference,\n OpenRouterProviderPreferences,\n OpenRouterImageConfig,\n OpenRouterHeaders,\n} from './types.ts';\n\nexport type { OpenRouterEmbedParams } from './embed.ts';\n"],"mappings":"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","names":["transformRequest","transformTool","normalizeSystem","transformMessage","isValidCacheControl","filterValidContent","transformResponse","createStreamState","transformStreamEvent","buildResponseFromState","OPENROUTER_CAPABILITIES","transformRequest","transformResponse","createStreamState","transformStreamEvent","buildResponseFromState"]}
|