190proof 1.0.95 → 1.0.97
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +136 -6
- package/dist/index.d.ts +136 -6
- package/dist/index.js +261 -74
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +261 -74
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../interfaces.ts","../logger.ts","../index.ts","../utils.ts"],"sourcesContent":["/** @deprecated Use provider prefix strings instead, e.g. `\"anthropic:claude-sonnet-4-5\"` */\nexport enum ClaudeModel {\n HAIKU_3 = \"claude-3-haiku-20240307\",\n SONNET_3 = \"claude-3-sonnet-20240229\",\n OPUS_3 = \"claude-3-opus-20240229\",\n HAIKU_3_5 = \"claude-3-5-haiku-20241022\",\n SONNET_3_5 = \"claude-3-5-sonnet-20241022\",\n SONNET_4 = \"claude-sonnet-4-20250514\",\n OPUS_4 = \"claude-opus-4-20250514\",\n OPUS_4_1 = \"claude-opus-4-1\",\n HAIKU_4_5 = \"claude-haiku-4-5\",\n SONNET_4_5 = \"claude-sonnet-4-5\",\n OPUS_4_5 = \"claude-opus-4-5\",\n}\n\n/** @deprecated Use provider prefix strings instead, e.g. `\"openai:gpt-4o\"` */\nexport enum GPTModel {\n GPT35_0613 = \"gpt-3.5-turbo-0613\",\n GPT35_0613_16K = \"gpt-3.5-turbo-16k-0613\",\n GPT35_0125 = \"gpt-3.5-turbo-0125\",\n GPT4_1106_PREVIEW = \"gpt-4-1106-preview\",\n GPT4_0125_PREVIEW = \"gpt-4-0125-preview\",\n GPT4_0409 = \"gpt-4-turbo-2024-04-09\",\n GPT4O = \"gpt-4o\",\n GPT4O_MINI = \"gpt-4o-mini\",\n O1_PREVIEW = \"o1-preview\",\n O1_MINI = \"o1-mini\",\n O3_MINI = \"o3-mini\",\n GPT4_1 = \"gpt-4.1\",\n GPT4_1_MINI = \"gpt-4.1-mini\",\n GPT4_1_NANO = \"gpt-4.1-nano\",\n GPT5 = \"gpt-5\",\n GPT5_MINI = \"gpt-5-mini\",\n}\n\n/** @deprecated Use provider prefix strings instead, e.g. `\"groq:llama-3.3-70b-versatile\"` */\nexport enum GroqModel {\n LLAMA_3_70B_8192 = \"llama3-70b-8192\",\n LLAMA_3_3_70B_VERSATILE = \"llama-3.3-70b-versatile\",\n QWEN3_32B = \"qwen/qwen3-32b\",\n DEEPSEEK_R1_DISTILL_LLAMA_70B = \"deepseek-r1-distill-llama-70b\",\n}\n\n/** @deprecated Use provider prefix strings instead, e.g. `\"openrouter:qwen/qwen3.6-plus:free\"` */\nexport enum OpenRouterModel {\n GEMMA_4_31B_IT_FREE = \"google/gemma-4-31b-it:free\",\n GEMMA_4_31B_IT = \"google/gemma-4-31b-it\",\n}\n\n/** @deprecated Use provider prefix strings instead, e.g. `\"google:gemini-2.0-flash\"` */\nexport enum GeminiModel {\n GEMINI_1_5_PRO = \"gemini-1.5-pro-latest\",\n GEMINI_EXP_1206 = \"gemini-exp-1206\",\n GEMINI_2_0_FLASH = \"gemini-2.0-flash\",\n GEMINI_2_0_FLASH_EXP_IMAGE_GENERATION = \"gemini-2.0-flash-exp-image-generation\",\n GEMINI_2_0_FLASH_THINKING_EXP = \"gemini-2.0-flash-thinking-exp\",\n GEMINI_2_0_FLASH_THINKING_EXP_01_21 = \"gemini-2.0-flash-thinking-exp-01-21\",\n GEMINI_2_5_FLASH_PREVIEW_04_17 = \"gemini-2.5-flash-preview-04-17\",\n GEMINI_3_FLASH_PREVIEW = \"gemini-3-flash-preview\",\n GEMINI_3_1_FLASH_LITE_PREVIEW = \"gemini-3.1-flash-lite-preview\",\n}\n\nexport interface GenericError {\n message: string;\n}\n\nexport enum ContentType {\n TEXT = \"text\",\n ATTACHMENT = \"attachment\",\n}\n\nexport type AIChainResponse = {\n content: string | null;\n contentType?: ContentType;\n functionCalls: FunctionCall[];\n};\n\nexport interface GenericMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n timestamp?: string;\n files?: File[];\n functionCalls?: FunctionCall[];\n}\n\nexport interface File {\n mimeType: string;\n url?: string;\n data?: string;\n}\n\nexport interface OpenAIMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string | OpenAIContentBlock[];\n}\n\nexport type OpenAIContentBlock =\n | OpenAITextContentBlock\n | OpenAIImageContentBlock\n | OpenAIAudioContentBlock;\n\nexport interface OpenAITextContentBlock {\n type: \"text\";\n text: string;\n}\n\nexport interface OpenAIImageContentBlock {\n type: \"image_url\";\n image_url: {\n url: string; // URL to the image, can also be a base64 string\n };\n}\n\nexport interface OpenAIAudioContentBlock {\n type: \"audio_url\";\n audio_url: {\n url: string; // URL to the audio, can also be a base64 string\n };\n}\n\nexport interface AnthropicAIMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string | AnthropicContentBlock[];\n}\n\nexport type AnthropicContentBlock =\n | AnthropicTextContentBlock\n | AnthropicImageContentBlock;\n\nexport interface AnthropicTextContentBlock {\n type: \"text\";\n text: string;\n}\n\nexport interface AnthropicImageContentBlock {\n type: \"image\";\n source: {\n type: \"base64\";\n media_type: \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\";\n data: string; // Must be a base64 string\n };\n}\n\nexport interface OpenAIResponseMessage {\n role: \"assistant\";\n content: string | null;\n function_call: {\n name: string;\n arguments: string; // unparsed arguments object\n } | null;\n}\n\nexport interface ParsedResponseMessage {\n role: \"assistant\";\n content: string | null;\n function_call: FunctionCall | null;\n function_calls: FunctionCall[];\n files: File[];\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n /** Prompt tokens served from the provider's cache (subset of prompt_tokens). */\n cached_tokens?: number;\n } | null;\n}\n\nexport interface FunctionCall {\n name: string;\n arguments: Record<string, any>;\n}\n\nexport interface OpenAIResponseMessage {\n role: \"assistant\";\n content: string | null;\n function_call: {\n name: string;\n arguments: string; // unparsed arguments object\n } | null;\n}\n\nexport interface FunctionCall {\n name: string;\n arguments: Record<string, any>;\n}\n\nexport interface OpenAIConfig {\n service: \"azure\" | \"openai\";\n apiKey: string;\n /**\n * Override the base URL for the OpenAI service (e.g. an OpenAI-compatible\n * proxy or self-hosted endpoint). The path `/chat/completions` is appended.\n * Ignored when `service === \"azure\"` (use `modelConfigMap` instead).\n * Defaults to `https://api.openai.com/v1`.\n */\n baseUrl?: string;\n orgId?: string;\n modelConfigMap?: Record<\n GPTModel,\n {\n resource: string;\n deployment: string;\n apiVersion: string;\n apiKey: string;\n endpoint?: string;\n }\n >;\n}\n\nexport interface AnthropicAIConfig {\n service: \"anthropic\" | \"bedrock\";\n}\n\nexport interface FunctionDefinition {\n name: string;\n description?: string;\n parameters: Record<string, any>;\n}\n\ninterface FunctionWrapped {\n type: \"function\";\n function: FunctionDefinition;\n}\n\nexport interface GroqPayload {\n model: GroqModel | string;\n messages: OpenAIMessage[];\n tools?: FunctionWrapped[];\n tool_choice?:\n | \"none\"\n | \"auto\"\n | { type: \"function\"; function: { name: string } };\n temperature?: number;\n\n functions?: any[]; // Deprecate this\n}\n\nexport interface OpenRouterPayload {\n model: OpenRouterModel | string;\n messages: OpenAIMessage[];\n tools?: FunctionWrapped[];\n tool_choice?:\n | \"none\"\n | \"auto\"\n | { type: \"function\"; function: { name: string } };\n temperature?: number;\n}\n\nexport interface OpenAIPayload {\n model: GPTModel | string;\n messages: OpenAIMessage[];\n tools?: FunctionWrapped[];\n tool_choice?:\n | \"none\"\n | \"auto\"\n | { type: \"function\"; function: { name: string } };\n}\n\nexport interface AnthropicAIPayload {\n model: ClaudeModel | string;\n messages: AnthropicAIMessage[];\n functions?: any[]; // TODO type this JSON schema\n temperature?: number;\n system?: string;\n}\n\nexport interface GoogleAITextPart {\n text: string;\n}\n\nexport interface GoogleAIInlineDataPart {\n inlineData: {\n mimeType: string;\n data: string;\n };\n}\n\nexport interface GoogleAIFileDataPart {\n fileData: {\n mimeType: string;\n fileUri: string;\n };\n}\n\nexport type GoogleAIPart = GoogleAITextPart | GoogleAIInlineDataPart | GoogleAIFileDataPart;\nexport interface GoogleAIMessage {\n role: \"user\" | \"model\";\n parts: GoogleAIPart[];\n}\nexport interface GoogleAIPayload {\n model: GeminiModel | string;\n messages: GoogleAIMessage[];\n tools?: {\n functionDeclarations: FunctionDefinition[];\n };\n systemInstruction?: string;\n}\n\nexport type Provider = \"openai\" | \"anthropic\" | \"google\" | \"groq\" | \"openrouter\";\n\nexport type AnyModel = GPTModel | ClaudeModel | GroqModel | GeminiModel | OpenRouterModel | (string & {});\n\nexport interface GenericPayload {\n model: AnyModel;\n messages: GenericMessage[];\n functions?: FunctionDefinition[];\n function_call?: \"none\" | \"auto\" | { name: string };\n temperature?: number;\n fallbackModel?: AnyModel;\n}\n\nexport interface OpenAIBody {\n choices: {\n message: OpenAIResponseMessage;\n }[];\n error?: {\n code: string;\n };\n usage: {\n completion_tokens: number;\n prompt_tokens: number;\n total_tokens: number;\n prompt_tokens_details?: {\n cached_tokens?: number;\n };\n };\n}\n","type LogLevel = \"LOG\" | \"WARN\" | \"ERROR\";\nexport type Identifier = string | string[];\n\nfunction formatIdentifier(identifier: Identifier): string {\n if (Array.isArray(identifier)) {\n return identifier.map((id) => `[${id}]`).join(\" \");\n }\n return `[${identifier}]`;\n}\n\nfunction formatMessage(\n level: LogLevel,\n identifier: Identifier,\n message: string\n): string {\n return `[${level}] ${formatIdentifier(identifier)} ${message}`;\n}\n\nexport function log(\n identifier: Identifier,\n message: string,\n ...args: any[]\n): void {\n console.log(formatMessage(\"LOG\", identifier, message), ...args);\n}\n\nexport function warn(\n identifier: Identifier,\n message: string,\n ...args: any[]\n): void {\n console.warn(formatMessage(\"WARN\", identifier, message), ...args);\n}\n\nexport function error(\n identifier: Identifier,\n message: string,\n ...args: any[]\n): void {\n console.error(formatMessage(\"ERROR\", identifier, message), ...args);\n}\n\nexport default {\n log,\n warn,\n error,\n};\n","import {\n ClaudeModel,\n GPTModel,\n OpenAIPayload,\n OpenAIMessage,\n OpenAIConfig,\n AnthropicAIPayload,\n AnthropicAIMessage,\n GenericMessage,\n AnthropicAIConfig,\n GenericPayload,\n GroqPayload,\n GroqModel,\n OpenRouterPayload,\n OpenRouterModel,\n ParsedResponseMessage,\n FunctionCall,\n AnthropicContentBlock,\n OpenAIContentBlock,\n GoogleAIPayload,\n GeminiModel,\n GoogleAIPart,\n File,\n GoogleAIMessage,\n AnyModel,\n Provider,\n} from \"./interfaces\";\nimport logger, { Identifier } from \"./logger\";\nimport {\n BedrockRuntimeClient,\n InvokeModelCommand,\n} from \"@aws-sdk/client-bedrock-runtime\";\nimport axios from \"axios\";\nimport { isHeicImage, timeout } from \"./utils\";\nimport { GoogleGenAI } from \"@google/genai\";\n\nconst sharp = require(\"sharp\");\nconst decode = require(\"heic-decode\");\n\nexport {\n ClaudeModel,\n GPTModel,\n GroqModel,\n GeminiModel,\n OpenRouterModel,\n OpenAIConfig,\n FunctionDefinition,\n GenericMessage,\n GenericPayload,\n AnyModel,\n Provider,\n} from \"./interfaces\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// SHARED UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Generic retry wrapper for API calls with exponential backoff.\n */\nasync function withRetries<T>(\n identifier: Identifier,\n apiName: string,\n fn: () => Promise<T>,\n options: {\n retries?: number;\n baseDelayMs?: number;\n onError?: (error: any, attempt: number) => void;\n } = {},\n): Promise<T> {\n const { retries = 5, baseDelayMs = 125, onError } = options;\n\n logger.log(identifier, `Calling ${apiName} API with retries`);\n\n let lastError: any;\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n return await fn();\n } catch (error: any) {\n lastError = error;\n\n if (onError) {\n onError(error, attempt);\n } else {\n logger.error(\n identifier,\n `Retry #${attempt} error: ${error.message}`,\n error.response?.data || error,\n );\n }\n\n await timeout(baseDelayMs * attempt);\n }\n }\n\n const error = new Error(\n `Failed to call ${apiName} API after ${retries} attempts`,\n ) as any;\n error.cause = lastError;\n throw error;\n}\n\nfunction parseStreamedResponse(\n identifier: Identifier,\n paragraph: string,\n toolCallAccumulators: { name: string; arguments: string }[],\n allowedFunctionNames: Set<string> | null,\n): ParsedResponseMessage {\n const functionCalls: FunctionCall[] = [];\n\n for (const acc of toolCallAccumulators) {\n if (!acc.name || !acc.arguments) continue;\n\n if (allowedFunctionNames && !allowedFunctionNames.has(acc.name)) {\n throw new Error(\n `Stream error: received function call with unknown name: ${acc.name}`,\n );\n }\n\n try {\n functionCalls.push({\n name: acc.name,\n arguments: JSON.parse(acc.arguments),\n });\n } catch (error) {\n logger.error(\n identifier,\n \"Error parsing function call arguments:\",\n acc.arguments,\n );\n throw error;\n }\n }\n\n if (!paragraph && !functionCalls.length) {\n logger.error(\n identifier,\n \"Stream error: received message without content or function_call:\",\n JSON.stringify({ paragraph, toolCallAccumulators }),\n );\n throw new Error(\n \"Stream error: received message without content or function_call\",\n );\n }\n\n return {\n role: \"assistant\",\n content: paragraph || null,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n usage: null,\n };\n}\n\nfunction truncatePayload(payload: OpenAIPayload): string {\n return JSON.stringify(\n {\n ...payload,\n messages: payload.messages.map((message) => {\n const truncatedMessage = { ...message };\n if (typeof truncatedMessage.content === \"string\") {\n truncatedMessage.content = truncatedMessage.content.slice(0, 100);\n } else if (Array.isArray(truncatedMessage.content)) {\n truncatedMessage.content = truncatedMessage.content.map((block) => {\n if (block.type === \"image_url\") {\n return {\n ...block,\n image_url: { url: block.image_url.url.slice(0, 100) },\n };\n }\n return block;\n });\n }\n return truncatedMessage;\n }),\n },\n null,\n 2,\n );\n}\n\nasync function getNormalizedBase64PNG(\n url: string,\n mime: string,\n): Promise<string> {\n const response = await axios.get(url, { responseType: \"arraybuffer\" });\n\n let imageBuffer = Buffer.from(response.data);\n let sharpOptions = {};\n\n if (isHeicImage(url, mime)) {\n const imageData = await decode({ buffer: imageBuffer });\n imageBuffer = Buffer.from(imageData.data);\n sharpOptions = {\n raw: {\n width: imageData.width,\n height: imageData.height,\n channels: 4,\n },\n };\n }\n\n // Limits size of image to < 5MB Anthropic limit\n const resizedBuffer = await sharp(imageBuffer, sharpOptions)\n .withMetadata()\n .resize(1024, 1024, { fit: \"inside\", withoutEnlargement: true })\n .png()\n .toBuffer();\n\n return resizedBuffer.toString(\"base64\");\n}\n\nconst ALLOWED_IMAGE_MIME_TYPES = [\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OPENAI\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface OpenAIRequestConfig {\n endpoint: string;\n headers: Record<string, string>;\n}\n\nfunction buildOpenAIRequestConfig(\n identifier: Identifier,\n model: string,\n config: OpenAIConfig | undefined,\n): OpenAIRequestConfig {\n if (!config) {\n config = {\n service: \"openai\",\n apiKey: process.env.OPENAI_API_KEY as string,\n baseUrl: \"\",\n };\n }\n\n if (config.service === \"azure\") {\n logger.log(identifier, \"Using Azure OpenAI service:\", model);\n\n if (!config.modelConfigMap) {\n throw new Error(\n \"OpenAI config modelConfigMap is required when using Azure OpenAI service.\",\n );\n }\n\n const azureConfig = config.modelConfigMap[model as GPTModel];\n if (!azureConfig?.endpoint) {\n throw new Error(\"Azure OpenAI endpoint is required in modelConfigMap.\");\n }\n\n const endpoint = `${azureConfig.endpoint}/openai/deployments/${azureConfig.deployment}/chat/completions?api-version=${azureConfig.apiVersion}`;\n logger.log(identifier, \"Using endpoint:\", endpoint);\n\n return {\n endpoint,\n headers: {\n \"Content-Type\": \"application/json\",\n \"api-key\": azureConfig.apiKey,\n },\n };\n }\n\n // Default: OpenAI (or any OpenAI-compatible server via config.baseUrl)\n logger.log(identifier, \"Using OpenAI service:\", model);\n if (config.orgId) {\n logger.log(identifier, \"Using orgId:\", config.orgId);\n }\n\n const base = (config.baseUrl?.trim() || \"https://api.openai.com/v1\").replace(\n /\\/$/,\n \"\",\n );\n return {\n endpoint: `${base}/chat/completions`,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${config.apiKey}`,\n ...(config.orgId ? { \"OpenAI-Organization\": config.orgId } : {}),\n },\n };\n}\n\nasync function prepareOpenAIPayload(\n identifier: Identifier,\n payload: GenericPayload,\n): Promise<OpenAIPayload> {\n const preparedPayload: OpenAIPayload = {\n model: payload.model as GPTModel,\n messages: [],\n tools: payload.functions?.map((fn) => ({\n type: \"function\",\n function: fn,\n })),\n tool_choice: payload.function_call\n ? typeof payload.function_call === \"string\"\n ? payload.function_call\n : { type: \"function\", function: payload.function_call }\n : undefined,\n };\n\n for (const message of payload.messages) {\n const contentBlocks: OpenAIContentBlock[] = [];\n\n if (message.content) {\n contentBlocks.push({ type: \"text\", text: message.content });\n }\n\n for (const file of message.files || []) {\n if (ALLOWED_IMAGE_MIME_TYPES.includes(file.mimeType)) {\n if (file.url) {\n contentBlocks.push({\n type: \"image_url\",\n image_url: { url: file.url },\n });\n contentBlocks.push({ type: \"text\", text: `Image (${file.url})` });\n } else if (file.data) {\n contentBlocks.push({\n type: \"image_url\",\n image_url: { url: `data:${file.mimeType};base64,${file.data}` },\n });\n }\n } else if (file.url) {\n // Non-image file with URL - add text reference\n contentBlocks.push({\n type: \"text\",\n text: `File (${file.url})`,\n });\n }\n }\n\n preparedPayload.messages.push({\n role: message.role,\n content: contentBlocks,\n });\n }\n\n return preparedPayload;\n}\n\nasync function callOpenAIStream(\n id: Identifier,\n openAiPayload: OpenAIPayload,\n openAiConfig: OpenAIConfig | undefined,\n chunkTimeoutMs: number,\n): Promise<ParsedResponseMessage> {\n const functionNames: Set<string> | null = openAiPayload.tools\n ? new Set(openAiPayload.tools.map((fn) => fn.function.name as string))\n : null;\n\n const { endpoint, headers } = buildOpenAIRequestConfig(\n id,\n openAiPayload.model,\n openAiConfig,\n );\n\n const controller = new AbortController();\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ ...openAiPayload, stream: true }),\n signal: controller.signal,\n });\n\n if (!response.body) {\n throw new Error(\"Stream error: no response body\");\n }\n\n let paragraph = \"\";\n const toolCallAccumulators: { name: string; arguments: string }[] = [];\n\n const reader = response.body.getReader();\n let partialChunk = \"\";\n let chunkIndex = -1;\n\n const createAbortTimeout = () =>\n setTimeout(() => {\n logger.error(id, `Stream timeout after ${chunkTimeoutMs}ms`);\n controller.abort();\n }, chunkTimeoutMs);\n\n while (true) {\n chunkIndex++;\n const abortTimeout = createAbortTimeout();\n const { done, value } = await reader.read();\n clearTimeout(abortTimeout);\n\n if (done) {\n logger.error(\n id,\n `Stream ended prematurely after ${chunkIndex + 1} chunks`,\n );\n throw new Error(\"Stream error: ended prematurely\");\n }\n\n let chunk = new TextDecoder().decode(value);\n if (partialChunk) {\n chunk = partialChunk + chunk;\n partialChunk = \"\";\n }\n\n const jsonStrings = chunk.split(/^data: /gm);\n\n for (const jsonString of jsonStrings) {\n if (!jsonString) continue;\n\n if (jsonString.includes(\"[DONE]\")) {\n return parseStreamedResponse(\n id,\n paragraph,\n toolCallAccumulators,\n functionNames,\n );\n }\n\n let json;\n try {\n json = JSON.parse(jsonString.trim());\n } catch {\n partialChunk = jsonString;\n continue;\n }\n\n if (!json.choices?.length) {\n if (json.error) {\n logger.error(id, \"Stream error from OpenAI:\", json.error);\n const error = new Error(\"Stream error: OpenAI error\") as any;\n error.data = json.error;\n error.requestBody = truncatePayload(openAiPayload);\n throw error;\n }\n if (chunkIndex !== 0) {\n logger.error(id, \"Stream error: no choices in JSON:\", json);\n }\n continue;\n }\n\n const toolCalls = json.choices[0]?.delta?.tool_calls;\n if (toolCalls) {\n for (const toolCall of toolCalls) {\n const idx = toolCall.index ?? 0;\n while (toolCallAccumulators.length <= idx) {\n toolCallAccumulators.push({ name: \"\", arguments: \"\" });\n }\n if (toolCall.function?.name)\n toolCallAccumulators[idx].name += toolCall.function.name;\n if (toolCall.function?.arguments)\n toolCallAccumulators[idx].arguments += toolCall.function.arguments;\n }\n }\n\n const text = json.choices[0]?.delta?.content;\n if (text) paragraph += text;\n }\n }\n}\n\nasync function callOpenAI(\n id: Identifier,\n openAiPayload: OpenAIPayload,\n openAiConfig: OpenAIConfig | undefined,\n): Promise<ParsedResponseMessage> {\n const { endpoint, headers } = buildOpenAIRequestConfig(\n id,\n openAiPayload.model,\n openAiConfig,\n );\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ ...openAiPayload, stream: false }),\n });\n\n if (!response.ok) {\n const errorData = await response.json();\n logger.error(id, \"OpenAI API error:\", errorData);\n throw new Error(`OpenAI API Error: ${errorData.error.message}`);\n }\n\n const data = await response.json();\n\n if (!data.choices?.length) {\n if (data.error) {\n logger.error(id, \"OpenAI error:\", data.error);\n throw new Error(`OpenAI error: ${data.error.message}`);\n }\n throw new Error(\"OpenAI error: No choices returned.\");\n }\n\n const choice = data.choices[0];\n\n // Check for tool_calls (modern API) first, fall back to function_call (legacy)\n const toolCalls = choice.message?.tool_calls;\n const functionCalls: FunctionCall[] = [];\n\n if (toolCalls?.length) {\n for (const tc of toolCalls) {\n functionCalls.push({\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n });\n }\n } else if (choice.function_call) {\n functionCalls.push({\n name: choice.function_call.name,\n arguments: JSON.parse(choice.function_call.arguments),\n });\n }\n\n // An empty 200 (no content, no tool call) is not a usable answer — throw so\n // withRetries retries and callWithRetries can fall back. (Mirrors the\n // streaming path's guard in parseStreamedResponse.)\n if (!choice.message?.content && !functionCalls.length) {\n logger.error(\n id,\n \"OpenAI: received message without content or function_call:\",\n JSON.stringify(data),\n );\n throw new Error(\n \"OpenAI: received message without content or function_call\",\n );\n }\n\n return {\n role: \"assistant\",\n content: choice.message.content || null,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n usage: data.usage\n ? {\n prompt_tokens: data.usage.prompt_tokens,\n completion_tokens: data.usage.completion_tokens,\n total_tokens: data.usage.total_tokens,\n cached_tokens: data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n : null,\n };\n}\n\nasync function callOpenAiWithRetries(\n id: Identifier,\n openAiPayload: OpenAIPayload,\n openAiConfig?: OpenAIConfig,\n retries: number = 5,\n chunkTimeoutMs: number = 15_000,\n): Promise<ParsedResponseMessage> {\n logger.log(\n id,\n \"Calling OpenAI API with retries:\",\n openAiConfig?.service,\n openAiPayload.model,\n );\n\n const modelStr = openAiPayload.model as string;\n const useStreaming =\n modelStr !== GPTModel.O1_MINI &&\n modelStr !== GPTModel.O1_PREVIEW &&\n !modelStr.startsWith(\"o1\");\n\n return withRetries(\n id,\n \"OpenAI\",\n async () => {\n if (useStreaming) {\n return callOpenAIStream(\n id,\n openAiPayload,\n openAiConfig,\n chunkTimeoutMs,\n );\n } else {\n return callOpenAI(id, openAiPayload, openAiConfig);\n }\n },\n {\n retries,\n baseDelayMs: 250,\n onError: (error, attempt) => {\n logger.error(\n id,\n `Retry #${attempt} error: ${error.message}`,\n error.response?.data || error.data || error,\n );\n\n // Remove images on content policy violation\n if (error.data?.code === \"content_policy_violation\") {\n logger.log(id, \"Removing images due to content policy violation\");\n openAiPayload.messages.forEach((message: OpenAIMessage) => {\n if (Array.isArray(message.content)) {\n message.content = message.content.filter(\n (content) => content.type === \"text\",\n );\n }\n });\n }\n },\n },\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ANTHROPIC\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction jigAnthropicMessages(\n messages: AnthropicAIMessage[],\n): AnthropicAIMessage[] {\n let jiggedMessages = messages.slice();\n\n // Ensure first message is from user\n if (jiggedMessages[0]?.role !== \"user\") {\n jiggedMessages = [\n { role: \"user\" as const, content: \"...\" },\n ...jiggedMessages,\n ];\n }\n\n // Group consecutive messages with the same role\n jiggedMessages = jiggedMessages.reduce((acc, message) => {\n if (acc.length === 0) return [message];\n\n const lastMessage = acc[acc.length - 1];\n if (lastMessage.role === message.role) {\n const lastContent = Array.isArray(lastMessage.content)\n ? lastMessage.content\n : [{ type: \"text\" as const, text: lastMessage.content }];\n const newContent = Array.isArray(message.content)\n ? message.content\n : [{ type: \"text\" as const, text: message.content }];\n\n lastMessage.content = [\n ...lastContent,\n { type: \"text\", text: \"\\n\\n---\\n\\n\" },\n ...newContent,\n ];\n return acc;\n }\n\n // Convert string content to text content block\n if (typeof message.content === \"string\") {\n message.content = [{ type: \"text\", text: message.content }];\n }\n\n return [...acc, message];\n }, [] as AnthropicAIMessage[]);\n\n // Ensure last message is from user\n if (jiggedMessages[jiggedMessages.length - 1]?.role === \"assistant\") {\n jiggedMessages.push({ role: \"user\", content: \"...\" });\n }\n\n return jiggedMessages;\n}\n\nasync function prepareAnthropicPayload(\n _identifier: Identifier,\n payload: GenericPayload,\n): Promise<AnthropicAIPayload> {\n const preparedPayload: AnthropicAIPayload = {\n model: payload.model as ClaudeModel,\n messages: [],\n functions: payload.functions,\n temperature: payload.temperature,\n };\n\n for (const message of payload.messages) {\n if (message.role === \"system\") {\n preparedPayload.system = message.content;\n continue;\n }\n\n const contentBlocks: AnthropicContentBlock[] = [];\n\n if (message.content) {\n contentBlocks.push({ type: \"text\", text: message.content });\n }\n\n for (const file of message.files || []) {\n if (ALLOWED_IMAGE_MIME_TYPES.includes(file.mimeType)) {\n if (file.url) {\n if (message.role == \"user\") {\n // anthropic assistant turns can't have images\n contentBlocks.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: \"image/png\",\n data: await getNormalizedBase64PNG(file.url, file.mimeType),\n },\n });\n }\n contentBlocks.push({ type: \"text\", text: `Image (${file.url})` });\n } else if (file.data) {\n if (message.role == \"user\") {\n // anthropic assistant turns can't have images\n contentBlocks.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: file.mimeType as any,\n data: file.data,\n },\n });\n }\n }\n } else if (file.url) {\n // Non-image file with URL - add text reference\n contentBlocks.push({\n type: \"text\",\n text: `File (${file.url})`,\n });\n }\n }\n\n preparedPayload.messages.push({\n role: message.role,\n content: contentBlocks,\n });\n }\n\n return preparedPayload;\n}\n\nasync function callAnthropic(\n id: Identifier,\n payload: AnthropicAIPayload,\n config?: AnthropicAIConfig,\n): Promise<ParsedResponseMessage> {\n const anthropicMessages = jigAnthropicMessages(payload.messages);\n const tools = payload.functions?.map((f) => ({\n ...f,\n input_schema: f.parameters,\n parameters: undefined,\n }));\n\n let data;\n\n if (config?.service === \"bedrock\") {\n const AWS_REGION = \"us-east-1\";\n const MODEL_ID = \"anthropic.claude-3-haiku-20240307-v1:0\";\n\n const client = new BedrockRuntimeClient({ region: AWS_REGION });\n const bedrockPayload = {\n anthropic_version: \"bedrock-2023-05-31\",\n max_tokens: 4096,\n messages: anthropicMessages,\n tools,\n };\n\n const response = await client.send(\n new InvokeModelCommand({\n contentType: \"application/json\",\n body: JSON.stringify(bedrockPayload),\n modelId: MODEL_ID,\n }),\n );\n\n const decodedResponseBody = new TextDecoder().decode(response.body);\n data = JSON.parse(decodedResponseBody);\n } else {\n // Default: Anthropic API\n // Prompt caching: mark a breakpoint on the last tool only. Tool schemas\n // are fully static and identical across users, so that span gets real\n // cache reads; the system prompt is left uncached because callers embed\n // per-user / per-minute content in it, and a breakpoint after a volatile\n // span pays 1.25x cache writes with near-zero reads. Anthropic ignores\n // breakpoints below the model's minimum cacheable length, so small tool\n // sets are a safe no-op.\n const cachedTools = tools?.length\n ? [\n ...tools.slice(0, -1),\n { ...tools[tools.length - 1], cache_control: { type: \"ephemeral\" } },\n ]\n : tools;\n const response = await axios.post(\n \"https://api.anthropic.com/v1/messages\",\n {\n model: payload.model,\n messages: anthropicMessages,\n tools: cachedTools,\n temperature: payload.temperature,\n system: payload.system,\n max_tokens: 4096,\n },\n {\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": process.env.ANTHROPIC_API_KEY as string,\n \"anthropic-version\": \"2023-06-01\",\n \"anthropic-beta\": \"tools-2024-04-04\",\n },\n timeout: 60000,\n },\n );\n data = response.data;\n }\n\n const answers = data.content;\n if (!answers?.[0]) {\n logger.error(id, \"Missing answer in Anthropic API response:\", data);\n throw new Error(\"Missing answer in Anthropic API\");\n }\n\n let textResponse = \"\";\n const functionCalls: FunctionCall[] = [];\n\n for (const answer of answers) {\n if (!answer.type) {\n logger.error(id, \"Missing answer type in Anthropic API response:\", data);\n throw new Error(\"Missing answer type in Anthropic API\");\n }\n\n if (answer.type === \"text\") {\n let text = answer.text\n .replace(/<thinking>.*?<\\/thinking>/gs, \"\")\n .replace(/<answer>|<\\/answer>/gs, \"\")\n .trim();\n\n if (!text) {\n text = answer.text.replace(\n /<thinking>|<\\/thinking>|<answer>|<\\/answer>/gs,\n \"\",\n );\n logger.log(id, \"No text in answer, returning text within tags:\", text);\n }\n\n textResponse = textResponse ? `${textResponse}\\n\\n${text}` : text;\n } else if (answer.type === \"tool_use\") {\n functionCalls.push({\n name: answer.name,\n arguments: answer.input,\n });\n }\n }\n\n if (!textResponse && !functionCalls.length) {\n logger.error(\n id,\n \"Missing text & functions in Anthropic API response:\",\n data,\n );\n throw new Error(\"Missing text & functions in Anthropic API response\");\n }\n\n // Anthropic's input_tokens EXCLUDES cache reads/writes; fold them back in\n // so prompt_tokens means \"all input tokens\" like OpenAI, where\n // cached_tokens is a subset of prompt_tokens.\n let usage: ParsedResponseMessage[\"usage\"] = null;\n if (data.usage) {\n const cacheRead = data.usage.cache_read_input_tokens ?? 0;\n const cacheWrite = data.usage.cache_creation_input_tokens ?? 0;\n const promptTokens = data.usage.input_tokens + cacheRead + cacheWrite;\n usage = {\n prompt_tokens: promptTokens,\n completion_tokens: data.usage.output_tokens,\n total_tokens: promptTokens + data.usage.output_tokens,\n cached_tokens: cacheRead,\n };\n }\n\n return {\n role: \"assistant\",\n content: textResponse,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n usage,\n };\n}\n\nasync function callAnthropicWithRetries(\n id: Identifier,\n payload: AnthropicAIPayload,\n config?: AnthropicAIConfig,\n retries: number = 5,\n): Promise<ParsedResponseMessage> {\n return withRetries(\n id,\n \"Anthropic\",\n () => callAnthropic(id, payload, config),\n {\n retries,\n },\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// GOOGLE AI\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction jigGoogleMessages(messages: GoogleAIMessage[]): GoogleAIMessage[] {\n let jiggedMessages = messages.slice();\n\n // Ensure first message is from user\n if (jiggedMessages[0]?.role === \"model\") {\n jiggedMessages = [\n { role: \"user\" as const, parts: [{ text: \"...\" }] },\n ...jiggedMessages,\n ];\n }\n\n // Group consecutive messages with the same role\n jiggedMessages = jiggedMessages.reduce((acc, message) => {\n if (acc.length === 0) return [message];\n\n const lastMessage = acc[acc.length - 1];\n if (lastMessage.role === message.role) {\n lastMessage.parts = [...lastMessage.parts, ...message.parts];\n return acc;\n }\n\n return [...acc, message];\n }, [] as GoogleAIMessage[]);\n\n // Ensure last message is from user\n if (jiggedMessages[jiggedMessages.length - 1]?.role === \"model\") {\n jiggedMessages.push({ role: \"user\", parts: [{ text: \"...\" }] });\n }\n\n return jiggedMessages;\n}\n\nasync function prepareGoogleAIPayload(\n _identifier: Identifier,\n payload: GenericPayload,\n): Promise<GoogleAIPayload> {\n const preparedPayload: GoogleAIPayload = {\n model: payload.model as GeminiModel,\n messages: [],\n tools: payload.functions\n ? {\n functionDeclarations: payload.functions.map((fn) => ({\n name: fn.name,\n parameters: {\n description: fn.description,\n ...fn.parameters,\n },\n })),\n }\n : undefined,\n };\n\n for (const message of payload.messages) {\n if (message.role === \"system\") {\n preparedPayload.systemInstruction = message.content;\n continue;\n }\n\n const parts: GoogleAIPart[] = [];\n\n if (message.content) {\n parts.push({ text: message.content });\n }\n\n for (const file of message.files || []) {\n if (ALLOWED_IMAGE_MIME_TYPES.includes(file.mimeType)) {\n if (file.url) {\n parts.push({\n fileData: {\n mimeType: file.mimeType,\n fileUri: file.url,\n },\n });\n parts.push({ text: `Image (${file.url})` });\n } else if (file.data) {\n parts.push({\n inlineData: {\n mimeType: file.mimeType,\n data: file.data,\n },\n });\n }\n } else if (file.url) {\n // Non-image file with URL - add text reference\n parts.push({\n text: `File (${file.url})`,\n });\n }\n }\n\n preparedPayload.messages.push({\n role: message.role === \"assistant\" ? \"model\" : message.role,\n parts,\n });\n }\n\n return preparedPayload;\n}\n\nasync function callGoogleAI(\n id: Identifier,\n payload: GoogleAIPayload,\n): Promise<ParsedResponseMessage> {\n const googleMessages = jigGoogleMessages(payload.messages);\n const history = googleMessages.slice(0, -1);\n const lastMessage = googleMessages.slice(-1)[0];\n\n const genAI = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });\n\n const chat = genAI.chats.create({\n model: payload.model,\n history,\n config: {\n responseModalities: [\"Text\"],\n tools: payload.tools ? [payload.tools] : undefined,\n systemInstruction: payload.systemInstruction,\n },\n });\n\n const response = await chat.sendMessage({ message: lastMessage.parts });\n\n let text = \"\";\n const files: File[] = [];\n\n for (const part of response.candidates?.[0]?.content?.parts || []) {\n if (part.text) text += part.text;\n if (part.inlineData?.data) {\n files.push({ mimeType: \"image/png\", data: part.inlineData.data });\n }\n }\n\n const functionCalls = response.functionCalls?.map((fc) => ({\n name: fc.name ?? \"\",\n arguments: fc.args ?? {},\n }));\n\n if (!text && !functionCalls?.length && !files.length) {\n const candidate = response.candidates?.[0];\n const finishReason = candidate?.finishReason;\n\n logger.error(id, \"Missing text & functions in Google AI API response:\", {\n finishReason,\n safetyRatings: candidate?.safetyRatings,\n usageMetadata: response.usageMetadata,\n modelVersion: response.modelVersion,\n candidateContent: candidate?.content,\n promptFeedback: response.promptFeedback,\n });\n\n let errorMessage = \"Missing text & functions in Google AI API response\";\n if (finishReason) {\n const reasonDescriptions: Record<string, string> = {\n MALFORMED_FUNCTION_CALL:\n \"(Google could not generate valid function call arguments)\",\n SAFETY: \"(blocked by safety filters)\",\n RECITATION: \"(blocked due to recitation)\",\n MAX_TOKENS: \"(response truncated due to max tokens)\",\n };\n errorMessage += `: finishReason=${finishReason} ${reasonDescriptions[finishReason] || \"\"}`;\n }\n\n const error = new Error(errorMessage) as any;\n error.finishReason = finishReason;\n error.safetyRatings = candidate?.safetyRatings;\n error.usageMetadata = response.usageMetadata;\n error.promptFeedback = response.promptFeedback;\n throw error;\n }\n\n return {\n role: \"assistant\",\n content: text || null,\n files,\n function_call: functionCalls?.[0] || null,\n function_calls: functionCalls || [],\n usage: response.usageMetadata\n ? {\n prompt_tokens: response.usageMetadata.promptTokenCount ?? 0,\n completion_tokens: response.usageMetadata.candidatesTokenCount ?? 0,\n total_tokens: response.usageMetadata.totalTokenCount ?? 0,\n cached_tokens: response.usageMetadata.cachedContentTokenCount ?? 0,\n }\n : null,\n };\n}\n\n/**\n * Content violation finish reasons that should trigger circuit breaker behavior.\n * These errors won't resolve with simple retries - the content itself is the problem.\n */\nconst CONTENT_VIOLATION_REASONS = new Set([\"PROHIBITED_CONTENT\", \"SAFETY\"]);\n\n/**\n * Removes inline image data from Google AI messages, preserving text content.\n * Used as a fallback when content violations are detected.\n */\nfunction removeImagesFromGooglePayload(payload: GoogleAIPayload): boolean {\n let removedImages = false;\n\n for (const message of payload.messages) {\n message.parts = message.parts.filter((part) => {\n if (\"inlineData\" in part || \"fileData\" in part) {\n removedImages = true;\n return false;\n }\n return true;\n });\n\n // Ensure message still has content after removing images\n if (message.parts.length === 0) {\n message.parts = [{ text: \"(image removed due to content policy)\" }];\n }\n }\n\n return removedImages;\n}\n\nasync function callGoogleAIWithRetries(\n id: Identifier,\n payload: GoogleAIPayload,\n retries: number = 5,\n): Promise<ParsedResponseMessage> {\n let hasTriedWithoutImages = false;\n\n return withRetries(id, \"Google AI\", () => callGoogleAI(id, payload), {\n retries,\n onError: (error, attempt) => {\n const errorDetails: Record<string, any> = {\n message: error.message,\n finishReason: error.finishReason,\n modelVersion: error.modelVersion,\n };\n\n if (error.safetyRatings) errorDetails.safetyRatings = error.safetyRatings;\n if (error.usageMetadata) errorDetails.usageMetadata = error.usageMetadata;\n if (error.promptFeedback)\n errorDetails.promptFeedback = error.promptFeedback;\n if (error.status) errorDetails.httpStatus = error.status;\n if (error.code) errorDetails.errorCode = error.code;\n if (error.details) errorDetails.errorDetails = error.details;\n\n const fileUris = payload.messages\n .flatMap((m) => m.parts)\n .filter((p) => \"fileData\" in p)\n .map((p) => (p as any).fileData.fileUri);\n if (fileUris.length) errorDetails.fileUris = fileUris;\n\n logger.error(\n id,\n `Retry #${attempt} error: ${error.message}`,\n errorDetails,\n );\n\n // Circuit breaker: Google's fetcher couldn't pull our image URL(s). We pass\n // images as fileData.fileUri, but arbitrary (non-Files-API) URLs are only\n // best-effort for Gemini, so this 400 is episodic and retrying the same URL\n // almost never recovers within a request. Fail fast so the caller's\n // fallbackModel (whose adapter inlines the image bytes) takes over instead of\n // burning all retries first. Unlike the content-violation path we do NOT strip\n // images — the fallback model should still see them.\n if (\n typeof error?.message === \"string\" &&\n error.message.includes(\"Cannot fetch content from the provided URL\")\n ) {\n logger.error(\n id,\n \"Circuit breaker: Google could not fetch image URL(s); failing over (no more Google retries)\",\n );\n const fetchError = new Error(\n \"Google AI could not fetch the provided image URL(s).\",\n ) as any;\n fetchError.cause = error;\n fetchError.googleFetchFailure = true;\n throw fetchError;\n }\n\n // Circuit breaker: detect content violations and try removing images\n // Check both finishReason (candidate-level) and promptFeedback.blockReason (prompt-level)\n const violationReason =\n (CONTENT_VIOLATION_REASONS.has(error.finishReason) &&\n error.finishReason) ||\n (CONTENT_VIOLATION_REASONS.has(error.promptFeedback?.blockReason) &&\n error.promptFeedback?.blockReason);\n\n if (violationReason) {\n if (!hasTriedWithoutImages) {\n const removedImages = removeImagesFromGooglePayload(payload);\n if (removedImages) {\n logger.log(\n id,\n `Circuit breaker triggered: removing images due to ${violationReason}`,\n );\n hasTriedWithoutImages = true;\n return; // Continue to next retry with images removed\n }\n }\n\n // If we already tried without images or there were no images, fail fast\n logger.error(\n id,\n `Circuit breaker: failing fast due to ${violationReason} (no more fallbacks)`,\n );\n const circuitBreakerError = new Error(\n `Google AI content violation: ${violationReason}. Request cannot succeed with current content.`,\n ) as any;\n circuitBreakerError.finishReason = error.finishReason;\n circuitBreakerError.safetyRatings = error.safetyRatings;\n circuitBreakerError.usageMetadata = error.usageMetadata;\n circuitBreakerError.circuitBreaker = true;\n throw circuitBreakerError;\n }\n },\n });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// GROQ\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction normalizeMessageContent(\n content: AnthropicAIMessage[\"content\"],\n): string {\n return Array.isArray(content)\n ? content\n .map((c) => (c.type === \"text\" ? c.text : `[${c.type}]`))\n .join(\"\\n\")\n : content;\n}\n\nfunction prepareGroqPayload(payload: GenericPayload): GroqPayload {\n return {\n model: payload.model as GroqModel,\n messages: payload.messages.map((message) => ({\n role: message.role,\n content: normalizeMessageContent(message.content),\n })),\n tools: payload.functions?.map((fn) => ({\n type: \"function\",\n function: fn,\n })),\n tool_choice: payload.function_call\n ? typeof payload.function_call === \"string\"\n ? payload.function_call\n : { type: \"function\", function: payload.function_call }\n : undefined,\n temperature: payload.temperature,\n };\n}\n\nasync function callGroq(\n id: Identifier,\n payload: GroqPayload,\n): Promise<ParsedResponseMessage> {\n const response = await axios.post(\n \"https://api.groq.com/openai/v1/chat/completions\",\n payload,\n {\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${process.env.GROQ_API_KEY}`,\n },\n },\n );\n\n const answer = response.data.choices[0]?.message;\n if (!answer) {\n logger.error(id, \"Missing answer in Groq API response:\", response.data);\n throw new Error(\"Missing answer in Groq API\");\n }\n\n const functionCalls: FunctionCall[] = [];\n if (answer.tool_calls?.length) {\n for (const tc of answer.tool_calls) {\n functionCalls.push({\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n });\n }\n }\n\n // An empty 200 (no content, no tool call) is not a usable answer — throw so\n // withRetries retries and callWithRetries can fall back. (Mirrors the\n // streaming path's guard in parseStreamedResponse.)\n if (!answer.content && !functionCalls.length) {\n logger.error(\n id,\n \"Groq: received message without content or function_call:\",\n JSON.stringify(response.data),\n );\n throw new Error(\n \"Groq: received message without content or function_call\",\n );\n }\n\n return {\n role: \"assistant\",\n content: answer.content || null,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n usage: response.data.usage\n ? {\n prompt_tokens: response.data.usage.prompt_tokens,\n completion_tokens: response.data.usage.completion_tokens,\n total_tokens: response.data.usage.total_tokens,\n cached_tokens:\n response.data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n : null,\n };\n}\n\nasync function callGroqWithRetries(\n id: Identifier,\n payload: GroqPayload,\n retries: number = 5,\n): Promise<ParsedResponseMessage> {\n return withRetries(id, \"Groq\", () => callGroq(id, payload), { retries });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OPENROUTER\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction prepareOpenRouterPayload(payload: GenericPayload): OpenRouterPayload {\n return {\n model: payload.model as OpenRouterModel,\n messages: payload.messages.map((message) => ({\n role: message.role,\n content: normalizeMessageContent(message.content),\n })),\n tools: payload.functions?.map((fn) => ({\n type: \"function\",\n function: fn,\n })),\n tool_choice: payload.function_call\n ? typeof payload.function_call === \"string\"\n ? payload.function_call\n : { type: \"function\", function: payload.function_call }\n : undefined,\n temperature: payload.temperature,\n };\n}\n\nasync function callOpenRouter(\n id: Identifier,\n payload: OpenRouterPayload,\n): Promise<ParsedResponseMessage> {\n const response = await axios.post(\n \"https://openrouter.ai/api/v1/chat/completions\",\n payload,\n {\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,\n },\n },\n );\n\n const answer = response.data.choices[0]?.message;\n if (!answer) {\n logger.error(id, \"Missing answer in OpenRouter API response:\", response.data);\n throw new Error(\"Missing answer in OpenRouter API\");\n }\n\n const functionCalls: FunctionCall[] = [];\n if (answer.tool_calls?.length) {\n for (const tc of answer.tool_calls) {\n functionCalls.push({\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n });\n }\n }\n\n // Reasoning models (e.g. deepseek) can return a completion whose output went\n // entirely to the (discarded) `reasoning` channel, leaving content empty. An\n // empty 200 is not a usable answer — throw so withRetries retries this model\n // and, on exhaustion, callWithRetries falls back to fallbackModel. (Mirrors\n // the streaming path's guard in parseStreamedResponse.)\n if (!answer.content && !functionCalls.length) {\n logger.error(\n id,\n \"OpenRouter: received message without content or function_call:\",\n JSON.stringify(response.data),\n );\n throw new Error(\n \"OpenRouter: received message without content or function_call\",\n );\n }\n\n return {\n role: \"assistant\",\n content: answer.content || null,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n usage: response.data.usage\n ? {\n prompt_tokens: response.data.usage.prompt_tokens,\n completion_tokens: response.data.usage.completion_tokens,\n total_tokens: response.data.usage.total_tokens,\n cached_tokens:\n response.data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n : null,\n };\n}\n\nasync function callOpenRouterWithRetries(\n id: Identifier,\n payload: OpenRouterPayload,\n retries: number = 5,\n): Promise<ParsedResponseMessage> {\n return withRetries(id, \"OpenRouter\", () => callOpenRouter(id, payload), { retries });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// MAIN ENTRY POINT\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst VALID_PROVIDERS: Provider[] = [\"openai\", \"anthropic\", \"google\", \"groq\", \"openrouter\"];\n\nconst ENUM_PROVIDER_MAP: { values: Set<string>; provider: Provider }[] = [\n { values: new Set(Object.values(GPTModel)), provider: \"openai\" },\n { values: new Set(Object.values(ClaudeModel)), provider: \"anthropic\" },\n { values: new Set(Object.values(GeminiModel)), provider: \"google\" },\n { values: new Set(Object.values(GroqModel)), provider: \"groq\" },\n { values: new Set(Object.values(OpenRouterModel)), provider: \"openrouter\" },\n];\n\nexport function parseModelString(model: string): { provider: Provider; modelId: string } {\n const colonIndex = model.indexOf(\":\");\n\n if (colonIndex !== -1) {\n const prefix = model.substring(0, colonIndex);\n\n if (VALID_PROVIDERS.includes(prefix as Provider)) {\n const modelId = model.substring(colonIndex + 1);\n\n if (!modelId) {\n throw new Error(\n `Empty model ID in model string '${model}'. Expected format: 'provider:model-id'`,\n );\n }\n\n return { provider: prefix as Provider, modelId };\n }\n\n // Prefix isn't a known provider — fall through to enum lookup\n // (handles model values that contain colons, e.g. OpenRouter \"google/gemma-4-31b-it:free\")\n }\n\n // Fallback: check enum values\n for (const { values, provider } of ENUM_PROVIDER_MAP) {\n if (values.has(model)) {\n return { provider, modelId: model };\n }\n }\n\n // If string had a colon but wasn't a known provider, give a specific error\n if (colonIndex !== -1) {\n const prefix = model.substring(0, colonIndex);\n throw new Error(\n `Unknown provider '${prefix}' in model string '${model}'. Valid providers: ${VALID_PROVIDERS.join(\", \")}`,\n );\n }\n\n throw new Error(\n `Unable to determine provider for model '${model}'. Use a provider prefix (e.g. 'openai:${model}') or a known model enum value. Valid providers: ${VALID_PROVIDERS.join(\", \")}`,\n );\n}\n\nexport async function callWithRetries(\n id: string | string[],\n aiPayload: GenericPayload,\n aiConfig?: OpenAIConfig | AnthropicAIConfig,\n retries: number = 5,\n chunkTimeoutMs: number = 15_000,\n): Promise<ParsedResponseMessage> {\n try {\n const { provider, modelId } = parseModelString(aiPayload.model);\n const routingPayload = { ...aiPayload, model: modelId as AnyModel };\n\n switch (provider) {\n case \"anthropic\":\n return await callAnthropicWithRetries(\n id,\n await prepareAnthropicPayload(id, routingPayload),\n aiConfig as AnthropicAIConfig,\n retries,\n );\n\n case \"openai\":\n return await callOpenAiWithRetries(\n id,\n await prepareOpenAIPayload(id, routingPayload),\n aiConfig as OpenAIConfig,\n retries,\n chunkTimeoutMs,\n );\n\n case \"groq\":\n return await callGroqWithRetries(\n id,\n prepareGroqPayload(routingPayload),\n retries,\n );\n\n case \"google\":\n return await callGoogleAIWithRetries(\n id,\n await prepareGoogleAIPayload(id, routingPayload),\n retries,\n );\n\n case \"openrouter\":\n return await callOpenRouterWithRetries(\n id,\n prepareOpenRouterPayload(routingPayload),\n retries,\n );\n }\n } catch (error) {\n if (aiPayload.fallbackModel) {\n logger.error(\n id,\n `Primary model ${aiPayload.model} failed, falling back to ${aiPayload.fallbackModel}`,\n {\n error: error instanceof Error ? error.message : error,\n cause:\n error instanceof Error && (error as any).cause instanceof Error\n ? (error as any).cause.message\n : undefined,\n },\n );\n return callWithRetries(\n id,\n {\n ...aiPayload,\n model: aiPayload.fallbackModel,\n fallbackModel: undefined,\n },\n aiConfig,\n retries,\n chunkTimeoutMs,\n );\n }\n throw error;\n }\n}\n","export function timeout(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function isHeicImage(name: string, mime?: string): boolean {\n const extension = name.split(\".\").pop()?.toLowerCase() || \"\";\n return (\n [\"heic\", \"heif\", \"heics\"].includes(extension) ||\n !!(\n mime && [\"image/heic\", \"image/heif\", \"image/heic-sequence\"].includes(mime)\n )\n );\n}\n"],"mappings":"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","names":["ClaudeModel","GPTModel","GroqModel","OpenRouterModel","GeminiModel","error","_a","_b"]}
|
|
1
|
+
{"version":3,"sources":["../interfaces.ts","../logger.ts","../index.ts","../utils.ts"],"sourcesContent":["/** @deprecated Use provider prefix strings instead, e.g. `\"anthropic:claude-sonnet-4-5\"` */\nexport enum ClaudeModel {\n HAIKU_3 = \"claude-3-haiku-20240307\",\n SONNET_3 = \"claude-3-sonnet-20240229\",\n OPUS_3 = \"claude-3-opus-20240229\",\n HAIKU_3_5 = \"claude-3-5-haiku-20241022\",\n SONNET_3_5 = \"claude-3-5-sonnet-20241022\",\n SONNET_4 = \"claude-sonnet-4-20250514\",\n OPUS_4 = \"claude-opus-4-20250514\",\n OPUS_4_1 = \"claude-opus-4-1\",\n HAIKU_4_5 = \"claude-haiku-4-5\",\n SONNET_4_5 = \"claude-sonnet-4-5\",\n OPUS_4_5 = \"claude-opus-4-5\",\n}\n\n/** @deprecated Use provider prefix strings instead, e.g. `\"openai:gpt-4o\"` */\nexport enum GPTModel {\n GPT35_0613 = \"gpt-3.5-turbo-0613\",\n GPT35_0613_16K = \"gpt-3.5-turbo-16k-0613\",\n GPT35_0125 = \"gpt-3.5-turbo-0125\",\n GPT4_1106_PREVIEW = \"gpt-4-1106-preview\",\n GPT4_0125_PREVIEW = \"gpt-4-0125-preview\",\n GPT4_0409 = \"gpt-4-turbo-2024-04-09\",\n GPT4O = \"gpt-4o\",\n GPT4O_MINI = \"gpt-4o-mini\",\n O1_PREVIEW = \"o1-preview\",\n O1_MINI = \"o1-mini\",\n O3_MINI = \"o3-mini\",\n GPT4_1 = \"gpt-4.1\",\n GPT4_1_MINI = \"gpt-4.1-mini\",\n GPT4_1_NANO = \"gpt-4.1-nano\",\n GPT5 = \"gpt-5\",\n GPT5_MINI = \"gpt-5-mini\",\n}\n\n/** @deprecated Use provider prefix strings instead, e.g. `\"groq:llama-3.3-70b-versatile\"` */\nexport enum GroqModel {\n LLAMA_3_70B_8192 = \"llama3-70b-8192\",\n LLAMA_3_3_70B_VERSATILE = \"llama-3.3-70b-versatile\",\n QWEN3_32B = \"qwen/qwen3-32b\",\n DEEPSEEK_R1_DISTILL_LLAMA_70B = \"deepseek-r1-distill-llama-70b\",\n}\n\n/** @deprecated Use provider prefix strings instead, e.g. `\"openrouter:qwen/qwen3.6-plus:free\"` */\nexport enum OpenRouterModel {\n GEMMA_4_31B_IT_FREE = \"google/gemma-4-31b-it:free\",\n GEMMA_4_31B_IT = \"google/gemma-4-31b-it\",\n}\n\n/** @deprecated Use provider prefix strings instead, e.g. `\"google:gemini-2.0-flash\"` */\nexport enum GeminiModel {\n GEMINI_1_5_PRO = \"gemini-1.5-pro-latest\",\n GEMINI_EXP_1206 = \"gemini-exp-1206\",\n GEMINI_2_0_FLASH = \"gemini-2.0-flash\",\n GEMINI_2_0_FLASH_EXP_IMAGE_GENERATION = \"gemini-2.0-flash-exp-image-generation\",\n GEMINI_2_0_FLASH_THINKING_EXP = \"gemini-2.0-flash-thinking-exp\",\n GEMINI_2_0_FLASH_THINKING_EXP_01_21 = \"gemini-2.0-flash-thinking-exp-01-21\",\n GEMINI_2_5_FLASH_PREVIEW_04_17 = \"gemini-2.5-flash-preview-04-17\",\n GEMINI_3_FLASH_PREVIEW = \"gemini-3-flash-preview\",\n GEMINI_3_1_FLASH_LITE_PREVIEW = \"gemini-3.1-flash-lite-preview\",\n}\n\nexport interface GenericError {\n message: string;\n}\n\nexport enum ContentType {\n TEXT = \"text\",\n ATTACHMENT = \"attachment\",\n}\n\nexport type AIChainResponse = {\n content: string | null;\n contentType?: ContentType;\n functionCalls: FunctionCall[];\n};\n\n/**\n * A single conversation turn passed to `callWithRetries`. The SDK serializes\n * these into each provider's native message format.\n *\n * ## Multi-turn tool calls\n * To continue after the model calls a tool, append the model's own assistant\n * turn and then the tool result, then call again:\n *\n * 1. Read the assistant turn off the response: `function_calls` (each with an\n * `id`) and — for reasoning models — `reasoning` / `reasoningDetails`.\n * 2. Push back an `assistant` message carrying those same `functionCalls` (and,\n * to keep the model's chain-of-thought, the captured reasoning fields).\n * 3. Push back one `role: \"tool\"` message whose `toolResults` answer each call\n * by `toolCallId`.\n *\n * The SDK is a pure transport: it does NOT echo reasoning or pair results for\n * you — it serializes exactly what you put here. Every tool/reasoning field is\n * optional, so a plain `{ role, content }` message behaves as before.\n *\n * @example\n * // turn 1 — model asks for the weather\n * const a = await callWithRetries(id, { model, messages, functions });\n * // a.function_calls -> [{ id: \"call_abc\", name: \"get_weather\", arguments: { city: \"Tokyo\" } }]\n *\n * // turn 2 — feed the call + its result back\n * const next = await callWithRetries(id, { model, functions, messages: [\n * ...messages,\n * { role: \"assistant\", content: a.content ?? \"\", functionCalls: a.function_calls,\n * reasoning: a.reasoning, reasoningDetails: a.reasoningDetails },\n * { role: \"tool\", content: \"\", toolResults: [\n * { toolCallId: \"call_abc\", name: \"get_weather\", content: '{\"tempC\":22}' } ] },\n * ]});\n */\nexport interface GenericMessage {\n /**\n * `\"tool\"` carries tool results (see `toolResults`) back to the model and\n * must immediately follow the `assistant` turn that made the matching calls.\n */\n role: \"user\" | \"assistant\" | \"system\" | \"tool\";\n /** Plain-text content. Use `\"\"` for a tool-call-only or tool-result turn. */\n content: string;\n timestamp?: string;\n files?: File[];\n /**\n * Tool calls the model made on an `assistant` turn. Pass back the `id`s you\n * received in `ParsedResponseMessage.function_calls` so the provider can pair\n * them with the `toolResults` that follow.\n */\n functionCalls?: FunctionCall[];\n /**\n * Tool outputs on a `role: \"tool\"` message — one entry per call (parallel\n * calls produce several). Each `toolCallId` must match a `FunctionCall.id`\n * from the preceding assistant turn.\n */\n toolResults?: ToolResult[];\n /**\n * Optional reasoning string to echo back on an `assistant` turn (e.g.\n * OpenRouter/DeepSeek `reasoning`). Round-tripping it keeps the model's\n * chain-of-thought across tool calls; some thinking models (DeepSeek V4)\n * require it to avoid a 400 on the next turn.\n */\n reasoning?: string;\n /**\n * Optional structured reasoning to echo back on an `assistant` turn\n * (OpenRouter `reasoning_details`, or Anthropic `thinking` /\n * `redacted_thinking` blocks captured in\n * `ParsedResponseMessage.reasoningDetails`). Preserves the signatures /\n * encrypted payloads that providers validate on round-trip.\n */\n reasoningDetails?: any;\n}\n\n/**\n * The result of executing one tool call, fed back to the model on a\n * `role: \"tool\"` message. The SDK maps this to each provider's native shape:\n * OpenAI/Groq/OpenRouter `{ role: \"tool\", tool_call_id, content }`, Anthropic a\n * `tool_result` block, Google a `functionResponse` part.\n */\nexport interface ToolResult {\n /** The `id` of the `FunctionCall` this answers (from the prior assistant turn). */\n toolCallId: string;\n /**\n * The tool/function name. Required by Anthropic and Google on round-trip; the\n * SDK falls back to the matching call's name when omitted, but supplying it is\n * recommended.\n */\n name?: string;\n /** The tool output, serialized to a string (JSON or plain text). */\n content: string;\n}\n\nexport interface File {\n mimeType: string;\n url?: string;\n data?: string;\n}\n\n/**\n * A tool/function call on the wire for OpenAI-compatible APIs (OpenAI, Groq,\n * OpenRouter).\n */\nexport interface OpenAIToolCall {\n id: string;\n type: \"function\";\n function: {\n name: string;\n /** JSON-stringified arguments object. */\n arguments: string;\n };\n}\n\nexport interface OpenAIMessage {\n role: \"user\" | \"assistant\" | \"system\" | \"tool\";\n /** `null` for an assistant turn that is tool-calls-only. */\n content: string | OpenAIContentBlock[] | null;\n /** Present on an assistant turn that called tools. */\n tool_calls?: OpenAIToolCall[];\n /** Present on a `role: \"tool\"` message; matches the originating `OpenAIToolCall.id`. */\n tool_call_id?: string;\n /** Reasoning echoed back on an assistant turn (OpenRouter/DeepSeek; OAI-compatible proxies). */\n reasoning?: string;\n /** Structured reasoning echoed back on an assistant turn (OpenRouter `reasoning_details`). */\n reasoning_details?: any;\n}\n\nexport type OpenAIContentBlock =\n | OpenAITextContentBlock\n | OpenAIImageContentBlock\n | OpenAIAudioContentBlock;\n\nexport interface OpenAITextContentBlock {\n type: \"text\";\n text: string;\n}\n\nexport interface OpenAIImageContentBlock {\n type: \"image_url\";\n image_url: {\n url: string; // URL to the image, can also be a base64 string\n };\n}\n\nexport interface OpenAIAudioContentBlock {\n type: \"audio_url\";\n audio_url: {\n url: string; // URL to the audio, can also be a base64 string\n };\n}\n\nexport interface AnthropicAIMessage {\n role: \"user\" | \"assistant\" | \"system\";\n content: string | AnthropicContentBlock[];\n}\n\nexport type AnthropicContentBlock =\n | AnthropicTextContentBlock\n | AnthropicImageContentBlock\n | AnthropicToolUseBlock\n | AnthropicToolResultBlock\n | AnthropicThinkingBlock\n | AnthropicRedactedThinkingBlock;\n\nexport interface AnthropicTextContentBlock {\n type: \"text\";\n text: string;\n}\n\nexport interface AnthropicImageContentBlock {\n type: \"image\";\n source: {\n type: \"base64\";\n media_type: \"image/jpeg\" | \"image/png\" | \"image/gif\" | \"image/webp\";\n data: string; // Must be a base64 string\n };\n}\n\n/** A tool call on an Anthropic assistant turn. */\nexport interface AnthropicToolUseBlock {\n type: \"tool_use\";\n id: string;\n name: string;\n input: Record<string, any>;\n}\n\n/** A tool result, carried on a (user-role) Anthropic message. */\nexport interface AnthropicToolResultBlock {\n type: \"tool_result\";\n tool_use_id: string;\n content: string;\n}\n\n/** A reasoning block round-tripped on an assistant turn; `signature` is validated by Anthropic. */\nexport interface AnthropicThinkingBlock {\n type: \"thinking\";\n thinking: string;\n signature: string;\n}\n\n/** An encrypted reasoning block round-tripped verbatim on an assistant turn. */\nexport interface AnthropicRedactedThinkingBlock {\n type: \"redacted_thinking\";\n data: string;\n}\n\nexport interface OpenAIResponseMessage {\n role: \"assistant\";\n content: string | null;\n function_call: {\n name: string;\n arguments: string; // unparsed arguments object\n } | null;\n}\n\nexport interface ParsedResponseMessage {\n role: \"assistant\";\n content: string | null;\n /** First of `function_calls` (backward-compat); carries `id` when the provider returns one. */\n function_call: FunctionCall | null;\n /** All tool calls the model made this turn, each with an `id` for round-tripping. */\n function_calls: FunctionCall[];\n files: File[];\n /**\n * Reasoning string from reasoning models (OpenRouter/DeepSeek `reasoning`).\n * Echo back via `GenericMessage.reasoning` to preserve chain-of-thought across\n * tool calls. Undefined when the model/provider returns none.\n */\n reasoning?: string;\n /**\n * Structured reasoning (OpenRouter `reasoning_details`, or Anthropic\n * `thinking` / `redacted_thinking` blocks). Echo back verbatim via\n * `GenericMessage.reasoningDetails` — it carries signatures some providers\n * validate. Undefined when the model/provider returns none.\n */\n reasoningDetails?: any;\n usage: {\n prompt_tokens: number;\n completion_tokens: number;\n total_tokens: number;\n /** Prompt tokens served from the provider's cache (subset of prompt_tokens). */\n cached_tokens?: number;\n } | null;\n}\n\nexport interface FunctionCall {\n /**\n * Provider tool-call id, surfaced on responses and used to pair a call with\n * its `ToolResult.toolCallId` on the next turn. The SDK synthesizes\n * `call_<index>` for providers that don't return one (e.g. Google).\n */\n id?: string;\n name: string;\n arguments: Record<string, any>;\n /**\n * Opaque per-call signature that must be echoed back verbatim on round-trip.\n * Currently Google's `thoughtSignature` — Gemini REQUIRES it on functionCall\n * parts in multi-turn tool use (a missing one 400s the next request). The SDK\n * captures it on responses and re-emits it when you pass the call back;\n * undefined for providers that don't use one.\n */\n thoughtSignature?: string;\n}\n\nexport interface OpenAIConfig {\n service: \"azure\" | \"openai\";\n apiKey: string;\n /**\n * Override the base URL for the OpenAI service (e.g. an OpenAI-compatible\n * proxy or self-hosted endpoint). The path `/chat/completions` is appended.\n * Ignored when `service === \"azure\"` (use `modelConfigMap` instead).\n * Defaults to `https://api.openai.com/v1`.\n */\n baseUrl?: string;\n orgId?: string;\n modelConfigMap?: Record<\n GPTModel,\n {\n resource: string;\n deployment: string;\n apiVersion: string;\n apiKey: string;\n endpoint?: string;\n }\n >;\n}\n\nexport interface AnthropicAIConfig {\n service: \"anthropic\" | \"bedrock\";\n}\n\nexport interface FunctionDefinition {\n name: string;\n description?: string;\n parameters: Record<string, any>;\n}\n\ninterface FunctionWrapped {\n type: \"function\";\n function: FunctionDefinition;\n}\n\nexport interface GroqPayload {\n model: GroqModel | string;\n messages: OpenAIMessage[];\n tools?: FunctionWrapped[];\n tool_choice?:\n | \"none\"\n | \"auto\"\n | { type: \"function\"; function: { name: string } };\n temperature?: number;\n\n functions?: any[]; // Deprecate this\n}\n\n/**\n * OpenRouter provider-routing preferences, forwarded verbatim as the request\n * body's `provider` field. See https://openrouter.ai/docs/guides/routing/provider-selection\n */\nexport interface OpenRouterProviderPreferences {\n /** Ordered list of provider slugs to try first (e.g. [\"baidu\", \"siliconflow\"]). */\n order?: string[];\n /** Restrict routing to exactly these provider slugs. */\n only?: string[];\n /** Provider slugs to exclude. */\n ignore?: string[];\n /** Only use providers serving these quantizations (e.g. [\"fp8\"]). */\n quantizations?: string[];\n /** When false, never fall back to providers outside `order`/`only`. */\n allow_fallbacks?: boolean;\n /** Override the default sort (\"price\" | \"throughput\" | \"latency\"). */\n sort?: string;\n}\n\nexport interface OpenRouterPayload {\n model: OpenRouterModel | string;\n messages: OpenAIMessage[];\n tools?: FunctionWrapped[];\n tool_choice?:\n | \"none\"\n | \"auto\"\n | { type: \"function\"; function: { name: string } };\n temperature?: number;\n provider?: OpenRouterProviderPreferences;\n}\n\nexport interface OpenAIPayload {\n model: GPTModel | string;\n messages: OpenAIMessage[];\n tools?: FunctionWrapped[];\n tool_choice?:\n | \"none\"\n | \"auto\"\n | { type: \"function\"; function: { name: string } };\n}\n\nexport interface AnthropicAIPayload {\n model: ClaudeModel | string;\n messages: AnthropicAIMessage[];\n functions?: any[]; // TODO type this JSON schema\n temperature?: number;\n system?: string;\n}\n\nexport interface GoogleAITextPart {\n text: string;\n}\n\nexport interface GoogleAIInlineDataPart {\n inlineData: {\n mimeType: string;\n data: string;\n };\n}\n\nexport interface GoogleAIFileDataPart {\n fileData: {\n mimeType: string;\n fileUri: string;\n };\n}\n\n/** A tool call on a Google `model` turn. */\nexport interface GoogleAIFunctionCallPart {\n functionCall: {\n id?: string;\n name: string;\n args: Record<string, any>;\n };\n /** Echoed back verbatim on round-trip — Gemini requires it for tool use. */\n thoughtSignature?: string;\n}\n\n/** A tool result, carried on a Google `user` turn. */\nexport interface GoogleAIFunctionResponsePart {\n functionResponse: {\n id?: string;\n name: string;\n response: Record<string, any>;\n };\n}\n\nexport type GoogleAIPart =\n | GoogleAITextPart\n | GoogleAIInlineDataPart\n | GoogleAIFileDataPart\n | GoogleAIFunctionCallPart\n | GoogleAIFunctionResponsePart;\nexport interface GoogleAIMessage {\n role: \"user\" | \"model\";\n parts: GoogleAIPart[];\n}\nexport interface GoogleAIPayload {\n model: GeminiModel | string;\n messages: GoogleAIMessage[];\n tools?: {\n functionDeclarations: FunctionDefinition[];\n };\n systemInstruction?: string;\n}\n\nexport type Provider = \"openai\" | \"anthropic\" | \"google\" | \"groq\" | \"openrouter\";\n\nexport type AnyModel = GPTModel | ClaudeModel | GroqModel | GeminiModel | OpenRouterModel | (string & {});\n\nexport interface GenericPayload {\n model: AnyModel;\n messages: GenericMessage[];\n functions?: FunctionDefinition[];\n function_call?: \"none\" | \"auto\" | { name: string };\n temperature?: number;\n fallbackModel?: AnyModel;\n /**\n * OpenRouter-only: provider-routing preferences. Ignored by non-OpenRouter\n * adapters. Forwarded as the request body's `provider` field.\n */\n provider?: OpenRouterProviderPreferences;\n}\n\nexport interface OpenAIBody {\n choices: {\n message: OpenAIResponseMessage;\n }[];\n error?: {\n code: string;\n };\n usage: {\n completion_tokens: number;\n prompt_tokens: number;\n total_tokens: number;\n prompt_tokens_details?: {\n cached_tokens?: number;\n };\n };\n}\n","type LogLevel = \"LOG\" | \"WARN\" | \"ERROR\";\nexport type Identifier = string | string[];\n\nfunction formatIdentifier(identifier: Identifier): string {\n if (Array.isArray(identifier)) {\n return identifier.map((id) => `[${id}]`).join(\" \");\n }\n return `[${identifier}]`;\n}\n\nfunction formatMessage(\n level: LogLevel,\n identifier: Identifier,\n message: string\n): string {\n return `[${level}] ${formatIdentifier(identifier)} ${message}`;\n}\n\nexport function log(\n identifier: Identifier,\n message: string,\n ...args: any[]\n): void {\n console.log(formatMessage(\"LOG\", identifier, message), ...args);\n}\n\nexport function warn(\n identifier: Identifier,\n message: string,\n ...args: any[]\n): void {\n console.warn(formatMessage(\"WARN\", identifier, message), ...args);\n}\n\nexport function error(\n identifier: Identifier,\n message: string,\n ...args: any[]\n): void {\n console.error(formatMessage(\"ERROR\", identifier, message), ...args);\n}\n\nexport default {\n log,\n warn,\n error,\n};\n","import {\n ClaudeModel,\n GPTModel,\n OpenAIPayload,\n OpenAIMessage,\n OpenAIConfig,\n AnthropicAIPayload,\n AnthropicAIMessage,\n GenericMessage,\n AnthropicAIConfig,\n GenericPayload,\n GroqPayload,\n GroqModel,\n OpenRouterPayload,\n OpenRouterModel,\n ParsedResponseMessage,\n FunctionCall,\n AnthropicContentBlock,\n OpenAIContentBlock,\n GoogleAIPayload,\n GeminiModel,\n GoogleAIPart,\n File,\n GoogleAIMessage,\n AnyModel,\n Provider,\n} from \"./interfaces\";\nimport logger, { Identifier } from \"./logger\";\nimport {\n BedrockRuntimeClient,\n InvokeModelCommand,\n} from \"@aws-sdk/client-bedrock-runtime\";\nimport axios from \"axios\";\nimport { isHeicImage, timeout } from \"./utils\";\n\nconst sharp = require(\"sharp\");\nconst decode = require(\"heic-decode\");\n\nexport {\n ClaudeModel,\n GPTModel,\n GroqModel,\n GeminiModel,\n OpenRouterModel,\n OpenAIConfig,\n FunctionDefinition,\n FunctionCall,\n GenericMessage,\n GenericPayload,\n ToolResult,\n ParsedResponseMessage,\n OpenRouterProviderPreferences,\n AnyModel,\n Provider,\n} from \"./interfaces\";\n\n// ─────────────────────────────────────────────────────────────────────────────\n// SHARED UTILITIES\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Generic retry wrapper for API calls with exponential backoff.\n */\nasync function withRetries<T>(\n identifier: Identifier,\n apiName: string,\n fn: () => Promise<T>,\n options: {\n retries?: number;\n baseDelayMs?: number;\n onError?: (error: any, attempt: number) => void;\n } = {},\n): Promise<T> {\n const { retries = 5, baseDelayMs = 125, onError } = options;\n\n logger.log(identifier, `Calling ${apiName} API with retries`);\n\n let lastError: any;\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n return await fn();\n } catch (error: any) {\n lastError = error;\n\n if (onError) {\n onError(error, attempt);\n } else {\n logger.error(\n identifier,\n `Retry #${attempt} error: ${error.message}`,\n error.response?.data || error,\n );\n }\n\n await timeout(baseDelayMs * attempt);\n }\n }\n\n const error = new Error(\n `Failed to call ${apiName} API after ${retries} attempts`,\n ) as any;\n error.cause = lastError;\n throw error;\n}\n\nfunction parseStreamedResponse(\n identifier: Identifier,\n paragraph: string,\n toolCallAccumulators: { id?: string; name: string; arguments: string }[],\n allowedFunctionNames: Set<string> | null,\n reasoning?: string,\n): ParsedResponseMessage {\n const functionCalls: FunctionCall[] = [];\n\n for (let i = 0; i < toolCallAccumulators.length; i++) {\n const acc = toolCallAccumulators[i];\n if (!acc.name || !acc.arguments) continue;\n\n if (allowedFunctionNames && !allowedFunctionNames.has(acc.name)) {\n throw new Error(\n `Stream error: received function call with unknown name: ${acc.name}`,\n );\n }\n\n try {\n functionCalls.push({\n id: acc.id || `call_${i}`,\n name: acc.name,\n arguments: JSON.parse(acc.arguments),\n });\n } catch (error) {\n logger.error(\n identifier,\n \"Error parsing function call arguments:\",\n acc.arguments,\n );\n throw error;\n }\n }\n\n if (!paragraph && !functionCalls.length) {\n logger.error(\n identifier,\n \"Stream error: received message without content or function_call:\",\n JSON.stringify({ paragraph, toolCallAccumulators }),\n );\n throw new Error(\n \"Stream error: received message without content or function_call\",\n );\n }\n\n return {\n role: \"assistant\",\n content: paragraph || null,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n reasoning: reasoning || undefined,\n usage: null,\n };\n}\n\nfunction truncatePayload(payload: OpenAIPayload): string {\n return JSON.stringify(\n {\n ...payload,\n messages: payload.messages.map((message) => {\n const truncatedMessage = { ...message };\n if (typeof truncatedMessage.content === \"string\") {\n truncatedMessage.content = truncatedMessage.content.slice(0, 100);\n } else if (Array.isArray(truncatedMessage.content)) {\n truncatedMessage.content = truncatedMessage.content.map((block) => {\n if (block.type === \"image_url\") {\n return {\n ...block,\n image_url: { url: block.image_url.url.slice(0, 100) },\n };\n }\n return block;\n });\n }\n return truncatedMessage;\n }),\n },\n null,\n 2,\n );\n}\n\nasync function getNormalizedBase64PNG(\n url: string,\n mime: string,\n): Promise<string> {\n const response = await axios.get(url, { responseType: \"arraybuffer\" });\n\n let imageBuffer = Buffer.from(response.data);\n let sharpOptions = {};\n\n if (isHeicImage(url, mime)) {\n const imageData = await decode({ buffer: imageBuffer });\n imageBuffer = Buffer.from(imageData.data);\n sharpOptions = {\n raw: {\n width: imageData.width,\n height: imageData.height,\n channels: 4,\n },\n };\n }\n\n // Limits size of image to < 5MB Anthropic limit\n const resizedBuffer = await sharp(imageBuffer, sharpOptions)\n .withMetadata()\n .resize(1024, 1024, { fit: \"inside\", withoutEnlargement: true })\n .png()\n .toBuffer();\n\n return resizedBuffer.toString(\"base64\");\n}\n\nconst ALLOWED_IMAGE_MIME_TYPES = [\n \"image/png\",\n \"image/jpeg\",\n \"image/gif\",\n \"image/webp\",\n];\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OPENAI\n// ─────────────────────────────────────────────────────────────────────────────\n\ninterface OpenAIRequestConfig {\n endpoint: string;\n headers: Record<string, string>;\n}\n\nfunction buildOpenAIRequestConfig(\n identifier: Identifier,\n model: string,\n config: OpenAIConfig | undefined,\n): OpenAIRequestConfig {\n if (!config) {\n config = {\n service: \"openai\",\n apiKey: process.env.OPENAI_API_KEY as string,\n baseUrl: \"\",\n };\n }\n\n if (config.service === \"azure\") {\n logger.log(identifier, \"Using Azure OpenAI service:\", model);\n\n if (!config.modelConfigMap) {\n throw new Error(\n \"OpenAI config modelConfigMap is required when using Azure OpenAI service.\",\n );\n }\n\n const azureConfig = config.modelConfigMap[model as GPTModel];\n if (!azureConfig?.endpoint) {\n throw new Error(\"Azure OpenAI endpoint is required in modelConfigMap.\");\n }\n\n const endpoint = `${azureConfig.endpoint}/openai/deployments/${azureConfig.deployment}/chat/completions?api-version=${azureConfig.apiVersion}`;\n logger.log(identifier, \"Using endpoint:\", endpoint);\n\n return {\n endpoint,\n headers: {\n \"Content-Type\": \"application/json\",\n \"api-key\": azureConfig.apiKey,\n },\n };\n }\n\n // Default: OpenAI (or any OpenAI-compatible server via config.baseUrl)\n logger.log(identifier, \"Using OpenAI service:\", model);\n if (config.orgId) {\n logger.log(identifier, \"Using orgId:\", config.orgId);\n }\n\n const base = (config.baseUrl?.trim() || \"https://api.openai.com/v1\").replace(\n /\\/$/,\n \"\",\n );\n return {\n endpoint: `${base}/chat/completions`,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${config.apiKey}`,\n ...(config.orgId ? { \"OpenAI-Organization\": config.orgId } : {}),\n },\n };\n}\n\nasync function prepareOpenAIPayload(\n identifier: Identifier,\n payload: GenericPayload,\n): Promise<OpenAIPayload> {\n const preparedPayload: OpenAIPayload = {\n model: payload.model as GPTModel,\n messages: [],\n tools: payload.functions?.map((fn) => ({\n type: \"function\",\n function: fn,\n })),\n tool_choice: payload.function_call\n ? typeof payload.function_call === \"string\"\n ? payload.function_call\n : { type: \"function\", function: payload.function_call }\n : undefined,\n };\n\n for (const message of payload.messages) {\n // role:\"tool\" → one OpenAI tool message per result (parallel calls expand).\n if (message.role === \"tool\") {\n for (const tr of message.toolResults || []) {\n preparedPayload.messages.push({\n role: \"tool\",\n tool_call_id: tr.toolCallId,\n content: tr.content,\n });\n }\n continue;\n }\n\n const contentBlocks: OpenAIContentBlock[] = [];\n\n if (message.content) {\n contentBlocks.push({ type: \"text\", text: message.content });\n }\n\n for (const file of message.files || []) {\n if (ALLOWED_IMAGE_MIME_TYPES.includes(file.mimeType)) {\n if (file.url) {\n contentBlocks.push({\n type: \"image_url\",\n image_url: { url: file.url },\n });\n contentBlocks.push({ type: \"text\", text: `Image (${file.url})` });\n } else if (file.data) {\n contentBlocks.push({\n type: \"image_url\",\n image_url: { url: `data:${file.mimeType};base64,${file.data}` },\n });\n }\n } else if (file.url) {\n // Non-image file with URL - add text reference\n contentBlocks.push({\n type: \"text\",\n text: `File (${file.url})`,\n });\n }\n }\n\n const outMessage: OpenAIMessage = {\n role: message.role,\n // OpenAI wants null (not []) content on a tool-call-only assistant turn.\n content: contentBlocks.length ? contentBlocks : null,\n };\n if (message.functionCalls?.length) {\n outMessage.tool_calls = message.functionCalls.map((fc, i) => ({\n id: fc.id ?? `call_${i}`,\n type: \"function\" as const,\n function: {\n name: fc.name,\n arguments: JSON.stringify(fc.arguments),\n },\n }));\n }\n // Reasoning passthrough — only when the caller supplied it (never injected).\n if (message.reasoning) outMessage.reasoning = message.reasoning;\n if (message.reasoningDetails)\n outMessage.reasoning_details = message.reasoningDetails;\n preparedPayload.messages.push(outMessage);\n }\n\n return preparedPayload;\n}\n\nasync function callOpenAIStream(\n id: Identifier,\n openAiPayload: OpenAIPayload,\n openAiConfig: OpenAIConfig | undefined,\n chunkTimeoutMs: number,\n): Promise<ParsedResponseMessage> {\n const functionNames: Set<string> | null = openAiPayload.tools\n ? new Set(openAiPayload.tools.map((fn) => fn.function.name as string))\n : null;\n\n const { endpoint, headers } = buildOpenAIRequestConfig(\n id,\n openAiPayload.model,\n openAiConfig,\n );\n\n const controller = new AbortController();\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ ...openAiPayload, stream: true }),\n signal: controller.signal,\n });\n\n if (!response.body) {\n throw new Error(\"Stream error: no response body\");\n }\n\n let paragraph = \"\";\n let reasoning = \"\";\n const toolCallAccumulators: { id?: string; name: string; arguments: string }[] =\n [];\n\n const reader = response.body.getReader();\n let partialChunk = \"\";\n let chunkIndex = -1;\n\n const createAbortTimeout = () =>\n setTimeout(() => {\n logger.error(id, `Stream timeout after ${chunkTimeoutMs}ms`);\n controller.abort();\n }, chunkTimeoutMs);\n\n while (true) {\n chunkIndex++;\n const abortTimeout = createAbortTimeout();\n const { done, value } = await reader.read();\n clearTimeout(abortTimeout);\n\n if (done) {\n logger.error(\n id,\n `Stream ended prematurely after ${chunkIndex + 1} chunks`,\n );\n throw new Error(\"Stream error: ended prematurely\");\n }\n\n let chunk = new TextDecoder().decode(value);\n if (partialChunk) {\n chunk = partialChunk + chunk;\n partialChunk = \"\";\n }\n\n const jsonStrings = chunk.split(/^data: /gm);\n\n for (const jsonString of jsonStrings) {\n if (!jsonString) continue;\n\n if (jsonString.includes(\"[DONE]\")) {\n return parseStreamedResponse(\n id,\n paragraph,\n toolCallAccumulators,\n functionNames,\n reasoning,\n );\n }\n\n let json;\n try {\n json = JSON.parse(jsonString.trim());\n } catch {\n partialChunk = jsonString;\n continue;\n }\n\n if (!json.choices?.length) {\n if (json.error) {\n logger.error(id, \"Stream error from OpenAI:\", json.error);\n const error = new Error(\"Stream error: OpenAI error\") as any;\n error.data = json.error;\n error.requestBody = truncatePayload(openAiPayload);\n throw error;\n }\n if (chunkIndex !== 0) {\n logger.error(id, \"Stream error: no choices in JSON:\", json);\n }\n continue;\n }\n\n const toolCalls = json.choices[0]?.delta?.tool_calls;\n if (toolCalls) {\n for (const toolCall of toolCalls) {\n const idx = toolCall.index ?? 0;\n while (toolCallAccumulators.length <= idx) {\n toolCallAccumulators.push({ name: \"\", arguments: \"\" });\n }\n // The id arrives on the first fragment of each call.\n if (toolCall.id) toolCallAccumulators[idx].id = toolCall.id;\n if (toolCall.function?.name)\n toolCallAccumulators[idx].name += toolCall.function.name;\n if (toolCall.function?.arguments)\n toolCallAccumulators[idx].arguments += toolCall.function.arguments;\n }\n }\n\n const text = json.choices[0]?.delta?.content;\n if (text) paragraph += text;\n\n // Reasoning models (OpenRouter/OAI-compatible) stream a parallel\n // `reasoning` channel; accumulate it so callers can round-trip it.\n const reasoningDelta = json.choices[0]?.delta?.reasoning;\n if (reasoningDelta) reasoning += reasoningDelta;\n }\n }\n}\n\nasync function callOpenAI(\n id: Identifier,\n openAiPayload: OpenAIPayload,\n openAiConfig: OpenAIConfig | undefined,\n): Promise<ParsedResponseMessage> {\n const { endpoint, headers } = buildOpenAIRequestConfig(\n id,\n openAiPayload.model,\n openAiConfig,\n );\n\n const response = await fetch(endpoint, {\n method: \"POST\",\n headers,\n body: JSON.stringify({ ...openAiPayload, stream: false }),\n });\n\n if (!response.ok) {\n const errorData = await response.json();\n logger.error(id, \"OpenAI API error:\", errorData);\n throw new Error(`OpenAI API Error: ${errorData.error.message}`);\n }\n\n const data = await response.json();\n\n if (!data.choices?.length) {\n if (data.error) {\n logger.error(id, \"OpenAI error:\", data.error);\n throw new Error(`OpenAI error: ${data.error.message}`);\n }\n throw new Error(\"OpenAI error: No choices returned.\");\n }\n\n const choice = data.choices[0];\n\n // Check for tool_calls (modern API) first, fall back to function_call (legacy)\n const toolCalls = choice.message?.tool_calls;\n const functionCalls: FunctionCall[] = [];\n\n if (toolCalls?.length) {\n for (let i = 0; i < toolCalls.length; i++) {\n const tc = toolCalls[i];\n functionCalls.push({\n id: tc.id ?? `call_${i}`,\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n });\n }\n } else if (choice.function_call) {\n functionCalls.push({\n id: \"call_0\",\n name: choice.function_call.name,\n arguments: JSON.parse(choice.function_call.arguments),\n });\n }\n\n // An empty 200 (no content, no tool call) is not a usable answer — throw so\n // withRetries retries and callWithRetries can fall back. (Mirrors the\n // streaming path's guard in parseStreamedResponse.)\n if (!choice.message?.content && !functionCalls.length) {\n logger.error(\n id,\n \"OpenAI: received message without content or function_call:\",\n JSON.stringify(data),\n );\n throw new Error(\n \"OpenAI: received message without content or function_call\",\n );\n }\n\n return {\n role: \"assistant\",\n content: choice.message.content || null,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n reasoning: choice.message?.reasoning ?? undefined,\n reasoningDetails: choice.message?.reasoning_details ?? undefined,\n usage: data.usage\n ? {\n prompt_tokens: data.usage.prompt_tokens,\n completion_tokens: data.usage.completion_tokens,\n total_tokens: data.usage.total_tokens,\n cached_tokens: data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n : null,\n };\n}\n\nasync function callOpenAiWithRetries(\n id: Identifier,\n openAiPayload: OpenAIPayload,\n openAiConfig?: OpenAIConfig,\n retries: number = 5,\n chunkTimeoutMs: number = 15_000,\n): Promise<ParsedResponseMessage> {\n logger.log(\n id,\n \"Calling OpenAI API with retries:\",\n openAiConfig?.service,\n openAiPayload.model,\n );\n\n const modelStr = openAiPayload.model as string;\n const useStreaming =\n modelStr !== GPTModel.O1_MINI &&\n modelStr !== GPTModel.O1_PREVIEW &&\n !modelStr.startsWith(\"o1\");\n\n return withRetries(\n id,\n \"OpenAI\",\n async () => {\n if (useStreaming) {\n return callOpenAIStream(\n id,\n openAiPayload,\n openAiConfig,\n chunkTimeoutMs,\n );\n } else {\n return callOpenAI(id, openAiPayload, openAiConfig);\n }\n },\n {\n retries,\n baseDelayMs: 250,\n onError: (error, attempt) => {\n logger.error(\n id,\n `Retry #${attempt} error: ${error.message}`,\n error.response?.data || error.data || error,\n );\n\n // Remove images on content policy violation\n if (error.data?.code === \"content_policy_violation\") {\n logger.log(id, \"Removing images due to content policy violation\");\n openAiPayload.messages.forEach((message: OpenAIMessage) => {\n if (Array.isArray(message.content)) {\n message.content = message.content.filter(\n (content) => content.type === \"text\",\n );\n }\n });\n }\n },\n },\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// ANTHROPIC\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction jigAnthropicMessages(\n messages: AnthropicAIMessage[],\n): AnthropicAIMessage[] {\n const hasToolBlock = (content: AnthropicAIMessage[\"content\"]) =>\n Array.isArray(content) &&\n content.some((b) => b.type === \"tool_use\" || b.type === \"tool_result\");\n\n let jiggedMessages = messages.slice();\n\n // Ensure first message is from user\n if (jiggedMessages[0]?.role !== \"user\") {\n jiggedMessages = [\n { role: \"user\" as const, content: \"...\" },\n ...jiggedMessages,\n ];\n }\n\n // Group consecutive messages with the same role\n jiggedMessages = jiggedMessages.reduce((acc, message) => {\n if (acc.length === 0) return [message];\n\n const lastMessage = acc[acc.length - 1];\n if (lastMessage.role === message.role) {\n const lastContent = Array.isArray(lastMessage.content)\n ? lastMessage.content\n : [{ type: \"text\" as const, text: lastMessage.content }];\n const newContent = Array.isArray(message.content)\n ? message.content\n : [{ type: \"text\" as const, text: message.content }];\n\n // Never inject a text separator into a turn carrying tool_use/tool_result\n // blocks — it would sit between a tool_use and its result and break\n // Anthropic's pairing requirement.\n const separator: AnthropicContentBlock[] =\n hasToolBlock(lastMessage.content) || hasToolBlock(message.content)\n ? []\n : [{ type: \"text\", text: \"\\n\\n---\\n\\n\" }];\n\n lastMessage.content = [...lastContent, ...separator, ...newContent];\n return acc;\n }\n\n // Convert string content to text content block\n if (typeof message.content === \"string\") {\n message.content = [{ type: \"text\", text: message.content }];\n }\n\n return [...acc, message];\n }, [] as AnthropicAIMessage[]);\n\n // Ensure last message is from user — but never append a placeholder after an\n // unanswered tool_use turn (a text-only user can't satisfy it).\n const last = jiggedMessages[jiggedMessages.length - 1];\n if (last?.role === \"assistant\" && !hasToolBlock(last.content)) {\n jiggedMessages.push({ role: \"user\", content: \"...\" });\n }\n\n return jiggedMessages;\n}\n\nasync function prepareAnthropicPayload(\n _identifier: Identifier,\n payload: GenericPayload,\n): Promise<AnthropicAIPayload> {\n const preparedPayload: AnthropicAIPayload = {\n model: payload.model as ClaudeModel,\n messages: [],\n functions: payload.functions,\n temperature: payload.temperature,\n };\n\n for (const message of payload.messages) {\n if (message.role === \"system\") {\n preparedPayload.system = message.content;\n continue;\n }\n\n // role:\"tool\" → a user message carrying tool_result blocks (parallel\n // results share one message, matching Anthropic's expected shape).\n if (message.role === \"tool\") {\n preparedPayload.messages.push({\n role: \"user\",\n content: (message.toolResults || []).map((tr) => ({\n type: \"tool_result\" as const,\n tool_use_id: tr.toolCallId,\n content: tr.content,\n })),\n });\n continue;\n }\n\n const contentBlocks: AnthropicContentBlock[] = [];\n\n if (message.content) {\n contentBlocks.push({ type: \"text\", text: message.content });\n }\n\n for (const file of message.files || []) {\n if (ALLOWED_IMAGE_MIME_TYPES.includes(file.mimeType)) {\n if (file.url) {\n if (message.role == \"user\") {\n // anthropic assistant turns can't have images\n contentBlocks.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: \"image/png\",\n data: await getNormalizedBase64PNG(file.url, file.mimeType),\n },\n });\n }\n contentBlocks.push({ type: \"text\", text: `Image (${file.url})` });\n } else if (file.data) {\n if (message.role == \"user\") {\n // anthropic assistant turns can't have images\n contentBlocks.push({\n type: \"image\",\n source: {\n type: \"base64\",\n media_type: file.mimeType as any,\n data: file.data,\n },\n });\n }\n }\n } else if (file.url) {\n // Non-image file with URL - add text reference\n contentBlocks.push({\n type: \"text\",\n text: `File (${file.url})`,\n });\n }\n }\n\n // Thinking blocks (if the caller echoes them) must lead an assistant turn,\n // before text; tool_use blocks come last.\n const leadingBlocks: AnthropicContentBlock[] =\n message.role === \"assistant\" && Array.isArray(message.reasoningDetails)\n ? message.reasoningDetails\n : [];\n const toolUseBlocks: AnthropicContentBlock[] = (\n message.functionCalls || []\n ).map((fc, i) => ({\n type: \"tool_use\" as const,\n id: fc.id ?? `call_${i}`,\n name: fc.name,\n input: fc.arguments,\n }));\n\n preparedPayload.messages.push({\n role: message.role,\n content: [...leadingBlocks, ...contentBlocks, ...toolUseBlocks],\n });\n }\n\n return preparedPayload;\n}\n\nasync function callAnthropic(\n id: Identifier,\n payload: AnthropicAIPayload,\n config?: AnthropicAIConfig,\n): Promise<ParsedResponseMessage> {\n const anthropicMessages = jigAnthropicMessages(payload.messages);\n const tools = payload.functions?.map((f) => ({\n ...f,\n input_schema: f.parameters,\n parameters: undefined,\n }));\n\n let data;\n\n if (config?.service === \"bedrock\") {\n const AWS_REGION = \"us-east-1\";\n const MODEL_ID = \"anthropic.claude-3-haiku-20240307-v1:0\";\n\n const client = new BedrockRuntimeClient({ region: AWS_REGION });\n const bedrockPayload = {\n anthropic_version: \"bedrock-2023-05-31\",\n max_tokens: 4096,\n messages: anthropicMessages,\n tools,\n };\n\n const response = await client.send(\n new InvokeModelCommand({\n contentType: \"application/json\",\n body: JSON.stringify(bedrockPayload),\n modelId: MODEL_ID,\n }),\n );\n\n const decodedResponseBody = new TextDecoder().decode(response.body);\n data = JSON.parse(decodedResponseBody);\n } else {\n // Default: Anthropic API\n // Prompt caching: mark a breakpoint on the last tool only. Tool schemas\n // are fully static and identical across users, so that span gets real\n // cache reads; the system prompt is left uncached because callers embed\n // per-user / per-minute content in it, and a breakpoint after a volatile\n // span pays 1.25x cache writes with near-zero reads. Anthropic ignores\n // breakpoints below the model's minimum cacheable length, so small tool\n // sets are a safe no-op.\n const cachedTools = tools?.length\n ? [\n ...tools.slice(0, -1),\n { ...tools[tools.length - 1], cache_control: { type: \"ephemeral\" } },\n ]\n : tools;\n const response = await axios.post(\n \"https://api.anthropic.com/v1/messages\",\n {\n model: payload.model,\n messages: anthropicMessages,\n tools: cachedTools,\n temperature: payload.temperature,\n system: payload.system,\n max_tokens: 4096,\n },\n {\n headers: {\n \"content-type\": \"application/json\",\n \"x-api-key\": process.env.ANTHROPIC_API_KEY as string,\n \"anthropic-version\": \"2023-06-01\",\n \"anthropic-beta\": \"tools-2024-04-04\",\n },\n timeout: 60000,\n },\n );\n data = response.data;\n }\n\n const answers = data.content;\n if (!answers?.[0]) {\n logger.error(id, \"Missing answer in Anthropic API response:\", data);\n throw new Error(\"Missing answer in Anthropic API\");\n }\n\n let textResponse = \"\";\n const functionCalls: FunctionCall[] = [];\n // Native API thinking blocks (`{type:\"thinking\",thinking,signature}` /\n // `redacted_thinking`), kept raw so callers can echo them back verbatim —\n // their signatures are validated by Anthropic on the next turn.\n const reasoningBlocks: any[] = [];\n\n for (const answer of answers) {\n if (!answer.type) {\n logger.error(id, \"Missing answer type in Anthropic API response:\", data);\n throw new Error(\"Missing answer type in Anthropic API\");\n }\n\n if (answer.type === \"text\") {\n let text = answer.text\n .replace(/<thinking>.*?<\\/thinking>/gs, \"\")\n .replace(/<answer>|<\\/answer>/gs, \"\")\n .trim();\n\n if (!text) {\n text = answer.text.replace(\n /<thinking>|<\\/thinking>|<answer>|<\\/answer>/gs,\n \"\",\n );\n logger.log(id, \"No text in answer, returning text within tags:\", text);\n }\n\n textResponse = textResponse ? `${textResponse}\\n\\n${text}` : text;\n } else if (answer.type === \"tool_use\") {\n functionCalls.push({\n id: answer.id,\n name: answer.name,\n arguments: answer.input,\n });\n } else if (\n answer.type === \"thinking\" ||\n answer.type === \"redacted_thinking\"\n ) {\n reasoningBlocks.push(answer);\n }\n }\n\n if (!textResponse && !functionCalls.length) {\n logger.error(\n id,\n \"Missing text & functions in Anthropic API response:\",\n data,\n );\n throw new Error(\"Missing text & functions in Anthropic API response\");\n }\n\n // Anthropic's input_tokens EXCLUDES cache reads/writes; fold them back in\n // so prompt_tokens means \"all input tokens\" like OpenAI, where\n // cached_tokens is a subset of prompt_tokens.\n let usage: ParsedResponseMessage[\"usage\"] = null;\n if (data.usage) {\n const cacheRead = data.usage.cache_read_input_tokens ?? 0;\n const cacheWrite = data.usage.cache_creation_input_tokens ?? 0;\n const promptTokens = data.usage.input_tokens + cacheRead + cacheWrite;\n usage = {\n prompt_tokens: promptTokens,\n completion_tokens: data.usage.output_tokens,\n total_tokens: promptTokens + data.usage.output_tokens,\n cached_tokens: cacheRead,\n };\n }\n\n return {\n role: \"assistant\",\n content: textResponse,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n reasoningDetails: reasoningBlocks.length ? reasoningBlocks : undefined,\n usage,\n };\n}\n\nasync function callAnthropicWithRetries(\n id: Identifier,\n payload: AnthropicAIPayload,\n config?: AnthropicAIConfig,\n retries: number = 5,\n): Promise<ParsedResponseMessage> {\n return withRetries(\n id,\n \"Anthropic\",\n () => callAnthropic(id, payload, config),\n {\n retries,\n },\n );\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// GOOGLE AI\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction jigGoogleMessages(messages: GoogleAIMessage[]): GoogleAIMessage[] {\n const hasFunctionPart = (parts: GoogleAIPart[]) =>\n parts.some((p) => \"functionCall\" in p || \"functionResponse\" in p);\n\n let jiggedMessages = messages.slice();\n\n // Ensure first message is from user\n if (jiggedMessages[0]?.role === \"model\") {\n jiggedMessages = [\n { role: \"user\" as const, parts: [{ text: \"...\" }] },\n ...jiggedMessages,\n ];\n }\n\n // Group consecutive messages with the same role\n jiggedMessages = jiggedMessages.reduce((acc, message) => {\n if (acc.length === 0) return [message];\n\n const lastMessage = acc[acc.length - 1];\n if (lastMessage.role === message.role) {\n lastMessage.parts = [...lastMessage.parts, ...message.parts];\n return acc;\n }\n\n return [...acc, message];\n }, [] as GoogleAIMessage[]);\n\n // Ensure last message is from user — but don't append a placeholder after a\n // model turn that ends in a functionCall (it would orphan the call into\n // history and send \"...\" as the message).\n const last = jiggedMessages[jiggedMessages.length - 1];\n if (last?.role === \"model\" && !hasFunctionPart(last.parts)) {\n jiggedMessages.push({ role: \"user\", parts: [{ text: \"...\" }] });\n }\n\n return jiggedMessages;\n}\n\nasync function prepareGoogleAIPayload(\n _identifier: Identifier,\n payload: GenericPayload,\n): Promise<GoogleAIPayload> {\n const preparedPayload: GoogleAIPayload = {\n model: payload.model as GeminiModel,\n messages: [],\n tools: payload.functions\n ? {\n functionDeclarations: payload.functions.map((fn) => ({\n name: fn.name,\n parameters: {\n description: fn.description,\n ...fn.parameters,\n },\n })),\n }\n : undefined,\n };\n\n // id -> tool name, to backfill functionResponse.name when a caller omits it.\n const toolNameById = new Map<string, string>();\n for (const m of payload.messages) {\n for (const fc of m.functionCalls || []) {\n if (fc.id) toolNameById.set(fc.id, fc.name);\n }\n }\n\n for (const message of payload.messages) {\n if (message.role === \"system\") {\n preparedPayload.systemInstruction = message.content;\n continue;\n }\n\n // role:\"tool\" → a user turn carrying functionResponse parts.\n if (message.role === \"tool\") {\n preparedPayload.messages.push({\n role: \"user\",\n parts: (message.toolResults || []).map((tr) => ({\n functionResponse: {\n id: tr.toolCallId,\n name: tr.name ?? toolNameById.get(tr.toolCallId) ?? \"\",\n response: { output: tr.content },\n },\n })),\n });\n continue;\n }\n\n const parts: GoogleAIPart[] = [];\n\n if (message.content) {\n parts.push({ text: message.content });\n }\n\n for (const file of message.files || []) {\n if (ALLOWED_IMAGE_MIME_TYPES.includes(file.mimeType)) {\n if (file.url) {\n parts.push({\n fileData: {\n mimeType: file.mimeType,\n fileUri: file.url,\n },\n });\n parts.push({ text: `Image (${file.url})` });\n } else if (file.data) {\n parts.push({\n inlineData: {\n mimeType: file.mimeType,\n data: file.data,\n },\n });\n }\n } else if (file.url) {\n // Non-image file with URL - add text reference\n parts.push({\n text: `File (${file.url})`,\n });\n }\n }\n\n for (const fc of message.functionCalls || []) {\n parts.push({\n functionCall: {\n id: fc.id,\n name: fc.name,\n args: fc.arguments,\n },\n // Gemini requires its thoughtSignature echoed back on the call part.\n ...(fc.thoughtSignature\n ? { thoughtSignature: fc.thoughtSignature }\n : {}),\n });\n }\n\n preparedPayload.messages.push({\n role: message.role === \"assistant\" ? \"model\" : message.role,\n parts,\n });\n }\n\n return preparedPayload;\n}\n\nasync function callGoogleAI(\n id: Identifier,\n payload: GoogleAIPayload,\n): Promise<ParsedResponseMessage> {\n const contents = jigGoogleMessages(payload.messages);\n\n // Call the REST generateContent endpoint directly rather than via @google/genai:\n // the pinned SDK (0.6.1) silently strips Gemini's per-call `thoughtSignature`,\n // which Gemini REQUIRES echoed back on multi-turn tool calls (a missing one\n // 400s the request). Going over the wire ourselves preserves it both ways.\n const requestBody: any = {\n contents,\n generationConfig: { responseModalities: [\"TEXT\"] },\n };\n if (payload.tools) requestBody.tools = [payload.tools];\n if (payload.systemInstruction) {\n requestBody.systemInstruction = {\n parts: [{ text: payload.systemInstruction }],\n };\n }\n\n let response: any;\n try {\n const httpResponse = await axios.post(\n `https://generativelanguage.googleapis.com/v1beta/models/${payload.model}:generateContent`,\n requestBody,\n {\n headers: {\n \"content-type\": \"application/json\",\n \"x-goog-api-key\": process.env.GEMINI_API_KEY as string,\n },\n timeout: 60000,\n },\n );\n response = httpResponse.data;\n } catch (err: any) {\n // Re-shape the API error so callGoogleAIWithRetries' circuit breaker can read\n // message / status / promptFeedback off it.\n const apiError = err?.response?.data?.error;\n const wrapped = new Error(\n apiError?.message || err?.message || \"Google AI API request failed\",\n ) as any;\n wrapped.status = apiError?.status ?? err?.response?.status;\n wrapped.code = apiError?.code;\n wrapped.details = apiError?.details;\n wrapped.promptFeedback = err?.response?.data?.promptFeedback;\n throw wrapped;\n }\n\n let text = \"\";\n const files: File[] = [];\n const reasoningParts: any[] = [];\n // Built from content.parts (not response.functionCalls) so we can keep each\n // call's thoughtSignature, which the accessor drops. Gemini may omit ids —\n // synthesize positional ones so the caller can pair each with a\n // `ToolResult.toolCallId` next turn; the thoughtSignature MUST be echoed back\n // on round-trip (else Gemini 400s \"missing a thought_signature\").\n const functionCalls: FunctionCall[] = [];\n\n for (const part of response.candidates?.[0]?.content?.parts || []) {\n // Thinking parts (thought:true) carry chain-of-thought, not the answer.\n if ((part as any).thought) {\n reasoningParts.push(part);\n continue;\n }\n if (part.functionCall) {\n functionCalls.push({\n id: part.functionCall.id ?? `call_${functionCalls.length}`,\n name: part.functionCall.name ?? \"\",\n arguments: part.functionCall.args ?? {},\n thoughtSignature: (part as any).thoughtSignature,\n });\n continue;\n }\n if (part.text) text += part.text;\n if (part.inlineData?.data) {\n files.push({ mimeType: \"image/png\", data: part.inlineData.data });\n }\n }\n\n if (!text && !functionCalls.length && !files.length) {\n const candidate = response.candidates?.[0];\n const finishReason = candidate?.finishReason;\n\n logger.error(id, \"Missing text & functions in Google AI API response:\", {\n finishReason,\n safetyRatings: candidate?.safetyRatings,\n usageMetadata: response.usageMetadata,\n modelVersion: response.modelVersion,\n candidateContent: candidate?.content,\n promptFeedback: response.promptFeedback,\n });\n\n let errorMessage = \"Missing text & functions in Google AI API response\";\n if (finishReason) {\n const reasonDescriptions: Record<string, string> = {\n MALFORMED_FUNCTION_CALL:\n \"(Google could not generate valid function call arguments)\",\n SAFETY: \"(blocked by safety filters)\",\n RECITATION: \"(blocked due to recitation)\",\n MAX_TOKENS: \"(response truncated due to max tokens)\",\n };\n errorMessage += `: finishReason=${finishReason} ${reasonDescriptions[finishReason] || \"\"}`;\n }\n\n const error = new Error(errorMessage) as any;\n error.finishReason = finishReason;\n error.safetyRatings = candidate?.safetyRatings;\n error.usageMetadata = response.usageMetadata;\n error.promptFeedback = response.promptFeedback;\n throw error;\n }\n\n return {\n role: \"assistant\",\n content: text || null,\n files,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n reasoningDetails: reasoningParts.length ? reasoningParts : undefined,\n usage: response.usageMetadata\n ? {\n prompt_tokens: response.usageMetadata.promptTokenCount ?? 0,\n completion_tokens: response.usageMetadata.candidatesTokenCount ?? 0,\n total_tokens: response.usageMetadata.totalTokenCount ?? 0,\n cached_tokens: response.usageMetadata.cachedContentTokenCount ?? 0,\n }\n : null,\n };\n}\n\n/**\n * Content violation finish reasons that should trigger circuit breaker behavior.\n * These errors won't resolve with simple retries - the content itself is the problem.\n */\nconst CONTENT_VIOLATION_REASONS = new Set([\"PROHIBITED_CONTENT\", \"SAFETY\"]);\n\n/**\n * Removes inline image data from Google AI messages, preserving text content.\n * Used as a fallback when content violations are detected.\n */\nfunction removeImagesFromGooglePayload(payload: GoogleAIPayload): boolean {\n let removedImages = false;\n\n for (const message of payload.messages) {\n message.parts = message.parts.filter((part) => {\n if (\"inlineData\" in part || \"fileData\" in part) {\n removedImages = true;\n return false;\n }\n return true;\n });\n\n // Ensure message still has content after removing images\n if (message.parts.length === 0) {\n message.parts = [{ text: \"(image removed due to content policy)\" }];\n }\n }\n\n return removedImages;\n}\n\nasync function callGoogleAIWithRetries(\n id: Identifier,\n payload: GoogleAIPayload,\n retries: number = 5,\n): Promise<ParsedResponseMessage> {\n let hasTriedWithoutImages = false;\n\n return withRetries(id, \"Google AI\", () => callGoogleAI(id, payload), {\n retries,\n onError: (error, attempt) => {\n const errorDetails: Record<string, any> = {\n message: error.message,\n finishReason: error.finishReason,\n modelVersion: error.modelVersion,\n };\n\n if (error.safetyRatings) errorDetails.safetyRatings = error.safetyRatings;\n if (error.usageMetadata) errorDetails.usageMetadata = error.usageMetadata;\n if (error.promptFeedback)\n errorDetails.promptFeedback = error.promptFeedback;\n if (error.status) errorDetails.httpStatus = error.status;\n if (error.code) errorDetails.errorCode = error.code;\n if (error.details) errorDetails.errorDetails = error.details;\n\n const fileUris = payload.messages\n .flatMap((m) => m.parts)\n .filter((p) => \"fileData\" in p)\n .map((p) => (p as any).fileData.fileUri);\n if (fileUris.length) errorDetails.fileUris = fileUris;\n\n logger.error(\n id,\n `Retry #${attempt} error: ${error.message}`,\n errorDetails,\n );\n\n // Circuit breaker: Google's fetcher couldn't pull our image URL(s). We pass\n // images as fileData.fileUri, but arbitrary (non-Files-API) URLs are only\n // best-effort for Gemini, so this 400 is episodic and retrying the same URL\n // almost never recovers within a request. Fail fast so the caller's\n // fallbackModel (whose adapter inlines the image bytes) takes over instead of\n // burning all retries first. Unlike the content-violation path we do NOT strip\n // images — the fallback model should still see them.\n if (\n typeof error?.message === \"string\" &&\n error.message.includes(\"Cannot fetch content from the provided URL\")\n ) {\n logger.error(\n id,\n \"Circuit breaker: Google could not fetch image URL(s); failing over (no more Google retries)\",\n );\n const fetchError = new Error(\n \"Google AI could not fetch the provided image URL(s).\",\n ) as any;\n fetchError.cause = error;\n fetchError.googleFetchFailure = true;\n throw fetchError;\n }\n\n // Circuit breaker: detect content violations and try removing images\n // Check both finishReason (candidate-level) and promptFeedback.blockReason (prompt-level)\n const violationReason =\n (CONTENT_VIOLATION_REASONS.has(error.finishReason) &&\n error.finishReason) ||\n (CONTENT_VIOLATION_REASONS.has(error.promptFeedback?.blockReason) &&\n error.promptFeedback?.blockReason);\n\n if (violationReason) {\n if (!hasTriedWithoutImages) {\n const removedImages = removeImagesFromGooglePayload(payload);\n if (removedImages) {\n logger.log(\n id,\n `Circuit breaker triggered: removing images due to ${violationReason}`,\n );\n hasTriedWithoutImages = true;\n return; // Continue to next retry with images removed\n }\n }\n\n // If we already tried without images or there were no images, fail fast\n logger.error(\n id,\n `Circuit breaker: failing fast due to ${violationReason} (no more fallbacks)`,\n );\n const circuitBreakerError = new Error(\n `Google AI content violation: ${violationReason}. Request cannot succeed with current content.`,\n ) as any;\n circuitBreakerError.finishReason = error.finishReason;\n circuitBreakerError.safetyRatings = error.safetyRatings;\n circuitBreakerError.usageMetadata = error.usageMetadata;\n circuitBreakerError.circuitBreaker = true;\n throw circuitBreakerError;\n }\n },\n });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// GROQ\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction normalizeMessageContent(\n content: AnthropicAIMessage[\"content\"],\n): string {\n return Array.isArray(content)\n ? content\n .map((c) => (c.type === \"text\" ? c.text : `[${c.type}]`))\n .join(\"\\n\")\n : content;\n}\n\n/**\n * Serialize generic messages for OpenAI-compatible chat APIs (Groq, OpenRouter).\n * Mirrors the OpenAI adapter but keeps content as a plain string. Tool calls\n * become assistant `tool_calls`, and a `role:\"tool\"` message expands to one\n * `{role:\"tool\", tool_call_id, content}` per result. Reasoning is passed\n * through only when the caller supplied it.\n */\nfunction prepareOpenAICompatMessages(\n messages: GenericMessage[],\n): OpenAIMessage[] {\n const out: OpenAIMessage[] = [];\n for (const message of messages) {\n if (message.role === \"tool\") {\n for (const tr of message.toolResults || []) {\n out.push({\n role: \"tool\",\n tool_call_id: tr.toolCallId,\n content: tr.content,\n });\n }\n continue;\n }\n\n const outMessage: OpenAIMessage = {\n role: message.role,\n content: normalizeMessageContent(message.content),\n };\n if (message.functionCalls?.length) {\n outMessage.tool_calls = message.functionCalls.map((fc, i) => ({\n id: fc.id ?? `call_${i}`,\n type: \"function\" as const,\n function: {\n name: fc.name,\n arguments: JSON.stringify(fc.arguments),\n },\n }));\n // OpenAI-compatible APIs want null content on a tool-call-only turn.\n if (!message.content) outMessage.content = null;\n }\n if (message.reasoning) outMessage.reasoning = message.reasoning;\n if (message.reasoningDetails)\n outMessage.reasoning_details = message.reasoningDetails;\n out.push(outMessage);\n }\n return out;\n}\n\nfunction prepareGroqPayload(payload: GenericPayload): GroqPayload {\n return {\n model: payload.model as GroqModel,\n messages: prepareOpenAICompatMessages(payload.messages),\n tools: payload.functions?.map((fn) => ({\n type: \"function\",\n function: fn,\n })),\n tool_choice: payload.function_call\n ? typeof payload.function_call === \"string\"\n ? payload.function_call\n : { type: \"function\", function: payload.function_call }\n : undefined,\n temperature: payload.temperature,\n };\n}\n\nasync function callGroq(\n id: Identifier,\n payload: GroqPayload,\n): Promise<ParsedResponseMessage> {\n const response = await axios.post(\n \"https://api.groq.com/openai/v1/chat/completions\",\n payload,\n {\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${process.env.GROQ_API_KEY}`,\n },\n },\n );\n\n // Like OpenRouter, Groq can return an error-shaped HTTP 200 with no `choices`\n // key; surface it instead of throwing a cryptic `choices[0]` TypeError.\n if (response.data.error) {\n logger.error(id, \"Groq error:\", response.data.error);\n throw new Error(`Groq error: ${response.data.error.message}`);\n }\n\n const answer = response.data.choices?.[0]?.message;\n if (!answer) {\n logger.error(id, \"Missing answer in Groq API response:\", response.data);\n throw new Error(\"Missing answer in Groq API\");\n }\n\n const functionCalls: FunctionCall[] = [];\n if (answer.tool_calls?.length) {\n for (let i = 0; i < answer.tool_calls.length; i++) {\n const tc = answer.tool_calls[i];\n functionCalls.push({\n id: tc.id ?? `call_${i}`,\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n });\n }\n }\n\n // An empty 200 (no content, no tool call) is not a usable answer — throw so\n // withRetries retries and callWithRetries can fall back. (Mirrors the\n // streaming path's guard in parseStreamedResponse.)\n if (!answer.content && !functionCalls.length) {\n logger.error(\n id,\n \"Groq: received message without content or function_call:\",\n JSON.stringify(response.data),\n );\n throw new Error(\n \"Groq: received message without content or function_call\",\n );\n }\n\n return {\n role: \"assistant\",\n content: answer.content || null,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n reasoning: answer.reasoning ?? undefined,\n usage: response.data.usage\n ? {\n prompt_tokens: response.data.usage.prompt_tokens,\n completion_tokens: response.data.usage.completion_tokens,\n total_tokens: response.data.usage.total_tokens,\n cached_tokens:\n response.data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n : null,\n };\n}\n\nasync function callGroqWithRetries(\n id: Identifier,\n payload: GroqPayload,\n retries: number = 5,\n): Promise<ParsedResponseMessage> {\n return withRetries(id, \"Groq\", () => callGroq(id, payload), { retries });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OPENROUTER\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction prepareOpenRouterPayload(payload: GenericPayload): OpenRouterPayload {\n return {\n model: payload.model as OpenRouterModel,\n messages: prepareOpenAICompatMessages(payload.messages),\n tools: payload.functions?.map((fn) => ({\n type: \"function\",\n function: fn,\n })),\n tool_choice: payload.function_call\n ? typeof payload.function_call === \"string\"\n ? payload.function_call\n : { type: \"function\", function: payload.function_call }\n : undefined,\n temperature: payload.temperature,\n provider: payload.provider,\n };\n}\n\nasync function callOpenRouter(\n id: Identifier,\n payload: OpenRouterPayload,\n): Promise<ParsedResponseMessage> {\n const response = await axios.post(\n \"https://openrouter.ai/api/v1/chat/completions\",\n payload,\n {\n headers: {\n \"content-type\": \"application/json\",\n Authorization: `Bearer ${process.env.OPENROUTER_API_KEY}`,\n },\n },\n );\n\n // OpenRouter wraps upstream provider failures (rate limits, moderation,\n // model-unavailable) in an HTTP 200 whose body is `{ error: {...} }` with no\n // `choices` key. Surface that error instead of letting `choices[0]` throw a\n // cryptic \"Cannot read properties of undefined (reading '0')\" TypeError that\n // hides the real reason. (Mirrors the OpenAI non-streaming guard above.)\n if (response.data.error) {\n logger.error(id, \"OpenRouter error:\", response.data.error);\n throw new Error(`OpenRouter error: ${response.data.error.message}`);\n }\n\n const answer = response.data.choices?.[0]?.message;\n if (!answer) {\n logger.error(id, \"Missing answer in OpenRouter API response:\", response.data);\n throw new Error(\"Missing answer in OpenRouter API\");\n }\n\n const functionCalls: FunctionCall[] = [];\n if (answer.tool_calls?.length) {\n for (let i = 0; i < answer.tool_calls.length; i++) {\n const tc = answer.tool_calls[i];\n functionCalls.push({\n id: tc.id ?? `call_${i}`,\n name: tc.function.name,\n arguments: JSON.parse(tc.function.arguments),\n });\n }\n }\n\n // Reasoning models (e.g. deepseek) can return a completion whose output went\n // entirely to the (discarded) `reasoning` channel, leaving content empty. An\n // empty 200 is not a usable answer — throw so withRetries retries this model\n // and, on exhaustion, callWithRetries falls back to fallbackModel. (Mirrors\n // the streaming path's guard in parseStreamedResponse.)\n if (!answer.content && !functionCalls.length) {\n logger.error(\n id,\n \"OpenRouter: received message without content or function_call:\",\n JSON.stringify(response.data),\n );\n throw new Error(\n \"OpenRouter: received message without content or function_call\",\n );\n }\n\n return {\n role: \"assistant\",\n content: answer.content || null,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n reasoning: answer.reasoning ?? undefined,\n reasoningDetails: answer.reasoning_details ?? undefined,\n usage: response.data.usage\n ? {\n prompt_tokens: response.data.usage.prompt_tokens,\n completion_tokens: response.data.usage.completion_tokens,\n total_tokens: response.data.usage.total_tokens,\n cached_tokens:\n response.data.usage.prompt_tokens_details?.cached_tokens ?? 0,\n }\n : null,\n };\n}\n\nasync function callOpenRouterWithRetries(\n id: Identifier,\n payload: OpenRouterPayload,\n retries: number = 5,\n): Promise<ParsedResponseMessage> {\n return withRetries(id, \"OpenRouter\", () => callOpenRouter(id, payload), { retries });\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// MAIN ENTRY POINT\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst VALID_PROVIDERS: Provider[] = [\"openai\", \"anthropic\", \"google\", \"groq\", \"openrouter\"];\n\nconst ENUM_PROVIDER_MAP: { values: Set<string>; provider: Provider }[] = [\n { values: new Set(Object.values(GPTModel)), provider: \"openai\" },\n { values: new Set(Object.values(ClaudeModel)), provider: \"anthropic\" },\n { values: new Set(Object.values(GeminiModel)), provider: \"google\" },\n { values: new Set(Object.values(GroqModel)), provider: \"groq\" },\n { values: new Set(Object.values(OpenRouterModel)), provider: \"openrouter\" },\n];\n\nexport function parseModelString(model: string): { provider: Provider; modelId: string } {\n const colonIndex = model.indexOf(\":\");\n\n if (colonIndex !== -1) {\n const prefix = model.substring(0, colonIndex);\n\n if (VALID_PROVIDERS.includes(prefix as Provider)) {\n const modelId = model.substring(colonIndex + 1);\n\n if (!modelId) {\n throw new Error(\n `Empty model ID in model string '${model}'. Expected format: 'provider:model-id'`,\n );\n }\n\n return { provider: prefix as Provider, modelId };\n }\n\n // Prefix isn't a known provider — fall through to enum lookup\n // (handles model values that contain colons, e.g. OpenRouter \"google/gemma-4-31b-it:free\")\n }\n\n // Fallback: check enum values\n for (const { values, provider } of ENUM_PROVIDER_MAP) {\n if (values.has(model)) {\n return { provider, modelId: model };\n }\n }\n\n // If string had a colon but wasn't a known provider, give a specific error\n if (colonIndex !== -1) {\n const prefix = model.substring(0, colonIndex);\n throw new Error(\n `Unknown provider '${prefix}' in model string '${model}'. Valid providers: ${VALID_PROVIDERS.join(\", \")}`,\n );\n }\n\n throw new Error(\n `Unable to determine provider for model '${model}'. Use a provider prefix (e.g. 'openai:${model}') or a known model enum value. Valid providers: ${VALID_PROVIDERS.join(\", \")}`,\n );\n}\n\nexport async function callWithRetries(\n id: string | string[],\n aiPayload: GenericPayload,\n aiConfig?: OpenAIConfig | AnthropicAIConfig,\n retries: number = 5,\n chunkTimeoutMs: number = 15_000,\n): Promise<ParsedResponseMessage> {\n try {\n const { provider, modelId } = parseModelString(aiPayload.model);\n const routingPayload = { ...aiPayload, model: modelId as AnyModel };\n\n switch (provider) {\n case \"anthropic\":\n return await callAnthropicWithRetries(\n id,\n await prepareAnthropicPayload(id, routingPayload),\n aiConfig as AnthropicAIConfig,\n retries,\n );\n\n case \"openai\":\n return await callOpenAiWithRetries(\n id,\n await prepareOpenAIPayload(id, routingPayload),\n aiConfig as OpenAIConfig,\n retries,\n chunkTimeoutMs,\n );\n\n case \"groq\":\n return await callGroqWithRetries(\n id,\n prepareGroqPayload(routingPayload),\n retries,\n );\n\n case \"google\":\n return await callGoogleAIWithRetries(\n id,\n await prepareGoogleAIPayload(id, routingPayload),\n retries,\n );\n\n case \"openrouter\":\n return await callOpenRouterWithRetries(\n id,\n prepareOpenRouterPayload(routingPayload),\n retries,\n );\n }\n } catch (error) {\n if (aiPayload.fallbackModel) {\n logger.error(\n id,\n `Primary model ${aiPayload.model} failed, falling back to ${aiPayload.fallbackModel}`,\n {\n error: error instanceof Error ? error.message : error,\n cause:\n error instanceof Error && (error as any).cause instanceof Error\n ? (error as any).cause.message\n : undefined,\n },\n );\n return callWithRetries(\n id,\n {\n ...aiPayload,\n model: aiPayload.fallbackModel,\n fallbackModel: undefined,\n },\n aiConfig,\n retries,\n chunkTimeoutMs,\n );\n }\n throw error;\n }\n}\n","export function timeout(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function isHeicImage(name: string, mime?: string): boolean {\n const extension = name.split(\".\").pop()?.toLowerCase() || \"\";\n return (\n [\"heic\", \"heif\", \"heics\"].includes(extension) ||\n !!(\n mime && [\"image/heic\", \"image/heif\", \"image/heic-sequence\"].includes(mime)\n )\n );\n}\n"],"mappings":"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","names":["ClaudeModel","GPTModel","GroqModel","OpenRouterModel","GeminiModel","error","_a"]}
|