From 371c10ea5f1184ffcb74d71f6bec15885c2dfe28 Mon Sep 17 00:00:00 2001 From: Diego Rodrigues de Sa e Souza Date: Fri, 31 Jul 2026 07:53:41 -0300 Subject: [PATCH] =?UTF-8?q?feat(sse):=20Cheaper=20Inference=20provider=20?= =?UTF-8?q?=E2=80=94=20chat=20+=20native=20Responses=20+=20images,=20spons?= =?UTF-8?q?or=20rail=202nd=20(#9043)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Registers Cheaper Inference (api.cheaperinference.com) as an OSS-sponsor gateway provider. - Canonical provider `cheaperinference` (alias `cinf`) + routing registry with 39 measured text models - Dedicated executor: forces `store:false` on the native /v1/responses endpoint (the shared strip in chatCore.ts deletes `store` for every provider != openai, so without this every Responses request 400'd) and resolves chat-vs-responses URL from the per-model targetFormat - 3 image models (grok-imagine, nano-banana-pro, nano-banana-2), prefix-only: the two nano-banana ids already belong to adobe-firefly, which keeps the bare-id routing - Resale pricing measured from GET /v1/models (30% off list); sponsor rail Kimi 1st / Cheaper Inference 2nd via an explicit rank map; supporter badge in 43 locales; README row No quota card: the gateway exposes no balance API (/v1/wallet and /v1/balance both 404). Validated live end-to-end through OmniRoute: chat, native Responses, streaming and image generation all 200 with real content; the Firefly collision guard verified at runtime. --- README.md | 14 + open-sse/config/imageRegistry.ts | 8 + open-sse/config/providers/index.ts | 2 + .../registry/cheaperinference/imageModels.ts | 34 +++ .../registry/cheaperinference/index.ts | 247 ++++++++++++++++++ open-sse/executors/cheaperinference.ts | 69 +++++ open-sse/executors/index.ts | 4 + public/providers/cheaperinference.svg | 7 + .../providers/components/ProviderCard.tsx | 36 ++- .../dashboard/providers/featuredProviders.ts | 64 ++++- .../dashboard/providers/providerPageUtils.ts | 27 +- src/i18n/messages/ar.json | 2 + src/i18n/messages/az.json | 2 + src/i18n/messages/bg.json | 2 + src/i18n/messages/bn.json | 2 + src/i18n/messages/cs.json | 2 + src/i18n/messages/da.json | 2 + src/i18n/messages/de.json | 2 + src/i18n/messages/en.json | 2 + src/i18n/messages/es.json | 2 + src/i18n/messages/fa.json | 2 + src/i18n/messages/fi.json | 2 + src/i18n/messages/fr.json | 2 + src/i18n/messages/gu.json | 2 + src/i18n/messages/he.json | 2 + src/i18n/messages/hi.json | 2 + src/i18n/messages/hu.json | 2 + src/i18n/messages/id.json | 2 + src/i18n/messages/in.json | 2 + src/i18n/messages/it.json | 2 + src/i18n/messages/ja.json | 2 + src/i18n/messages/ko.json | 2 + src/i18n/messages/mr.json | 2 + src/i18n/messages/ms.json | 2 + src/i18n/messages/nl.json | 2 + src/i18n/messages/no.json | 2 + src/i18n/messages/phi.json | 2 + src/i18n/messages/pl.json | 2 + src/i18n/messages/pt-BR.json | 2 + src/i18n/messages/pt.json | 2 + src/i18n/messages/ro.json | 2 + src/i18n/messages/ru.json | 2 + src/i18n/messages/sk.json | 2 + src/i18n/messages/sv.json | 2 + src/i18n/messages/sw.json | 2 + src/i18n/messages/ta.json | 2 + src/i18n/messages/te.json | 2 + src/i18n/messages/th.json | 2 + src/i18n/messages/tr.json | 2 + src/i18n/messages/uk-UA.json | 2 + src/i18n/messages/ur.json | 2 + src/i18n/messages/vi.json | 2 + src/i18n/messages/zh-CN.json | 2 + src/i18n/messages/zh-TW.json | 2 + src/shared/components/ProviderIcon.tsx | 1 + src/shared/constants/colors.ts | 2 + .../constants/pricing/inference-hosts.ts | 214 +++++++++++++++ .../constants/providers/apikey/gateways.ts | 16 ++ tests/snapshots/provider/translate-path.json | 23 ++ tests/unit/cheaperinference-executor.test.ts | 88 +++++++ .../cheaperinference-image-models.test.ts | 53 ++++ ...perinference-provider-registration.test.ts | 110 ++++++++ tests/unit/featured-providers-rank.test.ts | 72 +++++ tests/unit/providers-constants-split.test.ts | 15 +- 64 files changed, 1162 insertions(+), 30 deletions(-) create mode 100644 open-sse/config/providers/registry/cheaperinference/imageModels.ts create mode 100644 open-sse/config/providers/registry/cheaperinference/index.ts create mode 100644 open-sse/executors/cheaperinference.ts create mode 100644 public/providers/cheaperinference.svg create mode 100644 tests/unit/cheaperinference-executor.test.ts create mode 100644 tests/unit/cheaperinference-image-models.test.ts create mode 100644 tests/unit/cheaperinference-provider-registration.test.ts create mode 100644 tests/unit/featured-providers-rank.test.ts diff --git a/README.md b/README.md index 2f89a9a7e7..1d3d70c507 100644 --- a/README.md +++ b/README.md @@ -241,6 +241,20 @@ curl http://localhost:20128/v1/chat/completions \ What Kimi's support powers: Kimi's API credits power OmniRoute's AI-validated release pipeline — the merge validation powered by Kimi K3 stage that reviews every pull request before it ships — plus day-to-day feature development. First-class Kimi support ships on both rails: the direct Kimi API (kimi-k3) and the Kimi Code coding plan (OAuth and API key). OmniRoute is also the first Brazilian open-source project in Kimi's support program. Get a Kimi API key → + + + + Cheaper Inference + +
Cheaper Inference
cheaperinference.com

+ Open Source Friend + + + Thanks to Cheaper Inference, an OmniRoute Open Source Friend, for backing this project! Cheaper Inference is a cost-ranked gateway that resells 42 frontier models — Claude, GPT-5.x, Gemini, Kimi K3, GLM, DeepSeek, Grok and MiniMax — behind one OpenAI-compatible endpoint, routing each request to the cheapest eligible provider without ever charging above the model maker's list price. +

+ First-class support in OmniRoute: Chat Completions, the native /v1/responses endpoint, vision, tool calling and 3 image models (grok-imagine, nano-banana-pro, nano-banana-2, reachable as cheaperinference/<model>). Get an API key → + + Links tagged aff=omniroute are partner links. They fund the project at no extra cost to you. diff --git a/open-sse/config/imageRegistry.ts b/open-sse/config/imageRegistry.ts index 5676a9450e..becb18e008 100644 --- a/open-sse/config/imageRegistry.ts +++ b/open-sse/config/imageRegistry.ts @@ -11,6 +11,7 @@ import { KIE_IMAGE_MODELS } from "./providers/registry/kie/imageModels.ts"; import { FREEPIK_IMAGE_PROVIDER } from "./providers/registry/freepik/index.ts"; import { STABILITY_AI_IMAGE_MODELS } from "./providers/registry/stability-ai/imageModels.ts"; import { GEMINI_IMAGEN_PROVIDER } from "./providers/registry/gemini/imageModels.ts"; +import { CHEAPERINFERENCE_IMAGE_PROVIDER } from "./providers/registry/cheaperinference/imageModels.ts"; interface ImageModelEntry { id: string; @@ -714,6 +715,13 @@ export const IMAGE_PROVIDERS: Record = { supportedSizes: ["1:1", "16:9", "9:16", "4:3", "3:4", "1024x1024", "1792x1024", "1024x1792"], }, + // Cheaper Inference (OSS-sponsor gateway). Declared AFTER adobe-firefly on + // purpose: it shares the nano-banana-pro / nano-banana-2 ids, and parseImageModel + // resolves a bare id by first-match over this object's iteration order, so + // Firefly keeps the bare ids and these are prefix-only. See the module for the + // full collision note. + cheaperinference: CHEAPERINFERENCE_IMAGE_PROVIDER, + // Keep Bailian Coding Plan after existing duplicate model owners so adding // explicit `bailian-coding-plan/` and `bcp/` routes does not change // historical bare-model routing. diff --git a/open-sse/config/providers/index.ts b/open-sse/config/providers/index.ts index 1769f1aa13..e586b42301 100644 --- a/open-sse/config/providers/index.ts +++ b/open-sse/config/providers/index.ts @@ -117,6 +117,7 @@ import { uncloseaiProvider } from "./registry/uncloseai/index.ts"; import { nscaleProvider } from "./registry/nscale/index.ts"; import { chatgpt_webProvider } from "./registry/chatgpt-web/index.ts"; import { openrouterProvider } from "./registry/openrouter/index.ts"; +import { cheaperinferenceProvider } from "./registry/cheaperinference/index.ts"; import { openvectaProvider } from "./registry/openvecta/index.ts"; import { orcarouterProvider } from "./registry/orcarouter/index.ts"; import { copilot_webProvider } from "./registry/copilot-web/index.ts"; @@ -337,6 +338,7 @@ export const REGISTRY: Record = { nscale: nscaleProvider, "chatgpt-web": chatgpt_webProvider, openrouter: openrouterProvider, + cheaperinference: cheaperinferenceProvider, openvecta: openvectaProvider, orcarouter: orcarouterProvider, "copilot-web": copilot_webProvider, diff --git a/open-sse/config/providers/registry/cheaperinference/imageModels.ts b/open-sse/config/providers/registry/cheaperinference/imageModels.ts new file mode 100644 index 0000000000..8fe3a58e8e --- /dev/null +++ b/open-sse/config/providers/registry/cheaperinference/imageModels.ts @@ -0,0 +1,34 @@ +/** + * Cheaper Inference image provider registry entry. + * Extracted into its own module to keep open-sse/config/imageRegistry.ts + * under the file-size cap (god-file decomposition; semantic split) — same + * pattern as FREEPIK_IMAGE_PROVIDER / SEGMIND_IMAGE_PROVIDER. + * + * 3 image models measured from GET /v1/models?type=image on 2026-07-31. + * + * COLLISION NOTE: nano-banana-pro and nano-banana-2 are ALSO adobe-firefly model + * ids. parseImageModel() resolves a bare id by first-match over IMAGE_PROVIDERS + * iteration order, so this entry is spread into that object AFTER adobe-firefly: + * bare `nano-banana-2` keeps routing to Firefly (pre-existing behaviour) and these + * models are reachable only as `cheaperinference/` / `cinf/`. Do NOT add + * IMAGE_MODEL_ALIASES entries for them — that would silently re-route Firefly + * users. Guarded by tests/unit/cheaperinference-image-models.test.ts. + * + * The endpoint ignores `response_format:"url"` and always returns `b64_json` + * (measured twice). The OpenAI image path already handles b64_json; this is not a + * bug to "fix". /v1/images/edits returns 404 upstream, so no edit support. + */ +export const CHEAPERINFERENCE_IMAGE_PROVIDER = { + id: "cheaperinference", + alias: "cinf", + baseUrl: "https://api.cheaperinference.com/v1/images/generations", + authType: "apikey", + authHeader: "bearer", + format: "openai", + models: [ + { id: "grok-imagine", name: "Grok Imagine (Cheaper Inference)" }, + { id: "nano-banana-pro", name: "Nano Banana Pro (Cheaper Inference)" }, + { id: "nano-banana-2", name: "Nano Banana 2 (Cheaper Inference)" }, + ], + supportedSizes: ["1024x1024", "2048x2048", "4096x4096"], +}; diff --git a/open-sse/config/providers/registry/cheaperinference/index.ts b/open-sse/config/providers/registry/cheaperinference/index.ts new file mode 100644 index 0000000000..7bab005d36 --- /dev/null +++ b/open-sse/config/providers/registry/cheaperinference/index.ts @@ -0,0 +1,247 @@ +import type { RegistryEntry, RegistryModel } from "../../shared.ts"; + +/** + * Cheaper Inference (https://api.cheaperinference.com) — cost-ranked OpenAI-compatible + * gateway, OmniRoute Open Source Friend. + * + * Catalog captured from a live `GET /v1/models` on 2026-07-31 (42 entries: these 39 + * `type:"text"` models plus 3 `type:"image"` models that live in imageRegistry.ts — + * sending an image model here returns HTTP 400 "Use POST /v1/images/generations"). + * `supportsVision`/`supportsReasoning` mirror each entry's `capabilities` object + * verbatim; they are not inferred from the model name. + * + * The gateway also serves a native `/v1/responses` endpoint (`responsesBaseUrl`). + * It is stateless and REQUIRES `store:false` — see executors/cheaperinference.ts, + * which injects it and resolves the URL from the per-model `targetFormat` tag. + */ +export const CHEAPERINFERENCE_MODELS: RegistryModel[] = [ + { id: "aion-labs.aion-2-0", name: "Aion 2.0", supportsReasoning: true, toolCalling: true }, + { + id: "claude-fable-5", + name: "Claude Fable 5", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-haiku-4.5", + name: "Claude Haiku 4.5", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-opus-4-7-fast", + name: "Claude Opus 4.7 Fast", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-opus-4-8-fast", + name: "Claude Opus 4.8 Fast", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-opus-4.5", + name: "Claude Opus 4.5", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-opus-4.6", + name: "Claude Opus 4.6", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-opus-4.7", + name: "Claude Opus 4.7", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-opus-4.8", + name: "Claude Opus 4.8", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-opus-5", + name: "Claude Opus 5", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-opus-5-fast", + name: "Claude Opus 5 Fast", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-sonnet-4.5", + name: "Claude Sonnet 4.5", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-sonnet-4.6", + name: "Claude Sonnet 4.6", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "claude-sonnet-5", + name: "Claude Sonnet 5", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { id: "deepseek-v4-flash", name: "DeepSeek V4 Flash", supportsReasoning: true, toolCalling: true }, + { id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", supportsReasoning: true, toolCalling: true }, + { + id: "gemini-2.5-flash", + name: "Gemini 2.5 Flash", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "gemini-3-5-flash", + name: "Gemini 3.5 Flash", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "gemini-3-flash-preview", + name: "Gemini 3 Flash Preview", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "gemini-3.1-flash-lite", + name: "Gemini 3.1 Flash Lite", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "gemini-3.1-pro", + name: "Gemini 3.1 Pro", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "gemini-3.1-pro-preview", + name: "Gemini 3.1 Pro Preview", + supportsReasoning: true, + toolCalling: true, + }, + { id: "glm-4.5", name: "GLM-4.5", supportsReasoning: true, toolCalling: true }, + { id: "glm-4.5-air", name: "GLM-4.5 Air", supportsReasoning: true, toolCalling: true }, + { id: "glm-4.6", name: "GLM-4.6", supportsReasoning: true, toolCalling: true }, + { id: "glm-4.7", name: "GLM-4.7", supportsReasoning: true, toolCalling: true }, + { id: "glm-5", name: "GLM-5", supportsReasoning: true, toolCalling: true }, + { id: "glm-5.1", name: "GLM-5.1", supportsReasoning: true, toolCalling: true }, + { id: "glm-5.2", name: "GLM-5.2", supportsReasoning: true, toolCalling: true }, + { + id: "google/gemini-3.5-flash-lite", + name: "Gemini 3.5 Flash Lite", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + // The GPT-5.x family is tagged for the gateway's native /v1/responses endpoint — + // that is the surface OpenAI-family clients (Codex-style) expect for tool loops. + { + id: "gpt-5.4", + name: "GPT-5.4", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + targetFormat: "openai-responses", + }, + { + id: "gpt-5.4-mini", + name: "GPT-5.4 Mini", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + targetFormat: "openai-responses", + }, + { + id: "gpt-5.5", + name: "GPT-5.5", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + targetFormat: "openai-responses", + }, + { + id: "gpt-5.6-luna", + name: "GPT-5.6 Luna", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + targetFormat: "openai-responses", + }, + { + id: "gpt-5.6-sol", + name: "GPT-5.6 Sol", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + targetFormat: "openai-responses", + }, + { + id: "gpt-5.6-terra", + name: "GPT-5.6 Terra", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + targetFormat: "openai-responses", + }, + { + id: "grok-4.5", + name: "Grok 4.5", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { + id: "kimi-k3", + name: "Kimi K3", + supportsVision: true, + supportsReasoning: true, + toolCalling: true, + }, + { id: "minimax-m2.7", name: "MiniMax M2.7", supportsReasoning: true, toolCalling: true }, +]; + +export const cheaperinferenceProvider: RegistryEntry = { + id: "cheaperinference", + alias: "cinf", + format: "openai", + executor: "cheaperinference", + baseUrl: "https://api.cheaperinference.com/v1/chat/completions", + // The gateway serves a native, STATELESS /v1/responses endpoint alongside + // /v1/chat/completions. Consumed by CheaperInferenceExecutor.buildUrl for the + // models tagged targetFormat: "openai-responses" above. + responsesBaseUrl: "https://api.cheaperinference.com/v1/responses", + authType: "apikey", + authHeader: "bearer", + models: CHEAPERINFERENCE_MODELS, +}; diff --git a/open-sse/executors/cheaperinference.ts b/open-sse/executors/cheaperinference.ts new file mode 100644 index 0000000000..cc9c507b34 --- /dev/null +++ b/open-sse/executors/cheaperinference.ts @@ -0,0 +1,69 @@ +import { BaseExecutor, type ProviderCredentials } from "./base.ts"; +import { PROVIDERS } from "../config/constants.ts"; +import { getModelTargetFormat, PROVIDER_ID_TO_ALIAS } from "../config/providerModels.ts"; + +/** + * CheaperInferenceExecutor — api.cheaperinference.com. + * + * The gateway is OpenAI-compatible on both surfaces, so everything else comes from + * BaseExecutor. Two provider-specific facts need handling (both measured against the + * live API on 2026-07-31, not inferred from docs): + * + * 1. `/v1/responses` is STATELESS and REQUIRES `store:false`. Omitting it returns + * HTTP 400 ("This Responses-compatible endpoint is stateless. Send store=false…"). + * chatCore.ts deletes `store` for every provider except "openai" — a strip shared + * by ~290 providers that must not be special-cased — so we re-add it here, after + * that strip has run. A client-supplied `store:true` is overwritten rather than + * forwarded: the endpoint cannot honour it, and forwarding would 400. + * + * 2. Chat and Responses live at DIFFERENT URLs (unlike providers that switch on a + * path suffix). The per-model `targetFormat` registry tag is the single source of + * truth for which surface a model uses — the same tag chatCore reads to translate + * the body — so resolving the URL from it keeps URL and payload in lockstep. + * Same pattern as executors/xai.ts (9router#2439). + */ +export class CheaperInferenceExecutor extends BaseExecutor { + constructor(provider = "cheaperinference") { + super(provider, PROVIDERS[provider]); + } + + /** + * True when this model is served by the native /v1/responses endpoint. + * + * PROVIDER_MODELS is keyed by provider ALIAS ("cinf"), while PROVIDERS is keyed by + * provider ID ("cheaperinference") — so `this.provider` cannot be passed straight + * through the way executors/xai.ts does (there the alias equals the id, which hides + * the distinction). Resolve the alias first or every lookup silently returns null + * and every Responses request 400s upstream. + */ + private usesResponsesEndpoint(model: string): boolean { + const alias = PROVIDER_ID_TO_ALIAS[this.provider] || this.provider; + return getModelTargetFormat(alias, model) === "openai-responses"; + } + + buildUrl(model: string, _stream: boolean, _urlIndex = 0): string { + if (this.usesResponsesEndpoint(model)) { + return this.config.responsesBaseUrl || this.config.baseUrl; + } + return this.config.baseUrl; + } + + transformRequest( + model: string, + body: unknown, + stream: boolean, + credentials: ProviderCredentials + ): unknown { + const cleanedBody = super.transformRequest(model, body, stream, credentials); + if (!cleanedBody || typeof cleanedBody !== "object" || Array.isArray(cleanedBody)) { + return cleanedBody; + } + if (!this.usesResponsesEndpoint(model)) { + // Chat Completions rejects unknown params — never add `store` on that surface. + return cleanedBody; + } + return { ...(cleanedBody as Record), store: false }; + } +} + +export default CheaperInferenceExecutor; diff --git a/open-sse/executors/index.ts b/open-sse/executors/index.ts index 5cab182a16..49fe28ee6c 100644 --- a/open-sse/executors/index.ts +++ b/open-sse/executors/index.ts @@ -50,6 +50,7 @@ import { PoeWebExecutor } from "./poe-web.ts"; import { VeniceWebExecutor } from "./venice-web.ts"; import { NotionWebExecutor } from "./notion-web.ts"; import { V0VercelWebExecutor } from "./v0-vercel-web.ts"; +import { CheaperInferenceExecutor } from "./cheaperinference.ts"; import { KimiWebExecutor } from "./kimi-web.ts"; import { DoubaoWebExecutor } from "./doubao-web.ts"; import { QwenWebExecutor } from "./qwen-web.ts"; @@ -165,6 +166,8 @@ const executors = { "kimi-coding": new KimiExecutor(), // Alias moonshot: new MoonshotExecutor(), kimi: new MoonshotExecutor("kimi"), // Hidden legacy Moonshot provider id + cheaperinference: new CheaperInferenceExecutor(), + cinf: new CheaperInferenceExecutor("cheaperinference"), // Alias "doubao-web": new DoubaoWebExecutor(), db: new DoubaoWebExecutor(), // Alias "qwen-web": new QwenWebExecutor(), @@ -282,4 +285,5 @@ export { ZenmuxFreeExecutor } from "./zenmux-free.ts"; export { HyperAgentExecutor } from "./hyperagent.ts"; export { XaiExecutor } from "./xai.ts"; export { MoonshotExecutor } from "./moonshot.ts"; +export { CheaperInferenceExecutor } from "./cheaperinference.ts"; export { PromptQlExecutor } from "./promptql.ts"; diff --git a/public/providers/cheaperinference.svg b/public/providers/cheaperinference.svg new file mode 100644 index 0000000000..ee8d288ed6 --- /dev/null +++ b/public/providers/cheaperinference.svg @@ -0,0 +1,7 @@ + + Cheaper Inference gateway mark + + + + + diff --git a/src/app/(dashboard)/dashboard/providers/components/ProviderCard.tsx b/src/app/(dashboard)/dashboard/providers/components/ProviderCard.tsx index c1382ccf58..a1efc70ec6 100644 --- a/src/app/(dashboard)/dashboard/providers/components/ProviderCard.tsx +++ b/src/app/(dashboard)/dashboard/providers/components/ProviderCard.tsx @@ -16,7 +16,7 @@ import { } from "@/shared/constants/providers"; import { CategoryDot } from "./CategoryDot"; -import { isKimiPartnerProviderId } from "../featuredProviders"; +import { isCheaperInferenceProviderId, isKimiPartnerProviderId } from "../featuredProviders"; interface ProviderStats { total?: number; @@ -223,9 +223,11 @@ const ProviderCard = forwardRef(function const isCompatible = isOpenAICompatibleProvider(providerId); const isCcCompatible = isClaudeCodeCompatibleProvider(providerId); const isAnthropicCompatible = isAnthropicCompatibleProvider(providerId) && !isCcCompatible; - // Kimi (Moonshot AI) official-partnership highlight (2026-07): UI-only accent, - // see featuredProviders.ts — never affects routing/fallback order. + // Open Source Friend highlights (Kimi 2026-07, Cheaper Inference 2026-07): UI-only + // accents, see featuredProviders.ts — never affect routing/fallback order. const isKimiPartner = isKimiPartnerProviderId(provider.id || providerId); + const isCheaperInferencePartner = isCheaperInferenceProviderId(provider.id || providerId); + const isSponsorPartner = isKimiPartner || isCheaperInferencePartner; const codexServiceTierLabel = stats.codexServiceTier === "flex" ? providerText(t, "codexTierFlexLabel", "Flex") @@ -267,6 +269,24 @@ const ProviderCard = forwardRef(function ) : null; + // Cheaper Inference Open Source Friend badge — brand green (#31f889) with a dark + // foreground (the green is too bright for white text). Literal Tailwind arbitrary + // values must stay in sync with CHEAPERINFERENCE_BRAND_COLOR (featuredProviders.ts). + const cheaperInferenceSupporterChip = isCheaperInferencePartner ? ( + + verified + {providerText(t, "cheaperInferenceSupporterBadge", "Open Source Friend")} + + ) : null; + const dotLabels: Record = { free: tc("free"), "no-auth": t("noAuthLabel"), @@ -318,7 +338,12 @@ const ProviderCard = forwardRef(function // is a raw (non-token) brand hex, not a theme color. Keep the hex in // sync with KIMI_BRAND_COLOR (featuredProviders.ts). "border-2 border-[#1783FF]/70 hover:border-[#1783FF]/90 shadow-[inset_0_0_0_100px_rgba(23,131,255,0.035),0_4px_16px_-4px_rgba(23,131,255,0.45)]" - : "hover:border-primary/40" + : isCheaperInferencePartner + ? // Cheaper Inference Open Source Friend accent — same construction in + // its brand green (#31f889 = rgb(49,248,137)). Keep in sync with + // CHEAPERINFERENCE_BRAND_COLOR (featuredProviders.ts). + "border-2 border-[#31f889]/70 hover:border-[#31f889]/90 shadow-[inset_0_0_0_100px_rgba(49,248,137,0.035),0_4px_16px_-4px_rgba(49,248,137,0.45)]" + : "hover:border-primary/40" } ${allDisabled ? "opacity-50" : ""} ${provider.deprecated ? "opacity-60" : ""}`} >
@@ -392,9 +417,10 @@ const ProviderCard = forwardRef(function isCompatible || isCcCompatible || isAnthropicCompatible || - isKimiPartner) && ( + isSponsorPartner) && (
{kimiOfficialSupporterChip} + {cheaperInferenceSupporterChip} {provider.serviceKinds?.map((k) => ( = new Map([ + ...KIMI_PROVIDER_IDS.map((id) => [id, 1] as const), + ...CHEAPERINFERENCE_PROVIDER_IDS.map((id) => [id, 2] as const), +]); + +/** Brand accent per sponsor family, keyed by any of that family's provider ids. */ +export const SPONSOR_BRAND_COLORS: Readonly> = Object.freeze({ + ...Object.fromEntries(KIMI_PROVIDER_IDS.map((id) => [id, KIMI_BRAND_COLOR])), + ...Object.fromEntries( + CHEAPERINFERENCE_PROVIDER_IDS.map((id) => [id, CHEAPERINFERENCE_BRAND_COLOR]) + ), +}); + +/** Sponsor rank (1 = top), or null when the provider is not featured. */ +export function getFeaturedProviderRank(providerId: string | null | undefined): number | null { + if (typeof providerId !== "string") return null; + return FEATURED_PROVIDER_RANKS.get(providerId) ?? null; +} + /** * Providers pinned first within their dashboard category/group by - * `sortProviderEntriesFeaturedFirst`. A plain Set (not hardcoded inline at the - * sort call site) so a future partnership can extend it without touching the - * sort implementation. + * `sortProviderEntriesFeaturedFirst`. Retained for existing importers: the flat + * set of featured ids, derived from the rank map so the two cannot drift. */ -export const FEATURED_PROVIDER_IDS: ReadonlySet = new Set(KIMI_PROVIDER_IDS); +export const FEATURED_PROVIDER_IDS: ReadonlySet = new Set(FEATURED_PROVIDER_RANKS.keys()); export function isFeaturedProviderId(providerId: string | null | undefined): boolean { - return typeof providerId === "string" && FEATURED_PROVIDER_IDS.has(providerId); + return getFeaturedProviderRank(providerId) !== null; } /** True for providers that should render the Kimi official-supporter card accent. */ export function isKimiPartnerProviderId(providerId: string | null | undefined): boolean { return typeof providerId === "string" && KIMI_PROVIDER_IDS.includes(providerId); } + +/** True for providers that should render the Cheaper Inference card accent. */ +export function isCheaperInferenceProviderId(providerId: string | null | undefined): boolean { + return typeof providerId === "string" && CHEAPERINFERENCE_PROVIDER_IDS.includes(providerId); +} + +/** True for any Open Source Friend — drives the shared supporter chip. */ +export function isSponsorProviderId(providerId: string | null | undefined): boolean { + return isFeaturedProviderId(providerId); +} diff --git a/src/app/(dashboard)/dashboard/providers/providerPageUtils.ts b/src/app/(dashboard)/dashboard/providers/providerPageUtils.ts index 72fe8f163c..2f8d8faa04 100644 --- a/src/app/(dashboard)/dashboard/providers/providerPageUtils.ts +++ b/src/app/(dashboard)/dashboard/providers/providerPageUtils.ts @@ -16,7 +16,7 @@ import { providerHasServiceKind } from "@/lib/providers/serviceKindIndex"; import { compareTr, matchesAnyToken, matchesSearch } from "@/shared/utils/turkishText"; import { fetchWithTimeout } from "@/shared/utils/fetchTimeout"; import type { ProviderDisplayMode } from "./providerPageStorage"; -import { isFeaturedProviderId } from "./featuredProviders"; +import { getFeaturedProviderRank } from "./featuredProviders"; export interface ProviderStatsSnapshot { total?: number; @@ -165,22 +165,31 @@ export function sortProviderEntriesByName( /** * Sort provider entries alphabetically (via `sortProviderEntriesByName`), then - * stable-pin any `FEATURED_PROVIDER_IDS` member first — featured entries keep - * their alphabetical order among themselves, followed by the rest in - * alphabetical order. Presentation-only (see `featuredProviders.ts`): this must - * never influence routing/fallback order, only how the dashboard's provider - * category grids are sorted. + * stable-pin sponsors first in explicit rank order (see `featuredProviders.ts`): + * rank 1 block, then rank 2, then everything unranked — each block keeping the + * alphabetical order established above. Presentation-only: this must never + * influence routing/fallback order, only how the dashboard's provider category + * grids are sorted. */ export function sortProviderEntriesFeaturedFirst( entries: ProviderEntry[] ): ProviderEntry[] { const sorted = sortProviderEntriesByName(entries); - const featured: ProviderEntry[] = []; + // A plain "featured first" pin would order Cheaper Inference above Kimi (the + // alphabet), which is exactly what the explicit ranks prevent. + const ranked: ProviderEntry[] = []; const rest: ProviderEntry[] = []; for (const entry of sorted) { - (isFeaturedProviderId(entry.providerId) ? featured : rest).push(entry); + (getFeaturedProviderRank(entry.providerId) === null ? rest : ranked).push(entry); } - return [...featured, ...rest]; + // Array.prototype.sort is stable in ES2019+, so equal-rank entries keep the + // alphabetical order established above. + ranked.sort( + (a, b) => + (getFeaturedProviderRank(a.providerId) as number) - + (getFeaturedProviderRank(b.providerId) as number) + ); + return [...ranked, ...rest]; } export function buildProviderEntries>( diff --git a/src/i18n/messages/ar.json b/src/i18n/messages/ar.json index b3a61c40d3..3f0b337679 100644 --- a/src/i18n/messages/ar.json +++ b/src/i18n/messages/ar.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "افتح arena.ai، وسجل الدخول، ثم انسخ ترويسة Cookie الكاملة من طلب الشبكة. قم بتضمين arena-auth-prod-v1.0 و arena-auth-prod-v1.1 (وأي أجزاء أخرى إن وجدت)، ويفضل مع cf_clearance. لا تقم بلصق ملف تعريف الارتباط الفارغ arena-auth-prod-v1 فقط. اختياري: providerSpecificData.recaptchaV3Token إذا كان create-evaluation لا يزال يرجع 403.", "kimiOfficialSupporterBadge": "الصديق المؤسس", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) هو الصديق المؤسس للمصادر المفتوحة لـ OmniRoute", + "cheaperInferenceSupporterBadge": "صديق مفتوح المصدر", + "cheaperInferenceSupporterTooltip": "‏Cheaper Inference تدعم OmniRoute كصديق للمصادر المفتوحة", "kimiPartnerLinkNote": "رابط شريك — يدعم OmniRoute دون أي تكلفة إضافية عليك", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/az.json b/src/i18n/messages/az.json index 418c3bc0eb..6975c959e0 100644 --- a/src/i18n/messages/az.json +++ b/src/i18n/messages/az.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Open arena.ai, sign in, then copy the full Cookie header from a Network request. Include arena-auth-prod-v1.0 and arena-auth-prod-v1.1 (and further chunks if present), preferably with cf_clearance. Do not paste only the empty arena-auth-prod-v1 cookie. Optional: providerSpecificData.recaptchaV3Token if create-evaluation still returns 403.", "kimiOfficialSupporterBadge": "Təsisçi Dost", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) OmniRoute-un təsisçi Açıq Mənbə Dostudur", + "cheaperInferenceSupporterBadge": "Açıq Mənbə Dostu", + "cheaperInferenceSupporterTooltip": "Cheaper Inference OmniRoute-u Açıq Mənbə Dostu kimi dəstəkləyir", "kimiPartnerLinkNote": "Tərəfdaş linki — sizə heç bir əlavə xərc olmadan OmniRoute-u dəstəkləyir", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/bg.json b/src/i18n/messages/bg.json index 82295b9023..fa7b847385 100644 --- a/src/i18n/messages/bg.json +++ b/src/i18n/messages/bg.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Отворете arena.ai, влезте в профила си, след което копирайте пълната заглавка Cookie от мрежова заявка (Network request). Включете arena-auth-prod-v1.0 и arena-auth-prod-v1.1 (и следващите части, ако има такива), за предпочитане с cf_clearance. Не поставяйте само празната бисквитка arena-auth-prod-v1. По избор: providerSpecificData.recaptchaV3Token, ако create-evaluation все още връща 403.", "kimiOfficialSupporterBadge": "Учредяващ приятел", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) е основаващият приятел на отворения код на OmniRoute", + "cheaperInferenceSupporterBadge": "Приятел на отворения код", + "cheaperInferenceSupporterTooltip": "Cheaper Inference подкрепя OmniRoute като приятел на отворения код", "kimiPartnerLinkNote": "Партньорска връзка — поддържа OmniRoute без допълнителни разходи за вас", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/bn.json b/src/i18n/messages/bn.json index 87bddc2480..6be7b82b14 100644 --- a/src/i18n/messages/bn.json +++ b/src/i18n/messages/bn.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.ai খুলুন, সাইন ইন করুন, তারপর একটি Network রিকোয়েস্ট থেকে সম্পূর্ণ Cookie হেডার কপি করুন। arena-auth-prod-v1.0 এবং arena-auth-prod-v1.1 (এবং উপস্থিত থাকলে পরবর্তী অংশগুলি) অন্তর্ভুক্ত করুন, বিশেষ করে cf_clearance সহ। শুধুমাত্র খালি arena-auth-prod-v1 কুকি পেস্ট করবেন না। ঐচ্ছিক: create-evaluation এখনও 403 রিটার্ন করলে providerSpecificData.recaptchaV3Token।", "kimiOfficialSupporterBadge": "প্রতিষ্ঠাতা বন্ধু", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) হল OmniRoute-এর প্রতিষ্ঠাতা ওপেন সোর্স বন্ধু", + "cheaperInferenceSupporterBadge": "ওপেন সোর্স বন্ধু", + "cheaperInferenceSupporterTooltip": "Cheaper Inference একজন ওপেন সোর্স বন্ধু হিসেবে OmniRoute-কে সমর্থন করে", "kimiPartnerLinkNote": "পার্টনার লিঙ্ক — আপনার কোনো অতিরিক্ত খরচ ছাড়াই OmniRoute-কে সমর্থন করে", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/cs.json b/src/i18n/messages/cs.json index e3bb0fb746..5707bcf2ed 100644 --- a/src/i18n/messages/cs.json +++ b/src/i18n/messages/cs.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Otevřete arena.ai, přihlaste se a poté zkopírujte celou hlavičku Cookie ze síťového požadavku (Network request). Zahrňte arena-auth-prod-v1.0 a arena-auth-prod-v1.1 (a další části, pokud jsou přítomny), nejlépe s cf_clearance. Nevkládejte pouze prázdný cookie arena-auth-prod-v1. Volitelně: providerSpecificData.recaptchaV3Token, pokud create-evaluation stále vrací 403.", "kimiOfficialSupporterBadge": "Zakládající přítel", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) je zakládající open source přítel OmniRoute", + "cheaperInferenceSupporterBadge": "Přítel open source", + "cheaperInferenceSupporterTooltip": "Cheaper Inference podporuje OmniRoute jako přítel open source", "kimiPartnerLinkNote": "Partnerský odkaz — podporuje OmniRoute bez jakýchkoli dalších nákladů pro vás", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/da.json b/src/i18n/messages/da.json index ce03c456a3..45b6f3133d 100644 --- a/src/i18n/messages/da.json +++ b/src/i18n/messages/da.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Åbn arena.ai, log ind, og kopiér derefter den fulde Cookie-header fra en netværksanmodning. Inkluder arena-auth-prod-v1.0 og arena-auth-prod-v1.1 (og yderligere bidder, hvis de findes), helst med cf_clearance. Indsæt ikke kun den tomme arena-auth-prod-v1-cookie. Valgfrit: providerSpecificData.recaptchaV3Token hvis create-evaluation stadig returnerer 403.", "kimiOfficialSupporterBadge": "Grundlæggende ven", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) er OmniRoutes grundlæggende open source-ven", + "cheaperInferenceSupporterBadge": "Open source-ven", + "cheaperInferenceSupporterTooltip": "Cheaper Inference støtter OmniRoute som open source-ven", "kimiPartnerLinkNote": "Partnerlink — understøtter OmniRoute uden ekstra omkostninger for dig", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/de.json b/src/i18n/messages/de.json index abed70d555..6acb03e5d6 100644 --- a/src/i18n/messages/de.json +++ b/src/i18n/messages/de.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Öffnen Sie arena.ai, melden Sie sich an und kopieren Sie dann den vollständigen Cookie-Header aus einer Netzwerkanfrage. Fügen Sie arena-auth-prod-v1.0 und arena-auth-prod-v1.1 (und weitere Chunks, falls vorhanden) hinzu, vorzugsweise mit cf_clearance. Fügen Sie nicht nur das leere arena-auth-prod-v1-Cookie ein. Optional: providerSpecificData.recaptchaV3Token, falls create-evaluation weiterhin 403 zurückgibt.", "kimiOfficialSupporterBadge": "Gründungsfreund", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) ist OmniRoutes Gründungs-Open-Source-Freund", + "cheaperInferenceSupporterBadge": "Open-Source-Freund", + "cheaperInferenceSupporterTooltip": "Cheaper Inference unterstützt OmniRoute als Open-Source-Freund", "kimiPartnerLinkNote": "Partnerlink — unterstützt OmniRoute ohne zusätzliche Kosten für Sie", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 3d9bb9bc8e..ee50e4e21d 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -6013,6 +6013,8 @@ "lmarenaWebCookieHint": "Open arena.ai, sign in, then copy the full Cookie header from a Network request. Include arena-auth-prod-v1.0 and arena-auth-prod-v1.1 (and further chunks if present), preferably with cf_clearance. Do not paste only the empty arena-auth-prod-v1 cookie. Optional: providerSpecificData.recaptchaV3Token if create-evaluation still returns 403.", "kimiOfficialSupporterBadge": "Founding Friend", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) is OmniRoute's founding Open Source Friend", + "cheaperInferenceSupporterBadge": "Open Source Friend", + "cheaperInferenceSupporterTooltip": "Cheaper Inference backs OmniRoute as an Open Source Friend", "kimiPartnerLinkNote": "Partner link — supports OmniRoute at no extra cost to you" }, "settings": { diff --git a/src/i18n/messages/es.json b/src/i18n/messages/es.json index 7d7e8cc49f..c26df50811 100644 --- a/src/i18n/messages/es.json +++ b/src/i18n/messages/es.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Open arena.ai, sign in, then copy the full Cookie header from a Network request. Include arena-auth-prod-v1.0 and arena-auth-prod-v1.1 (and further chunks if present), preferably with cf_clearance. Do not paste only the empty arena-auth-prod-v1 cookie. Optional: providerSpecificData.recaptchaV3Token if create-evaluation still returns 403.", "kimiOfficialSupporterBadge": "Official Supporter", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) is an official OmniRoute launch partner", + "cheaperInferenceSupporterBadge": "Amigo del código abierto", + "cheaperInferenceSupporterTooltip": "Cheaper Inference apoya a OmniRoute como amigo del código abierto", "kimiPartnerLinkNote": "Partner link — supports OmniRoute at no extra cost to you", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/fa.json b/src/i18n/messages/fa.json index a07a9fc9a4..bcb708b0e6 100644 --- a/src/i18n/messages/fa.json +++ b/src/i18n/messages/fa.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "سایت arena.ai را باز کنید، وارد شوید، سپس هدر کامل Cookie را از یک درخواست Network کپی کنید. شامل arena-auth-prod-v1.0 و arena-auth-prod-v1.1 (و بخش‌های بعدی در صورت وجود)، ترجیحاً همراه با cf_clearance. فقط کوکی خالی arena-auth-prod-v1 را جای‌گذاری نکنید. اختیاری: providerSpecificData.recaptchaV3Token اگر create-evaluation همچنان خطای 403 برمی‌گرداند.", "kimiOfficialSupporterBadge": "دوست بنیان‌گذار", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) دوست بنیان‌گذار متن‌باز OmniRoute است", + "cheaperInferenceSupporterBadge": "دوست متن‌باز", + "cheaperInferenceSupporterTooltip": "‏Cheaper Inference از OmniRoute به‌عنوان دوست متن‌باز حمایت می‌کند", "kimiPartnerLinkNote": "لینک همکاری — پشتیبانی از OmniRoute بدون هزینه اضافی برای شما", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/fi.json b/src/i18n/messages/fi.json index a4f3239898..aec971da14 100644 --- a/src/i18n/messages/fi.json +++ b/src/i18n/messages/fi.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Avaa arena.ai, kirjaudu sisään ja kopioi sitten koko Cookie-otsake Network-pyynnöstä. Sisällytä arena-auth-prod-v1.0 ja arena-auth-prod-v1.1 (ja mahdolliset muut osat), mieluiten cf_clearance-arvon kanssa. Älä liitä pelkkää tyhjää arena-auth-prod-v1-evästettä. Valinnainen: providerSpecificData.recaptchaV3Token, jos create-evaluation palauttaa edelleen virheen 403.", "kimiOfficialSupporterBadge": "Perustajaystävä", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) on OmniRouten perustajan avoimen lähdekoodin ystävä", + "cheaperInferenceSupporterBadge": "Avoimen lähdekoodin ystävä", + "cheaperInferenceSupporterTooltip": "Cheaper Inference tukee OmniRoutea avoimen lähdekoodin ystävänä", "kimiPartnerLinkNote": "Kumppanilinkki — tukee OmniRoutea ilman lisäkustannuksia sinulle", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index c963fa1fcb..f37a9e4f03 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Ouvrez arena.ai, connectez-vous, puis copiez l'en-tête Cookie complet depuis une requête Réseau. Incluez arena-auth-prod-v1.0 et arena-auth-prod-v1.1 (et les fragments suivants s'ils sont présents), de préférence avec cf_clearance. Ne collez pas uniquement le cookie arena-auth-prod-v1 vide. Facultatif : providerSpecificData.recaptchaV3Token si create-evaluation renvoie toujours 403.", "kimiOfficialSupporterBadge": "Ami fondateur", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) est l'ami open source fondateur d'OmniRoute", + "cheaperInferenceSupporterBadge": "Ami open source", + "cheaperInferenceSupporterTooltip": "Cheaper Inference soutient OmniRoute en tant qu'ami open source", "kimiPartnerLinkNote": "Lien partenaire — soutient OmniRoute sans frais supplémentaires pour vous", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/gu.json b/src/i18n/messages/gu.json index 89f696a61f..97b516ba39 100644 --- a/src/i18n/messages/gu.json +++ b/src/i18n/messages/gu.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.ai ખોલો, સાઇન ઇન કરો, પછી Network વિનંતીમાંથી સંપૂર્ણ Cookie હેડર કૉપિ કરો. arena-auth-prod-v1.0 અને arena-auth-prod-v1.1 (અને જો હાજર હોય તો આગળના ભાગો) શામેલ કરો, પ્રાધાન્યમાં cf_clearance સાથે. ફક્ત ખાલી arena-auth-prod-v1 કૂકી પેસ્ટ કરશો નહીં. વૈકલ્પિક: providerSpecificData.recaptchaV3Token જો create-evaluation હજી પણ 403 પરત કરે છે.", "kimiOfficialSupporterBadge": "સ્થાપક મિત્ર", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) એ OmniRoute નો સ્થાપક ઓપન સોર્સ મિત્ર છે", + "cheaperInferenceSupporterBadge": "ઓપન સોર્સ મિત્ર", + "cheaperInferenceSupporterTooltip": "Cheaper Inference ઓપન સોર્સ મિત્ર તરીકે OmniRoute ને સમર્થન આપે છે", "kimiPartnerLinkNote": "પાર્ટનર લિંક — તમારા માટે કોઈ વધારાના ખર્ચ વિના OmniRoute ને સપોર્ટ કરે છે", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/he.json b/src/i18n/messages/he.json index ac23997432..f161156a85 100644 --- a/src/i18n/messages/he.json +++ b/src/i18n/messages/he.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "פתח את arena.ai, התחבר, ולאחר מכן העתק את כותרת ה-Cookie המלאה מבקשת Network. כלול את arena-auth-prod-v1.0 ואת arena-auth-prod-v1.1 (וחלקים נוספים אם קיימים), רצוי עם cf_clearance. אל תדביק רק את עוגיית arena-auth-prod-v1 הריקה. אופציונלי: providerSpecificData.recaptchaV3Token אם create-evaluation עדיין מחזיר 403.", "kimiOfficialSupporterBadge": "חבר מייסד", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) הוא חבר הקוד הפתוח המייסד של OmniRoute", + "cheaperInferenceSupporterBadge": "ידיד קוד פתוח", + "cheaperInferenceSupporterTooltip": "‏Cheaper Inference תומכת ב-OmniRoute כידידת קוד פתוח", "kimiPartnerLinkNote": "קישור שותף — תומך ב-OmniRoute ללא עלות נוספת עבורך", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/hi.json b/src/i18n/messages/hi.json index 56f409ab0b..7c8159ef9c 100644 --- a/src/i18n/messages/hi.json +++ b/src/i18n/messages/hi.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.ai खोलें, साइन इन करें, फिर Network अनुरोध से पूरा Cookie हेडर कॉपी करें। arena-auth-prod-v1.0 और arena-auth-prod-v1.1 (और यदि मौजूद हों तो आगे के हिस्से) शामिल करें, अधिमानतः cf_clearance के साथ। केवल खाली arena-auth-prod-v1 कुकी पेस्ट न करें। वैकल्पिक: providerSpecificData.recaptchaV3Token यदि create-evaluation अभी भी 403 लौटाता है।", "kimiOfficialSupporterBadge": "संस्थापक मित्र", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI), OmniRoute का संस्थापक ओपन सोर्स मित्र है", + "cheaperInferenceSupporterBadge": "ओपन सोर्स मित्र", + "cheaperInferenceSupporterTooltip": "Cheaper Inference एक ओपन सोर्स मित्र के रूप में OmniRoute का समर्थन करता है", "kimiPartnerLinkNote": "पार्टनर लिंक — बिना किसी अतिरिक्त लागत के OmniRoute का समर्थन करता है", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/hu.json b/src/i18n/messages/hu.json index 21695842a3..f698b6f59b 100644 --- a/src/i18n/messages/hu.json +++ b/src/i18n/messages/hu.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Open arena.ai, sign in, then copy the full Cookie header from a Network request. Include arena-auth-prod-v1.0 and arena-auth-prod-v1.1 (and further chunks if present), preferably with cf_clearance. Do not paste only the empty arena-auth-prod-v1 cookie. Optional: providerSpecificData.recaptchaV3Token if create-evaluation still returns 403.", "kimiOfficialSupporterBadge": "Alapító barát", "kimiOfficialSupporterTooltip": "A Kimi (Moonshot AI) az OmniRoute alapító nyílt forráskódú barátja", + "cheaperInferenceSupporterBadge": "Nyílt forráskódú barát", + "cheaperInferenceSupporterTooltip": "A Cheaper Inference nyílt forráskódú barátként támogatja az OmniRoute-ot", "kimiPartnerLinkNote": "Partnerhivatkozás — az Ön számára további költség nélkül támogatja az OmniRoute-ot", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/id.json b/src/i18n/messages/id.json index c65693c536..36d3eec7e3 100644 --- a/src/i18n/messages/id.json +++ b/src/i18n/messages/id.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Buka arena.ai, masuk, lalu salin header Cookie lengkap dari permintaan Network. Sertakan arena-auth-prod-v1.0 dan arena-auth-prod-v1.1 (dan chunk selanjutnya jika ada), sebaiknya dengan cf_clearance. Jangan hanya menempelkan cookie arena-auth-prod-v1 yang kosong. Opsional: providerSpecificData.recaptchaV3Token jika create-evaluation masih mengembalikan 403.", "kimiOfficialSupporterBadge": "Sahabat Pendiri", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) adalah sahabat open source pendiri OmniRoute", + "cheaperInferenceSupporterBadge": "Teman Open Source", + "cheaperInferenceSupporterTooltip": "Cheaper Inference mendukung OmniRoute sebagai Teman Open Source", "kimiPartnerLinkNote": "Tautan mitra — mendukung OmniRoute tanpa biaya tambahan bagi Anda", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/in.json b/src/i18n/messages/in.json index a69d33694e..fc5120d9cd 100644 --- a/src/i18n/messages/in.json +++ b/src/i18n/messages/in.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Buka arena.ai, masuk, lalu salin header Cookie lengkap dari permintaan Jaringan. Sertakan arena-auth-prod-v1.0 and arena-auth-prod-v1.1 (dan bagian selanjutnya jika ada), sebaiknya dengan cf_clearance. Jangan tempel hanya cookie arena-auth-prod-v1 yang kosong. Opsional: providerSpecificData.recaptchaV3Token jika create-evaluation masih mengembalikan 403.", "kimiOfficialSupporterBadge": "Sahabat Pendiri", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) adalah sahabat open source pendiri OmniRoute", + "cheaperInferenceSupporterBadge": "Teman Open Source", + "cheaperInferenceSupporterTooltip": "Cheaper Inference mendukung OmniRoute sebagai Teman Open Source", "kimiPartnerLinkNote": "Tautan mitra — mendukung OmniRoute tanpa biaya tambahan bagi Anda", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/it.json b/src/i18n/messages/it.json index 21329d2aaf..ca9178ccf7 100644 --- a/src/i18n/messages/it.json +++ b/src/i18n/messages/it.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Apri arena.ai, accedi, quindi copia l'intestazione Cookie completa da una richiesta Network. Includi arena-auth-prod-v1.0 e arena-auth-prod-v1.1 (e ulteriori blocchi se presenti), preferibilmente con cf_clearance. Non incollare solo il cookie vuoto arena-auth-prod-v1. Facoltativo: providerSpecificData.recaptchaV3Token se create-evaluation restituisce ancora 403.", "kimiOfficialSupporterBadge": "Amico Fondatore", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) è l'amico open source fondatore di OmniRoute", + "cheaperInferenceSupporterBadge": "Amico open source", + "cheaperInferenceSupporterTooltip": "Cheaper Inference sostiene OmniRoute come amico open source", "kimiPartnerLinkNote": "Link partner — supporta OmniRoute senza costi aggiuntivi per te", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/ja.json b/src/i18n/messages/ja.json index aac71c81f7..f9559c1873 100644 --- a/src/i18n/messages/ja.json +++ b/src/i18n/messages/ja.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.aiを開いてサインインし、ネットワークリクエストからCookieヘッダー全体をコピーします。arena-auth-prod-v1.0とarena-auth-prod-v1.1(および存在する場合はそれ以降のチャンク)を含め、できればcf_clearanceも一緒に含めてください。空のarena-auth-prod-v1クッキーのみを貼り付けないでください。オプション: create-evaluationが依然として403を返す場合はproviderSpecificData.recaptchaV3Token。", "kimiOfficialSupporterBadge": "創設フレンド", "kimiOfficialSupporterTooltip": "Kimi(Moonshot AI)は OmniRoute の創設オープンソースフレンドです", + "cheaperInferenceSupporterBadge": "オープンソースフレンド", + "cheaperInferenceSupporterTooltip": "Cheaper Inference は OmniRoute をオープンソースフレンドとして支援しています", "kimiPartnerLinkNote": "パートナーリンク — 追加費用なしで OmniRoute をサポートします", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/ko.json b/src/i18n/messages/ko.json index 11c649976a..01d5c7edfa 100644 --- a/src/i18n/messages/ko.json +++ b/src/i18n/messages/ko.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.ai를 열고 로그인한 다음 Network 요청에서 전체 Cookie 헤더를 복사하세요. arena-auth-prod-v1.0 및 arena-auth-prod-v1.1(있는 경우 추가 청크 포함)을 포함해야 하며, 가급적 cf_clearance도 포함하는 것이 좋습니다. 비어 있는 arena-auth-prod-v1 쿠키만 붙여넣지 마세요. 선택 사항: create-evaluation에서 여전히 403을 반환하는 경우 providerSpecificData.recaptchaV3Token.", "kimiOfficialSupporterBadge": "창립 프렌드", "kimiOfficialSupporterTooltip": "Kimi(Moonshot AI)는 OmniRoute의 창립 오픈소스 프렌드입니다", + "cheaperInferenceSupporterBadge": "오픈 소스 친구", + "cheaperInferenceSupporterTooltip": "Cheaper Inference는 오픈 소스 친구로서 OmniRoute를 후원합니다", "kimiPartnerLinkNote": "파트너 링크 — 추가 비용 없이 OmniRoute를 지원합니다", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/mr.json b/src/i18n/messages/mr.json index 5451454675..060f2feffd 100644 --- a/src/i18n/messages/mr.json +++ b/src/i18n/messages/mr.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.ai उघडा, साइन इन करा, नंतर नेटवर्क विनंतीवरून (Network request) संपूर्ण Cookie हेडर कॉपी करा. arena-auth-prod-v1.0 आणि arena-auth-prod-v1.1 (आणि उपस्थित असल्यास पुढील भाग) समाविष्ट करा, शक्यतो cf_clearance सह. केवळ रिकामी arena-auth-prod-v1 कुकी पेस्ट करू नका. पर्यायी: create-evaluation अजूनही 403 परत करत असल्यास providerSpecificData.recaptchaV3Token.", "kimiOfficialSupporterBadge": "संस्थापक मित्र", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) हा OmniRoute चा संस्थापक ओपन सोर्स मित्र आहे", + "cheaperInferenceSupporterBadge": "ओपन सोर्स मित्र", + "cheaperInferenceSupporterTooltip": "Cheaper Inference ओपन सोर्स मित्र म्हणून OmniRoute ला पाठिंबा देते", "kimiPartnerLinkNote": "भागीदार लिंक — तुमच्यासाठी कोणत्याही अतिरिक्त खर्चाशिवाय OmniRoute ला सपोर्ट करते", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/ms.json b/src/i18n/messages/ms.json index 592e2bd368..2fe34426d9 100644 --- a/src/i18n/messages/ms.json +++ b/src/i18n/messages/ms.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Buka arena.ai, log masuk, kemudian salin pengepala Cookie penuh daripada permintaan Rangkaian. Sertakan arena-auth-prod-v1.0 dan arena-auth-prod-v1.1 (dan bahagian selanjutnya jika ada), sebaik-baiknya dengan cf_clearance. Jangan tampal kuki arena-auth-prod-v1 yang kosong sahaja. Pilihan: providerSpecificData.recaptchaV3Token jika create-evaluation masih mengembalikan 403.", "kimiOfficialSupporterBadge": "Rakan Pengasas", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) ialah rakan sumber terbuka pengasas OmniRoute", + "cheaperInferenceSupporterBadge": "Rakan Sumber Terbuka", + "cheaperInferenceSupporterTooltip": "Cheaper Inference menyokong OmniRoute sebagai Rakan Sumber Terbuka", "kimiPartnerLinkNote": "Pautan rakan kongsi — menyokong OmniRoute tanpa kos tambahan kepada anda", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/nl.json b/src/i18n/messages/nl.json index afe5aea540..86043ad9a1 100644 --- a/src/i18n/messages/nl.json +++ b/src/i18n/messages/nl.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Open arena.ai, meld u aan en kopieer vervolgens de volledige Cookie-header van een netwerkverzoek. Voeg arena-auth-prod-v1.0 en arena-auth-prod-v1.1 toe (en verdere chunks indien aanwezig), bij voorkeur met cf_clearance. Plak niet alleen de lege arena-auth-prod-v1-cookie. Optioneel: providerSpecificData.recaptchaV3Token als create-evaluation nog steeds 403 retourneert.", "kimiOfficialSupporterBadge": "Oprichtende Vriend", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) is OmniRoute's oprichtende open source-vriend", + "cheaperInferenceSupporterBadge": "Opensourcevriend", + "cheaperInferenceSupporterTooltip": "Cheaper Inference steunt OmniRoute als opensourcevriend", "kimiPartnerLinkNote": "Partnerlink — ondersteunt OmniRoute zonder extra kosten voor u", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/no.json b/src/i18n/messages/no.json index 82dbeff23f..894692a4ac 100644 --- a/src/i18n/messages/no.json +++ b/src/i18n/messages/no.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Åpne arena.ai, logg inn, og kopier deretter hele Cookie-headeren fra en nettverksforespørsel. Inkluder arena-auth-prod-v1.0 og arena-auth-prod-v1.1 (og ytterligere deler hvis tilgjengelig), helst med cf_clearance. Ikke lim inn bare den tomme arena-auth-prod-v1-cookien. Valgfritt: providerSpecificData.recaptchaV3Token hvis create-evaluation fortsatt returnerer 403.", "kimiOfficialSupporterBadge": "Grunnleggende venn", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) er OmniRoutes grunnleggende åpen kildekode-venn", + "cheaperInferenceSupporterBadge": "Åpen kildekode-venn", + "cheaperInferenceSupporterTooltip": "Cheaper Inference støtter OmniRoute som åpen kildekode-venn", "kimiPartnerLinkNote": "Partnerlenke — støtter OmniRoute uten ekstra kostnad for deg", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/phi.json b/src/i18n/messages/phi.json index 23074a502f..c2849454ab 100644 --- a/src/i18n/messages/phi.json +++ b/src/i18n/messages/phi.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Buksan ang arena.ai, mag-sign in, pagkatapos ay kopyahin ang buong Cookie header mula sa isang Network request. Isama ang arena-auth-prod-v1.0 at arena-auth-prod-v1.1 (at iba pang mga chunk kung mayroon), mas mainam kung may cf_clearance. Huwag i-paste ang walang lamang arena-auth-prod-v1 cookie lamang. Opsyonal: providerSpecificData.recaptchaV3Token kung nagbabalik pa rin ng 403 ang create-evaluation.", "kimiOfficialSupporterBadge": "Tagapagtatag na Kaibigan", "kimiOfficialSupporterTooltip": "Ang Kimi (Moonshot AI) ang tagapagtatag na open source na kaibigan ng OmniRoute", + "cheaperInferenceSupporterBadge": "Kaibigan ng Open Source", + "cheaperInferenceSupporterTooltip": "Sinusuportahan ng Cheaper Inference ang OmniRoute bilang Kaibigan ng Open Source", "kimiPartnerLinkNote": "Link ng kasosyo — sumusuporta sa OmniRoute nang walang karagdagang gastos sa iyo", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/pl.json b/src/i18n/messages/pl.json index 378b493abd..1461f73a34 100644 --- a/src/i18n/messages/pl.json +++ b/src/i18n/messages/pl.json @@ -5998,6 +5998,8 @@ "lmarenaWebCookieHint": "Otwórz arena.ai, zaloguj się, a następnie skopiuj pełny nagłówek Cookie z żądania Network. Dołącz arena-auth-prod-v1.0 i arena-auth-prod-v1.1 (oraz kolejne fragmenty, jeśli występują), najlepiej z cf_clearance. Nie wklejaj samego pustego cookie arena-auth-prod-v1. Opcjonalnie: providerSpecificData.recaptchaV3Token, jeśli create-evaluation nadal zwraca 403.", "kimiOfficialSupporterBadge": "Przyjaciel-założyciel", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) jest przyjacielem-założycielem open source OmniRoute", + "cheaperInferenceSupporterBadge": "Przyjaciel open source", + "cheaperInferenceSupporterTooltip": "Cheaper Inference wspiera OmniRoute jako przyjaciel open source", "kimiPartnerLinkNote": "Link partnerski — wspiera OmniRoute bez żadnych dodatkowych kosztów dla Ciebie", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/pt-BR.json b/src/i18n/messages/pt-BR.json index 8f836bb504..3c2b09f6b5 100644 --- a/src/i18n/messages/pt-BR.json +++ b/src/i18n/messages/pt-BR.json @@ -6001,6 +6001,8 @@ "lmarenaWebCookieHint": "Abra arena.ai, faça login e depois copie o cabeçalho Cookie completo de uma requisição de rede. Inclua arena-auth-prod-v1.0 e arena-auth-prod-v1.1 (e outros fragmentos, se houver), preferencialmente com cf_clearance. Não cole apenas o cookie vazio arena-auth-prod-v1. Opcional: providerSpecificData.recaptchaV3Token se create-evaluation ainda retornar 403.", "kimiOfficialSupporterBadge": "Amigo Fundador", "kimiOfficialSupporterTooltip": "A Kimi (Moonshot AI) é a amiga fundadora de código aberto do OmniRoute", + "cheaperInferenceSupporterBadge": "Amigo do Código Aberto", + "cheaperInferenceSupporterTooltip": "A Cheaper Inference apoia o OmniRoute como amiga do código aberto", "kimiPartnerLinkNote": "Link de parceiro — apoia o OmniRoute sem custo extra para você", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/pt.json b/src/i18n/messages/pt.json index 9891203fee..e19674282b 100644 --- a/src/i18n/messages/pt.json +++ b/src/i18n/messages/pt.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Abra o arena.ai, inicie sessão e, em seguida, copie o cabeçalho Cookie completo de um pedido de Rede. Inclua arena-auth-prod-v1.0 e arena-auth-prod-v1.1 (e partes adicionais, se presentes), de preferência com cf_clearance. Não cole apenas o cookie arena-auth-prod-v1 vazio. Opcional: providerSpecificData.recaptchaV3Token se create-evaluation continuar a devolver 403.", "kimiOfficialSupporterBadge": "Amigo Fundador", "kimiOfficialSupporterTooltip": "A Kimi (Moonshot AI) é a amiga fundadora de código aberto do OmniRoute", + "cheaperInferenceSupporterBadge": "Amigo do Código Aberto", + "cheaperInferenceSupporterTooltip": "A Cheaper Inference apoia o OmniRoute como amiga do código aberto", "kimiPartnerLinkNote": "Link de parceiro — apoia o OmniRoute sem custos adicionais para si", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/ro.json b/src/i18n/messages/ro.json index 68c9f99780..e90fb8ed5a 100644 --- a/src/i18n/messages/ro.json +++ b/src/i18n/messages/ro.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Deschide arena.ai, conectează-te, apoi copiază antetul Cookie complet dintr-o cerere Network. Include arena-auth-prod-v1.0 și arena-auth-prod-v1.1 (și fragmentele ulterioare dacă sunt prezente), de preferință cu cf_clearance. Nu lipi doar cookie-ul gol arena-auth-prod-v1. Opțional: providerSpecificData.recaptchaV3Token dacă create-evaluation returnează în continuare 403.", "kimiOfficialSupporterBadge": "Prieten Fondator", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) este prietenul fondator open source al OmniRoute", + "cheaperInferenceSupporterBadge": "Prieten open source", + "cheaperInferenceSupporterTooltip": "Cheaper Inference susține OmniRoute ca prieten open source", "kimiPartnerLinkNote": "Link de partener — susține OmniRoute fără costuri suplimentare pentru dvs.", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/ru.json b/src/i18n/messages/ru.json index 2a337ee4fb..363498218a 100644 --- a/src/i18n/messages/ru.json +++ b/src/i18n/messages/ru.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Откройте arena.ai, войдите в систему, затем скопируйте весь заголовок Cookie из сетевого запроса (Network). Включите arena-auth-prod-v1.0 и arena-auth-prod-v1.1 (и последующие части, если они есть), желательно с cf_clearance. Не вставляйте только пустой cookie arena-auth-prod-v1. Необязательно: providerSpecificData.recaptchaV3Token, если create-evaluation по-прежнему возвращает 403.", "kimiOfficialSupporterBadge": "Друг-основатель", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) — друг-основатель открытого кода OmniRoute", + "cheaperInferenceSupporterBadge": "Друг открытого кода", + "cheaperInferenceSupporterTooltip": "Cheaper Inference поддерживает OmniRoute как друг открытого кода", "kimiPartnerLinkNote": "Партнерская ссылка — поддерживает OmniRoute без дополнительных затрат с вашей стороны", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/sk.json b/src/i18n/messages/sk.json index a3ed834ac0..2aa552deed 100644 --- a/src/i18n/messages/sk.json +++ b/src/i18n/messages/sk.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Otvorte arena.ai, prihláste sa a potom skopírujte celú hlavičku Cookie zo sieťovej požiadavky (Network request). Zahrňte arena-auth-prod-v1.0 a arena-auth-prod-v1.1 (a ďalšie časti, ak sú prítomné), najlepšie s cf_clearance. Nevkladajte iba prázdny cookie arena-auth-prod-v1. Voliteľné: providerSpecificData.recaptchaV3Token, ak create-evaluation stále vracia 403.", "kimiOfficialSupporterBadge": "Zakladajúci priateľ", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) je zakladajúci open source priateľ OmniRoute", + "cheaperInferenceSupporterBadge": "Priateľ open source", + "cheaperInferenceSupporterTooltip": "Cheaper Inference podporuje OmniRoute ako priateľ open source", "kimiPartnerLinkNote": "Partnerský odkaz — podporuje OmniRoute bez akýchkoľvek dodatočných nákladov pre vás", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/sv.json b/src/i18n/messages/sv.json index 4cbcc38ea1..46220430ca 100644 --- a/src/i18n/messages/sv.json +++ b/src/i18n/messages/sv.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Öppna arena.ai, logga in och kopiera sedan hela Cookie-headern från en nätverksbegäran. Inkludera arena-auth-prod-v1.0 och arena-auth-prod-v1.1 (och ytterligare delar om de finns), helst med cf_clearance. Klistra inte in bara den tomma arena-auth-prod-v1-cookien. Valfritt: providerSpecificData.recaptchaV3Token om create-evaluation fortfarande returnerar 403.", "kimiOfficialSupporterBadge": "Grundande vän", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) är OmniRoutes grundande öppen källkod-vän", + "cheaperInferenceSupporterBadge": "Öppen källkod-vän", + "cheaperInferenceSupporterTooltip": "Cheaper Inference stödjer OmniRoute som öppen källkod-vän", "kimiPartnerLinkNote": "Partnerlänk — stöder OmniRoute utan extra kostnad för dig", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/sw.json b/src/i18n/messages/sw.json index e85b452beb..031b62968e 100644 --- a/src/i18n/messages/sw.json +++ b/src/i18n/messages/sw.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Fungua arena.ai, ingia, kisha nakili kichwa kizima cha Cookie kutoka kwa ombi la Network. Jumuisha arena-auth-prod-v1.0 na arena-auth-prod-v1.1 (na vipande zaidi vikiwepo), ikiwezekana pamoja na cf_clearance. Usibandike tu kuki tupu ya arena-auth-prod-v1. Ya hiari: providerSpecificData.recaptchaV3Token ikiwa create-evaluation bado inarudisha 403.", "kimiOfficialSupporterBadge": "Rafiki Mwanzilishi", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) ni rafiki mwanzilishi wa chanzo huria wa OmniRoute", + "cheaperInferenceSupporterBadge": "Rafiki wa Chanzo Huria", + "cheaperInferenceSupporterTooltip": "Cheaper Inference inaunga mkono OmniRoute kama Rafiki wa Chanzo Huria", "kimiPartnerLinkNote": "Kiungo cha mshirika — kinaunga mkono OmniRoute bila gharama ya ziada kwako", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/ta.json b/src/i18n/messages/ta.json index b66212a388..31f1c945e7 100644 --- a/src/i18n/messages/ta.json +++ b/src/i18n/messages/ta.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.ai-ஐத் திறந்து, உள்நுழைந்து, பின்னர் Network கோரிக்கையிலிருந்து முழு Cookie தலைப்பை நகலெடுக்கவும். arena-auth-prod-v1.0 மற்றும் arena-auth-prod-v1.1 (மற்றும் கூடுதல் பகுதிகள் இருந்தால்) ஆகியவற்றைச் சேர்க்கவும், முன்னுரிமையாக cf_clearance உடன். வெற்று arena-auth-prod-v1 குக்கியை மட்டும் ஒட்ட வேண்டாம். விருப்பத்தேர்வு: create-evaluation இன்னும் 403-ஐ வழங்கினால் providerSpecificData.recaptchaV3Token.", "kimiOfficialSupporterBadge": "நிறுவன நண்பர்", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) என்பது OmniRoute இன் நிறுவன திறந்த மூல நண்பர் ஆகும்", + "cheaperInferenceSupporterBadge": "திறந்த மூல நண்பர்", + "cheaperInferenceSupporterTooltip": "Cheaper Inference ஒரு திறந்த மூல நண்பராக OmniRoute-ஐ ஆதரிக்கிறது", "kimiPartnerLinkNote": "பங்குதாரர் இணைப்பு — உங்களுக்கு எந்த கூடுதல் கட்டணமும் இன்றி OmniRoute-ஐ ஆதரிக்கிறது", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/te.json b/src/i18n/messages/te.json index ce813f0f93..60ae0fbdf0 100644 --- a/src/i18n/messages/te.json +++ b/src/i18n/messages/te.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.aiని తెరవండి, సైన్ ఇన్ చేయండి, ఆపై నెట్‌వర్క్ అభ్యర్థన నుండి పూర్తి Cookie హెడర్‌ను కాపీ చేయండి. arena-auth-prod-v1.0 మరియు arena-auth-prod-v1.1 (మరియు మరిన్ని భాగాలు ఉంటే వాటిని) చేర్చండి, ప్రాధాన్యంగా cf_clearanceతో. కేవలం ఖాళీ arena-auth-prod-v1 కుకీని మాత్రమే పేస్ట్ చేయవద్దు. ఐచ్ఛికం: create-evaluation ఇప్పటికీ 403ని అందిస్తే providerSpecificData.recaptchaV3Token.", "kimiOfficialSupporterBadge": "వ్యవస్థాపక మిత్రుడు", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) అనేది OmniRoute యొక్క వ్యవస్థాపక ఓపెన్ సోర్స్ మిత్రుడు", + "cheaperInferenceSupporterBadge": "ఓపెన్ సోర్స్ స్నేహితుడు", + "cheaperInferenceSupporterTooltip": "Cheaper Inference ఓపెన్ సోర్స్ స్నేహితురాలిగా OmniRoute కు మద్దతు ఇస్తోంది", "kimiPartnerLinkNote": "భాగస్వామి లింక్ — మీకు ఎటువంటి అదనపు ఖర్చు లేకుండా OmniRouteకు మద్దతు ఇస్తుంది", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/th.json b/src/i18n/messages/th.json index ca78348afe..13cd3a536a 100644 --- a/src/i18n/messages/th.json +++ b/src/i18n/messages/th.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "เปิด arena.ai เข้าสู่ระบบ แล้วคัดลอกส่วนหัว Cookie ทั้งหมดจากคำขอ Network รวม arena-auth-prod-v1.0 และ arena-auth-prod-v1.1 (และส่วนย่อยเพิ่มเติมหากมี) โดยควรมี cf_clearance ด้วย อย่าวางเฉพาะคุกกี้ arena-auth-prod-v1 ที่ว่างเปล่า ไม่บังคับ: providerSpecificData.recaptchaV3Token หาก create-evaluation ยังคงส่งคืน 403", "kimiOfficialSupporterBadge": "เพื่อนผู้ก่อตั้ง", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) คือเพื่อนโอเพนซอร์สผู้ก่อตั้งของ OmniRoute", + "cheaperInferenceSupporterBadge": "เพื่อนโอเพนซอร์ส", + "cheaperInferenceSupporterTooltip": "Cheaper Inference สนับสนุน OmniRoute ในฐานะเพื่อนโอเพนซอร์ส", "kimiPartnerLinkNote": "ลิงก์พันธมิตร — สนับสนุน OmniRoute โดยไม่มีค่าใช้จ่ายเพิ่มเติมสำหรับคุณ", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/tr.json b/src/i18n/messages/tr.json index 43d3035400..dedf6e35f1 100644 --- a/src/i18n/messages/tr.json +++ b/src/i18n/messages/tr.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.ai adresini açın, oturum açın ve ardından bir Ağ isteğinden tam Cookie başlığını kopyalayın. Tercihen cf_clearance ile birlikte arena-auth-prod-v1.0 ve arena-auth-prod-v1.1 (ve varsa diğer parçaları) ekleyin. Yalnızca boş arena-auth-prod-v1 çerezini yapıştırmayın. İsteğe bağlı: create-evaluation hala 403 döndürüyorsa providerSpecificData.recaptchaV3Token.", "kimiOfficialSupporterBadge": "Kurucu Dost", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI), OmniRoute'un kurucu açık kaynak dostu", + "cheaperInferenceSupporterBadge": "Açık Kaynak Dostu", + "cheaperInferenceSupporterTooltip": "Cheaper Inference, OmniRoute'u Açık Kaynak Dostu olarak destekliyor", "kimiPartnerLinkNote": "Ortaklık bağlantısı — size hiçbir ek ücret ödetmeden OmniRoute'u destekler", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/uk-UA.json b/src/i18n/messages/uk-UA.json index 6685571c5d..abcc651e73 100644 --- a/src/i18n/messages/uk-UA.json +++ b/src/i18n/messages/uk-UA.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "Відкрийте arena.ai, увійдіть, а потім скопіюйте повний заголовок Cookie з мережевого запиту. Включіть arena-auth-prod-v1.0 та arena-auth-prod-v1.1 (та наступні частини, якщо вони є), бажано з cf_clearance. Не вставляйте лише порожній cookie arena-auth-prod-v1. Необов'язково: providerSpecificData.recaptchaV3Token, якщо create-evaluation все ще повертає 403.", "kimiOfficialSupporterBadge": "Друг-засновник", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) — друг-засновник відкритого коду OmniRoute", + "cheaperInferenceSupporterBadge": "Друг відкритого коду", + "cheaperInferenceSupporterTooltip": "Cheaper Inference підтримує OmniRoute як друг відкритого коду", "kimiPartnerLinkNote": "Партнерське посилання — підтримує OmniRoute без додаткових витрат для вас", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/ur.json b/src/i18n/messages/ur.json index dedbb20e5e..33b248d777 100644 --- a/src/i18n/messages/ur.json +++ b/src/i18n/messages/ur.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "arena.ai کھولیں، سائن ان کریں، پھر نیٹ ورک کی درخواست سے مکمل Cookie ہیڈر کاپی کریں۔ arena-auth-prod-v1.0 اور arena-auth-prod-v1.1 (اور اگر مزید چنکس موجود ہوں تو انہیں بھی) شامل کریں، ترجیحاً cf_clearance کے ساتھ۔ صرف خالی arena-auth-prod-v1 کوکی پیسٹ نہ کریں۔ اختیاری: providerSpecificData.recaptchaV3Token اگر create-evaluation اب بھی 403 واپس کرتا ہے۔", "kimiOfficialSupporterBadge": "بانی دوست", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) OmniRoute کا بانی اوپن سورس دوست ہے", + "cheaperInferenceSupporterBadge": "اوپن سورس دوست", + "cheaperInferenceSupporterTooltip": "‏Cheaper Inference اوپن سورس دوست کے طور پر OmniRoute کی حمایت کرتی ہے", "kimiPartnerLinkNote": "پارٹنر لنک — آپ کے لیے بغیر کسی اضافی قیمت کے OmniRoute کو سپورٹ کرتا ہے", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/vi.json b/src/i18n/messages/vi.json index 9ad7c0abe6..091e603d25 100644 --- a/src/i18n/messages/vi.json +++ b/src/i18n/messages/vi.json @@ -6001,6 +6001,8 @@ "lmarenaWebCookieHint": "Mở arena.ai, đăng nhập, sau đó sao chép toàn bộ header Cookie từ một yêu cầu mạng. Bao gồm arena-auth-prod-v1.0 và arena-auth-prod-v1.1 (và các phần tiếp theo nếu có), ưu tiên kèm theo cf_clearance. Không chỉ dán cookie arena-auth-prod-v1 trống. Tùy chọn: providerSpecificData.recaptchaV3Token nếu create-evaluation vẫn trả về 403.", "kimiOfficialSupporterBadge": "Người Bạn Sáng Lập", "kimiOfficialSupporterTooltip": "Kimi (Moonshot AI) là người bạn mã nguồn mở sáng lập của OmniRoute", + "cheaperInferenceSupporterBadge": "Người bạn mã nguồn mở", + "cheaperInferenceSupporterTooltip": "Cheaper Inference hỗ trợ OmniRoute với tư cách là người bạn mã nguồn mở", "kimiPartnerLinkNote": "Partner link — supports OmniRoute at no extra cost to you", "ccAliasSectionTitle": "Hiển thị trong Claude Code (claude/…)", "ccAliasSectionHint": "Công bố các mô hình của nhà cung cấp này dưới dạng id phản chiếu claude/<provider>/<model> để tính năng khám phá mô hình qua gateway của Claude Code có thể liệt kê chúng. Mặc định tắt — bật lên sẽ nhân đôi số mục trong danh mục với mọi client.", diff --git a/src/i18n/messages/zh-CN.json b/src/i18n/messages/zh-CN.json index 3bf881c7f0..550c727030 100644 --- a/src/i18n/messages/zh-CN.json +++ b/src/i18n/messages/zh-CN.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "打开 arena.ai,登录,然后从网络请求中复制完整的 Cookie 请求头。包含 arena-auth-prod-v1.0 和 arena-auth-prod-v1.1(如果存在更多分块也一并包含),最好附带 cf_clearance。请勿仅粘贴空的 arena-auth-prod-v1 cookie。可选:如果 create-evaluation 仍返回 403,可提供 providerSpecificData.recaptchaV3Token。", "kimiOfficialSupporterBadge": "创始好友", "kimiOfficialSupporterTooltip": "Kimi(Moonshot AI)是 OmniRoute 的创始开源好友", + "cheaperInferenceSupporterBadge": "开源好友", + "cheaperInferenceSupporterTooltip": "Cheaper Inference 作为开源好友支持 OmniRoute", "kimiPartnerLinkNote": "合作伙伴链接 — 支持 OmniRoute,您无需承担额外费用", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/i18n/messages/zh-TW.json b/src/i18n/messages/zh-TW.json index 638231c2b1..8f64e8beff 100644 --- a/src/i18n/messages/zh-TW.json +++ b/src/i18n/messages/zh-TW.json @@ -5976,6 +5976,8 @@ "lmarenaWebCookieHint": "開啟 arena.ai,登入後從網路請求中複製完整的 Cookie 標頭。請包含 arena-auth-prod-v1.0 和 arena-auth-prod-v1.1(以及後續區塊,如有),最好附帶 cf_clearance。請勿僅貼上空白的 arena-auth-prod-v1 cookie。可選:若 create-evaluation 仍然回傳 403,可提供 providerSpecificData.recaptchaV3Token。", "kimiOfficialSupporterBadge": "創始好友", "kimiOfficialSupporterTooltip": "Kimi(Moonshot AI)是 OmniRoute 的創始開源好友", + "cheaperInferenceSupporterBadge": "開源好友", + "cheaperInferenceSupporterTooltip": "Cheaper Inference 作為開源好友支持 OmniRoute", "kimiPartnerLinkNote": "合作夥伴連結 — 支援 OmniRoute,您無需額外付費", "ccAliasSectionTitle": "__MISSING__:Expose in Claude Code (claude/…)", "ccAliasSectionHint": "__MISSING__:Advertise this provider's models under claude/<provider>/<model> mirror ids so Claude Code's gateway model discovery can list them. Off by default — enabling this doubles catalog entries for all clients.", diff --git a/src/shared/components/ProviderIcon.tsx b/src/shared/components/ProviderIcon.tsx index 07df452556..099912f742 100644 --- a/src/shared/components/ProviderIcon.tsx +++ b/src/shared/components/ProviderIcon.tsx @@ -81,6 +81,7 @@ const KNOWN_SVGS = new Set([ "cartesia", "cerebras", "charm-hyper", + "cheaperinference", "chipotle", "chutes", "clarifai", diff --git a/src/shared/constants/colors.ts b/src/shared/constants/colors.ts index 4cd8e718e5..73730ad244 100644 --- a/src/shared/constants/colors.ts +++ b/src/shared/constants/colors.ts @@ -22,6 +22,8 @@ export const PROVIDER_COLORS = { qoder: { bg: "#EC4899", text: "#fff", label: "Qoder" }, fireworks: { bg: "#F97316", text: "#fff", label: "Fireworks" }, kimi: { bg: "#06B6D4", text: "#fff", label: "Kimi" }, + // Dark foreground: #31f889 is a bright green, white text on it fails contrast. + cheaperinference: { bg: "#31f889", text: "#04170d", label: "Cheaper Inference" }, }; // ═══════════════════════════════════════════ diff --git a/src/shared/constants/pricing/inference-hosts.ts b/src/shared/constants/pricing/inference-hosts.ts index b3dcf7b39f..3ceec84ec5 100644 --- a/src/shared/constants/pricing/inference-hosts.ts +++ b/src/shared/constants/pricing/inference-hosts.ts @@ -15,6 +15,220 @@ export const DEFAULT_PRICING_INFERENCE = { cache_creation: 2.0, }, }, + // Cheaper Inference resale rates — captured from GET /v1/models on 2026-07-31 + // (the catalog reports discount_percent "30.00" against model-maker list price). + // USD per 1M tokens. `reasoning` mirrors `output`: the gateway bills reasoning + // tokens at the output rate. Live drift is available via GET /v1/pricing/changes, + // which is intentionally not auto-synced. + cheaperinference: { + "aion-labs.aion-2-0": { + input: 0.56, + output: 1.12, + cached: 0.175, + reasoning: 1.12, + cache_creation: 0.56, + }, + "claude-fable-5": { + input: 7.0, + output: 35.0, + cached: 0.84, + reasoning: 35.0, + cache_creation: 10.5, + }, + "claude-haiku-4.5": { + input: 1.0, + output: 5.0, + cached: 0.1, + reasoning: 5.0, + cache_creation: 1.0, + }, + "claude-opus-4-7-fast": { + input: 21.0, + output: 105.0, + cached: 2.1, + reasoning: 105.0, + cache_creation: 21.0, + }, + "claude-opus-4-8-fast": { + input: 7.0, + output: 35.0, + cached: 0.7, + reasoning: 35.0, + cache_creation: 7.0, + }, + "claude-opus-4.5": { + input: 3.5, + output: 17.5, + cached: 0.42, + reasoning: 17.5, + cache_creation: 3.5, + }, + "claude-opus-4.6": { + input: 3.5, + output: 17.5, + cached: 0.42, + reasoning: 17.5, + cache_creation: 3.5, + }, + "claude-opus-4.7": { + input: 3.5, + output: 17.5, + cached: 0.42, + reasoning: 17.5, + cache_creation: 3.5, + }, + "claude-opus-4.8": { + input: 4.2, + output: 21.0, + cached: 0.42, + reasoning: 21.0, + cache_creation: 5.25, + }, + "claude-opus-5": { + input: 3.5, + output: 17.5, + cached: 0.35, + reasoning: 17.5, + cache_creation: 4.375, + }, + "claude-opus-5-fast": { + input: 7.0, + output: 35.0, + cached: 0.7, + reasoning: 35.0, + cache_creation: 8.75, + }, + "claude-sonnet-4.5": { + input: 2.1, + output: 10.5, + cached: 0.2625, + reasoning: 10.5, + cache_creation: 3.2812, + }, + "claude-sonnet-4.6": { + input: 2.1, + output: 10.5, + cached: 0.252, + reasoning: 10.5, + cache_creation: 3.15, + }, + "claude-sonnet-5": { + input: 1.4, + output: 7.0, + cached: 0.14, + reasoning: 7.0, + cache_creation: 1.75, + }, + "deepseek-v4-flash": { + input: 0.098, + output: 0.196, + cached: 0.0196, + reasoning: 0.196, + cache_creation: 0.098, + }, + "deepseek-v4-pro": { + input: 0.3045, + output: 0.609, + cached: 0.231, + reasoning: 0.609, + cache_creation: 0.3045, + }, + "gemini-2.5-flash": { + input: 0.21, + output: 1.75, + cached: 0.021, + reasoning: 1.75, + cache_creation: 0.0583, + }, + "gemini-3-5-flash": { + input: 1.05, + output: 6.3, + cached: 0.1085, + reasoning: 6.3, + cache_creation: 0.0602, + }, + "gemini-3-flash-preview": { + input: 0.35, + output: 2.1, + cached: 0.049, + reasoning: 2.1, + cache_creation: 0.35, + }, + "gemini-3.1-flash-lite": { + input: 0.2485, + output: 1.4913, + cached: 0.0249, + reasoning: 1.4913, + cache_creation: 0.0828, + }, + "gemini-3.1-pro": { + input: 2.0, + output: 12.0, + cached: 0.2, + reasoning: 12.0, + cache_creation: 0.375, + }, + "gemini-3.1-pro-preview": { + input: 1.4, + output: 8.4, + cached: 0.4375, + reasoning: 8.4, + cache_creation: 1.4, + }, + "glm-4.5": { input: 0.42, output: 1.54, cached: 0.077, reasoning: 1.54, cache_creation: 0.42 }, + "glm-4.5-air": { + input: 0.14, + output: 0.77, + cached: 0.021, + reasoning: 0.77, + cache_creation: 0.14, + }, + "glm-4.6": { input: 0.42, output: 1.54, cached: 0.21, reasoning: 1.54, cache_creation: 0.42 }, + "glm-4.7": { input: 0.42, output: 1.54, cached: 0.11, reasoning: 1.54, cache_creation: 0.42 }, + "glm-5": { input: 0.7, output: 2.24, cached: 0.2, reasoning: 2.24, cache_creation: 0.7 }, + "glm-5.1": { input: 0.98, output: 3.08, cached: 0.2275, reasoning: 3.08, cache_creation: 0.98 }, + "glm-5.2": { input: 0.77, output: 2.42, cached: 0.11, reasoning: 2.42, cache_creation: 0.77 }, + "google/gemini-3.5-flash-lite": { + input: 0.3, + output: 2.5, + cached: 0.03, + reasoning: 2.5, + cache_creation: 0.3, + }, + "gpt-5.4": { + input: 1.75, + output: 10.5, + cached: 0.2191, + reasoning: 10.5, + cache_creation: 1.75, + }, + "gpt-5.4-mini": { + input: 0.525, + output: 3.15, + cached: 0.0656, + reasoning: 3.15, + cache_creation: 0.525, + }, + "gpt-5.5": { input: 3.5, output: 21.0, cached: 0.4375, reasoning: 21.0, cache_creation: 3.5 }, + "gpt-5.6-luna": { input: 0.4, output: 2.4, cached: 0.05, reasoning: 2.4, cache_creation: 0.4 }, + "gpt-5.6-sol": { + input: 3.5, + output: 21.0, + cached: 0.4375, + reasoning: 21.0, + cache_creation: 3.5, + }, + "gpt-5.6-terra": { input: 1.0, output: 6.0, cached: 0.125, reasoning: 6.0, cache_creation: 1.0 }, + "grok-4.5": { input: 1.4, output: 4.2, cached: 0.35, reasoning: 4.2, cache_creation: 1.4 }, + "kimi-k3": { input: 2.1, output: 10.5, cached: 0.2625, reasoning: 10.5, cache_creation: 2.1 }, + "minimax-m2.7": { + input: 0.168, + output: 0.672, + cached: 0.0525, + reasoning: 0.672, + cache_creation: 0.168, + }, + }, synthetic: { "hf:openai/gpt-oss-120b": { input: 0.1, diff --git a/src/shared/constants/providers/apikey/gateways.ts b/src/shared/constants/providers/apikey/gateways.ts index 7824944098..0382cae471 100644 --- a/src/shared/constants/providers/apikey/gateways.ts +++ b/src/shared/constants/providers/apikey/gateways.ts @@ -3,6 +3,22 @@ * Pure data; merged by apikey/index.ts via spread (god-file decomposition; semantic split). */ export const APIKEY_PROVIDERS_GATEWAYS = { + // Cheaper Inference (https://cheaperinference.com) — OSS-sponsor gateway. + // Cost-ranked reseller of 42 upstream models (Anthropic/OpenAI/Google/Moonshot/ + // xAI/Z.AI/DeepSeek/MiniMax) behind one OpenAI-compatible surface, with a native + // /v1/responses endpoint and 3 image models. Keys are `ir_live_…` bearer tokens. + cheaperinference: { + id: "cheaperinference", + alias: "cinf", + name: "Cheaper Inference", + icon: "savings", + color: "#31f889", + textIcon: "CI", + website: "https://cheaperinference.com", + apiHint: + "Create an API key at https://cheaperinference.com (needs the `inference` scope), then paste the ir_live_… token here.", + passthroughModels: true, + }, "charm-hyper": { id: "charm-hyper", alias: "charm-hyper", diff --git a/tests/snapshots/provider/translate-path.json b/tests/snapshots/provider/translate-path.json index 7f2d7ae323..05494b731c 100644 --- a/tests/snapshots/provider/translate-path.json +++ b/tests/snapshots/provider/translate-path.json @@ -773,6 +773,29 @@ "stream": "https://chatgpt.com/backend-api/conversation" } }, + "cheaperinference": { + "format": "openai", + "headers": { + "apiKey": { + "Accept": "text/event-stream", + "Authorization": "Bearer ", + "Content-Type": "application/json" + }, + "nonStream": { + "Authorization": "Bearer ", + "Content-Type": "application/json" + }, + "oauth": { + "Accept": "text/event-stream", + "Authorization": "Bearer ", + "Content-Type": "application/json" + } + }, + "url": { + "nonStream": "https://api.cheaperinference.com/v1/chat/completions", + "stream": "https://api.cheaperinference.com/v1/chat/completions" + } + }, "chenzk": { "format": "openai", "headers": { diff --git a/tests/unit/cheaperinference-executor.test.ts b/tests/unit/cheaperinference-executor.test.ts new file mode 100644 index 0000000000..ba35d0a4b4 --- /dev/null +++ b/tests/unit/cheaperinference-executor.test.ts @@ -0,0 +1,88 @@ +// Cheaper Inference executor — the two behaviours that make /v1/responses work. +// +// Measured 2026-07-31 against api.cheaperinference.com with a live key: +// POST /v1/responses {"model":"deepseek-v4-flash","input":"hi"} -> 400 +// POST /v1/responses {"model":"deepseek-v4-flash","input":"hi","store":false} -> 200 +// and chatCore.ts strips `store` for every provider !== "openai", so without this +// executor every Responses request through this gateway would 400. +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { CheaperInferenceExecutor } from "@omniroute/open-sse/executors/cheaperinference.ts"; + +const CREDENTIALS = { apiKey: "ir_live_test" } as never; + +test("injects store:false on a Responses-tagged model", () => { + const executor = new CheaperInferenceExecutor(); + // gpt-5.5 is tagged targetFormat:"openai-responses" in the registry. + const out = executor.transformRequest( + "gpt-5.5", + { model: "gpt-5.5", input: "hi" }, + false, + CREDENTIALS + ) as Record; + assert.equal(out.store, false, "Responses requests must carry store:false"); +}); + +test("overwrites a client-supplied store:true — the endpoint is stateless", () => { + const executor = new CheaperInferenceExecutor(); + const out = executor.transformRequest( + "gpt-5.5", + { model: "gpt-5.5", input: "hi", store: true }, + false, + CREDENTIALS + ) as Record; + assert.equal(out.store, false, "store:true would 400 upstream; it must be forced to false"); +}); + +test("does NOT inject store on a chat-completions model", () => { + const executor = new CheaperInferenceExecutor(); + // deepseek-v4-flash has no targetFormat tag -> plain /v1/chat/completions. + const out = executor.transformRequest( + "deepseek-v4-flash", + { model: "deepseek-v4-flash", messages: [{ role: "user", content: "hi" }] }, + false, + CREDENTIALS + ) as Record; + assert.ok(!("store" in out), "chat/completions rejects unknown params; do not add store there"); +}); + +test("resolves the Responses URL only for Responses-tagged models", () => { + const executor = new CheaperInferenceExecutor(); + assert.equal( + executor.buildUrl("gpt-5.5", false, 0), + "https://api.cheaperinference.com/v1/responses" + ); + assert.equal( + executor.buildUrl("deepseek-v4-flash", false, 0), + "https://api.cheaperinference.com/v1/chat/completions" + ); +}); + +test("REGRESSION: targetFormat lookup resolves the provider ALIAS, not the id", async () => { + // PROVIDER_MODELS is keyed by alias ("cinf"); PROVIDERS is keyed by id + // ("cheaperinference"). Passing the raw provider id to getModelTargetFormat — + // which is what executors/xai.ts does, safely, because there alias === id — + // returns null here, silently downgrading every Responses model to + // chat-completions and 400ing upstream. This asserts the two keyings really do + // differ, so the alias resolution in the executor is not accidental. + const { PROVIDER_MODELS, PROVIDER_ID_TO_ALIAS, getModelTargetFormat } = await import( + "@omniroute/open-sse/config/providerModels.ts" + ); + assert.equal(PROVIDER_ID_TO_ALIAS.cheaperinference, "cinf"); + assert.ok(PROVIDER_MODELS.cinf, "PROVIDER_MODELS is keyed by alias"); + assert.equal(PROVIDER_MODELS.cheaperinference, undefined, "…and NOT by provider id"); + assert.equal(getModelTargetFormat("cheaperinference", "gpt-5.5"), null); + assert.equal(getModelTargetFormat("cinf", "gpt-5.5"), "openai-responses"); +}); + +test("preserves the body the base executor already sanitized", () => { + const executor = new CheaperInferenceExecutor(); + const out = executor.transformRequest( + "gpt-5.5", + { model: "gpt-5.5", input: "hi", temperature: 0.3, tools: [] }, + false, + CREDENTIALS + ) as Record; + assert.equal(out.model, "gpt-5.5"); + assert.equal(out.temperature, 0.3); +}); diff --git a/tests/unit/cheaperinference-image-models.test.ts b/tests/unit/cheaperinference-image-models.test.ts new file mode 100644 index 0000000000..7a85fc5a8d --- /dev/null +++ b/tests/unit/cheaperinference-image-models.test.ts @@ -0,0 +1,53 @@ +// Cheaper Inference image models + the Adobe Firefly collision guard. +// +// nano-banana-pro / nano-banana-2 exist in BOTH providers. parseImageModel resolves a +// bare id by first-match over IMAGE_PROVIDERS iteration order, so the bare ids must +// keep going to adobe-firefly (pre-existing behaviour) and Cheaper Inference must be +// reachable only via its prefix. Operator decision 2026-07-31. +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { IMAGE_PROVIDERS, parseImageModel } from "@omniroute/open-sse/config/imageRegistry.ts"; + +test("cheaperinference is registered as an image provider with the 3 measured models", () => { + const provider = IMAGE_PROVIDERS.cheaperinference; + assert.ok(provider, "cheaperinference missing from IMAGE_PROVIDERS"); + assert.equal(provider.baseUrl, "https://api.cheaperinference.com/v1/images/generations"); + assert.equal(provider.authType, "apikey"); + assert.equal(provider.authHeader, "bearer"); + assert.equal(provider.format, "openai"); + assert.equal(provider.alias, "cinf"); + const ids = provider.models.map((m) => m.id).sort(); + assert.deepEqual(ids, ["grok-imagine", "nano-banana-2", "nano-banana-pro"]); +}); + +test("prefixed ids resolve to cheaperinference", () => { + assert.deepEqual(parseImageModel("cheaperinference/nano-banana-2"), { + provider: "cheaperinference", + model: "nano-banana-2", + }); + assert.deepEqual(parseImageModel("cinf/grok-imagine"), { + provider: "cheaperinference", + model: "grok-imagine", + }); +}); + +test("REGRESSION GUARD: bare nano-banana ids still route to adobe-firefly", () => { + // If this flips to cheaperinference, someone added an IMAGE_MODEL_ALIASES entry + // (forbidden) or declared cheaperinference before adobe-firefly in IMAGE_PROVIDERS. + assert.equal(parseImageModel("nano-banana-2").provider, "adobe-firefly"); + assert.equal(parseImageModel("nano-banana-pro").provider, "adobe-firefly"); +}); + +test("cheaperinference image models are NOT in the chat registry", async () => { + const { REGISTRY } = await import("@omniroute/open-sse/config/providers/index.ts"); + const chatIds = new Set( + (REGISTRY.cheaperinference as unknown as { models: Array<{ id: string }> }).models.map( + (m) => m.id + ) + ); + // Upstream returns HTTP 400 for these on /v1/chat/completions: + // "…is an image-generation model. Use POST /v1/images/generations." + for (const id of ["grok-imagine", "nano-banana-2", "nano-banana-pro"]) { + assert.ok(!chatIds.has(id), `${id} must not be routable as a chat model`); + } +}); diff --git a/tests/unit/cheaperinference-provider-registration.test.ts b/tests/unit/cheaperinference-provider-registration.test.ts new file mode 100644 index 0000000000..dd1e47fafa --- /dev/null +++ b/tests/unit/cheaperinference-provider-registration.test.ts @@ -0,0 +1,110 @@ +// Cheaper Inference (api.cheaperinference.com) — OSS-sponsor gateway provider. +// Locks the canonical catalog entry so the id/alias/brand cannot drift, and +// guards the two invariants the provider gates enforce (Zod shape + a registry +// entry that maps back to a canonical provider). +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { + AI_PROVIDERS, + getProviderByAlias, + USAGE_SUPPORTED_PROVIDERS, +} from "@/shared/constants/providers"; + +test("cheaperinference is a canonical provider with the agreed id/alias/brand", () => { + const provider = AI_PROVIDERS.cheaperinference as unknown as Record; + assert.ok(provider, "cheaperinference missing from AI_PROVIDERS"); + assert.equal(provider.id, "cheaperinference"); + assert.equal(provider.alias, "cinf"); + assert.equal(provider.name, "Cheaper Inference"); + // Brand green from the supplied logomark (stroke="#31f889"). + assert.equal(provider.color, "#31f889"); + assert.match(String(provider.website), /^https:\/\/cheaperinference\.com/); +}); + +test("cheaperinference resolves by alias", () => { + // getProviderByAlias is the alias-aware lookup; getProviderById indexes by + // catalog key only and would never resolve "cinf". + const byAlias = getProviderByAlias("cinf") as unknown as Record | null; + assert.ok(byAlias, "alias cinf does not resolve"); + assert.equal(byAlias.id, "cheaperinference"); +}); + +test("cheaperinference is NOT wired into any quota/usage surface", () => { + // Operator decision 2026-07-31: no quota card. The provider exposes no + // balance API (/v1/wallet and /v1/balance both 404), so a quota card would + // have to invent a number. Guard the decision so a later sweep does not + // silently add one. + assert.ok( + !USAGE_SUPPORTED_PROVIDERS.includes("cheaperinference"), + "cheaperinference must not be in USAGE_SUPPORTED_PROVIDERS (no balance API upstream)" + ); +}); + +test("cheaperinference registry entry points at the measured API surface", async () => { + const { REGISTRY } = await import("@omniroute/open-sse/config/providers/index.ts"); + const entry = REGISTRY.cheaperinference as unknown as Record; + assert.ok(entry, "cheaperinference missing from REGISTRY"); + assert.equal(entry.format, "openai"); + assert.equal(entry.authType, "apikey"); + assert.equal(entry.authHeader, "bearer"); + assert.equal(entry.executor, "cheaperinference"); + assert.equal(entry.baseUrl, "https://api.cheaperinference.com/v1/chat/completions"); + assert.equal(entry.responsesBaseUrl, "https://api.cheaperinference.com/v1/responses"); +}); + +test("cheaperinference catalog matches the measured GET /v1/models text set", async () => { + const { REGISTRY } = await import("@omniroute/open-sse/config/providers/index.ts"); + const models = (REGISTRY.cheaperinference as unknown as { models: Array<{ id: string }> }) + .models; + // 39 text models measured on 2026-07-31; the 3 image models live in + // imageRegistry.ts, never here (chat requests for them 400 upstream). + assert.equal(models.length, 39); + const ids = new Set(models.map((m) => m.id)); + for (const expected of ["claude-opus-5", "gpt-5.4", "kimi-k3", "deepseek-v4-flash", "grok-4.5"]) { + assert.ok(ids.has(expected), `missing model ${expected}`); + } + for (const imageOnly of ["nano-banana-2", "nano-banana-pro", "grok-imagine"]) { + assert.ok(!ids.has(imageOnly), `${imageOnly} is image-only and must not be a chat model`); + } +}); + +test("cheaperinference tags its Responses-capable models", async () => { + const { REGISTRY } = await import("@omniroute/open-sse/config/providers/index.ts"); + const models = ( + REGISTRY.cheaperinference as unknown as { + models: Array<{ id: string; targetFormat?: string }>; + } + ).models; + const responsesModels = models.filter((m) => m.targetFormat === "openai-responses"); + assert.ok(responsesModels.length > 0, "no model routed to the native /v1/responses endpoint"); + for (const m of responsesModels) { + assert.match(m.id, /^gpt-5\./, "only the GPT-5.x family is tagged for native Responses"); + } +}); + +test("cheaperinference resale pricing covers every catalog model", async () => { + const { DEFAULT_PRICING } = await import("@/shared/constants/pricing/default-pricing"); + const { REGISTRY } = await import("@omniroute/open-sse/config/providers/index.ts"); + const pricing = (DEFAULT_PRICING as Record>).cheaperinference; + assert.ok(pricing, "no pricing block for cheaperinference"); + const models = (REGISTRY.cheaperinference as unknown as { models: Array<{ id: string }> }) + .models; + for (const model of models) { + assert.ok(pricing[model.id], `missing pricing for ${model.id}`); + } +}); + +test("cheaperinference pricing uses the gateway's discounted rates, not list price", async () => { + const { DEFAULT_PRICING } = (await import("@/shared/constants/pricing/default-pricing")) as { + DEFAULT_PRICING: Record>>; + }; + // Measured 2026-07-31: the gateway resells claude-opus-5 at $3.50/$17.50 per 1M + // (30% off Anthropic list). A drift here means the table was copied from the + // model maker instead of GET /v1/models. + const opus = DEFAULT_PRICING.cheaperinference["claude-opus-5"]; + assert.equal(opus.input, 3.5); + assert.equal(opus.output, 17.5); + const flash = DEFAULT_PRICING.cheaperinference["deepseek-v4-flash"]; + assert.equal(flash.input, 0.098); + assert.equal(flash.output, 0.196); +}); diff --git a/tests/unit/featured-providers-rank.test.ts b/tests/unit/featured-providers-rank.test.ts new file mode 100644 index 0000000000..71d33b7bea --- /dev/null +++ b/tests/unit/featured-providers-rank.test.ts @@ -0,0 +1,72 @@ +// Featured-provider ordering on /dashboard/providers. +// +// The sponsor rail is explicitly ranked, not alphabetical: Kimi (founding friend) +// first, Cheaper Inference second, everything else alphabetical below them. A plain +// Set would order "Cheaper Inference" ABOVE "Kimi" alphabetically — the exact bug +// this rank map exists to prevent. +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { + getFeaturedProviderRank, + isFeaturedProviderId, + SPONSOR_BRAND_COLORS, +} from "@/app/(dashboard)/dashboard/providers/featuredProviders"; +import { sortProviderEntriesFeaturedFirst } from "@/app/(dashboard)/dashboard/providers/providerPageUtils"; + +const entry = (providerId: string, name: string) => + ({ + providerId, + provider: { id: providerId, name }, + stats: { total: 0 }, + displayAuthType: "apikey" as const, + toggleAuthType: "apikey" as const, + }) as never; + +test("Kimi family ranks 1, Cheaper Inference ranks 2", () => { + assert.equal(getFeaturedProviderRank("moonshot"), 1); + assert.equal(getFeaturedProviderRank("kimi-coding"), 1); + assert.equal(getFeaturedProviderRank("kimi-web"), 1); + assert.equal(getFeaturedProviderRank("cheaperinference"), 2); + assert.equal(getFeaturedProviderRank("openrouter"), null); +}); + +test("isFeaturedProviderId still answers for every ranked provider", () => { + assert.equal(isFeaturedProviderId("moonshot"), true); + assert.equal(isFeaturedProviderId("cheaperinference"), true); + assert.equal(isFeaturedProviderId("openrouter"), false); + assert.equal(isFeaturedProviderId(null), false); +}); + +test("sort puts Kimi first and Cheaper Inference second despite the alphabet", () => { + // Deliberately seeded in an order where a naive alphabetical sort fails: + // "Anthropic" < "Cheaper Inference" < "Kimi" < "Zed". + const sorted = sortProviderEntriesFeaturedFirst([ + entry("zed", "Zed"), + entry("cheaperinference", "Cheaper Inference"), + entry("anthropic", "Anthropic"), + entry("moonshot", "Kimi"), + ]); + assert.deepEqual( + sorted.map((e) => e.providerId), + ["moonshot", "cheaperinference", "anthropic", "zed"] + ); +}); + +test("providers sharing a rank stay alphabetical among themselves", () => { + const sorted = sortProviderEntriesFeaturedFirst([ + entry("kimi-web", "Kimi Web"), + entry("moonshot", "Kimi"), + entry("cheaperinference", "Cheaper Inference"), + ]); + // Both Kimi entries are rank 1 -> alphabetical between them ("Kimi" < "Kimi Web"), + // and both still precede rank 2. + assert.deepEqual( + sorted.map((e) => e.providerId), + ["moonshot", "kimi-web", "cheaperinference"] + ); +}); + +test("each sponsor declares a brand color used by the card accent", () => { + assert.equal(SPONSOR_BRAND_COLORS.moonshot, "#1783FF"); + assert.equal(SPONSOR_BRAND_COLORS.cheaperinference, "#31f889"); +}); diff --git a/tests/unit/providers-constants-split.test.ts b/tests/unit/providers-constants-split.test.ts index ac6f4b2ace..e885fae237 100644 --- a/tests/unit/providers-constants-split.test.ts +++ b/tests/unit/providers-constants-split.test.ts @@ -1,7 +1,7 @@ // Characterization of the providers.ts catalog split (god-file decomposition): the host became a // barrel that re-exports 10 data catalogs now living under constants/providers/*, and APIKEY is // merged from 6 semantic family files (apikey/.ts). Locks: the public surface (every catalog -// + helpers still exported), the spread-merge integrity (195 APIKEY entries, no loss/dup), and that +// + helpers still exported), the spread-merge integrity (196 APIKEY entries, no loss/dup), and that // load-time Zod validation still runs. Pure-data move → behavior must be identical. // Count was 171 before obsolete provider removals (PR #6675: glhf/kluster/cablyai/inclusionai etc., // 171->167) plus #6126 (ClinePass dual-auth): the API-key-only APIKEY_PROVIDERS_GATEWAYS entry was @@ -16,7 +16,8 @@ // internlm/ant-ling, all regional) to 190, then #8161 (sarvam/writer/plamo — writer in frontier-labs, // sarvam+plamo in regional) to 193, then #8170 (inception/typhoon — inception in frontier-labs, // typhoon in regional) to 195, then Firecrawl dual search+fetch under SEARCH_PROVIDERS.firecrawl -// (removed specialty-media duplicate) to 194, and #8861 (Xiaomi MiMo Token Plan, regional) to 195. +// (removed specialty-media duplicate) to 194, #8861 (Xiaomi MiMo Token Plan, regional) to 195, and +// the Cheaper Inference gateway (OSS-sponsor reseller, gateways family) to 196. import { test } from "node:test"; import assert from "node:assert/strict"; @@ -45,12 +46,12 @@ test("barrel still exports every catalog + key helpers", () => { } }); -test("APIKEY_PROVIDERS merges the 6 family files into 195 entries (no loss / no dup)", async () => { +test("APIKEY_PROVIDERS merges the 6 family files into 196 entries (no loss / no dup)", async () => { const keys = Object.keys((P as Record).APIKEY_PROVIDERS); - assert.equal(keys.length, 195); - assert.equal(new Set(keys).size, 195, "duplicate keys after spread-merge"); + assert.equal(keys.length, 196); + assert.equal(new Set(keys).size, 196, "duplicate keys after spread-merge"); // the merged object's entry-count equals the sum of the 6 semantic family files; families are a - // strict partition (every provider in exactly one), so the sum must be exactly 195. + // strict partition (every provider in exactly one), so the sum must be exactly 196. const families: [string, string][] = [ ["gateways", "APIKEY_PROVIDERS_GATEWAYS"], ["frontier-labs", "APIKEY_PROVIDERS_FRONTIER"], @@ -70,7 +71,7 @@ test("APIKEY_PROVIDERS merges the 6 family files into 195 entries (no loss / no seen.add(k); } } - assert.equal(famTotal, 195, "families must partition all 195 providers"); + assert.equal(famTotal, 196, "families must partition all 196 providers"); }); test("AI_PROVIDERS Proxy aggregates all sections; lookups resolve", () => {