190proof 1.0.92 → 1.0.94

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -642,26 +642,13 @@ async function prepareAnthropicPayload(_identifier, payload) {
642
642
  return preparedPayload;
643
643
  }
644
644
  async function callAnthropic(id, payload, config) {
645
- var _a;
645
+ var _a, _b, _c;
646
646
  const anthropicMessages = jigAnthropicMessages(payload.messages);
647
647
  const tools = (_a = payload.functions) == null ? void 0 : _a.map((f) => ({
648
648
  ...f,
649
649
  input_schema: f.parameters,
650
650
  parameters: void 0
651
651
  }));
652
- if (tools == null ? void 0 : tools.length) {
653
- tools[tools.length - 1] = {
654
- ...tools[tools.length - 1],
655
- cache_control: { type: "ephemeral" }
656
- };
657
- }
658
- const system = payload.system ? [
659
- {
660
- type: "text",
661
- text: payload.system,
662
- cache_control: { type: "ephemeral" }
663
- }
664
- ] : void 0;
665
652
  let data;
666
653
  if ((config == null ? void 0 : config.service) === "bedrock") {
667
654
  const AWS_REGION = "us-east-1";
@@ -671,8 +658,7 @@ async function callAnthropic(id, payload, config) {
671
658
  anthropic_version: "bedrock-2023-05-31",
672
659
  max_tokens: 4096,
673
660
  messages: anthropicMessages,
674
- // The pinned Bedrock model predates prompt caching; strip breakpoints
675
- tools: tools == null ? void 0 : tools.map(({ cache_control, ...t }) => t)
661
+ tools
676
662
  };
677
663
  const response = await client.send(
678
664
  new import_client_bedrock_runtime.InvokeModelCommand({
@@ -684,14 +670,18 @@ async function callAnthropic(id, payload, config) {
684
670
  const decodedResponseBody = new TextDecoder().decode(response.body);
685
671
  data = JSON.parse(decodedResponseBody);
686
672
  } else {
673
+ const cachedTools = (tools == null ? void 0 : tools.length) ? [
674
+ ...tools.slice(0, -1),
675
+ { ...tools[tools.length - 1], cache_control: { type: "ephemeral" } }
676
+ ] : tools;
687
677
  const response = await import_axios.default.post(
688
678
  "https://api.anthropic.com/v1/messages",
689
679
  {
690
680
  model: payload.model,
691
681
  messages: anthropicMessages,
692
- tools,
682
+ tools: cachedTools,
693
683
  temperature: payload.temperature,
694
- system,
684
+ system: payload.system,
695
685
  max_tokens: 4096
696
686
  },
697
687
  {
@@ -745,24 +735,25 @@ ${text}` : text;
745
735
  );
746
736
  throw new Error("Missing text & functions in Anthropic API response");
747
737
  }
738
+ let usage = null;
739
+ if (data.usage) {
740
+ const cacheRead = (_b = data.usage.cache_read_input_tokens) != null ? _b : 0;
741
+ const cacheWrite = (_c = data.usage.cache_creation_input_tokens) != null ? _c : 0;
742
+ const promptTokens = data.usage.input_tokens + cacheRead + cacheWrite;
743
+ usage = {
744
+ prompt_tokens: promptTokens,
745
+ completion_tokens: data.usage.output_tokens,
746
+ total_tokens: promptTokens + data.usage.output_tokens,
747
+ cached_tokens: cacheRead
748
+ };
749
+ }
748
750
  return {
749
751
  role: "assistant",
750
752
  content: textResponse,
751
753
  function_call: functionCalls[0] || null,
752
754
  function_calls: functionCalls,
753
755
  files: [],
754
- usage: data.usage ? (() => {
755
- var _a2, _b;
756
- const cacheRead = (_a2 = data.usage.cache_read_input_tokens) != null ? _a2 : 0;
757
- const cacheWrite = (_b = data.usage.cache_creation_input_tokens) != null ? _b : 0;
758
- const promptTokens = data.usage.input_tokens + cacheRead + cacheWrite;
759
- return {
760
- prompt_tokens: promptTokens,
761
- completion_tokens: data.usage.output_tokens,
762
- total_tokens: promptTokens + data.usage.output_tokens,
763
- cached_tokens: cacheRead
764
- };
765
- })() : null
756
+ usage
766
757
  };
767
758
  }
768
759
  async function callAnthropicWithRetries(id, payload, config, retries = 5) {
@@ -975,6 +966,18 @@ async function callGoogleAIWithRetries(id, payload, retries = 5) {
975
966
  `Retry #${attempt} error: ${error2.message}`,
976
967
  errorDetails
977
968
  );
969
+ if (typeof (error2 == null ? void 0 : error2.message) === "string" && error2.message.includes("Cannot fetch content from the provided URL")) {
970
+ logger_default.error(
971
+ id,
972
+ "Circuit breaker: Google could not fetch image URL(s); failing over (no more Google retries)"
973
+ );
974
+ const fetchError = new Error(
975
+ "Google AI could not fetch the provided image URL(s)."
976
+ );
977
+ fetchError.cause = error2;
978
+ fetchError.googleFetchFailure = true;
979
+ throw fetchError;
980
+ }
978
981
  const violationReason = CONTENT_VIOLATION_REASONS.has(error2.finishReason) && error2.finishReason || CONTENT_VIOLATION_REASONS.has((_a = error2.promptFeedback) == null ? void 0 : _a.blockReason) && ((_b = error2.promptFeedback) == null ? void 0 : _b.blockReason);
979
982
  if (violationReason) {
980
983
  if (!hasTriedWithoutImages) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../index.ts","../interfaces.ts","../logger.ts","../utils.ts"],"sourcesContent":["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 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 })) as Record<string, any>[] | undefined;\n\n // Prompt caching: tools and system form the stable prompt prefix, so mark\n // cache breakpoints on the last tool and on the system block. Anthropic\n // ignores breakpoints below the model's minimum cacheable length, so this\n // is safe for small prompts.\n if (tools?.length) {\n tools[tools.length - 1] = {\n ...tools[tools.length - 1],\n cache_control: { type: \"ephemeral\" },\n };\n }\n const system = payload.system\n ? [\n {\n type: \"text\",\n text: payload.system,\n cache_control: { type: \"ephemeral\" },\n },\n ]\n : undefined;\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 // The pinned Bedrock model predates prompt caching; strip breakpoints\n tools: tools?.map(({ cache_control, ...t }) => t),\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 const response = await axios.post(\n \"https://api.anthropic.com/v1/messages\",\n {\n model: payload.model,\n messages: anthropicMessages,\n tools,\n temperature: payload.temperature,\n 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 return {\n role: \"assistant\",\n content: textResponse,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n usage: data.usage\n ? (() => {\n // Anthropic's input_tokens EXCLUDES cache reads/writes; fold them\n // back in so prompt_tokens means \"all input tokens\" like OpenAI,\n // where cached_tokens is a subset of prompt_tokens.\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 return {\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 : null,\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: 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 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 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","/** @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","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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCO,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,cAAW;AACX,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,eAAY;AACZ,EAAAA,aAAA,gBAAa;AACb,EAAAA,aAAA,cAAW;AACX,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,cAAW;AACX,EAAAA,aAAA,eAAY;AACZ,EAAAA,aAAA,gBAAa;AACb,EAAAA,aAAA,cAAW;AAXD,SAAAA;AAAA,GAAA;AAeL,IAAK,WAAL,kBAAKC,cAAL;AACL,EAAAA,UAAA,gBAAa;AACb,EAAAA,UAAA,oBAAiB;AACjB,EAAAA,UAAA,gBAAa;AACb,EAAAA,UAAA,uBAAoB;AACpB,EAAAA,UAAA,uBAAoB;AACpB,EAAAA,UAAA,eAAY;AACZ,EAAAA,UAAA,WAAQ;AACR,EAAAA,UAAA,gBAAa;AACb,EAAAA,UAAA,gBAAa;AACb,EAAAA,UAAA,aAAU;AACV,EAAAA,UAAA,aAAU;AACV,EAAAA,UAAA,YAAS;AACT,EAAAA,UAAA,iBAAc;AACd,EAAAA,UAAA,iBAAc;AACd,EAAAA,UAAA,UAAO;AACP,EAAAA,UAAA,eAAY;AAhBF,SAAAA;AAAA,GAAA;AAoBL,IAAK,YAAL,kBAAKC,eAAL;AACL,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,eAAY;AACZ,EAAAA,WAAA,mCAAgC;AAJtB,SAAAA;AAAA,GAAA;AAQL,IAAK,kBAAL,kBAAKC,qBAAL;AACL,EAAAA,iBAAA,yBAAsB;AACtB,EAAAA,iBAAA,oBAAiB;AAFP,SAAAA;AAAA,GAAA;AAML,IAAK,cAAL,kBAAKC,iBAAL;AACL,EAAAA,aAAA,oBAAiB;AACjB,EAAAA,aAAA,qBAAkB;AAClB,EAAAA,aAAA,sBAAmB;AACnB,EAAAA,aAAA,2CAAwC;AACxC,EAAAA,aAAA,mCAAgC;AAChC,EAAAA,aAAA,yCAAsC;AACtC,EAAAA,aAAA,oCAAiC;AACjC,EAAAA,aAAA,4BAAyB;AACzB,EAAAA,aAAA,mCAAgC;AATtB,SAAAA;AAAA,GAAA;;;AC/CZ,SAAS,iBAAiB,YAAgC;AACxD,MAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,WAAO,WAAW,IAAI,CAAC,OAAO,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;AAAA,EACnD;AACA,SAAO,IAAI,UAAU;AACvB;AAEA,SAAS,cACP,OACA,YACA,SACQ;AACR,SAAO,IAAI,KAAK,KAAK,iBAAiB,UAAU,CAAC,IAAI,OAAO;AAC9D;AAEO,SAAS,IACd,YACA,YACG,MACG;AACN,UAAQ,IAAI,cAAc,OAAO,YAAY,OAAO,GAAG,GAAG,IAAI;AAChE;AAEO,SAAS,KACd,YACA,YACG,MACG;AACN,UAAQ,KAAK,cAAc,QAAQ,YAAY,OAAO,GAAG,GAAG,IAAI;AAClE;AAEO,SAAS,MACd,YACA,YACG,MACG;AACN,UAAQ,MAAM,cAAc,SAAS,YAAY,OAAO,GAAG,GAAG,IAAI;AACpE;AAEA,IAAO,iBAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACF;;;AFlBA,oCAGO;AACP,mBAAkB;;;AGhCX,SAAS,QAAQ,IAA2B;AACjD,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEO,SAAS,YAAY,MAAc,MAAwB;AAJlE;AAKE,QAAM,cAAY,UAAK,MAAM,GAAG,EAAE,IAAI,MAApB,mBAAuB,kBAAiB;AAC1D,SACE,CAAC,QAAQ,QAAQ,OAAO,EAAE,SAAS,SAAS,KAC5C,CAAC,EACC,QAAQ,CAAC,cAAc,cAAc,qBAAqB,EAAE,SAAS,IAAI;AAG/E;;;AHsBA,mBAA4B;AAE5B,IAAM,QAAQ,QAAQ,OAAO;AAC7B,IAAM,SAAS,QAAQ,aAAa;AAuBpC,eAAe,YACb,YACA,SACA,IACA,UAII,CAAC,GACO;AArEd;AAsEE,QAAM,EAAE,UAAU,GAAG,cAAc,KAAK,QAAQ,IAAI;AAEpD,iBAAO,IAAI,YAAY,WAAW,OAAO,mBAAmB;AAE5D,MAAI;AACJ,WAAS,UAAU,GAAG,UAAU,SAAS,WAAW;AAClD,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAASC,QAAY;AACnB,kBAAYA;AAEZ,UAAI,SAAS;AACX,gBAAQA,QAAO,OAAO;AAAA,MACxB,OAAO;AACL,uBAAO;AAAA,UACL;AAAA,UACA,UAAU,OAAO,WAAWA,OAAM,OAAO;AAAA,YACzC,KAAAA,OAAM,aAAN,mBAAgB,SAAQA;AAAA,QAC1B;AAAA,MACF;AAEA,YAAM,QAAQ,cAAc,OAAO;AAAA,IACrC;AAAA,EACF;AAEA,QAAMA,SAAQ,IAAI;AAAA,IAChB,kBAAkB,OAAO,cAAc,OAAO;AAAA,EAChD;AACA,EAAAA,OAAM,QAAQ;AACd,QAAMA;AACR;AAEA,SAAS,sBACP,YACA,WACA,sBACA,sBACuB;AACvB,QAAM,gBAAgC,CAAC;AAEvC,aAAW,OAAO,sBAAsB;AACtC,QAAI,CAAC,IAAI,QAAQ,CAAC,IAAI;AAAW;AAEjC,QAAI,wBAAwB,CAAC,qBAAqB,IAAI,IAAI,IAAI,GAAG;AAC/D,YAAM,IAAI;AAAA,QACR,2DAA2D,IAAI,IAAI;AAAA,MACrE;AAAA,IACF;AAEA,QAAI;AACF,oBAAc,KAAK;AAAA,QACjB,MAAM,IAAI;AAAA,QACV,WAAW,KAAK,MAAM,IAAI,SAAS;AAAA,MACrC,CAAC;AAAA,IACH,SAASA,QAAO;AACd,qBAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,IAAI;AAAA,MACN;AACA,YAAMA;AAAA,IACR;AAAA,EACF;AAEA,MAAI,CAAC,aAAa,CAAC,cAAc,QAAQ;AACvC,mBAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,KAAK,UAAU,EAAE,WAAW,qBAAqB,CAAC;AAAA,IACpD;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,aAAa;AAAA,IACtB,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO;AAAA,EACT;AACF;AAEA,SAAS,gBAAgB,SAAgC;AACvD,SAAO,KAAK;AAAA,IACV;AAAA,MACE,GAAG;AAAA,MACH,UAAU,QAAQ,SAAS,IAAI,CAAC,YAAY;AAC1C,cAAM,mBAAmB,EAAE,GAAG,QAAQ;AACtC,YAAI,OAAO,iBAAiB,YAAY,UAAU;AAChD,2BAAiB,UAAU,iBAAiB,QAAQ,MAAM,GAAG,GAAG;AAAA,QAClE,WAAW,MAAM,QAAQ,iBAAiB,OAAO,GAAG;AAClD,2BAAiB,UAAU,iBAAiB,QAAQ,IAAI,CAAC,UAAU;AACjE,gBAAI,MAAM,SAAS,aAAa;AAC9B,qBAAO;AAAA,gBACL,GAAG;AAAA,gBACH,WAAW,EAAE,KAAK,MAAM,UAAU,IAAI,MAAM,GAAG,GAAG,EAAE;AAAA,cACtD;AAAA,YACF;AACA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,uBACb,KACA,MACiB;AACjB,QAAM,WAAW,MAAM,aAAAC,QAAM,IAAI,KAAK,EAAE,cAAc,cAAc,CAAC;AAErE,MAAI,cAAc,OAAO,KAAK,SAAS,IAAI;AAC3C,MAAI,eAAe,CAAC;AAEpB,MAAI,YAAY,KAAK,IAAI,GAAG;AAC1B,UAAM,YAAY,MAAM,OAAO,EAAE,QAAQ,YAAY,CAAC;AACtD,kBAAc,OAAO,KAAK,UAAU,IAAI;AACxC,mBAAe;AAAA,MACb,KAAK;AAAA,QACH,OAAO,UAAU;AAAA,QACjB,QAAQ,UAAU;AAAA,QAClB,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,MAAM,MAAM,aAAa,YAAY,EACxD,aAAa,EACb,OAAO,MAAM,MAAM,EAAE,KAAK,UAAU,oBAAoB,KAAK,CAAC,EAC9D,IAAI,EACJ,SAAS;AAEZ,SAAO,cAAc,SAAS,QAAQ;AACxC;AAEA,IAAM,2BAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAWA,SAAS,yBACP,YACA,OACA,QACqB;AAzOvB;AA0OE,MAAI,CAAC,QAAQ;AACX,aAAS;AAAA,MACP,SAAS;AAAA,MACT,QAAQ,QAAQ,IAAI;AAAA,MACpB,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,OAAO,YAAY,SAAS;AAC9B,mBAAO,IAAI,YAAY,+BAA+B,KAAK;AAE3D,QAAI,CAAC,OAAO,gBAAgB;AAC1B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,cAAc,OAAO,eAAe,KAAiB;AAC3D,QAAI,EAAC,2CAAa,WAAU;AAC1B,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAEA,UAAM,WAAW,GAAG,YAAY,QAAQ,uBAAuB,YAAY,UAAU,iCAAiC,YAAY,UAAU;AAC5I,mBAAO,IAAI,YAAY,mBAAmB,QAAQ;AAElD,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,WAAW,YAAY;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAGA,iBAAO,IAAI,YAAY,yBAAyB,KAAK;AACrD,MAAI,OAAO,OAAO;AAChB,mBAAO,IAAI,YAAY,gBAAgB,OAAO,KAAK;AAAA,EACrD;AAEA,QAAM,UAAQ,YAAO,YAAP,mBAAgB,WAAU,6BAA6B;AAAA,IACnE;AAAA,IACA;AAAA,EACF;AACA,SAAO;AAAA,IACL,UAAU,GAAG,IAAI;AAAA,IACjB,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,OAAO,MAAM;AAAA,MACtC,GAAI,OAAO,QAAQ,EAAE,uBAAuB,OAAO,MAAM,IAAI,CAAC;AAAA,IAChE;AAAA,EACF;AACF;AAEA,eAAe,qBACb,YACA,SACwB;AAnS1B;AAoSE,QAAM,kBAAiC;AAAA,IACrC,OAAO,QAAQ;AAAA,IACf,UAAU,CAAC;AAAA,IACX,QAAO,aAAQ,cAAR,mBAAmB,IAAI,CAAC,QAAQ;AAAA,MACrC,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,aAAa,QAAQ,gBACjB,OAAO,QAAQ,kBAAkB,WAC/B,QAAQ,gBACR,EAAE,MAAM,YAAY,UAAU,QAAQ,cAAc,IACtD;AAAA,EACN;AAEA,aAAW,WAAW,QAAQ,UAAU;AACtC,UAAM,gBAAsC,CAAC;AAE7C,QAAI,QAAQ,SAAS;AACnB,oBAAc,KAAK,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,IAC5D;AAEA,eAAW,QAAQ,QAAQ,SAAS,CAAC,GAAG;AACtC,UAAI,yBAAyB,SAAS,KAAK,QAAQ,GAAG;AACpD,YAAI,KAAK,KAAK;AACZ,wBAAc,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,WAAW,EAAE,KAAK,KAAK,IAAI;AAAA,UAC7B,CAAC;AACD,wBAAc,KAAK,EAAE,MAAM,QAAQ,MAAM,UAAU,KAAK,GAAG,IAAI,CAAC;AAAA,QAClE,WAAW,KAAK,MAAM;AACpB,wBAAc,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,WAAW,EAAE,KAAK,QAAQ,KAAK,QAAQ,WAAW,KAAK,IAAI,GAAG;AAAA,UAChE,CAAC;AAAA,QACH;AAAA,MACF,WAAW,KAAK,KAAK;AAEnB,sBAAc,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,MAAM,SAAS,KAAK,GAAG;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,oBAAgB,SAAS,KAAK;AAAA,MAC5B,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,iBACb,IACA,eACA,cACA,gBACgC;AA9VlC;AA+VE,QAAM,gBAAoC,cAAc,QACpD,IAAI,IAAI,cAAc,MAAM,IAAI,CAAC,OAAO,GAAG,SAAS,IAAc,CAAC,IACnE;AAEJ,QAAM,EAAE,UAAU,QAAQ,IAAI;AAAA,IAC5B;AAAA,IACA,cAAc;AAAA,IACd;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,MAAM,MAAM,UAAU;AAAA,IACrC,QAAQ;AAAA,IACR;AAAA,IACA,MAAM,KAAK,UAAU,EAAE,GAAG,eAAe,QAAQ,KAAK,CAAC;AAAA,IACvD,QAAQ,WAAW;AAAA,EACrB,CAAC;AAED,MAAI,CAAC,SAAS,MAAM;AAClB,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAEA,MAAI,YAAY;AAChB,QAAM,uBAA8D,CAAC;AAErE,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,MAAI,eAAe;AACnB,MAAI,aAAa;AAEjB,QAAM,qBAAqB,MACzB,WAAW,MAAM;AACf,mBAAO,MAAM,IAAI,wBAAwB,cAAc,IAAI;AAC3D,eAAW,MAAM;AAAA,EACnB,GAAG,cAAc;AAEnB,SAAO,MAAM;AACX;AACA,UAAM,eAAe,mBAAmB;AACxC,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,iBAAa,YAAY;AAEzB,QAAI,MAAM;AACR,qBAAO;AAAA,QACL;AAAA,QACA,kCAAkC,aAAa,CAAC;AAAA,MAClD;AACA,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAEA,QAAI,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK;AAC1C,QAAI,cAAc;AAChB,cAAQ,eAAe;AACvB,qBAAe;AAAA,IACjB;AAEA,UAAM,cAAc,MAAM,MAAM,WAAW;AAE3C,eAAW,cAAc,aAAa;AACpC,UAAI,CAAC;AAAY;AAEjB,UAAI,WAAW,SAAS,QAAQ,GAAG;AACjC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACJ,UAAI;AACF,eAAO,KAAK,MAAM,WAAW,KAAK,CAAC;AAAA,MACrC,SAAQ;AACN,uBAAe;AACf;AAAA,MACF;AAEA,UAAI,GAAC,UAAK,YAAL,mBAAc,SAAQ;AACzB,YAAI,KAAK,OAAO;AACd,yBAAO,MAAM,IAAI,6BAA6B,KAAK,KAAK;AACxD,gBAAMD,SAAQ,IAAI,MAAM,4BAA4B;AACpD,UAAAA,OAAM,OAAO,KAAK;AAClB,UAAAA,OAAM,cAAc,gBAAgB,aAAa;AACjD,gBAAMA;AAAA,QACR;AACA,YAAI,eAAe,GAAG;AACpB,yBAAO,MAAM,IAAI,qCAAqC,IAAI;AAAA,QAC5D;AACA;AAAA,MACF;AAEA,YAAM,aAAY,gBAAK,QAAQ,CAAC,MAAd,mBAAiB,UAAjB,mBAAwB;AAC1C,UAAI,WAAW;AACb,mBAAW,YAAY,WAAW;AAChC,gBAAM,OAAM,cAAS,UAAT,YAAkB;AAC9B,iBAAO,qBAAqB,UAAU,KAAK;AACzC,iCAAqB,KAAK,EAAE,MAAM,IAAI,WAAW,GAAG,CAAC;AAAA,UACvD;AACA,eAAI,cAAS,aAAT,mBAAmB;AACrB,iCAAqB,GAAG,EAAE,QAAQ,SAAS,SAAS;AACtD,eAAI,cAAS,aAAT,mBAAmB;AACrB,iCAAqB,GAAG,EAAE,aAAa,SAAS,SAAS;AAAA,QAC7D;AAAA,MACF;AAEA,YAAM,QAAO,gBAAK,QAAQ,CAAC,MAAd,mBAAiB,UAAjB,mBAAwB;AACrC,UAAI;AAAM,qBAAa;AAAA,IACzB;AAAA,EACF;AACF;AAEA,eAAe,WACb,IACA,eACA,cACgC;AAldlC;AAmdE,QAAM,EAAE,UAAU,QAAQ,IAAI;AAAA,IAC5B;AAAA,IACA,cAAc;AAAA,IACd;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,MAAM,UAAU;AAAA,IACrC,QAAQ;AAAA,IACR;AAAA,IACA,MAAM,KAAK,UAAU,EAAE,GAAG,eAAe,QAAQ,MAAM,CAAC;AAAA,EAC1D,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,MAAM,SAAS,KAAK;AACtC,mBAAO,MAAM,IAAI,qBAAqB,SAAS;AAC/C,UAAM,IAAI,MAAM,qBAAqB,UAAU,MAAM,OAAO,EAAE;AAAA,EAChE;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,MAAI,GAAC,UAAK,YAAL,mBAAc,SAAQ;AACzB,QAAI,KAAK,OAAO;AACd,qBAAO,MAAM,IAAI,iBAAiB,KAAK,KAAK;AAC5C,YAAM,IAAI,MAAM,iBAAiB,KAAK,MAAM,OAAO,EAAE;AAAA,IACvD;AACA,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,QAAM,SAAS,KAAK,QAAQ,CAAC;AAG7B,QAAM,aAAY,YAAO,YAAP,mBAAgB;AAClC,QAAM,gBAAgC,CAAC;AAEvC,MAAI,uCAAW,QAAQ;AACrB,eAAW,MAAM,WAAW;AAC1B,oBAAc,KAAK;AAAA,QACjB,MAAM,GAAG,SAAS;AAAA,QAClB,WAAW,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,EACF,WAAW,OAAO,eAAe;AAC/B,kBAAc,KAAK;AAAA,MACjB,MAAM,OAAO,cAAc;AAAA,MAC3B,WAAW,KAAK,MAAM,OAAO,cAAc,SAAS;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,OAAO,QAAQ,WAAW;AAAA,IACnC,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO,KAAK,QACR;AAAA,MACE,eAAe,KAAK,MAAM;AAAA,MAC1B,mBAAmB,KAAK,MAAM;AAAA,MAC9B,cAAc,KAAK,MAAM;AAAA,MACzB,gBAAe,gBAAK,MAAM,0BAAX,mBAAkC,kBAAlC,YAAmD;AAAA,IACpE,IACA;AAAA,EACN;AACF;AAEA,eAAe,sBACb,IACA,eACA,cACA,UAAkB,GAClB,iBAAyB,MACO;AAChC,iBAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,6CAAc;AAAA,IACd,cAAc;AAAA,EAChB;AAEA,QAAM,WAAW,cAAc;AAC/B,QAAM,eACJ,wCACA,8CACA,CAAC,SAAS,WAAW,IAAI;AAE3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY;AACV,UAAI,cAAc;AAChB,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,OAAO;AACL,eAAO,WAAW,IAAI,eAAe,YAAY;AAAA,MACnD;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA,aAAa;AAAA,MACb,SAAS,CAACA,QAAO,YAAY;AA1jBnC;AA2jBQ,uBAAO;AAAA,UACL;AAAA,UACA,UAAU,OAAO,WAAWA,OAAM,OAAO;AAAA,YACzC,KAAAA,OAAM,aAAN,mBAAgB,SAAQA,OAAM,QAAQA;AAAA,QACxC;AAGA,cAAI,KAAAA,OAAM,SAAN,mBAAY,UAAS,4BAA4B;AACnD,yBAAO,IAAI,IAAI,iDAAiD;AAChE,wBAAc,SAAS,QAAQ,CAAC,YAA2B;AACzD,gBAAI,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAClC,sBAAQ,UAAU,QAAQ,QAAQ;AAAA,gBAChC,CAAC,YAAY,QAAQ,SAAS;AAAA,cAChC;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,qBACP,UACsB;AAvlBxB;AAwlBE,MAAI,iBAAiB,SAAS,MAAM;AAGpC,QAAI,oBAAe,CAAC,MAAhB,mBAAmB,UAAS,QAAQ;AACtC,qBAAiB;AAAA,MACf,EAAE,MAAM,QAAiB,SAAS,MAAM;AAAA,MACxC,GAAG;AAAA,IACL;AAAA,EACF;AAGA,mBAAiB,eAAe,OAAO,CAAC,KAAK,YAAY;AACvD,QAAI,IAAI,WAAW;AAAG,aAAO,CAAC,OAAO;AAErC,UAAM,cAAc,IAAI,IAAI,SAAS,CAAC;AACtC,QAAI,YAAY,SAAS,QAAQ,MAAM;AACrC,YAAM,cAAc,MAAM,QAAQ,YAAY,OAAO,IACjD,YAAY,UACZ,CAAC,EAAE,MAAM,QAAiB,MAAM,YAAY,QAAQ,CAAC;AACzD,YAAM,aAAa,MAAM,QAAQ,QAAQ,OAAO,IAC5C,QAAQ,UACR,CAAC,EAAE,MAAM,QAAiB,MAAM,QAAQ,QAAQ,CAAC;AAErD,kBAAY,UAAU;AAAA,QACpB,GAAG;AAAA,QACH,EAAE,MAAM,QAAQ,MAAM,cAAc;AAAA,QACpC,GAAG;AAAA,MACL;AACA,aAAO;AAAA,IACT;AAGA,QAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,cAAQ,UAAU,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,IAC5D;AAEA,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB,GAAG,CAAC,CAAyB;AAG7B,QAAI,oBAAe,eAAe,SAAS,CAAC,MAAxC,mBAA2C,UAAS,aAAa;AACnE,mBAAe,KAAK,EAAE,MAAM,QAAQ,SAAS,MAAM,CAAC;AAAA,EACtD;AAEA,SAAO;AACT;AAEA,eAAe,wBACb,aACA,SAC6B;AAC7B,QAAM,kBAAsC;AAAA,IAC1C,OAAO,QAAQ;AAAA,IACf,UAAU,CAAC;AAAA,IACX,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA,EACvB;AAEA,aAAW,WAAW,QAAQ,UAAU;AACtC,QAAI,QAAQ,SAAS,UAAU;AAC7B,sBAAgB,SAAS,QAAQ;AACjC;AAAA,IACF;AAEA,UAAM,gBAAyC,CAAC;AAEhD,QAAI,QAAQ,SAAS;AACnB,oBAAc,KAAK,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,IAC5D;AAEA,eAAW,QAAQ,QAAQ,SAAS,CAAC,GAAG;AACtC,UAAI,yBAAyB,SAAS,KAAK,QAAQ,GAAG;AACpD,YAAI,KAAK,KAAK;AACZ,cAAI,QAAQ,QAAQ,QAAQ;AAE1B,0BAAc,KAAK;AAAA,cACjB,MAAM;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY;AAAA,gBACZ,MAAM,MAAM,uBAAuB,KAAK,KAAK,KAAK,QAAQ;AAAA,cAC5D;AAAA,YACF,CAAC;AAAA,UACH;AACA,wBAAc,KAAK,EAAE,MAAM,QAAQ,MAAM,UAAU,KAAK,GAAG,IAAI,CAAC;AAAA,QAClE,WAAW,KAAK,MAAM;AACpB,cAAI,QAAQ,QAAQ,QAAQ;AAE1B,0BAAc,KAAK;AAAA,cACjB,MAAM;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY,KAAK;AAAA,gBACjB,MAAM,KAAK;AAAA,cACb;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF,WAAW,KAAK,KAAK;AAEnB,sBAAc,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,MAAM,SAAS,KAAK,GAAG;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,oBAAgB,SAAS,KAAK;AAAA,MAC5B,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,cACb,IACA,SACA,QACgC;AAhtBlC;AAitBE,QAAM,oBAAoB,qBAAqB,QAAQ,QAAQ;AAC/D,QAAM,SAAQ,aAAQ,cAAR,mBAAmB,IAAI,CAAC,OAAO;AAAA,IAC3C,GAAG;AAAA,IACH,cAAc,EAAE;AAAA,IAChB,YAAY;AAAA,EACd;AAMA,MAAI,+BAAO,QAAQ;AACjB,UAAM,MAAM,SAAS,CAAC,IAAI;AAAA,MACxB,GAAG,MAAM,MAAM,SAAS,CAAC;AAAA,MACzB,eAAe,EAAE,MAAM,YAAY;AAAA,IACrC;AAAA,EACF;AACA,QAAM,SAAS,QAAQ,SACnB;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,MAAM,QAAQ;AAAA,MACd,eAAe,EAAE,MAAM,YAAY;AAAA,IACrC;AAAA,EACF,IACA;AAEJ,MAAI;AAEJ,OAAI,iCAAQ,aAAY,WAAW;AACjC,UAAM,aAAa;AACnB,UAAM,WAAW;AAEjB,UAAM,SAAS,IAAI,mDAAqB,EAAE,QAAQ,WAAW,CAAC;AAC9D,UAAM,iBAAiB;AAAA,MACrB,mBAAmB;AAAA,MACnB,YAAY;AAAA,MACZ,UAAU;AAAA;AAAA,MAEV,OAAO,+BAAO,IAAI,CAAC,EAAE,eAAe,GAAG,EAAE,MAAM;AAAA,IACjD;AAEA,UAAM,WAAW,MAAM,OAAO;AAAA,MAC5B,IAAI,iDAAmB;AAAA,QACrB,aAAa;AAAA,QACb,MAAM,KAAK,UAAU,cAAc;AAAA,QACnC,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,UAAM,sBAAsB,IAAI,YAAY,EAAE,OAAO,SAAS,IAAI;AAClE,WAAO,KAAK,MAAM,mBAAmB;AAAA,EACvC,OAAO;AAEL,UAAM,WAAW,MAAM,aAAAC,QAAM;AAAA,MAC3B;AAAA,MACA;AAAA,QACE,OAAO,QAAQ;AAAA,QACf,UAAU;AAAA,QACV;AAAA,QACA,aAAa,QAAQ;AAAA,QACrB;AAAA,QACA,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,aAAa,QAAQ,IAAI;AAAA,UACzB,qBAAqB;AAAA,UACrB,kBAAkB;AAAA,QACpB;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AACA,WAAO,SAAS;AAAA,EAClB;AAEA,QAAM,UAAU,KAAK;AACrB,MAAI,EAAC,mCAAU,KAAI;AACjB,mBAAO,MAAM,IAAI,6CAA6C,IAAI;AAClE,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AAEA,MAAI,eAAe;AACnB,QAAM,gBAAgC,CAAC;AAEvC,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAO,MAAM;AAChB,qBAAO,MAAM,IAAI,kDAAkD,IAAI;AACvE,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AAEA,QAAI,OAAO,SAAS,QAAQ;AAC1B,UAAI,OAAO,OAAO,KACf,QAAQ,+BAA+B,EAAE,EACzC,QAAQ,yBAAyB,EAAE,EACnC,KAAK;AAER,UAAI,CAAC,MAAM;AACT,eAAO,OAAO,KAAK;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AACA,uBAAO,IAAI,IAAI,kDAAkD,IAAI;AAAA,MACvE;AAEA,qBAAe,eAAe,GAAG,YAAY;AAAA;AAAA,EAAO,IAAI,KAAK;AAAA,IAC/D,WAAW,OAAO,SAAS,YAAY;AACrC,oBAAc,KAAK;AAAA,QACjB,MAAM,OAAO;AAAA,QACb,WAAW,OAAO;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,CAAC,gBAAgB,CAAC,cAAc,QAAQ;AAC1C,mBAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO,KAAK,SACP,MAAM;AAp1Bf,UAAAC,KAAA;AAw1BU,YAAM,aAAYA,MAAA,KAAK,MAAM,4BAAX,OAAAA,MAAsC;AACxD,YAAM,cAAa,UAAK,MAAM,gCAAX,YAA0C;AAC7D,YAAM,eAAe,KAAK,MAAM,eAAe,YAAY;AAC3D,aAAO;AAAA,QACL,eAAe;AAAA,QACf,mBAAmB,KAAK,MAAM;AAAA,QAC9B,cAAc,eAAe,KAAK,MAAM;AAAA,QACxC,eAAe;AAAA,MACjB;AAAA,IACF,GAAG,IACH;AAAA,EACN;AACF;AAEA,eAAe,yBACb,IACA,SACA,QACA,UAAkB,GACc;AAChC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,cAAc,IAAI,SAAS,MAAM;AAAA,IACvC;AAAA,MACE;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,kBAAkB,UAAgD;AA13B3E;AA23BE,MAAI,iBAAiB,SAAS,MAAM;AAGpC,QAAI,oBAAe,CAAC,MAAhB,mBAAmB,UAAS,SAAS;AACvC,qBAAiB;AAAA,MACf,EAAE,MAAM,QAAiB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,EAAE;AAAA,MAClD,GAAG;AAAA,IACL;AAAA,EACF;AAGA,mBAAiB,eAAe,OAAO,CAAC,KAAK,YAAY;AACvD,QAAI,IAAI,WAAW;AAAG,aAAO,CAAC,OAAO;AAErC,UAAM,cAAc,IAAI,IAAI,SAAS,CAAC;AACtC,QAAI,YAAY,SAAS,QAAQ,MAAM;AACrC,kBAAY,QAAQ,CAAC,GAAG,YAAY,OAAO,GAAG,QAAQ,KAAK;AAC3D,aAAO;AAAA,IACT;AAEA,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB,GAAG,CAAC,CAAsB;AAG1B,QAAI,oBAAe,eAAe,SAAS,CAAC,MAAxC,mBAA2C,UAAS,SAAS;AAC/D,mBAAe,KAAK,EAAE,MAAM,QAAQ,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC;AAAA,EAChE;AAEA,SAAO;AACT;AAEA,eAAe,uBACb,aACA,SAC0B;AAC1B,QAAM,kBAAmC;AAAA,IACvC,OAAO,QAAQ;AAAA,IACf,UAAU,CAAC;AAAA,IACX,OAAO,QAAQ,YACX;AAAA,MACE,sBAAsB,QAAQ,UAAU,IAAI,CAAC,QAAQ;AAAA,QACnD,MAAM,GAAG;AAAA,QACT,YAAY;AAAA,UACV,aAAa,GAAG;AAAA,UAChB,GAAG,GAAG;AAAA,QACR;AAAA,MACF,EAAE;AAAA,IACJ,IACA;AAAA,EACN;AAEA,aAAW,WAAW,QAAQ,UAAU;AACtC,QAAI,QAAQ,SAAS,UAAU;AAC7B,sBAAgB,oBAAoB,QAAQ;AAC5C;AAAA,IACF;AAEA,UAAM,QAAwB,CAAC;AAE/B,QAAI,QAAQ,SAAS;AACnB,YAAM,KAAK,EAAE,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACtC;AAEA,eAAW,QAAQ,QAAQ,SAAS,CAAC,GAAG;AACtC,UAAI,yBAAyB,SAAS,KAAK,QAAQ,GAAG;AACpD,YAAI,KAAK,KAAK;AACZ,gBAAM,KAAK;AAAA,YACT,UAAU;AAAA,cACR,UAAU,KAAK;AAAA,cACf,SAAS,KAAK;AAAA,YAChB;AAAA,UACF,CAAC;AACD,gBAAM,KAAK,EAAE,MAAM,UAAU,KAAK,GAAG,IAAI,CAAC;AAAA,QAC5C,WAAW,KAAK,MAAM;AACpB,gBAAM,KAAK;AAAA,YACT,YAAY;AAAA,cACV,UAAU,KAAK;AAAA,cACf,MAAM,KAAK;AAAA,YACb;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,WAAW,KAAK,KAAK;AAEnB,cAAM,KAAK;AAAA,UACT,MAAM,SAAS,KAAK,GAAG;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,oBAAgB,SAAS,KAAK;AAAA,MAC5B,MAAM,QAAQ,SAAS,cAAc,UAAU,QAAQ;AAAA,MACvD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,aACb,IACA,SACgC;AAh+BlC;AAi+BE,QAAM,iBAAiB,kBAAkB,QAAQ,QAAQ;AACzD,QAAM,UAAU,eAAe,MAAM,GAAG,EAAE;AAC1C,QAAM,cAAc,eAAe,MAAM,EAAE,EAAE,CAAC;AAE9C,QAAM,QAAQ,IAAI,yBAAY,EAAE,QAAQ,QAAQ,IAAI,eAAe,CAAC;AAEpE,QAAM,OAAO,MAAM,MAAM,OAAO;AAAA,IAC9B,OAAO,QAAQ;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,oBAAoB,CAAC,MAAM;AAAA,MAC3B,OAAO,QAAQ,QAAQ,CAAC,QAAQ,KAAK,IAAI;AAAA,MACzC,mBAAmB,QAAQ;AAAA,IAC7B;AAAA,EACF,CAAC;AAED,QAAM,WAAW,MAAM,KAAK,YAAY,EAAE,SAAS,YAAY,MAAM,CAAC;AAEtE,MAAI,OAAO;AACX,QAAM,QAAgB,CAAC;AAEvB,aAAW,UAAQ,0BAAS,eAAT,mBAAsB,OAAtB,mBAA0B,YAA1B,mBAAmC,UAAS,CAAC,GAAG;AACjE,QAAI,KAAK;AAAM,cAAQ,KAAK;AAC5B,SAAI,UAAK,eAAL,mBAAiB,MAAM;AACzB,YAAM,KAAK,EAAE,UAAU,aAAa,MAAM,KAAK,WAAW,KAAK,CAAC;AAAA,IAClE;AAAA,EACF;AAEA,QAAM,iBAAgB,cAAS,kBAAT,mBAAwB,IAAI,CAAC,OAAI;AA7/BzD,QAAAA,KAAAC;AA6/B6D;AAAA,MACzD,OAAMD,MAAA,GAAG,SAAH,OAAAA,MAAW;AAAA,MACjB,YAAWC,MAAA,GAAG,SAAH,OAAAA,MAAW,CAAC;AAAA,IACzB;AAAA;AAEA,MAAI,CAAC,QAAQ,EAAC,+CAAe,WAAU,CAAC,MAAM,QAAQ;AACpD,UAAM,aAAY,cAAS,eAAT,mBAAsB;AACxC,UAAM,eAAe,uCAAW;AAEhC,mBAAO,MAAM,IAAI,uDAAuD;AAAA,MACtE;AAAA,MACA,eAAe,uCAAW;AAAA,MAC1B,eAAe,SAAS;AAAA,MACxB,cAAc,SAAS;AAAA,MACvB,kBAAkB,uCAAW;AAAA,MAC7B,gBAAgB,SAAS;AAAA,IAC3B,CAAC;AAED,QAAI,eAAe;AACnB,QAAI,cAAc;AAChB,YAAM,qBAA6C;AAAA,QACjD,yBACE;AAAA,QACF,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,MACd;AACA,sBAAgB,kBAAkB,YAAY,IAAI,mBAAmB,YAAY,KAAK,EAAE;AAAA,IAC1F;AAEA,UAAMH,SAAQ,IAAI,MAAM,YAAY;AACpC,IAAAA,OAAM,eAAe;AACrB,IAAAA,OAAM,gBAAgB,uCAAW;AACjC,IAAAA,OAAM,gBAAgB,SAAS;AAC/B,IAAAA,OAAM,iBAAiB,SAAS;AAChC,UAAMA;AAAA,EACR;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA,gBAAe,+CAAgB,OAAM;AAAA,IACrC,gBAAgB,iBAAiB,CAAC;AAAA,IAClC,OAAO,SAAS,gBACZ;AAAA,MACE,gBAAe,cAAS,cAAc,qBAAvB,YAA2C;AAAA,MAC1D,oBAAmB,cAAS,cAAc,yBAAvB,YAA+C;AAAA,MAClE,eAAc,cAAS,cAAc,oBAAvB,YAA0C;AAAA,MACxD,gBAAe,cAAS,cAAc,4BAAvB,YAAkD;AAAA,IACnE,IACA;AAAA,EACN;AACF;AAMA,IAAM,4BAA4B,oBAAI,IAAI,CAAC,sBAAsB,QAAQ,CAAC;AAM1E,SAAS,8BAA8B,SAAmC;AACxE,MAAI,gBAAgB;AAEpB,aAAW,WAAW,QAAQ,UAAU;AACtC,YAAQ,QAAQ,QAAQ,MAAM,OAAO,CAAC,SAAS;AAC7C,UAAI,gBAAgB,QAAQ,cAAc,MAAM;AAC9C,wBAAgB;AAChB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AAGD,QAAI,QAAQ,MAAM,WAAW,GAAG;AAC9B,cAAQ,QAAQ,CAAC,EAAE,MAAM,wCAAwC,CAAC;AAAA,IACpE;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,wBACb,IACA,SACA,UAAkB,GACc;AAChC,MAAI,wBAAwB;AAE5B,SAAO,YAAY,IAAI,aAAa,MAAM,aAAa,IAAI,OAAO,GAAG;AAAA,IACnE;AAAA,IACA,SAAS,CAACA,QAAO,YAAY;AA5lCjC;AA6lCM,YAAM,eAAoC;AAAA,QACxC,SAASA,OAAM;AAAA,QACf,cAAcA,OAAM;AAAA,QACpB,cAAcA,OAAM;AAAA,MACtB;AAEA,UAAIA,OAAM;AAAe,qBAAa,gBAAgBA,OAAM;AAC5D,UAAIA,OAAM;AAAe,qBAAa,gBAAgBA,OAAM;AAC5D,UAAIA,OAAM;AACR,qBAAa,iBAAiBA,OAAM;AACtC,UAAIA,OAAM;AAAQ,qBAAa,aAAaA,OAAM;AAClD,UAAIA,OAAM;AAAM,qBAAa,YAAYA,OAAM;AAC/C,UAAIA,OAAM;AAAS,qBAAa,eAAeA,OAAM;AAErD,YAAM,WAAW,QAAQ,SACtB,QAAQ,CAAC,MAAM,EAAE,KAAK,EACtB,OAAO,CAAC,MAAM,cAAc,CAAC,EAC7B,IAAI,CAAC,MAAO,EAAU,SAAS,OAAO;AACzC,UAAI,SAAS;AAAQ,qBAAa,WAAW;AAE7C,qBAAO;AAAA,QACL;AAAA,QACA,UAAU,OAAO,WAAWA,OAAM,OAAO;AAAA,QACzC;AAAA,MACF;AAIA,YAAM,kBACH,0BAA0B,IAAIA,OAAM,YAAY,KAC/CA,OAAM,gBACP,0BAA0B,KAAI,KAAAA,OAAM,mBAAN,mBAAsB,WAAW,OAC9D,KAAAA,OAAM,mBAAN,mBAAsB;AAE1B,UAAI,iBAAiB;AACnB,YAAI,CAAC,uBAAuB;AAC1B,gBAAM,gBAAgB,8BAA8B,OAAO;AAC3D,cAAI,eAAe;AACjB,2BAAO;AAAA,cACL;AAAA,cACA,qDAAqD,eAAe;AAAA,YACtE;AACA,oCAAwB;AACxB;AAAA,UACF;AAAA,QACF;AAGA,uBAAO;AAAA,UACL;AAAA,UACA,wCAAwC,eAAe;AAAA,QACzD;AACA,cAAM,sBAAsB,IAAI;AAAA,UAC9B,gCAAgC,eAAe;AAAA,QACjD;AACA,4BAAoB,eAAeA,OAAM;AACzC,4BAAoB,gBAAgBA,OAAM;AAC1C,4BAAoB,gBAAgBA,OAAM;AAC1C,4BAAoB,iBAAiB;AACrC,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAMA,SAAS,wBACP,SACQ;AACR,SAAO,MAAM,QAAQ,OAAO,IACxB,QACG,IAAI,CAAC,MAAO,EAAE,SAAS,SAAS,EAAE,OAAO,IAAI,EAAE,IAAI,GAAI,EACvD,KAAK,IAAI,IACZ;AACN;AAEA,SAAS,mBAAmB,SAAsC;AA5qClE;AA6qCE,SAAO;AAAA,IACL,OAAO,QAAQ;AAAA,IACf,UAAU,QAAQ,SAAS,IAAI,CAAC,aAAa;AAAA,MAC3C,MAAM,QAAQ;AAAA,MACd,SAAS,wBAAwB,QAAQ,OAAO;AAAA,IAClD,EAAE;AAAA,IACF,QAAO,aAAQ,cAAR,mBAAmB,IAAI,CAAC,QAAQ;AAAA,MACrC,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,aAAa,QAAQ,gBACjB,OAAO,QAAQ,kBAAkB,WAC/B,QAAQ,gBACR,EAAE,MAAM,YAAY,UAAU,QAAQ,cAAc,IACtD;AAAA,IACJ,aAAa,QAAQ;AAAA,EACvB;AACF;AAEA,eAAe,SACb,IACA,SACgC;AAnsClC;AAosCE,QAAM,WAAW,MAAM,aAAAC,QAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,QAAQ,IAAI,YAAY;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAS,cAAS,KAAK,QAAQ,CAAC,MAAvB,mBAA0B;AACzC,MAAI,CAAC,QAAQ;AACX,mBAAO,MAAM,IAAI,wCAAwC,SAAS,IAAI;AACtE,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,QAAM,gBAAgC,CAAC;AACvC,OAAI,YAAO,eAAP,mBAAmB,QAAQ;AAC7B,eAAW,MAAM,OAAO,YAAY;AAClC,oBAAc,KAAK;AAAA,QACjB,MAAM,GAAG,SAAS;AAAA,QAClB,WAAW,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,OAAO,WAAW;AAAA,IAC3B,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO,SAAS,KAAK,QACjB;AAAA,MACE,eAAe,SAAS,KAAK,MAAM;AAAA,MACnC,mBAAmB,SAAS,KAAK,MAAM;AAAA,MACvC,cAAc,SAAS,KAAK,MAAM;AAAA,MAClC,gBACE,oBAAS,KAAK,MAAM,0BAApB,mBAA2C,kBAA3C,YAA4D;AAAA,IAChE,IACA;AAAA,EACN;AACF;AAEA,eAAe,oBACb,IACA,SACA,UAAkB,GACc;AAChC,SAAO,YAAY,IAAI,QAAQ,MAAM,SAAS,IAAI,OAAO,GAAG,EAAE,QAAQ,CAAC;AACzE;AAMA,SAAS,yBAAyB,SAA4C;AA7vC9E;AA8vCE,SAAO;AAAA,IACL,OAAO,QAAQ;AAAA,IACf,UAAU,QAAQ,SAAS,IAAI,CAAC,aAAa;AAAA,MAC3C,MAAM,QAAQ;AAAA,MACd,SAAS,wBAAwB,QAAQ,OAAO;AAAA,IAClD,EAAE;AAAA,IACF,QAAO,aAAQ,cAAR,mBAAmB,IAAI,CAAC,QAAQ;AAAA,MACrC,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,aAAa,QAAQ,gBACjB,OAAO,QAAQ,kBAAkB,WAC/B,QAAQ,gBACR,EAAE,MAAM,YAAY,UAAU,QAAQ,cAAc,IACtD;AAAA,IACJ,aAAa,QAAQ;AAAA,EACvB;AACF;AAEA,eAAe,eACb,IACA,SACgC;AApxClC;AAqxCE,QAAM,WAAW,MAAM,aAAAA,QAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,QAAQ,IAAI,kBAAkB;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAS,cAAS,KAAK,QAAQ,CAAC,MAAvB,mBAA0B;AACzC,MAAI,CAAC,QAAQ;AACX,mBAAO,MAAM,IAAI,8CAA8C,SAAS,IAAI;AAC5E,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAEA,QAAM,gBAAgC,CAAC;AACvC,OAAI,YAAO,eAAP,mBAAmB,QAAQ;AAC7B,eAAW,MAAM,OAAO,YAAY;AAClC,oBAAc,KAAK;AAAA,QACjB,MAAM,GAAG,SAAS;AAAA,QAClB,WAAW,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,OAAO,WAAW;AAAA,IAC3B,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO,SAAS,KAAK,QACjB;AAAA,MACE,eAAe,SAAS,KAAK,MAAM;AAAA,MACnC,mBAAmB,SAAS,KAAK,MAAM;AAAA,MACvC,cAAc,SAAS,KAAK,MAAM;AAAA,MAClC,gBACE,oBAAS,KAAK,MAAM,0BAApB,mBAA2C,kBAA3C,YAA4D;AAAA,IAChE,IACA;AAAA,EACN;AACF;AAEA,eAAe,0BACb,IACA,SACA,UAAkB,GACc;AAChC,SAAO,YAAY,IAAI,cAAc,MAAM,eAAe,IAAI,OAAO,GAAG,EAAE,QAAQ,CAAC;AACrF;AAMA,IAAM,kBAA8B,CAAC,UAAU,aAAa,UAAU,QAAQ,YAAY;AAE1F,IAAM,oBAAmE;AAAA,EACvE,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,QAAQ,CAAC,GAAG,UAAU,SAAS;AAAA,EAC/D,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,WAAW,CAAC,GAAG,UAAU,YAAY;AAAA,EACrE,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,WAAW,CAAC,GAAG,UAAU,SAAS;AAAA,EAClE,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,SAAS,CAAC,GAAG,UAAU,OAAO;AAAA,EAC9D,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,eAAe,CAAC,GAAG,UAAU,aAAa;AAC5E;AAEO,SAAS,iBAAiB,OAAwD;AACvF,QAAM,aAAa,MAAM,QAAQ,GAAG;AAEpC,MAAI,eAAe,IAAI;AACrB,UAAM,SAAS,MAAM,UAAU,GAAG,UAAU;AAE5C,QAAI,gBAAgB,SAAS,MAAkB,GAAG;AAChD,YAAM,UAAU,MAAM,UAAU,aAAa,CAAC;AAE9C,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI;AAAA,UACR,mCAAmC,KAAK;AAAA,QAC1C;AAAA,MACF;AAEA,aAAO,EAAE,UAAU,QAAoB,QAAQ;AAAA,IACjD;AAAA,EAIF;AAGA,aAAW,EAAE,QAAQ,SAAS,KAAK,mBAAmB;AACpD,QAAI,OAAO,IAAI,KAAK,GAAG;AACrB,aAAO,EAAE,UAAU,SAAS,MAAM;AAAA,IACpC;AAAA,EACF;AAGA,MAAI,eAAe,IAAI;AACrB,UAAM,SAAS,MAAM,UAAU,GAAG,UAAU;AAC5C,UAAM,IAAI;AAAA,MACR,qBAAqB,MAAM,sBAAsB,KAAK,uBAAuB,gBAAgB,KAAK,IAAI,CAAC;AAAA,IACzG;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,2CAA2C,KAAK,0CAA0C,KAAK,oDAAoD,gBAAgB,KAAK,IAAI,CAAC;AAAA,EAC/K;AACF;AAEA,eAAsB,gBACpB,IACA,WACA,UACA,UAAkB,GAClB,iBAAyB,MACO;AAChC,MAAI;AACF,UAAM,EAAE,UAAU,QAAQ,IAAI,iBAAiB,UAAU,KAAK;AAC9D,UAAM,iBAAiB,EAAE,GAAG,WAAW,OAAO,QAAoB;AAElE,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,MAAM,wBAAwB,IAAI,cAAc;AAAA,UAChD;AAAA,UACA;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,MAAM,qBAAqB,IAAI,cAAc;AAAA,UAC7C;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,mBAAmB,cAAc;AAAA,UACjC;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,MAAM,uBAAuB,IAAI,cAAc;AAAA,UAC/C;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,yBAAyB,cAAc;AAAA,UACvC;AAAA,QACF;AAAA,IACJ;AAAA,EACF,SAASD,QAAO;AACd,QAAI,UAAU,eAAe;AAC3B,qBAAO;AAAA,QACL;AAAA,QACA,iBAAiB,UAAU,KAAK,4BAA4B,UAAU,aAAa;AAAA,QACnF;AAAA,UACE,OAAOA,kBAAiB,QAAQA,OAAM,UAAUA;AAAA,UAChD,OACEA,kBAAiB,SAAUA,OAAc,iBAAiB,QACrDA,OAAc,MAAM,UACrB;AAAA,QACR;AAAA,MACF;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,UACE,GAAG;AAAA,UACH,OAAO,UAAU;AAAA,UACjB,eAAe;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAMA;AAAA,EACR;AACF;","names":["ClaudeModel","GPTModel","GroqModel","OpenRouterModel","GeminiModel","error","axios","_a","_b"]}
1
+ {"version":3,"sources":["../index.ts","../interfaces.ts","../logger.ts","../utils.ts"],"sourcesContent":["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 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 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 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","/** @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","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","axios","_a","_b"]}
package/dist/index.mjs CHANGED
@@ -611,26 +611,13 @@ async function prepareAnthropicPayload(_identifier, payload) {
611
611
  return preparedPayload;
612
612
  }
613
613
  async function callAnthropic(id, payload, config) {
614
- var _a;
614
+ var _a, _b, _c;
615
615
  const anthropicMessages = jigAnthropicMessages(payload.messages);
616
616
  const tools = (_a = payload.functions) == null ? void 0 : _a.map((f) => ({
617
617
  ...f,
618
618
  input_schema: f.parameters,
619
619
  parameters: void 0
620
620
  }));
621
- if (tools == null ? void 0 : tools.length) {
622
- tools[tools.length - 1] = {
623
- ...tools[tools.length - 1],
624
- cache_control: { type: "ephemeral" }
625
- };
626
- }
627
- const system = payload.system ? [
628
- {
629
- type: "text",
630
- text: payload.system,
631
- cache_control: { type: "ephemeral" }
632
- }
633
- ] : void 0;
634
621
  let data;
635
622
  if ((config == null ? void 0 : config.service) === "bedrock") {
636
623
  const AWS_REGION = "us-east-1";
@@ -640,8 +627,7 @@ async function callAnthropic(id, payload, config) {
640
627
  anthropic_version: "bedrock-2023-05-31",
641
628
  max_tokens: 4096,
642
629
  messages: anthropicMessages,
643
- // The pinned Bedrock model predates prompt caching; strip breakpoints
644
- tools: tools == null ? void 0 : tools.map(({ cache_control, ...t }) => t)
630
+ tools
645
631
  };
646
632
  const response = await client.send(
647
633
  new InvokeModelCommand({
@@ -653,14 +639,18 @@ async function callAnthropic(id, payload, config) {
653
639
  const decodedResponseBody = new TextDecoder().decode(response.body);
654
640
  data = JSON.parse(decodedResponseBody);
655
641
  } else {
642
+ const cachedTools = (tools == null ? void 0 : tools.length) ? [
643
+ ...tools.slice(0, -1),
644
+ { ...tools[tools.length - 1], cache_control: { type: "ephemeral" } }
645
+ ] : tools;
656
646
  const response = await axios.post(
657
647
  "https://api.anthropic.com/v1/messages",
658
648
  {
659
649
  model: payload.model,
660
650
  messages: anthropicMessages,
661
- tools,
651
+ tools: cachedTools,
662
652
  temperature: payload.temperature,
663
- system,
653
+ system: payload.system,
664
654
  max_tokens: 4096
665
655
  },
666
656
  {
@@ -714,24 +704,25 @@ ${text}` : text;
714
704
  );
715
705
  throw new Error("Missing text & functions in Anthropic API response");
716
706
  }
707
+ let usage = null;
708
+ if (data.usage) {
709
+ const cacheRead = (_b = data.usage.cache_read_input_tokens) != null ? _b : 0;
710
+ const cacheWrite = (_c = data.usage.cache_creation_input_tokens) != null ? _c : 0;
711
+ const promptTokens = data.usage.input_tokens + cacheRead + cacheWrite;
712
+ usage = {
713
+ prompt_tokens: promptTokens,
714
+ completion_tokens: data.usage.output_tokens,
715
+ total_tokens: promptTokens + data.usage.output_tokens,
716
+ cached_tokens: cacheRead
717
+ };
718
+ }
717
719
  return {
718
720
  role: "assistant",
719
721
  content: textResponse,
720
722
  function_call: functionCalls[0] || null,
721
723
  function_calls: functionCalls,
722
724
  files: [],
723
- usage: data.usage ? (() => {
724
- var _a2, _b;
725
- const cacheRead = (_a2 = data.usage.cache_read_input_tokens) != null ? _a2 : 0;
726
- const cacheWrite = (_b = data.usage.cache_creation_input_tokens) != null ? _b : 0;
727
- const promptTokens = data.usage.input_tokens + cacheRead + cacheWrite;
728
- return {
729
- prompt_tokens: promptTokens,
730
- completion_tokens: data.usage.output_tokens,
731
- total_tokens: promptTokens + data.usage.output_tokens,
732
- cached_tokens: cacheRead
733
- };
734
- })() : null
725
+ usage
735
726
  };
736
727
  }
737
728
  async function callAnthropicWithRetries(id, payload, config, retries = 5) {
@@ -944,6 +935,18 @@ async function callGoogleAIWithRetries(id, payload, retries = 5) {
944
935
  `Retry #${attempt} error: ${error2.message}`,
945
936
  errorDetails
946
937
  );
938
+ if (typeof (error2 == null ? void 0 : error2.message) === "string" && error2.message.includes("Cannot fetch content from the provided URL")) {
939
+ logger_default.error(
940
+ id,
941
+ "Circuit breaker: Google could not fetch image URL(s); failing over (no more Google retries)"
942
+ );
943
+ const fetchError = new Error(
944
+ "Google AI could not fetch the provided image URL(s)."
945
+ );
946
+ fetchError.cause = error2;
947
+ fetchError.googleFetchFailure = true;
948
+ throw fetchError;
949
+ }
947
950
  const violationReason = CONTENT_VIOLATION_REASONS.has(error2.finishReason) && error2.finishReason || CONTENT_VIOLATION_REASONS.has((_a = error2.promptFeedback) == null ? void 0 : _a.blockReason) && ((_b = error2.promptFeedback) == null ? void 0 : _b.blockReason);
948
951
  if (violationReason) {
949
952
  if (!hasTriedWithoutImages) {
@@ -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 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 })) as Record<string, any>[] | undefined;\n\n // Prompt caching: tools and system form the stable prompt prefix, so mark\n // cache breakpoints on the last tool and on the system block. Anthropic\n // ignores breakpoints below the model's minimum cacheable length, so this\n // is safe for small prompts.\n if (tools?.length) {\n tools[tools.length - 1] = {\n ...tools[tools.length - 1],\n cache_control: { type: \"ephemeral\" },\n };\n }\n const system = payload.system\n ? [\n {\n type: \"text\",\n text: payload.system,\n cache_control: { type: \"ephemeral\" },\n },\n ]\n : undefined;\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 // The pinned Bedrock model predates prompt caching; strip breakpoints\n tools: tools?.map(({ cache_control, ...t }) => t),\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 const response = await axios.post(\n \"https://api.anthropic.com/v1/messages\",\n {\n model: payload.model,\n messages: anthropicMessages,\n tools,\n temperature: payload.temperature,\n 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 return {\n role: \"assistant\",\n content: textResponse,\n function_call: functionCalls[0] || null,\n function_calls: functionCalls,\n files: [],\n usage: data.usage\n ? (() => {\n // Anthropic's input_tokens EXCLUDES cache reads/writes; fold them\n // back in so prompt_tokens means \"all input tokens\" like OpenAI,\n // where cached_tokens is a subset of prompt_tokens.\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 return {\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 : null,\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: 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 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 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":";;;;;;;;;AACO,IAAK,cAAL,kBAAKA,iBAAL;AACL,EAAAA,aAAA,aAAU;AACV,EAAAA,aAAA,cAAW;AACX,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,eAAY;AACZ,EAAAA,aAAA,gBAAa;AACb,EAAAA,aAAA,cAAW;AACX,EAAAA,aAAA,YAAS;AACT,EAAAA,aAAA,cAAW;AACX,EAAAA,aAAA,eAAY;AACZ,EAAAA,aAAA,gBAAa;AACb,EAAAA,aAAA,cAAW;AAXD,SAAAA;AAAA,GAAA;AAeL,IAAK,WAAL,kBAAKC,cAAL;AACL,EAAAA,UAAA,gBAAa;AACb,EAAAA,UAAA,oBAAiB;AACjB,EAAAA,UAAA,gBAAa;AACb,EAAAA,UAAA,uBAAoB;AACpB,EAAAA,UAAA,uBAAoB;AACpB,EAAAA,UAAA,eAAY;AACZ,EAAAA,UAAA,WAAQ;AACR,EAAAA,UAAA,gBAAa;AACb,EAAAA,UAAA,gBAAa;AACb,EAAAA,UAAA,aAAU;AACV,EAAAA,UAAA,aAAU;AACV,EAAAA,UAAA,YAAS;AACT,EAAAA,UAAA,iBAAc;AACd,EAAAA,UAAA,iBAAc;AACd,EAAAA,UAAA,UAAO;AACP,EAAAA,UAAA,eAAY;AAhBF,SAAAA;AAAA,GAAA;AAoBL,IAAK,YAAL,kBAAKC,eAAL;AACL,EAAAA,WAAA,sBAAmB;AACnB,EAAAA,WAAA,6BAA0B;AAC1B,EAAAA,WAAA,eAAY;AACZ,EAAAA,WAAA,mCAAgC;AAJtB,SAAAA;AAAA,GAAA;AAQL,IAAK,kBAAL,kBAAKC,qBAAL;AACL,EAAAA,iBAAA,yBAAsB;AACtB,EAAAA,iBAAA,oBAAiB;AAFP,SAAAA;AAAA,GAAA;AAML,IAAK,cAAL,kBAAKC,iBAAL;AACL,EAAAA,aAAA,oBAAiB;AACjB,EAAAA,aAAA,qBAAkB;AAClB,EAAAA,aAAA,sBAAmB;AACnB,EAAAA,aAAA,2CAAwC;AACxC,EAAAA,aAAA,mCAAgC;AAChC,EAAAA,aAAA,yCAAsC;AACtC,EAAAA,aAAA,oCAAiC;AACjC,EAAAA,aAAA,4BAAyB;AACzB,EAAAA,aAAA,mCAAgC;AATtB,SAAAA;AAAA,GAAA;;;AC/CZ,SAAS,iBAAiB,YAAgC;AACxD,MAAI,MAAM,QAAQ,UAAU,GAAG;AAC7B,WAAO,WAAW,IAAI,CAAC,OAAO,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG;AAAA,EACnD;AACA,SAAO,IAAI,UAAU;AACvB;AAEA,SAAS,cACP,OACA,YACA,SACQ;AACR,SAAO,IAAI,KAAK,KAAK,iBAAiB,UAAU,CAAC,IAAI,OAAO;AAC9D;AAEO,SAAS,IACd,YACA,YACG,MACG;AACN,UAAQ,IAAI,cAAc,OAAO,YAAY,OAAO,GAAG,GAAG,IAAI;AAChE;AAEO,SAAS,KACd,YACA,YACG,MACG;AACN,UAAQ,KAAK,cAAc,QAAQ,YAAY,OAAO,GAAG,GAAG,IAAI;AAClE;AAEO,SAAS,MACd,YACA,YACG,MACG;AACN,UAAQ,MAAM,cAAc,SAAS,YAAY,OAAO,GAAG,GAAG,IAAI;AACpE;AAEA,IAAO,iBAAQ;AAAA,EACb;AAAA,EACA;AAAA,EACA;AACF;;;AClBA;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,OAAO,WAAW;;;AChCX,SAAS,QAAQ,IAA2B;AACjD,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEO,SAAS,YAAY,MAAc,MAAwB;AAJlE;AAKE,QAAM,cAAY,UAAK,MAAM,GAAG,EAAE,IAAI,MAApB,mBAAuB,kBAAiB;AAC1D,SACE,CAAC,QAAQ,QAAQ,OAAO,EAAE,SAAS,SAAS,KAC5C,CAAC,EACC,QAAQ,CAAC,cAAc,cAAc,qBAAqB,EAAE,SAAS,IAAI;AAG/E;;;ADsBA,SAAS,mBAAmB;AAE5B,IAAM,QAAQ,UAAQ,OAAO;AAC7B,IAAM,SAAS,UAAQ,aAAa;AAuBpC,eAAe,YACb,YACA,SACA,IACA,UAII,CAAC,GACO;AArEd;AAsEE,QAAM,EAAE,UAAU,GAAG,cAAc,KAAK,QAAQ,IAAI;AAEpD,iBAAO,IAAI,YAAY,WAAW,OAAO,mBAAmB;AAE5D,MAAI;AACJ,WAAS,UAAU,GAAG,UAAU,SAAS,WAAW;AAClD,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAASC,QAAY;AACnB,kBAAYA;AAEZ,UAAI,SAAS;AACX,gBAAQA,QAAO,OAAO;AAAA,MACxB,OAAO;AACL,uBAAO;AAAA,UACL;AAAA,UACA,UAAU,OAAO,WAAWA,OAAM,OAAO;AAAA,YACzC,KAAAA,OAAM,aAAN,mBAAgB,SAAQA;AAAA,QAC1B;AAAA,MACF;AAEA,YAAM,QAAQ,cAAc,OAAO;AAAA,IACrC;AAAA,EACF;AAEA,QAAMA,SAAQ,IAAI;AAAA,IAChB,kBAAkB,OAAO,cAAc,OAAO;AAAA,EAChD;AACA,EAAAA,OAAM,QAAQ;AACd,QAAMA;AACR;AAEA,SAAS,sBACP,YACA,WACA,sBACA,sBACuB;AACvB,QAAM,gBAAgC,CAAC;AAEvC,aAAW,OAAO,sBAAsB;AACtC,QAAI,CAAC,IAAI,QAAQ,CAAC,IAAI;AAAW;AAEjC,QAAI,wBAAwB,CAAC,qBAAqB,IAAI,IAAI,IAAI,GAAG;AAC/D,YAAM,IAAI;AAAA,QACR,2DAA2D,IAAI,IAAI;AAAA,MACrE;AAAA,IACF;AAEA,QAAI;AACF,oBAAc,KAAK;AAAA,QACjB,MAAM,IAAI;AAAA,QACV,WAAW,KAAK,MAAM,IAAI,SAAS;AAAA,MACrC,CAAC;AAAA,IACH,SAASA,QAAO;AACd,qBAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA,IAAI;AAAA,MACN;AACA,YAAMA;AAAA,IACR;AAAA,EACF;AAEA,MAAI,CAAC,aAAa,CAAC,cAAc,QAAQ;AACvC,mBAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA,KAAK,UAAU,EAAE,WAAW,qBAAqB,CAAC;AAAA,IACpD;AACA,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,aAAa;AAAA,IACtB,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO;AAAA,EACT;AACF;AAEA,SAAS,gBAAgB,SAAgC;AACvD,SAAO,KAAK;AAAA,IACV;AAAA,MACE,GAAG;AAAA,MACH,UAAU,QAAQ,SAAS,IAAI,CAAC,YAAY;AAC1C,cAAM,mBAAmB,EAAE,GAAG,QAAQ;AACtC,YAAI,OAAO,iBAAiB,YAAY,UAAU;AAChD,2BAAiB,UAAU,iBAAiB,QAAQ,MAAM,GAAG,GAAG;AAAA,QAClE,WAAW,MAAM,QAAQ,iBAAiB,OAAO,GAAG;AAClD,2BAAiB,UAAU,iBAAiB,QAAQ,IAAI,CAAC,UAAU;AACjE,gBAAI,MAAM,SAAS,aAAa;AAC9B,qBAAO;AAAA,gBACL,GAAG;AAAA,gBACH,WAAW,EAAE,KAAK,MAAM,UAAU,IAAI,MAAM,GAAG,GAAG,EAAE;AAAA,cACtD;AAAA,YACF;AACA,mBAAO;AAAA,UACT,CAAC;AAAA,QACH;AACA,eAAO;AAAA,MACT,CAAC;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,uBACb,KACA,MACiB;AACjB,QAAM,WAAW,MAAM,MAAM,IAAI,KAAK,EAAE,cAAc,cAAc,CAAC;AAErE,MAAI,cAAc,OAAO,KAAK,SAAS,IAAI;AAC3C,MAAI,eAAe,CAAC;AAEpB,MAAI,YAAY,KAAK,IAAI,GAAG;AAC1B,UAAM,YAAY,MAAM,OAAO,EAAE,QAAQ,YAAY,CAAC;AACtD,kBAAc,OAAO,KAAK,UAAU,IAAI;AACxC,mBAAe;AAAA,MACb,KAAK;AAAA,QACH,OAAO,UAAU;AAAA,QACjB,QAAQ,UAAU;AAAA,QAClB,UAAU;AAAA,MACZ;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,MAAM,MAAM,aAAa,YAAY,EACxD,aAAa,EACb,OAAO,MAAM,MAAM,EAAE,KAAK,UAAU,oBAAoB,KAAK,CAAC,EAC9D,IAAI,EACJ,SAAS;AAEZ,SAAO,cAAc,SAAS,QAAQ;AACxC;AAEA,IAAM,2BAA2B;AAAA,EAC/B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAWA,SAAS,yBACP,YACA,OACA,QACqB;AAzOvB;AA0OE,MAAI,CAAC,QAAQ;AACX,aAAS;AAAA,MACP,SAAS;AAAA,MACT,QAAQ,QAAQ,IAAI;AAAA,MACpB,SAAS;AAAA,IACX;AAAA,EACF;AAEA,MAAI,OAAO,YAAY,SAAS;AAC9B,mBAAO,IAAI,YAAY,+BAA+B,KAAK;AAE3D,QAAI,CAAC,OAAO,gBAAgB;AAC1B,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,cAAc,OAAO,eAAe,KAAiB;AAC3D,QAAI,EAAC,2CAAa,WAAU;AAC1B,YAAM,IAAI,MAAM,sDAAsD;AAAA,IACxE;AAEA,UAAM,WAAW,GAAG,YAAY,QAAQ,uBAAuB,YAAY,UAAU,iCAAiC,YAAY,UAAU;AAC5I,mBAAO,IAAI,YAAY,mBAAmB,QAAQ;AAElD,WAAO;AAAA,MACL;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,WAAW,YAAY;AAAA,MACzB;AAAA,IACF;AAAA,EACF;AAGA,iBAAO,IAAI,YAAY,yBAAyB,KAAK;AACrD,MAAI,OAAO,OAAO;AAChB,mBAAO,IAAI,YAAY,gBAAgB,OAAO,KAAK;AAAA,EACrD;AAEA,QAAM,UAAQ,YAAO,YAAP,mBAAgB,WAAU,6BAA6B;AAAA,IACnE;AAAA,IACA;AAAA,EACF;AACA,SAAO;AAAA,IACL,UAAU,GAAG,IAAI;AAAA,IACjB,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,eAAe,UAAU,OAAO,MAAM;AAAA,MACtC,GAAI,OAAO,QAAQ,EAAE,uBAAuB,OAAO,MAAM,IAAI,CAAC;AAAA,IAChE;AAAA,EACF;AACF;AAEA,eAAe,qBACb,YACA,SACwB;AAnS1B;AAoSE,QAAM,kBAAiC;AAAA,IACrC,OAAO,QAAQ;AAAA,IACf,UAAU,CAAC;AAAA,IACX,QAAO,aAAQ,cAAR,mBAAmB,IAAI,CAAC,QAAQ;AAAA,MACrC,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,aAAa,QAAQ,gBACjB,OAAO,QAAQ,kBAAkB,WAC/B,QAAQ,gBACR,EAAE,MAAM,YAAY,UAAU,QAAQ,cAAc,IACtD;AAAA,EACN;AAEA,aAAW,WAAW,QAAQ,UAAU;AACtC,UAAM,gBAAsC,CAAC;AAE7C,QAAI,QAAQ,SAAS;AACnB,oBAAc,KAAK,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,IAC5D;AAEA,eAAW,QAAQ,QAAQ,SAAS,CAAC,GAAG;AACtC,UAAI,yBAAyB,SAAS,KAAK,QAAQ,GAAG;AACpD,YAAI,KAAK,KAAK;AACZ,wBAAc,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,WAAW,EAAE,KAAK,KAAK,IAAI;AAAA,UAC7B,CAAC;AACD,wBAAc,KAAK,EAAE,MAAM,QAAQ,MAAM,UAAU,KAAK,GAAG,IAAI,CAAC;AAAA,QAClE,WAAW,KAAK,MAAM;AACpB,wBAAc,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,WAAW,EAAE,KAAK,QAAQ,KAAK,QAAQ,WAAW,KAAK,IAAI,GAAG;AAAA,UAChE,CAAC;AAAA,QACH;AAAA,MACF,WAAW,KAAK,KAAK;AAEnB,sBAAc,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,MAAM,SAAS,KAAK,GAAG;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,oBAAgB,SAAS,KAAK;AAAA,MAC5B,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,iBACb,IACA,eACA,cACA,gBACgC;AA9VlC;AA+VE,QAAM,gBAAoC,cAAc,QACpD,IAAI,IAAI,cAAc,MAAM,IAAI,CAAC,OAAO,GAAG,SAAS,IAAc,CAAC,IACnE;AAEJ,QAAM,EAAE,UAAU,QAAQ,IAAI;AAAA,IAC5B;AAAA,IACA,cAAc;AAAA,IACd;AAAA,EACF;AAEA,QAAM,aAAa,IAAI,gBAAgB;AACvC,QAAM,WAAW,MAAM,MAAM,UAAU;AAAA,IACrC,QAAQ;AAAA,IACR;AAAA,IACA,MAAM,KAAK,UAAU,EAAE,GAAG,eAAe,QAAQ,KAAK,CAAC;AAAA,IACvD,QAAQ,WAAW;AAAA,EACrB,CAAC;AAED,MAAI,CAAC,SAAS,MAAM;AAClB,UAAM,IAAI,MAAM,gCAAgC;AAAA,EAClD;AAEA,MAAI,YAAY;AAChB,QAAM,uBAA8D,CAAC;AAErE,QAAM,SAAS,SAAS,KAAK,UAAU;AACvC,MAAI,eAAe;AACnB,MAAI,aAAa;AAEjB,QAAM,qBAAqB,MACzB,WAAW,MAAM;AACf,mBAAO,MAAM,IAAI,wBAAwB,cAAc,IAAI;AAC3D,eAAW,MAAM;AAAA,EACnB,GAAG,cAAc;AAEnB,SAAO,MAAM;AACX;AACA,UAAM,eAAe,mBAAmB;AACxC,UAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,iBAAa,YAAY;AAEzB,QAAI,MAAM;AACR,qBAAO;AAAA,QACL;AAAA,QACA,kCAAkC,aAAa,CAAC;AAAA,MAClD;AACA,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AAEA,QAAI,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK;AAC1C,QAAI,cAAc;AAChB,cAAQ,eAAe;AACvB,qBAAe;AAAA,IACjB;AAEA,UAAM,cAAc,MAAM,MAAM,WAAW;AAE3C,eAAW,cAAc,aAAa;AACpC,UAAI,CAAC;AAAY;AAEjB,UAAI,WAAW,SAAS,QAAQ,GAAG;AACjC,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AAEA,UAAI;AACJ,UAAI;AACF,eAAO,KAAK,MAAM,WAAW,KAAK,CAAC;AAAA,MACrC,SAAQ;AACN,uBAAe;AACf;AAAA,MACF;AAEA,UAAI,GAAC,UAAK,YAAL,mBAAc,SAAQ;AACzB,YAAI,KAAK,OAAO;AACd,yBAAO,MAAM,IAAI,6BAA6B,KAAK,KAAK;AACxD,gBAAMA,SAAQ,IAAI,MAAM,4BAA4B;AACpD,UAAAA,OAAM,OAAO,KAAK;AAClB,UAAAA,OAAM,cAAc,gBAAgB,aAAa;AACjD,gBAAMA;AAAA,QACR;AACA,YAAI,eAAe,GAAG;AACpB,yBAAO,MAAM,IAAI,qCAAqC,IAAI;AAAA,QAC5D;AACA;AAAA,MACF;AAEA,YAAM,aAAY,gBAAK,QAAQ,CAAC,MAAd,mBAAiB,UAAjB,mBAAwB;AAC1C,UAAI,WAAW;AACb,mBAAW,YAAY,WAAW;AAChC,gBAAM,OAAM,cAAS,UAAT,YAAkB;AAC9B,iBAAO,qBAAqB,UAAU,KAAK;AACzC,iCAAqB,KAAK,EAAE,MAAM,IAAI,WAAW,GAAG,CAAC;AAAA,UACvD;AACA,eAAI,cAAS,aAAT,mBAAmB;AACrB,iCAAqB,GAAG,EAAE,QAAQ,SAAS,SAAS;AACtD,eAAI,cAAS,aAAT,mBAAmB;AACrB,iCAAqB,GAAG,EAAE,aAAa,SAAS,SAAS;AAAA,QAC7D;AAAA,MACF;AAEA,YAAM,QAAO,gBAAK,QAAQ,CAAC,MAAd,mBAAiB,UAAjB,mBAAwB;AACrC,UAAI;AAAM,qBAAa;AAAA,IACzB;AAAA,EACF;AACF;AAEA,eAAe,WACb,IACA,eACA,cACgC;AAldlC;AAmdE,QAAM,EAAE,UAAU,QAAQ,IAAI;AAAA,IAC5B;AAAA,IACA,cAAc;AAAA,IACd;AAAA,EACF;AAEA,QAAM,WAAW,MAAM,MAAM,UAAU;AAAA,IACrC,QAAQ;AAAA,IACR;AAAA,IACA,MAAM,KAAK,UAAU,EAAE,GAAG,eAAe,QAAQ,MAAM,CAAC;AAAA,EAC1D,CAAC;AAED,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,YAAY,MAAM,SAAS,KAAK;AACtC,mBAAO,MAAM,IAAI,qBAAqB,SAAS;AAC/C,UAAM,IAAI,MAAM,qBAAqB,UAAU,MAAM,OAAO,EAAE;AAAA,EAChE;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AAEjC,MAAI,GAAC,UAAK,YAAL,mBAAc,SAAQ;AACzB,QAAI,KAAK,OAAO;AACd,qBAAO,MAAM,IAAI,iBAAiB,KAAK,KAAK;AAC5C,YAAM,IAAI,MAAM,iBAAiB,KAAK,MAAM,OAAO,EAAE;AAAA,IACvD;AACA,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACtD;AAEA,QAAM,SAAS,KAAK,QAAQ,CAAC;AAG7B,QAAM,aAAY,YAAO,YAAP,mBAAgB;AAClC,QAAM,gBAAgC,CAAC;AAEvC,MAAI,uCAAW,QAAQ;AACrB,eAAW,MAAM,WAAW;AAC1B,oBAAc,KAAK;AAAA,QACjB,MAAM,GAAG,SAAS;AAAA,QAClB,WAAW,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,EACF,WAAW,OAAO,eAAe;AAC/B,kBAAc,KAAK;AAAA,MACjB,MAAM,OAAO,cAAc;AAAA,MAC3B,WAAW,KAAK,MAAM,OAAO,cAAc,SAAS;AAAA,IACtD,CAAC;AAAA,EACH;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,OAAO,QAAQ,WAAW;AAAA,IACnC,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO,KAAK,QACR;AAAA,MACE,eAAe,KAAK,MAAM;AAAA,MAC1B,mBAAmB,KAAK,MAAM;AAAA,MAC9B,cAAc,KAAK,MAAM;AAAA,MACzB,gBAAe,gBAAK,MAAM,0BAAX,mBAAkC,kBAAlC,YAAmD;AAAA,IACpE,IACA;AAAA,EACN;AACF;AAEA,eAAe,sBACb,IACA,eACA,cACA,UAAkB,GAClB,iBAAyB,MACO;AAChC,iBAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,6CAAc;AAAA,IACd,cAAc;AAAA,EAChB;AAEA,QAAM,WAAW,cAAc;AAC/B,QAAM,eACJ,wCACA,8CACA,CAAC,SAAS,WAAW,IAAI;AAE3B,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,YAAY;AACV,UAAI,cAAc;AAChB,eAAO;AAAA,UACL;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF,OAAO;AACL,eAAO,WAAW,IAAI,eAAe,YAAY;AAAA,MACnD;AAAA,IACF;AAAA,IACA;AAAA,MACE;AAAA,MACA,aAAa;AAAA,MACb,SAAS,CAACA,QAAO,YAAY;AA1jBnC;AA2jBQ,uBAAO;AAAA,UACL;AAAA,UACA,UAAU,OAAO,WAAWA,OAAM,OAAO;AAAA,YACzC,KAAAA,OAAM,aAAN,mBAAgB,SAAQA,OAAM,QAAQA;AAAA,QACxC;AAGA,cAAI,KAAAA,OAAM,SAAN,mBAAY,UAAS,4BAA4B;AACnD,yBAAO,IAAI,IAAI,iDAAiD;AAChE,wBAAc,SAAS,QAAQ,CAAC,YAA2B;AACzD,gBAAI,MAAM,QAAQ,QAAQ,OAAO,GAAG;AAClC,sBAAQ,UAAU,QAAQ,QAAQ;AAAA,gBAChC,CAAC,YAAY,QAAQ,SAAS;AAAA,cAChC;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,qBACP,UACsB;AAvlBxB;AAwlBE,MAAI,iBAAiB,SAAS,MAAM;AAGpC,QAAI,oBAAe,CAAC,MAAhB,mBAAmB,UAAS,QAAQ;AACtC,qBAAiB;AAAA,MACf,EAAE,MAAM,QAAiB,SAAS,MAAM;AAAA,MACxC,GAAG;AAAA,IACL;AAAA,EACF;AAGA,mBAAiB,eAAe,OAAO,CAAC,KAAK,YAAY;AACvD,QAAI,IAAI,WAAW;AAAG,aAAO,CAAC,OAAO;AAErC,UAAM,cAAc,IAAI,IAAI,SAAS,CAAC;AACtC,QAAI,YAAY,SAAS,QAAQ,MAAM;AACrC,YAAM,cAAc,MAAM,QAAQ,YAAY,OAAO,IACjD,YAAY,UACZ,CAAC,EAAE,MAAM,QAAiB,MAAM,YAAY,QAAQ,CAAC;AACzD,YAAM,aAAa,MAAM,QAAQ,QAAQ,OAAO,IAC5C,QAAQ,UACR,CAAC,EAAE,MAAM,QAAiB,MAAM,QAAQ,QAAQ,CAAC;AAErD,kBAAY,UAAU;AAAA,QACpB,GAAG;AAAA,QACH,EAAE,MAAM,QAAQ,MAAM,cAAc;AAAA,QACpC,GAAG;AAAA,MACL;AACA,aAAO;AAAA,IACT;AAGA,QAAI,OAAO,QAAQ,YAAY,UAAU;AACvC,cAAQ,UAAU,CAAC,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,IAC5D;AAEA,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB,GAAG,CAAC,CAAyB;AAG7B,QAAI,oBAAe,eAAe,SAAS,CAAC,MAAxC,mBAA2C,UAAS,aAAa;AACnE,mBAAe,KAAK,EAAE,MAAM,QAAQ,SAAS,MAAM,CAAC;AAAA,EACtD;AAEA,SAAO;AACT;AAEA,eAAe,wBACb,aACA,SAC6B;AAC7B,QAAM,kBAAsC;AAAA,IAC1C,OAAO,QAAQ;AAAA,IACf,UAAU,CAAC;AAAA,IACX,WAAW,QAAQ;AAAA,IACnB,aAAa,QAAQ;AAAA,EACvB;AAEA,aAAW,WAAW,QAAQ,UAAU;AACtC,QAAI,QAAQ,SAAS,UAAU;AAC7B,sBAAgB,SAAS,QAAQ;AACjC;AAAA,IACF;AAEA,UAAM,gBAAyC,CAAC;AAEhD,QAAI,QAAQ,SAAS;AACnB,oBAAc,KAAK,EAAE,MAAM,QAAQ,MAAM,QAAQ,QAAQ,CAAC;AAAA,IAC5D;AAEA,eAAW,QAAQ,QAAQ,SAAS,CAAC,GAAG;AACtC,UAAI,yBAAyB,SAAS,KAAK,QAAQ,GAAG;AACpD,YAAI,KAAK,KAAK;AACZ,cAAI,QAAQ,QAAQ,QAAQ;AAE1B,0BAAc,KAAK;AAAA,cACjB,MAAM;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY;AAAA,gBACZ,MAAM,MAAM,uBAAuB,KAAK,KAAK,KAAK,QAAQ;AAAA,cAC5D;AAAA,YACF,CAAC;AAAA,UACH;AACA,wBAAc,KAAK,EAAE,MAAM,QAAQ,MAAM,UAAU,KAAK,GAAG,IAAI,CAAC;AAAA,QAClE,WAAW,KAAK,MAAM;AACpB,cAAI,QAAQ,QAAQ,QAAQ;AAE1B,0BAAc,KAAK;AAAA,cACjB,MAAM;AAAA,cACN,QAAQ;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY,KAAK;AAAA,gBACjB,MAAM,KAAK;AAAA,cACb;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AAAA,MACF,WAAW,KAAK,KAAK;AAEnB,sBAAc,KAAK;AAAA,UACjB,MAAM;AAAA,UACN,MAAM,SAAS,KAAK,GAAG;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,oBAAgB,SAAS,KAAK;AAAA,MAC5B,MAAM,QAAQ;AAAA,MACd,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,cACb,IACA,SACA,QACgC;AAhtBlC;AAitBE,QAAM,oBAAoB,qBAAqB,QAAQ,QAAQ;AAC/D,QAAM,SAAQ,aAAQ,cAAR,mBAAmB,IAAI,CAAC,OAAO;AAAA,IAC3C,GAAG;AAAA,IACH,cAAc,EAAE;AAAA,IAChB,YAAY;AAAA,EACd;AAMA,MAAI,+BAAO,QAAQ;AACjB,UAAM,MAAM,SAAS,CAAC,IAAI;AAAA,MACxB,GAAG,MAAM,MAAM,SAAS,CAAC;AAAA,MACzB,eAAe,EAAE,MAAM,YAAY;AAAA,IACrC;AAAA,EACF;AACA,QAAM,SAAS,QAAQ,SACnB;AAAA,IACE;AAAA,MACE,MAAM;AAAA,MACN,MAAM,QAAQ;AAAA,MACd,eAAe,EAAE,MAAM,YAAY;AAAA,IACrC;AAAA,EACF,IACA;AAEJ,MAAI;AAEJ,OAAI,iCAAQ,aAAY,WAAW;AACjC,UAAM,aAAa;AACnB,UAAM,WAAW;AAEjB,UAAM,SAAS,IAAI,qBAAqB,EAAE,QAAQ,WAAW,CAAC;AAC9D,UAAM,iBAAiB;AAAA,MACrB,mBAAmB;AAAA,MACnB,YAAY;AAAA,MACZ,UAAU;AAAA;AAAA,MAEV,OAAO,+BAAO,IAAI,CAAC,EAAE,eAAe,GAAG,EAAE,MAAM;AAAA,IACjD;AAEA,UAAM,WAAW,MAAM,OAAO;AAAA,MAC5B,IAAI,mBAAmB;AAAA,QACrB,aAAa;AAAA,QACb,MAAM,KAAK,UAAU,cAAc;AAAA,QACnC,SAAS;AAAA,MACX,CAAC;AAAA,IACH;AAEA,UAAM,sBAAsB,IAAI,YAAY,EAAE,OAAO,SAAS,IAAI;AAClE,WAAO,KAAK,MAAM,mBAAmB;AAAA,EACvC,OAAO;AAEL,UAAM,WAAW,MAAM,MAAM;AAAA,MAC3B;AAAA,MACA;AAAA,QACE,OAAO,QAAQ;AAAA,QACf,UAAU;AAAA,QACV;AAAA,QACA,aAAa,QAAQ;AAAA,QACrB;AAAA,QACA,YAAY;AAAA,MACd;AAAA,MACA;AAAA,QACE,SAAS;AAAA,UACP,gBAAgB;AAAA,UAChB,aAAa,QAAQ,IAAI;AAAA,UACzB,qBAAqB;AAAA,UACrB,kBAAkB;AAAA,QACpB;AAAA,QACA,SAAS;AAAA,MACX;AAAA,IACF;AACA,WAAO,SAAS;AAAA,EAClB;AAEA,QAAM,UAAU,KAAK;AACrB,MAAI,EAAC,mCAAU,KAAI;AACjB,mBAAO,MAAM,IAAI,6CAA6C,IAAI;AAClE,UAAM,IAAI,MAAM,iCAAiC;AAAA,EACnD;AAEA,MAAI,eAAe;AACnB,QAAM,gBAAgC,CAAC;AAEvC,aAAW,UAAU,SAAS;AAC5B,QAAI,CAAC,OAAO,MAAM;AAChB,qBAAO,MAAM,IAAI,kDAAkD,IAAI;AACvE,YAAM,IAAI,MAAM,sCAAsC;AAAA,IACxD;AAEA,QAAI,OAAO,SAAS,QAAQ;AAC1B,UAAI,OAAO,OAAO,KACf,QAAQ,+BAA+B,EAAE,EACzC,QAAQ,yBAAyB,EAAE,EACnC,KAAK;AAER,UAAI,CAAC,MAAM;AACT,eAAO,OAAO,KAAK;AAAA,UACjB;AAAA,UACA;AAAA,QACF;AACA,uBAAO,IAAI,IAAI,kDAAkD,IAAI;AAAA,MACvE;AAEA,qBAAe,eAAe,GAAG,YAAY;AAAA;AAAA,EAAO,IAAI,KAAK;AAAA,IAC/D,WAAW,OAAO,SAAS,YAAY;AACrC,oBAAc,KAAK;AAAA,QACjB,MAAM,OAAO;AAAA,QACb,WAAW,OAAO;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,MAAI,CAAC,gBAAgB,CAAC,cAAc,QAAQ;AAC1C,mBAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,UAAM,IAAI,MAAM,oDAAoD;AAAA,EACtE;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS;AAAA,IACT,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO,KAAK,SACP,MAAM;AAp1Bf,UAAAC,KAAA;AAw1BU,YAAM,aAAYA,MAAA,KAAK,MAAM,4BAAX,OAAAA,MAAsC;AACxD,YAAM,cAAa,UAAK,MAAM,gCAAX,YAA0C;AAC7D,YAAM,eAAe,KAAK,MAAM,eAAe,YAAY;AAC3D,aAAO;AAAA,QACL,eAAe;AAAA,QACf,mBAAmB,KAAK,MAAM;AAAA,QAC9B,cAAc,eAAe,KAAK,MAAM;AAAA,QACxC,eAAe;AAAA,MACjB;AAAA,IACF,GAAG,IACH;AAAA,EACN;AACF;AAEA,eAAe,yBACb,IACA,SACA,QACA,UAAkB,GACc;AAChC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,cAAc,IAAI,SAAS,MAAM;AAAA,IACvC;AAAA,MACE;AAAA,IACF;AAAA,EACF;AACF;AAMA,SAAS,kBAAkB,UAAgD;AA13B3E;AA23BE,MAAI,iBAAiB,SAAS,MAAM;AAGpC,QAAI,oBAAe,CAAC,MAAhB,mBAAmB,UAAS,SAAS;AACvC,qBAAiB;AAAA,MACf,EAAE,MAAM,QAAiB,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,EAAE;AAAA,MAClD,GAAG;AAAA,IACL;AAAA,EACF;AAGA,mBAAiB,eAAe,OAAO,CAAC,KAAK,YAAY;AACvD,QAAI,IAAI,WAAW;AAAG,aAAO,CAAC,OAAO;AAErC,UAAM,cAAc,IAAI,IAAI,SAAS,CAAC;AACtC,QAAI,YAAY,SAAS,QAAQ,MAAM;AACrC,kBAAY,QAAQ,CAAC,GAAG,YAAY,OAAO,GAAG,QAAQ,KAAK;AAC3D,aAAO;AAAA,IACT;AAEA,WAAO,CAAC,GAAG,KAAK,OAAO;AAAA,EACzB,GAAG,CAAC,CAAsB;AAG1B,QAAI,oBAAe,eAAe,SAAS,CAAC,MAAxC,mBAA2C,UAAS,SAAS;AAC/D,mBAAe,KAAK,EAAE,MAAM,QAAQ,OAAO,CAAC,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC;AAAA,EAChE;AAEA,SAAO;AACT;AAEA,eAAe,uBACb,aACA,SAC0B;AAC1B,QAAM,kBAAmC;AAAA,IACvC,OAAO,QAAQ;AAAA,IACf,UAAU,CAAC;AAAA,IACX,OAAO,QAAQ,YACX;AAAA,MACE,sBAAsB,QAAQ,UAAU,IAAI,CAAC,QAAQ;AAAA,QACnD,MAAM,GAAG;AAAA,QACT,YAAY;AAAA,UACV,aAAa,GAAG;AAAA,UAChB,GAAG,GAAG;AAAA,QACR;AAAA,MACF,EAAE;AAAA,IACJ,IACA;AAAA,EACN;AAEA,aAAW,WAAW,QAAQ,UAAU;AACtC,QAAI,QAAQ,SAAS,UAAU;AAC7B,sBAAgB,oBAAoB,QAAQ;AAC5C;AAAA,IACF;AAEA,UAAM,QAAwB,CAAC;AAE/B,QAAI,QAAQ,SAAS;AACnB,YAAM,KAAK,EAAE,MAAM,QAAQ,QAAQ,CAAC;AAAA,IACtC;AAEA,eAAW,QAAQ,QAAQ,SAAS,CAAC,GAAG;AACtC,UAAI,yBAAyB,SAAS,KAAK,QAAQ,GAAG;AACpD,YAAI,KAAK,KAAK;AACZ,gBAAM,KAAK;AAAA,YACT,UAAU;AAAA,cACR,UAAU,KAAK;AAAA,cACf,SAAS,KAAK;AAAA,YAChB;AAAA,UACF,CAAC;AACD,gBAAM,KAAK,EAAE,MAAM,UAAU,KAAK,GAAG,IAAI,CAAC;AAAA,QAC5C,WAAW,KAAK,MAAM;AACpB,gBAAM,KAAK;AAAA,YACT,YAAY;AAAA,cACV,UAAU,KAAK;AAAA,cACf,MAAM,KAAK;AAAA,YACb;AAAA,UACF,CAAC;AAAA,QACH;AAAA,MACF,WAAW,KAAK,KAAK;AAEnB,cAAM,KAAK;AAAA,UACT,MAAM,SAAS,KAAK,GAAG;AAAA,QACzB,CAAC;AAAA,MACH;AAAA,IACF;AAEA,oBAAgB,SAAS,KAAK;AAAA,MAC5B,MAAM,QAAQ,SAAS,cAAc,UAAU,QAAQ;AAAA,MACvD;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,aACb,IACA,SACgC;AAh+BlC;AAi+BE,QAAM,iBAAiB,kBAAkB,QAAQ,QAAQ;AACzD,QAAM,UAAU,eAAe,MAAM,GAAG,EAAE;AAC1C,QAAM,cAAc,eAAe,MAAM,EAAE,EAAE,CAAC;AAE9C,QAAM,QAAQ,IAAI,YAAY,EAAE,QAAQ,QAAQ,IAAI,eAAe,CAAC;AAEpE,QAAM,OAAO,MAAM,MAAM,OAAO;AAAA,IAC9B,OAAO,QAAQ;AAAA,IACf;AAAA,IACA,QAAQ;AAAA,MACN,oBAAoB,CAAC,MAAM;AAAA,MAC3B,OAAO,QAAQ,QAAQ,CAAC,QAAQ,KAAK,IAAI;AAAA,MACzC,mBAAmB,QAAQ;AAAA,IAC7B;AAAA,EACF,CAAC;AAED,QAAM,WAAW,MAAM,KAAK,YAAY,EAAE,SAAS,YAAY,MAAM,CAAC;AAEtE,MAAI,OAAO;AACX,QAAM,QAAgB,CAAC;AAEvB,aAAW,UAAQ,0BAAS,eAAT,mBAAsB,OAAtB,mBAA0B,YAA1B,mBAAmC,UAAS,CAAC,GAAG;AACjE,QAAI,KAAK;AAAM,cAAQ,KAAK;AAC5B,SAAI,UAAK,eAAL,mBAAiB,MAAM;AACzB,YAAM,KAAK,EAAE,UAAU,aAAa,MAAM,KAAK,WAAW,KAAK,CAAC;AAAA,IAClE;AAAA,EACF;AAEA,QAAM,iBAAgB,cAAS,kBAAT,mBAAwB,IAAI,CAAC,OAAI;AA7/BzD,QAAAA,KAAAC;AA6/B6D;AAAA,MACzD,OAAMD,MAAA,GAAG,SAAH,OAAAA,MAAW;AAAA,MACjB,YAAWC,MAAA,GAAG,SAAH,OAAAA,MAAW,CAAC;AAAA,IACzB;AAAA;AAEA,MAAI,CAAC,QAAQ,EAAC,+CAAe,WAAU,CAAC,MAAM,QAAQ;AACpD,UAAM,aAAY,cAAS,eAAT,mBAAsB;AACxC,UAAM,eAAe,uCAAW;AAEhC,mBAAO,MAAM,IAAI,uDAAuD;AAAA,MACtE;AAAA,MACA,eAAe,uCAAW;AAAA,MAC1B,eAAe,SAAS;AAAA,MACxB,cAAc,SAAS;AAAA,MACvB,kBAAkB,uCAAW;AAAA,MAC7B,gBAAgB,SAAS;AAAA,IAC3B,CAAC;AAED,QAAI,eAAe;AACnB,QAAI,cAAc;AAChB,YAAM,qBAA6C;AAAA,QACjD,yBACE;AAAA,QACF,QAAQ;AAAA,QACR,YAAY;AAAA,QACZ,YAAY;AAAA,MACd;AACA,sBAAgB,kBAAkB,YAAY,IAAI,mBAAmB,YAAY,KAAK,EAAE;AAAA,IAC1F;AAEA,UAAMF,SAAQ,IAAI,MAAM,YAAY;AACpC,IAAAA,OAAM,eAAe;AACrB,IAAAA,OAAM,gBAAgB,uCAAW;AACjC,IAAAA,OAAM,gBAAgB,SAAS;AAC/B,IAAAA,OAAM,iBAAiB,SAAS;AAChC,UAAMA;AAAA,EACR;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,QAAQ;AAAA,IACjB;AAAA,IACA,gBAAe,+CAAgB,OAAM;AAAA,IACrC,gBAAgB,iBAAiB,CAAC;AAAA,IAClC,OAAO,SAAS,gBACZ;AAAA,MACE,gBAAe,cAAS,cAAc,qBAAvB,YAA2C;AAAA,MAC1D,oBAAmB,cAAS,cAAc,yBAAvB,YAA+C;AAAA,MAClE,eAAc,cAAS,cAAc,oBAAvB,YAA0C;AAAA,MACxD,gBAAe,cAAS,cAAc,4BAAvB,YAAkD;AAAA,IACnE,IACA;AAAA,EACN;AACF;AAMA,IAAM,4BAA4B,oBAAI,IAAI,CAAC,sBAAsB,QAAQ,CAAC;AAM1E,SAAS,8BAA8B,SAAmC;AACxE,MAAI,gBAAgB;AAEpB,aAAW,WAAW,QAAQ,UAAU;AACtC,YAAQ,QAAQ,QAAQ,MAAM,OAAO,CAAC,SAAS;AAC7C,UAAI,gBAAgB,QAAQ,cAAc,MAAM;AAC9C,wBAAgB;AAChB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC;AAGD,QAAI,QAAQ,MAAM,WAAW,GAAG;AAC9B,cAAQ,QAAQ,CAAC,EAAE,MAAM,wCAAwC,CAAC;AAAA,IACpE;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAe,wBACb,IACA,SACA,UAAkB,GACc;AAChC,MAAI,wBAAwB;AAE5B,SAAO,YAAY,IAAI,aAAa,MAAM,aAAa,IAAI,OAAO,GAAG;AAAA,IACnE;AAAA,IACA,SAAS,CAACA,QAAO,YAAY;AA5lCjC;AA6lCM,YAAM,eAAoC;AAAA,QACxC,SAASA,OAAM;AAAA,QACf,cAAcA,OAAM;AAAA,QACpB,cAAcA,OAAM;AAAA,MACtB;AAEA,UAAIA,OAAM;AAAe,qBAAa,gBAAgBA,OAAM;AAC5D,UAAIA,OAAM;AAAe,qBAAa,gBAAgBA,OAAM;AAC5D,UAAIA,OAAM;AACR,qBAAa,iBAAiBA,OAAM;AACtC,UAAIA,OAAM;AAAQ,qBAAa,aAAaA,OAAM;AAClD,UAAIA,OAAM;AAAM,qBAAa,YAAYA,OAAM;AAC/C,UAAIA,OAAM;AAAS,qBAAa,eAAeA,OAAM;AAErD,YAAM,WAAW,QAAQ,SACtB,QAAQ,CAAC,MAAM,EAAE,KAAK,EACtB,OAAO,CAAC,MAAM,cAAc,CAAC,EAC7B,IAAI,CAAC,MAAO,EAAU,SAAS,OAAO;AACzC,UAAI,SAAS;AAAQ,qBAAa,WAAW;AAE7C,qBAAO;AAAA,QACL;AAAA,QACA,UAAU,OAAO,WAAWA,OAAM,OAAO;AAAA,QACzC;AAAA,MACF;AAIA,YAAM,kBACH,0BAA0B,IAAIA,OAAM,YAAY,KAC/CA,OAAM,gBACP,0BAA0B,KAAI,KAAAA,OAAM,mBAAN,mBAAsB,WAAW,OAC9D,KAAAA,OAAM,mBAAN,mBAAsB;AAE1B,UAAI,iBAAiB;AACnB,YAAI,CAAC,uBAAuB;AAC1B,gBAAM,gBAAgB,8BAA8B,OAAO;AAC3D,cAAI,eAAe;AACjB,2BAAO;AAAA,cACL;AAAA,cACA,qDAAqD,eAAe;AAAA,YACtE;AACA,oCAAwB;AACxB;AAAA,UACF;AAAA,QACF;AAGA,uBAAO;AAAA,UACL;AAAA,UACA,wCAAwC,eAAe;AAAA,QACzD;AACA,cAAM,sBAAsB,IAAI;AAAA,UAC9B,gCAAgC,eAAe;AAAA,QACjD;AACA,4BAAoB,eAAeA,OAAM;AACzC,4BAAoB,gBAAgBA,OAAM;AAC1C,4BAAoB,gBAAgBA,OAAM;AAC1C,4BAAoB,iBAAiB;AACrC,cAAM;AAAA,MACR;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAMA,SAAS,wBACP,SACQ;AACR,SAAO,MAAM,QAAQ,OAAO,IACxB,QACG,IAAI,CAAC,MAAO,EAAE,SAAS,SAAS,EAAE,OAAO,IAAI,EAAE,IAAI,GAAI,EACvD,KAAK,IAAI,IACZ;AACN;AAEA,SAAS,mBAAmB,SAAsC;AA5qClE;AA6qCE,SAAO;AAAA,IACL,OAAO,QAAQ;AAAA,IACf,UAAU,QAAQ,SAAS,IAAI,CAAC,aAAa;AAAA,MAC3C,MAAM,QAAQ;AAAA,MACd,SAAS,wBAAwB,QAAQ,OAAO;AAAA,IAClD,EAAE;AAAA,IACF,QAAO,aAAQ,cAAR,mBAAmB,IAAI,CAAC,QAAQ;AAAA,MACrC,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,aAAa,QAAQ,gBACjB,OAAO,QAAQ,kBAAkB,WAC/B,QAAQ,gBACR,EAAE,MAAM,YAAY,UAAU,QAAQ,cAAc,IACtD;AAAA,IACJ,aAAa,QAAQ;AAAA,EACvB;AACF;AAEA,eAAe,SACb,IACA,SACgC;AAnsClC;AAosCE,QAAM,WAAW,MAAM,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,QAAQ,IAAI,YAAY;AAAA,MACnD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAS,cAAS,KAAK,QAAQ,CAAC,MAAvB,mBAA0B;AACzC,MAAI,CAAC,QAAQ;AACX,mBAAO,MAAM,IAAI,wCAAwC,SAAS,IAAI;AACtE,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAEA,QAAM,gBAAgC,CAAC;AACvC,OAAI,YAAO,eAAP,mBAAmB,QAAQ;AAC7B,eAAW,MAAM,OAAO,YAAY;AAClC,oBAAc,KAAK;AAAA,QACjB,MAAM,GAAG,SAAS;AAAA,QAClB,WAAW,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,OAAO,WAAW;AAAA,IAC3B,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO,SAAS,KAAK,QACjB;AAAA,MACE,eAAe,SAAS,KAAK,MAAM;AAAA,MACnC,mBAAmB,SAAS,KAAK,MAAM;AAAA,MACvC,cAAc,SAAS,KAAK,MAAM;AAAA,MAClC,gBACE,oBAAS,KAAK,MAAM,0BAApB,mBAA2C,kBAA3C,YAA4D;AAAA,IAChE,IACA;AAAA,EACN;AACF;AAEA,eAAe,oBACb,IACA,SACA,UAAkB,GACc;AAChC,SAAO,YAAY,IAAI,QAAQ,MAAM,SAAS,IAAI,OAAO,GAAG,EAAE,QAAQ,CAAC;AACzE;AAMA,SAAS,yBAAyB,SAA4C;AA7vC9E;AA8vCE,SAAO;AAAA,IACL,OAAO,QAAQ;AAAA,IACf,UAAU,QAAQ,SAAS,IAAI,CAAC,aAAa;AAAA,MAC3C,MAAM,QAAQ;AAAA,MACd,SAAS,wBAAwB,QAAQ,OAAO;AAAA,IAClD,EAAE;AAAA,IACF,QAAO,aAAQ,cAAR,mBAAmB,IAAI,CAAC,QAAQ;AAAA,MACrC,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA,aAAa,QAAQ,gBACjB,OAAO,QAAQ,kBAAkB,WAC/B,QAAQ,gBACR,EAAE,MAAM,YAAY,UAAU,QAAQ,cAAc,IACtD;AAAA,IACJ,aAAa,QAAQ;AAAA,EACvB;AACF;AAEA,eAAe,eACb,IACA,SACgC;AApxClC;AAqxCE,QAAM,WAAW,MAAM,MAAM;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,MACE,SAAS;AAAA,QACP,gBAAgB;AAAA,QAChB,eAAe,UAAU,QAAQ,IAAI,kBAAkB;AAAA,MACzD;AAAA,IACF;AAAA,EACF;AAEA,QAAM,UAAS,cAAS,KAAK,QAAQ,CAAC,MAAvB,mBAA0B;AACzC,MAAI,CAAC,QAAQ;AACX,mBAAO,MAAM,IAAI,8CAA8C,SAAS,IAAI;AAC5E,UAAM,IAAI,MAAM,kCAAkC;AAAA,EACpD;AAEA,QAAM,gBAAgC,CAAC;AACvC,OAAI,YAAO,eAAP,mBAAmB,QAAQ;AAC7B,eAAW,MAAM,OAAO,YAAY;AAClC,oBAAc,KAAK;AAAA,QACjB,MAAM,GAAG,SAAS;AAAA,QAClB,WAAW,KAAK,MAAM,GAAG,SAAS,SAAS;AAAA,MAC7C,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM;AAAA,IACN,SAAS,OAAO,WAAW;AAAA,IAC3B,eAAe,cAAc,CAAC,KAAK;AAAA,IACnC,gBAAgB;AAAA,IAChB,OAAO,CAAC;AAAA,IACR,OAAO,SAAS,KAAK,QACjB;AAAA,MACE,eAAe,SAAS,KAAK,MAAM;AAAA,MACnC,mBAAmB,SAAS,KAAK,MAAM;AAAA,MACvC,cAAc,SAAS,KAAK,MAAM;AAAA,MAClC,gBACE,oBAAS,KAAK,MAAM,0BAApB,mBAA2C,kBAA3C,YAA4D;AAAA,IAChE,IACA;AAAA,EACN;AACF;AAEA,eAAe,0BACb,IACA,SACA,UAAkB,GACc;AAChC,SAAO,YAAY,IAAI,cAAc,MAAM,eAAe,IAAI,OAAO,GAAG,EAAE,QAAQ,CAAC;AACrF;AAMA,IAAM,kBAA8B,CAAC,UAAU,aAAa,UAAU,QAAQ,YAAY;AAE1F,IAAM,oBAAmE;AAAA,EACvE,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,QAAQ,CAAC,GAAG,UAAU,SAAS;AAAA,EAC/D,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,WAAW,CAAC,GAAG,UAAU,YAAY;AAAA,EACrE,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,WAAW,CAAC,GAAG,UAAU,SAAS;AAAA,EAClE,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,SAAS,CAAC,GAAG,UAAU,OAAO;AAAA,EAC9D,EAAE,QAAQ,IAAI,IAAI,OAAO,OAAO,eAAe,CAAC,GAAG,UAAU,aAAa;AAC5E;AAEO,SAAS,iBAAiB,OAAwD;AACvF,QAAM,aAAa,MAAM,QAAQ,GAAG;AAEpC,MAAI,eAAe,IAAI;AACrB,UAAM,SAAS,MAAM,UAAU,GAAG,UAAU;AAE5C,QAAI,gBAAgB,SAAS,MAAkB,GAAG;AAChD,YAAM,UAAU,MAAM,UAAU,aAAa,CAAC;AAE9C,UAAI,CAAC,SAAS;AACZ,cAAM,IAAI;AAAA,UACR,mCAAmC,KAAK;AAAA,QAC1C;AAAA,MACF;AAEA,aAAO,EAAE,UAAU,QAAoB,QAAQ;AAAA,IACjD;AAAA,EAIF;AAGA,aAAW,EAAE,QAAQ,SAAS,KAAK,mBAAmB;AACpD,QAAI,OAAO,IAAI,KAAK,GAAG;AACrB,aAAO,EAAE,UAAU,SAAS,MAAM;AAAA,IACpC;AAAA,EACF;AAGA,MAAI,eAAe,IAAI;AACrB,UAAM,SAAS,MAAM,UAAU,GAAG,UAAU;AAC5C,UAAM,IAAI;AAAA,MACR,qBAAqB,MAAM,sBAAsB,KAAK,uBAAuB,gBAAgB,KAAK,IAAI,CAAC;AAAA,IACzG;AAAA,EACF;AAEA,QAAM,IAAI;AAAA,IACR,2CAA2C,KAAK,0CAA0C,KAAK,oDAAoD,gBAAgB,KAAK,IAAI,CAAC;AAAA,EAC/K;AACF;AAEA,eAAsB,gBACpB,IACA,WACA,UACA,UAAkB,GAClB,iBAAyB,MACO;AAChC,MAAI;AACF,UAAM,EAAE,UAAU,QAAQ,IAAI,iBAAiB,UAAU,KAAK;AAC9D,UAAM,iBAAiB,EAAE,GAAG,WAAW,OAAO,QAAoB;AAElE,YAAQ,UAAU;AAAA,MAChB,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,MAAM,wBAAwB,IAAI,cAAc;AAAA,UAChD;AAAA,UACA;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,MAAM,qBAAqB,IAAI,cAAc;AAAA,UAC7C;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,mBAAmB,cAAc;AAAA,UACjC;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,MAAM,uBAAuB,IAAI,cAAc;AAAA,UAC/C;AAAA,QACF;AAAA,MAEF,KAAK;AACH,eAAO,MAAM;AAAA,UACX;AAAA,UACA,yBAAyB,cAAc;AAAA,UACvC;AAAA,QACF;AAAA,IACJ;AAAA,EACF,SAASA,QAAO;AACd,QAAI,UAAU,eAAe;AAC3B,qBAAO;AAAA,QACL;AAAA,QACA,iBAAiB,UAAU,KAAK,4BAA4B,UAAU,aAAa;AAAA,QACnF;AAAA,UACE,OAAOA,kBAAiB,QAAQA,OAAM,UAAUA;AAAA,UAChD,OACEA,kBAAiB,SAAUA,OAAc,iBAAiB,QACrDA,OAAc,MAAM,UACrB;AAAA,QACR;AAAA,MACF;AACA,aAAO;AAAA,QACL;AAAA,QACA;AAAA,UACE,GAAG;AAAA,UACH,OAAO,UAAU;AAAA,UACjB,eAAe;AAAA,QACjB;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AACA,UAAMA;AAAA,EACR;AACF;","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\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 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 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 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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "190proof",
3
- "version": "1.0.92",
3
+ "version": "1.0.94",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",