From 808769189072c388d496adefb173ac2db65ed837 Mon Sep 17 00:00:00 2001 From: yrooogerg Date: Tue, 28 Jul 2026 16:23:26 +0800 Subject: [PATCH 1/5] feat(providers): add Volcengine Ark presets --- .../src/content/docs/guides/providers.md | 9 +- .../src/content/docs/ja/guides/providers.md | 9 +- .../src/content/docs/ko/guides/providers.md | 9 +- .../src/content/docs/ru/guides/providers.md | 9 +- .../content/docs/zh-cn/guides/providers.md | 8 +- gui/src/provider-icons.ts | 3 + src/providers/derive.ts | 4 + src/providers/registry.ts | 46 ++++++- src/router.ts | 3 + structure/00_overview.md | 3 +- tests/provider-registry-parity.test.ts | 2 +- tests/volcengine-providers.test.ts | 129 ++++++++++++++++++ 12 files changed, 226 insertions(+), 8 deletions(-) create mode 100644 tests/volcengine-providers.test.ts diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index 2e70c4dae..c303ceeef 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -182,7 +182,7 @@ selectors, then retry. Signing in from a machine with no existing `kiro-cli` ses ## 3. API-key catalog -opencodex ships 53 built-in presets: 42 key-based, seven OAuth, three local, and the default +opencodex ships 63 built-in presets: 52 key-based, seven OAuth, three local, and the default ChatGPT-forward preset. The dashboard's **Add provider** picker opens a key provider's dashboard, validates the key, and stores it. Notable entries: @@ -209,6 +209,7 @@ validates the key, and stores it. Notable entries: | Qwen Cloud | Token plan (default): `https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1` · Pay as you go: `https://dashscope.aliyuncs.com/compatible-mode/v1` · or Custom | | Tencent Cloud Coding Plan | `https://api.lkeap.cloud.tencent.com/coding/v3` | | SiliconFlow | `https://api.siliconflow.cn/v1` | +| Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitLab Duo | `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | @@ -217,6 +218,12 @@ validates the key, and stores it. Notable entries: Most use the `openai-chat` adapter with a bearer key; a few that expose only an Anthropic-compatible endpoint (e.g. **Xiaomi MiMo**) use the `anthropic` adapter (`x-api-key`). +Volcengine Agent Plan uses its native Responses endpoint through `openai-responses`. + +> **Three Volcengine billing routes:** `volcengine` is the pay-as-you-go Ark API, +> `volcengine-coding-plan` consumes Coding Plan quota, and `volcengine-agent-plan` consumes Agent +> Plan quota. Use the key and endpoint issued for the same product; the ordinary `/api/v3` endpoint +> can incur pay-as-you-go charges even when a Plan subscription exists. > **Tencent Cloud Coding Plan usage restriction:** Tencent documents this subscription for > interactive coding tools only. General API automation, custom application backends, and diff --git a/docs-site/src/content/docs/ja/guides/providers.md b/docs-site/src/content/docs/ja/guides/providers.md index ef2dd1d54..cf56adea3 100644 --- a/docs-site/src/content/docs/ja/guides/providers.md +++ b/docs-site/src/content/docs/ja/guides/providers.md @@ -116,7 +116,7 @@ Kiro のログインには Kiro CLI が必要です。`curl -fsSL https://cli.ki ## 3. API キーカタログ -opencodex v2.7.1 には組み込みプリセットが 50 個含まれています。キー方式 40、OAuth 6、ローカル 3、 +opencodex には組み込みプリセットが 63 個含まれています。キー方式 52、OAuth 7、ローカル 3、 デフォルト ChatGPT 転送プリセット 1 です。ダッシュボードの **Add provider** ピッカーはキー発行ページを開き、 入力したキーを検証した後保存します。主な項目は以下のとおりです: @@ -143,6 +143,7 @@ opencodex v2.7.1 には組み込みプリセットが 50 個含まれていま | Qwen Cloud | トークンプラン(デフォルト): `https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1` · 従量課金: `https://dashscope.aliyuncs.com/compatible-mode/v1` · またはカスタム | | Tencent Cloud Coding Plan | `https://api.lkeap.cloud.tencent.com/coding/v3` | | SiliconFlow | `https://api.siliconflow.cn/v1` | +| Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitHub Copilot · GitLab Duo | `https://api.githubcopilot.com` · `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | @@ -151,6 +152,12 @@ opencodex v2.7.1 には組み込みプリセットが 50 個含まれていま 大半は bearer キーと共に `openai-chat` アダプターを使い、Anthropic 互換エンドポイントのみを公開する一部 (例: **Xiaomi MiMo**)は `anthropic` アダプター(`x-api-key`)を使います。 +Volcengine Agent Plan は `openai-responses` アダプターでネイティブ Responses エンドポイントを使用します。 + +> **Volcengine の 3 つの課金経路:** `volcengine` は従量課金 Ark API、 +> `volcengine-coding-plan` は Coding Plan の割り当て、`volcengine-agent-plan` は Agent Plan +> の割り当てを使用します。同じ製品で発行されたキーとエンドポイントを組み合わせてください。 +> Plan 契約があっても通常の `/api/v3` 呼び出しには従量課金が発生する場合があります。 > **Tencent Cloud Coding Plan の利用制限:** Tencent はこのサブスクリプションを対話型 > コーディングツール専用としています。一般的な API 自動化、カスタムアプリのバックエンド、 diff --git a/docs-site/src/content/docs/ko/guides/providers.md b/docs-site/src/content/docs/ko/guides/providers.md index 208839d81..b8f770930 100644 --- a/docs-site/src/content/docs/ko/guides/providers.md +++ b/docs-site/src/content/docs/ko/guides/providers.md @@ -116,7 +116,7 @@ Kiro 로그인에는 Kiro CLI가 필요합니다. `curl -fsSL https://cli.kiro.d ## 3. API 키 카탈로그 -opencodex v2.7.1에는 빌트인 프리셋이 50개 들어 있습니다. 키 방식 40개, OAuth 6개, 로컬 3개, +opencodex에는 빌트인 프리셋이 63개 들어 있습니다. 키 방식 52개, OAuth 7개, 로컬 3개, 기본 ChatGPT 포워드 프리셋 1개입니다. 대시보드의 **Add provider** 선택기는 키 발급 페이지를 열고, 입력한 키를 검증한 뒤 저장합니다. 주요 항목은 다음과 같습니다: @@ -143,6 +143,7 @@ opencodex v2.7.1에는 빌트인 프리셋이 50개 들어 있습니다. 키 방 | Qwen Cloud | Token plan(기본): `https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1` · 종량제: `https://dashscope.aliyuncs.com/compatible-mode/v1` · 또는 사용자 지정 | | Tencent Cloud Coding Plan | `https://api.lkeap.cloud.tencent.com/coding/v3` | | SiliconFlow | `https://api.siliconflow.cn/v1` | +| Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitHub Copilot · GitLab Duo | `https://api.githubcopilot.com` · `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | @@ -151,6 +152,12 @@ opencodex v2.7.1에는 빌트인 프리셋이 50개 들어 있습니다. 키 방 대부분은 bearer 키와 함께 `openai-chat` 어댑터를 사용하며, Anthropic 호환 엔드포인트만 노출하는 일부 (예: **Xiaomi MiMo**)는 `anthropic` 어댑터(`x-api-key`)를 사용합니다. +Volcengine Agent Plan은 `openai-responses` 어댑터로 네이티브 Responses 엔드포인트를 사용합니다. + +> **Volcengine의 세 가지 과금 경로:** `volcengine`은 종량제 Ark API, +> `volcengine-coding-plan`은 Coding Plan 할당량, `volcengine-agent-plan`은 Agent Plan +> 할당량을 사용합니다. 같은 상품에서 발급된 키와 엔드포인트를 함께 사용해야 하며, Plan 구독이 +> 있어도 일반 `/api/v3` 엔드포인트 호출에는 종량제 요금이 발생할 수 있습니다. > **Tencent Cloud Coding Plan 사용 제한:** Tencent는 이 구독을 대화형 코딩 도구 전용으로 > 안내합니다. 일반 API 자동화, 사용자 애플리케이션 백엔드 및 비대화형 일괄 호출은 금지되며 diff --git a/docs-site/src/content/docs/ru/guides/providers.md b/docs-site/src/content/docs/ru/guides/providers.md index d6df82506..11c0b9f12 100644 --- a/docs-site/src/content/docs/ru/guides/providers.md +++ b/docs-site/src/content/docs/ru/guides/providers.md @@ -126,7 +126,7 @@ OAuth-провайдеры, чьи учётные данные содержат ## 3. Каталог API-ключей -opencodex поставляется с 53 встроенными пресетами: 42 на основе ключей, семь OAuth, три локальных и +opencodex поставляется с 63 встроенными пресетами: 52 на основе ключей, семь OAuth, три локальных и пресет ChatGPT-форварда по умолчанию. Селектор **Add provider** в дашборде открывает страницу выдачи ключей провайдера, проверяет ключ и сохраняет его. Наиболее заметные записи: @@ -153,6 +153,7 @@ opencodex поставляется с 53 встроенными пресетам | Qwen Cloud | Token plan (по умолчанию): `https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1` · Pay as you go: `https://dashscope.aliyuncs.com/compatible-mode/v1` · или Custom | | Tencent Cloud Coding Plan | `https://api.lkeap.cloud.tencent.com/coding/v3` | | SiliconFlow | `https://api.siliconflow.cn/v1` | +| Volcengine Ark · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitLab Duo | `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | @@ -162,6 +163,12 @@ opencodex поставляется с 53 встроенными пресетам Большинство использует адаптер `openai-chat` с bearer-ключом; немногие провайдеры, предоставляющие только Anthropic-совместимую конечную точку (например, **Xiaomi MiMo**), используют адаптер `anthropic` (`x-api-key`). +Volcengine Agent Plan использует нативную конечную точку Responses через адаптер `openai-responses`. + +> **Три маршрута тарификации Volcengine:** `volcengine` — Ark API с оплатой по факту, +> `volcengine-coding-plan` расходует квоту Coding Plan, а `volcengine-agent-plan` — квоту Agent +> Plan. Используйте ключ и конечную точку одного продукта; обычный `/api/v3` может тарифицироваться +> отдельно даже при активной подписке Plan. > **Ограничение Tencent Cloud Coding Plan:** Tencent разрешает использовать эту подписку только > в интерактивных инструментах программирования. Автоматизация общего API, серверы пользовательских diff --git a/docs-site/src/content/docs/zh-cn/guides/providers.md b/docs-site/src/content/docs/zh-cn/guides/providers.md index 357ddbcac..09b142a6c 100644 --- a/docs-site/src/content/docs/zh-cn/guides/providers.md +++ b/docs-site/src/content/docs/zh-cn/guides/providers.md @@ -108,7 +108,7 @@ Kiro 登录需要 Kiro CLI:使用 `curl -fsSL https://cli.kiro.dev/install | b ## 3. API 密钥目录 -opencodex v2.7.1 内置 50 个预设:40 个密钥预设、6 个 OAuth 预设、3 个本地预设,以及默认的 +opencodex 内置 63 个预设:52 个密钥预设、7 个 OAuth 预设、3 个本地预设,以及默认的 ChatGPT 转发预设。仪表盘的 **Add provider** 选择器会打开密钥提供商的控制台,验证并保存密钥。 主要条目包括: @@ -135,6 +135,7 @@ ChatGPT 转发预设。仪表盘的 **Add provider** 选择器会打开密钥提 | Qwen Cloud | Token plan(默认): `https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1` · 按量付费: `https://dashscope.aliyuncs.com/compatible-mode/v1` · 或自定义 | | 腾讯云 Coding Plan | `https://api.lkeap.cloud.tencent.com/coding/v3` | | SiliconFlow | `https://api.siliconflow.cn/v1` | +| 火山方舟 · Coding Plan · Agent Plan | `https://ark.cn-beijing.volces.com/api/v3` · `https://ark.cn-beijing.volces.com/api/coding/v3` · `https://ark.cn-beijing.volces.com/api/plan/v3` | | Xiaomi MiMo | `https://api.xiaomimimo.com/anthropic` | | Kilo | `https://api.kilo.ai/api/gateway` | | GitHub Copilot · GitLab Duo | `https://api.githubcopilot.com` · `https://cloud.gitlab.com/ai/v1/proxy/openai/v1` | @@ -142,6 +143,11 @@ ChatGPT 转发预设。仪表盘的 **Add provider** 选择器会打开密钥提 | ……以及更多 | opencode zen、Vercel AI Gateway、Venice、NanoGPT、Synthetic、Qianfan、Alibaba、Parallel、ZenMux、LiteLLM | 大多数使用带 bearer 密钥的 `openai-chat` adapter;少数仅暴露 Anthropic 兼容端点的提供商(例如 **Xiaomi MiMo**)使用 `anthropic` adapter(`x-api-key`)。 +火山方舟 Agent Plan 通过 `openai-responses` adapter 使用原生 Responses 端点。 + +> **三条火山方舟计费线路:**`volcengine` 是按量付费方舟 API,`volcengine-coding-plan` +> 消耗 Coding Plan 额度,`volcengine-agent-plan` 消耗 Agent Plan 额度。密钥与端点需要属于 +> 同一产品;已经订阅 Plan 时调用普通 `/api/v3` 端点仍可能产生按量费用。 > **腾讯云 Coding Plan 使用限制:**腾讯将此订阅限定为交互式编程工具使用。禁止通用 API > 自动化、自定义应用后端和非交互式批量调用;违规使用可能导致套餐密钥被停用。 diff --git a/gui/src/provider-icons.ts b/gui/src/provider-icons.ts index 6249a91ca..3c2faabee 100644 --- a/gui/src/provider-icons.ts +++ b/gui/src/provider-icons.ts @@ -87,6 +87,9 @@ const PROVIDER_DISPLAY_NAMES: Record = { "qwen-cloud": "Qwen Cloud", siliconflow: "SiliconFlow", "tencent-coding-plan": "Tencent Cloud Coding Plan", + volcengine: "Volcengine Ark", + "volcengine-coding-plan": "Volcengine Ark Coding Plan", + "volcengine-agent-plan": "Volcengine Ark Agent Plan", "vercel-ai-gateway": "Vercel AI Gateway", vllm: "vLLM", litellm: "LiteLLM", diff --git a/src/providers/derive.ts b/src/providers/derive.ts index 5a44d7e7a..1172bb589 100644 --- a/src/providers/derive.ts +++ b/src/providers/derive.ts @@ -4,6 +4,7 @@ import { PROVIDER_REGISTRY, type ProviderRegistryEntry } from "./registry"; export interface DerivedKeyLoginProvider { label: string; baseUrl: string; + responsesPath?: string; adapter: string; apiKeyTransport?: OcxProviderConfig["apiKeyTransport"]; dashboardUrl: string; @@ -105,6 +106,7 @@ export function providerConfigSeed(entry: ProviderRegistryEntry): OcxProviderCon adapter: entry.adapter, baseUrl: entry.baseUrl, ...(entry.apiKeyTransport !== undefined ? { apiKeyTransport: entry.apiKeyTransport } : {}), + ...(entry.responsesPath ? { responsesPath: entry.responsesPath } : {}), authMode: entry.authKind === "local" ? undefined : entry.authKind, ...(entry.codexAccountMode ? { codexAccountMode: entry.codexAccountMode } : {}), ...(entry.keyOptional !== undefined ? { keyOptional: entry.keyOptional } : {}), @@ -152,6 +154,7 @@ export function deriveKeyLoginMap(): Record { out[entry.id] = { label: entry.label, baseUrl: entry.baseUrl, + ...(entry.responsesPath ? { responsesPath: entry.responsesPath } : {}), adapter: entry.adapter, ...(entry.apiKeyTransport !== undefined ? { apiKeyTransport: entry.apiKeyTransport } : {}), dashboardUrl: entry.dashboardUrl, @@ -227,6 +230,7 @@ export function enrichProviderFromRegistry(name: string, prov: OcxProviderConfig const seed = providerConfigSeed(entry); if (prov.apiKeyTransport === undefined && seed.apiKeyTransport !== undefined) prov.apiKeyTransport = seed.apiKeyTransport; if (!prov.defaultModel && seed.defaultModel) prov.defaultModel = seed.defaultModel; + if (prov.responsesPath === undefined && seed.responsesPath !== undefined) prov.responsesPath = seed.responsesPath; // Fill mode only when absent: an explicit persisted `direct` must never be overwritten. if (prov.codexAccountMode === undefined && seed.codexAccountMode !== undefined) prov.codexAccountMode = seed.codexAccountMode; if (!prov.models && seed.models) prov.models = [...seed.models]; diff --git a/src/providers/registry.ts b/src/providers/registry.ts index 7fea6644f..c6fe403b4 100644 --- a/src/providers/registry.ts +++ b/src/providers/registry.ts @@ -23,6 +23,8 @@ export interface ProviderRegistryEntry { adapter: string; baseUrl: string; apiKeyTransport?: OcxProviderConfig["apiKeyTransport"]; + /** Relative Responses resource for key-auth openai-responses gateways with versioned bases. */ + responsesPath?: string; authKind: ProviderAuthKind; codexAccountMode?: CodexAccountMode; /** OAuth preset may explicitly honor a persisted API-key billing mode. */ @@ -89,7 +91,7 @@ export interface ProviderRegistryEntry { export type ProviderConfigSeed = Pick< OcxProviderConfig, - "adapter" | "baseUrl" | "apiKeyTransport" | "authMode" | "keyOptional" | "freeTier" | "modelSuffixBracketStrip" | "defaultModel" | "models" + "adapter" | "baseUrl" | "apiKeyTransport" | "responsesPath" | "authMode" | "keyOptional" | "freeTier" | "modelSuffixBracketStrip" | "defaultModel" | "models" | "liveModels" | "contextWindow" | "modelContextWindows" | "modelInputModalities" | "modelMaxInputTokens" | "defaultMaxOutputTokens" | "modelMaxOutputTokens" | "reasoningEfforts" | "modelReasoningEfforts" | "modelDefaultReasoningEfforts" | "reasoningEffortMap" | "modelReasoningEffortMap" @@ -887,6 +889,48 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ noVisionModels: TENCENT_CODING_PLAN_MODELS, note: "Coding tools only. Tencent forbids general API automation, custom backends, and non-interactive batch use.", }, + { + id: "volcengine", + label: "Volcengine Ark", + baseUrl: "https://ark.cn-beijing.volces.com/api/v3", + adapter: "openai-chat", + authKind: "key", + dashboardUrl: "https://console.volcengine.com/ark/region:ark+cn-beijing/apikey", + defaultModel: "doubao-seed-2-0-lite-260215", + models: ["doubao-seed-2-0-lite-260215"], + liveModels: true, + modelReasoningEfforts: { + "doubao-seed-2-0-lite-260215": THINKING_TOGGLE_EFFORTS, + }, + modelReasoningEffortMap: { + "doubao-seed-2-0-lite-260215": THINKING_TOGGLE_MAP, + }, + thinkingToggleModels: ["doubao-seed-2-0-lite-260215"], + note: "Pay-as-you-go Ark API. Calls on this endpoint do not consume Coding Plan or Agent Plan quota.", + }, + { + id: "volcengine-coding-plan", + label: "Volcengine Ark Coding Plan", + baseUrl: "https://ark.cn-beijing.volces.com/api/coding/v3", + adapter: "openai-chat", + authKind: "key", + dashboardUrl: "https://console.volcengine.com/ark/region:ark+cn-beijing/overview", + defaultModel: "ark-code-latest", + models: ["ark-code-latest"], + liveModels: true, + note: "Coding Plan subscription endpoint. Use the plan key issued by the Ark console.", + }, + { + id: "volcengine-agent-plan", + label: "Volcengine Ark Agent Plan", + baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3", + responsesPath: "/responses", + adapter: "openai-responses", + authKind: "key", + dashboardUrl: "https://console.volcengine.com/ark/region:ark+cn-beijing/overview", + liveModels: true, + note: "Agent Plan subscription endpoint over the native Responses API.", + }, // 2026-07-10: docs unverified; model data frozen. Evidence: devlog/_plan/260710_provider_hardening/002_research_cn.md. { id: "qianfan", label: "Qianfan (Baidu)", baseUrl: "https://qianfan.baidubce.com/v2", adapter: "openai-chat", authKind: "key", dashboardUrl: "https://console.bce.baidu.com/iam/#/iam/apikey/list" }, // 2026-07-10: docs unverified; model data frozen. Evidence: devlog/_plan/260710_provider_hardening/002_research_cn.md. diff --git a/src/router.ts b/src/router.ts index 6dc331f4d..33ac92d8d 100644 --- a/src/router.ts +++ b/src/router.ts @@ -245,6 +245,9 @@ function routedProviderConfig(providerName: string, provider: OcxProviderConfig) ...provider, adapter: registryEntry.adapter, baseUrl, + ...(provider.responsesPath === undefined && registryEntry.responsesPath !== undefined + ? { responsesPath: registryEntry.responsesPath } + : {}), authMode: canonicalAuthMode, apiKey: resolvedApiKey, // Backfill the Google wire mode + Vertex project/location from the registry when the user diff --git a/structure/00_overview.md b/structure/00_overview.md index de2608ea3..437c48f81 100644 --- a/structure/00_overview.md +++ b/structure/00_overview.md @@ -33,7 +33,8 @@ The default install keeps native OpenAI/ChatGPT passthrough working through one `openai` provider. Pool is the default and selects across main plus added accounts; Direct uses only the current caller/main login. `openai-apikey` explicitly selects API-key transport, and the two credential routes never fall through into one another. Built-in provider presets include Anthropic, -Google, Azure, Neuralwatt Cloud, Tencent Cloud Coding Plan, and SiliconFlow. Additional +Google, Azure, Neuralwatt Cloud, Tencent Cloud Coding Plan, SiliconFlow, and separate Volcengine Ark +pay-as-you-go, Coding Plan, and Agent Plan endpoints. Additional providers are routed by explicit `provider/model`, provider model lists, or the configured `defaultProvider`. diff --git a/tests/provider-registry-parity.test.ts b/tests/provider-registry-parity.test.ts index d2f7d5735..a9b3b6ceb 100644 --- a/tests/provider-registry-parity.test.ts +++ b/tests/provider-registry-parity.test.ts @@ -33,7 +33,7 @@ const EXPECTED_KEY_PROVIDER_IDS = [ "anthropic-apikey", "openai-apikey", "umans", "opencode-go", "neuralwatt", "openrouter", "orcarouter", "bizrouter", "groq", "google", "google-vertex", "azure-openai", "deepseek", "cerebras", "together", "fireworks", "firepass", "moonshot", "huggingface", "nvidia", "venice", "zai", "zhipu-bigmodel", "nanogpt", "synthetic", "siliconflow", "qwen-cloud", "tencent-coding-plan", - "qianfan", "alibaba", "alibaba-token-plan", "alibaba-token-plan-intl", "parallel", "zenmux", "litellm", "ollama-cloud", "mistral", + "volcengine", "volcengine-coding-plan", "volcengine-agent-plan", "qianfan", "alibaba", "alibaba-token-plan", "alibaba-token-plan-intl", "parallel", "zenmux", "litellm", "ollama-cloud", "mistral", "minimax", "minimax-cn", "kimi-code", "opencode-zen", "vercel-ai-gateway", "opencode-free", "xiaomi", "kilo", "mimo-free", "cloudflare-ai-gateway", "cloudflare-workers-ai", "gitlab-duo", ]; diff --git a/tests/volcengine-providers.test.ts b/tests/volcengine-providers.test.ts new file mode 100644 index 000000000..a809219ec --- /dev/null +++ b/tests/volcengine-providers.test.ts @@ -0,0 +1,129 @@ +import { describe, expect, test } from "bun:test"; +import { createOpenAIChatAdapter } from "../src/adapters/openai-chat"; +import { createResponsesPassthroughAdapter } from "../src/adapters/openai-responses"; +import { KEY_LOGIN_PROVIDERS } from "../src/oauth/key-providers"; +import { deriveProviderPresets, providerConfigSeed } from "../src/providers/derive"; +import { PROVIDER_REGISTRY } from "../src/providers/registry"; +import { routeModel } from "../src/router"; +import type { OcxConfig } from "../src/types"; +import { formatProviderDisplayName, isCatalogProviderId } from "../gui/src/provider-icons"; + +describe("Volcengine Ark providers", () => { + test("publishes separate pay-as-you-go, Coding Plan, and Agent Plan contracts", () => { + expect(PROVIDER_REGISTRY.find(provider => provider.id === "volcengine")).toMatchObject({ + label: "Volcengine Ark", + baseUrl: "https://ark.cn-beijing.volces.com/api/v3", + adapter: "openai-chat", + authKind: "key", + defaultModel: "doubao-seed-2-0-lite-260215", + models: ["doubao-seed-2-0-lite-260215"], + liveModels: true, + thinkingToggleModels: ["doubao-seed-2-0-lite-260215"], + }); + expect(PROVIDER_REGISTRY.find(provider => provider.id === "volcengine-coding-plan")).toMatchObject({ + label: "Volcengine Ark Coding Plan", + baseUrl: "https://ark.cn-beijing.volces.com/api/coding/v3", + adapter: "openai-chat", + authKind: "key", + defaultModel: "ark-code-latest", + models: ["ark-code-latest"], + liveModels: true, + }); + expect(PROVIDER_REGISTRY.find(provider => provider.id === "volcengine-agent-plan")).toMatchObject({ + label: "Volcengine Ark Agent Plan", + baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3", + responsesPath: "/responses", + adapter: "openai-responses", + authKind: "key", + liveModels: true, + }); + }); + + test("derives key login and dashboard presets from the canonical registry", () => { + expect(KEY_LOGIN_PROVIDERS.volcengine).toMatchObject({ + baseUrl: "https://ark.cn-beijing.volces.com/api/v3", + defaultModel: "doubao-seed-2-0-lite-260215", + liveModels: true, + }); + expect(KEY_LOGIN_PROVIDERS["volcengine-coding-plan"]).toMatchObject({ + baseUrl: "https://ark.cn-beijing.volces.com/api/coding/v3", + defaultModel: "ark-code-latest", + liveModels: true, + }); + expect(KEY_LOGIN_PROVIDERS["volcengine-agent-plan"]).toMatchObject({ + baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3", + responsesPath: "/responses", + adapter: "openai-responses", + liveModels: true, + }); + for (const id of ["volcengine", "volcengine-coding-plan", "volcengine-agent-plan"]) { + expect(deriveProviderPresets().find(provider => provider.id === id)).toMatchObject({ auth: "key" }); + } + }); + + test("routes a minimal Agent Plan config to its native Responses resource", () => { + const config: OcxConfig = { + port: 10100, + defaultProvider: "volcengine-agent-plan", + providers: { + "volcengine-agent-plan": { + adapter: "openai-responses", + baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3", + authMode: "key", + apiKey: "test-key", + }, + }, + }; + const route = routeModel(config, "volcengine-agent-plan/ark-agent-latest"); + expect(route.provider.responsesPath).toBe("/responses"); + + const request = createResponsesPassthroughAdapter(route.provider).buildRequest({ + modelId: route.modelId, + context: { messages: [] }, + stream: true, + options: {}, + _rawBody: { model: route.modelId, input: "ping", stream: true }, + }, { headers: new Headers() }); + expect(request.url).toBe("https://ark.cn-beijing.volces.com/api/plan/v3/responses"); + }); + + test("maps the documented Ark thinking toggle on the pay-as-you-go Chat wire", () => { + const config: OcxConfig = { + port: 10100, + defaultProvider: "volcengine", + providers: { + volcengine: { + adapter: "openai-chat", + baseUrl: "https://ark.cn-beijing.volces.com/api/v3", + authMode: "key", + apiKey: "test-key", + }, + }, + }; + const route = routeModel(config, "volcengine/doubao-seed-2-0-lite-260215"); + const request = createOpenAIChatAdapter(route.provider).buildRequest({ + modelId: route.modelId, + context: { + messages: [{ role: "user", content: "ping", timestamp: 0 }], + }, + stream: true, + options: { reasoning: "high" }, + }); + const body = JSON.parse(request.body) as Record; + + expect(request.url).toBe("https://ark.cn-beijing.volces.com/api/v3/chat/completions"); + expect(body.thinking).toEqual({ type: "enabled" }); + expect(body).not.toHaveProperty("reasoning_effort"); + }); + + test("keeps registry response paths in provider seeds and GUI display metadata", () => { + const agentPlan = PROVIDER_REGISTRY.find(provider => provider.id === "volcengine-agent-plan")!; + expect(providerConfigSeed(agentPlan).responsesPath).toBe("/responses"); + expect(formatProviderDisplayName("volcengine")).toBe("Volcengine Ark"); + expect(formatProviderDisplayName("volcengine-coding-plan")).toBe("Volcengine Ark Coding Plan"); + expect(formatProviderDisplayName("volcengine-agent-plan")).toBe("Volcengine Ark Agent Plan"); + expect(isCatalogProviderId("volcengine")).toBe(true); + expect(isCatalogProviderId("volcengine-coding-plan")).toBe(true); + expect(isCatalogProviderId("volcengine-agent-plan")).toBe(true); + }); +}); From 403cf31a150e286ede2a00e5800753411b2e582b Mon Sep 17 00:00:00 2001 From: yrooogerg Date: Tue, 28 Jul 2026 16:57:50 +0800 Subject: [PATCH 2/5] fix(providers): curate Volcengine model catalogs --- .../src/content/docs/guides/providers.md | 6 ++ .../src/content/docs/ja/guides/providers.md | 6 ++ .../src/content/docs/ko/guides/providers.md | 5 ++ .../src/content/docs/ru/guides/providers.md | 6 ++ .../content/docs/zh-cn/guides/providers.md | 5 ++ src/providers/registry.ts | 82 +++++++++++++++---- tests/volcengine-providers.test.ts | 57 ++++++++++--- 7 files changed, 138 insertions(+), 29 deletions(-) diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index c303ceeef..7aa6d7343 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -224,6 +224,12 @@ Volcengine Agent Plan uses its native Responses endpoint through `openai-respons > `volcengine-coding-plan` consumes Coding Plan quota, and `volcengine-agent-plan` consumes Agent > Plan quota. Use the key and endpoint issued for the same product; the ordinary `/api/v3` endpoint > can incur pay-as-you-go charges even when a Plan subscription exists. +> The presets use curated static model catalogs because Ark's `/models` response also includes +> embedding, image, video, and 3D resources, the Coding gateway returns that same broad catalog, +> and the Agent Plan gateway has no `/models` resource. Pay-as-you-go defaults to +> `doubao-seed-2-1-pro-260628`; its curated catalog also includes current DeepSeek and GLM text +> models. Coding Plan defaults to `ark-code-latest`, while Agent Plan defaults to +> `deepseek-v4-pro`. > **Tencent Cloud Coding Plan usage restriction:** Tencent documents this subscription for > interactive coding tools only. General API automation, custom application backends, and diff --git a/docs-site/src/content/docs/ja/guides/providers.md b/docs-site/src/content/docs/ja/guides/providers.md index cf56adea3..2785e761f 100644 --- a/docs-site/src/content/docs/ja/guides/providers.md +++ b/docs-site/src/content/docs/ja/guides/providers.md @@ -158,6 +158,12 @@ Volcengine Agent Plan は `openai-responses` アダプターでネイティブ R > `volcengine-coding-plan` は Coding Plan の割り当て、`volcengine-agent-plan` は Agent Plan > の割り当てを使用します。同じ製品で発行されたキーとエンドポイントを組み合わせてください。 > Plan 契約があっても通常の `/api/v3` 呼び出しには従量課金が発生する場合があります。 +> 3 つの preset は選別済みの静的モデルカタログを使用します。Ark の `/models` はテキストに加えて +> Embedding、画像、動画、3D リソースも返し、Coding ゲートウェイも同じ広範なカタログを返します。 +> Agent Plan ゲートウェイには `/models` リソースがありません。従量課金のデフォルトは +> `doubao-seed-2-1-pro-260628` で、静的カタログには現在の DeepSeek と GLM のテキストモデルも +> 含まれます。Coding Plan のデフォルトは `ark-code-latest`、Agent Plan は +> `deepseek-v4-pro` です。 > **Tencent Cloud Coding Plan の利用制限:** Tencent はこのサブスクリプションを対話型 > コーディングツール専用としています。一般的な API 自動化、カスタムアプリのバックエンド、 diff --git a/docs-site/src/content/docs/ko/guides/providers.md b/docs-site/src/content/docs/ko/guides/providers.md index b8f770930..4969e7078 100644 --- a/docs-site/src/content/docs/ko/guides/providers.md +++ b/docs-site/src/content/docs/ko/guides/providers.md @@ -158,6 +158,11 @@ Volcengine Agent Plan은 `openai-responses` 어댑터로 네이티브 Responses > `volcengine-coding-plan`은 Coding Plan 할당량, `volcengine-agent-plan`은 Agent Plan > 할당량을 사용합니다. 같은 상품에서 발급된 키와 엔드포인트를 함께 사용해야 하며, Plan 구독이 > 있어도 일반 `/api/v3` 엔드포인트 호출에는 종량제 요금이 발생할 수 있습니다. +> 세 preset은 선별된 정적 모델 카탈로그를 사용합니다. Ark의 `/models`는 텍스트와 함께 +> Embedding, 이미지, 비디오, 3D 리소스도 반환하고 Coding 게이트웨이도 같은 광범위한 카탈로그를 +> 반환합니다. Agent Plan 게이트웨이에는 `/models` 리소스가 없습니다. 종량제 기본값은 +> `doubao-seed-2-1-pro-260628`이며 정적 카탈로그에는 현재 DeepSeek와 GLM 텍스트 모델도 +> 포함됩니다. Coding Plan의 기본값은 `ark-code-latest`, Agent Plan은 `deepseek-v4-pro`입니다. > **Tencent Cloud Coding Plan 사용 제한:** Tencent는 이 구독을 대화형 코딩 도구 전용으로 > 안내합니다. 일반 API 자동화, 사용자 애플리케이션 백엔드 및 비대화형 일괄 호출은 금지되며 diff --git a/docs-site/src/content/docs/ru/guides/providers.md b/docs-site/src/content/docs/ru/guides/providers.md index 11c0b9f12..54527d196 100644 --- a/docs-site/src/content/docs/ru/guides/providers.md +++ b/docs-site/src/content/docs/ru/guides/providers.md @@ -169,6 +169,12 @@ Volcengine Agent Plan использует нативную конечную т > `volcengine-coding-plan` расходует квоту Coding Plan, а `volcengine-agent-plan` — квоту Agent > Plan. Используйте ключ и конечную точку одного продукта; обычный `/api/v3` может тарифицироваться > отдельно даже при активной подписке Plan. +> Все три preset используют отобранные статические каталоги моделей. Ark `/models` возвращает +> текстовые, embedding-, графические, видео- и 3D-ресурсы, а шлюз Coding выдаёт тот же широкий +> каталог. У шлюза Agent Plan ресурса `/models` нет. Для pay-as-you-go модель по умолчанию — +> `doubao-seed-2-1-pro-260628`; его статический каталог также включает актуальные текстовые модели +> DeepSeek и GLM. Для Coding Plan модель по умолчанию — `ark-code-latest`, для Agent Plan — +> `deepseek-v4-pro`. > **Ограничение Tencent Cloud Coding Plan:** Tencent разрешает использовать эту подписку только > в интерактивных инструментах программирования. Автоматизация общего API, серверы пользовательских diff --git a/docs-site/src/content/docs/zh-cn/guides/providers.md b/docs-site/src/content/docs/zh-cn/guides/providers.md index 09b142a6c..6c45f1853 100644 --- a/docs-site/src/content/docs/zh-cn/guides/providers.md +++ b/docs-site/src/content/docs/zh-cn/guides/providers.md @@ -148,6 +148,11 @@ ChatGPT 转发预设。仪表盘的 **Add provider** 选择器会打开密钥提 > **三条火山方舟计费线路:**`volcengine` 是按量付费方舟 API,`volcengine-coding-plan` > 消耗 Coding Plan 额度,`volcengine-agent-plan` 消耗 Agent Plan 额度。密钥与端点需要属于 > 同一产品;已经订阅 Plan 时调用普通 `/api/v3` 端点仍可能产生按量费用。 +> 三个 preset 使用经过筛选的静态模型目录:方舟 `/models` 同时返回文本、Embedding、图片、 +> 视频和 3D 资源,Coding 网关也会返回这份宽泛目录,Agent Plan 网关没有 `/models` 资源。 +> 按量付费默认使用 `doubao-seed-2-1-pro-260628`,静态目录还包含当前 DeepSeek 和 GLM +> 文本模型。Coding Plan 默认使用 `ark-code-latest`,Agent Plan 默认使用 +> `deepseek-v4-pro`。 > **腾讯云 Coding Plan 使用限制:**腾讯将此订阅限定为交互式编程工具使用。禁止通用 API > 自动化、自定义应用后端和非交互式批量调用;违规使用可能导致套餐密钥被停用。 diff --git a/src/providers/registry.ts b/src/providers/registry.ts index c6fe403b4..bd45ff496 100644 --- a/src/providers/registry.ts +++ b/src/providers/registry.ts @@ -255,6 +255,41 @@ const ALIBABA_INTL_TOKEN_PLAN_QWEN_MODELS = [ // coding tools (not custom application backends or non-interactive batch automation). // Evidence: https://cloud.tencent.cn/document/product/1823/130092 const TENCENT_CODING_PLAN_MODELS = ["tc-code-latest", "glm-5", "kimi-k2.5", "minimax-m2.5"]; +// Volcengine's authenticated /api/v3/models catalog mixes chat models with embedding, +// image, video, and 3D generation resources. Keep the Codex-facing presets scoped to +// models documented for text/agent or Coding Plan use. +const VOLCENGINE_ARK_MODELS = [ + "doubao-seed-2-1-pro-260628", + "doubao-seed-2-1-turbo-260628", + "doubao-seed-evolving", + "deepseek-v4-pro-260425", + "deepseek-v4-flash-260425", + "deepseek-v3-2-251201", + "glm-5-2-260617", + "glm-4-7-251222", +]; +const VOLCENGINE_DOUBAO_THINKING_MODELS = [ + "doubao-seed-2-1-pro-260628", + "doubao-seed-2-1-turbo-260628", + "doubao-seed-evolving", +]; +const VOLCENGINE_CODING_PLAN_MODELS = [ + "ark-code-latest", + "doubao-seed-2.0-code", + "deepseek-v4-pro", + "deepseek-v4-flash", + "glm-5.1", + "kimi-k2.6", + "minimax-m3", +]; +const VOLCENGINE_AGENT_PLAN_MODELS = [ + "deepseek-v4-pro", + "deepseek-v4-flash", + "glm-5.1", + "kimi-k2.6", + "minimax-m3", + "doubao-seed-2.0-pro", +]; const ALIBABA_INTL_TOKEN_PLAN_INPUT_MODALITIES: Record = { "qwen3.8-max-preview": ["text", "image"], "qwen3.7-max": ["text", "image"], @@ -896,17 +931,30 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ adapter: "openai-chat", authKind: "key", dashboardUrl: "https://console.volcengine.com/ark/region:ark+cn-beijing/apikey", - defaultModel: "doubao-seed-2-0-lite-260215", - models: ["doubao-seed-2-0-lite-260215"], - liveModels: true, - modelReasoningEfforts: { - "doubao-seed-2-0-lite-260215": THINKING_TOGGLE_EFFORTS, - }, - modelReasoningEffortMap: { - "doubao-seed-2-0-lite-260215": THINKING_TOGGLE_MAP, - }, - thinkingToggleModels: ["doubao-seed-2-0-lite-260215"], - note: "Pay-as-you-go Ark API. Calls on this endpoint do not consume Coding Plan or Agent Plan quota.", + defaultModel: "doubao-seed-2-1-pro-260628", + models: VOLCENGINE_ARK_MODELS, + liveModels: false, + modelReasoningEfforts: Object.fromEntries( + VOLCENGINE_DOUBAO_THINKING_MODELS.map(id => [id, THINKING_TOGGLE_EFFORTS]), + ), + modelReasoningEffortMap: Object.fromEntries( + VOLCENGINE_DOUBAO_THINKING_MODELS.map(id => [id, THINKING_TOGGLE_MAP]), + ), + thinkingToggleModels: VOLCENGINE_DOUBAO_THINKING_MODELS, + preserveReasoningContentModels: [ + "deepseek-v4-pro-260425", + "deepseek-v4-flash-260425", + "glm-5-2-260617", + "glm-4-7-251222", + ], + noVisionModels: [ + "deepseek-v4-pro-260425", + "deepseek-v4-flash-260425", + "deepseek-v3-2-251201", + "glm-5-2-260617", + "glm-4-7-251222", + ], + note: "Pay-as-you-go Ark API with a curated text/agent catalog. Calls on this endpoint do not consume Coding Plan or Agent Plan quota.", }, { id: "volcengine-coding-plan", @@ -916,9 +964,9 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ authKind: "key", dashboardUrl: "https://console.volcengine.com/ark/region:ark+cn-beijing/overview", defaultModel: "ark-code-latest", - models: ["ark-code-latest"], - liveModels: true, - note: "Coding Plan subscription endpoint. Use the plan key issued by the Ark console.", + models: VOLCENGINE_CODING_PLAN_MODELS, + liveModels: false, + note: "Coding Plan subscription endpoint with plan-scoped model aliases. Use the plan key issued by the Ark console.", }, { id: "volcengine-agent-plan", @@ -928,8 +976,10 @@ export const PROVIDER_REGISTRY: readonly ProviderRegistryEntry[] = [ adapter: "openai-responses", authKind: "key", dashboardUrl: "https://console.volcengine.com/ark/region:ark+cn-beijing/overview", - liveModels: true, - note: "Agent Plan subscription endpoint over the native Responses API.", + defaultModel: "deepseek-v4-pro", + models: VOLCENGINE_AGENT_PLAN_MODELS, + liveModels: false, + note: "Agent Plan subscription endpoint over the native Responses API with a static fallback catalog.", }, // 2026-07-10: docs unverified; model data frozen. Evidence: devlog/_plan/260710_provider_hardening/002_research_cn.md. { id: "qianfan", label: "Qianfan (Baidu)", baseUrl: "https://qianfan.baidubce.com/v2", adapter: "openai-chat", authKind: "key", dashboardUrl: "https://console.bce.baidu.com/iam/#/iam/apikey/list" }, diff --git a/tests/volcengine-providers.test.ts b/tests/volcengine-providers.test.ts index a809219ec..c7eefcbc8 100644 --- a/tests/volcengine-providers.test.ts +++ b/tests/volcengine-providers.test.ts @@ -15,10 +15,23 @@ describe("Volcengine Ark providers", () => { baseUrl: "https://ark.cn-beijing.volces.com/api/v3", adapter: "openai-chat", authKind: "key", - defaultModel: "doubao-seed-2-0-lite-260215", - models: ["doubao-seed-2-0-lite-260215"], - liveModels: true, - thinkingToggleModels: ["doubao-seed-2-0-lite-260215"], + defaultModel: "doubao-seed-2-1-pro-260628", + models: [ + "doubao-seed-2-1-pro-260628", + "doubao-seed-2-1-turbo-260628", + "doubao-seed-evolving", + "deepseek-v4-pro-260425", + "deepseek-v4-flash-260425", + "deepseek-v3-2-251201", + "glm-5-2-260617", + "glm-4-7-251222", + ], + liveModels: false, + thinkingToggleModels: [ + "doubao-seed-2-1-pro-260628", + "doubao-seed-2-1-turbo-260628", + "doubao-seed-evolving", + ], }); expect(PROVIDER_REGISTRY.find(provider => provider.id === "volcengine-coding-plan")).toMatchObject({ label: "Volcengine Ark Coding Plan", @@ -26,8 +39,16 @@ describe("Volcengine Ark providers", () => { adapter: "openai-chat", authKind: "key", defaultModel: "ark-code-latest", - models: ["ark-code-latest"], - liveModels: true, + models: [ + "ark-code-latest", + "doubao-seed-2.0-code", + "deepseek-v4-pro", + "deepseek-v4-flash", + "glm-5.1", + "kimi-k2.6", + "minimax-m3", + ], + liveModels: false, }); expect(PROVIDER_REGISTRY.find(provider => provider.id === "volcengine-agent-plan")).toMatchObject({ label: "Volcengine Ark Agent Plan", @@ -35,26 +56,36 @@ describe("Volcengine Ark providers", () => { responsesPath: "/responses", adapter: "openai-responses", authKind: "key", - liveModels: true, + defaultModel: "deepseek-v4-pro", + models: [ + "deepseek-v4-pro", + "deepseek-v4-flash", + "glm-5.1", + "kimi-k2.6", + "minimax-m3", + "doubao-seed-2.0-pro", + ], + liveModels: false, }); }); test("derives key login and dashboard presets from the canonical registry", () => { expect(KEY_LOGIN_PROVIDERS.volcengine).toMatchObject({ baseUrl: "https://ark.cn-beijing.volces.com/api/v3", - defaultModel: "doubao-seed-2-0-lite-260215", - liveModels: true, + defaultModel: "doubao-seed-2-1-pro-260628", + liveModels: false, }); expect(KEY_LOGIN_PROVIDERS["volcengine-coding-plan"]).toMatchObject({ baseUrl: "https://ark.cn-beijing.volces.com/api/coding/v3", defaultModel: "ark-code-latest", - liveModels: true, + liveModels: false, }); expect(KEY_LOGIN_PROVIDERS["volcengine-agent-plan"]).toMatchObject({ baseUrl: "https://ark.cn-beijing.volces.com/api/plan/v3", responsesPath: "/responses", adapter: "openai-responses", - liveModels: true, + defaultModel: "deepseek-v4-pro", + liveModels: false, }); for (const id of ["volcengine", "volcengine-coding-plan", "volcengine-agent-plan"]) { expect(deriveProviderPresets().find(provider => provider.id === id)).toMatchObject({ auth: "key" }); @@ -74,7 +105,7 @@ describe("Volcengine Ark providers", () => { }, }, }; - const route = routeModel(config, "volcengine-agent-plan/ark-agent-latest"); + const route = routeModel(config, "volcengine-agent-plan/deepseek-v4-pro"); expect(route.provider.responsesPath).toBe("/responses"); const request = createResponsesPassthroughAdapter(route.provider).buildRequest({ @@ -100,7 +131,7 @@ describe("Volcengine Ark providers", () => { }, }, }; - const route = routeModel(config, "volcengine/doubao-seed-2-0-lite-260215"); + const route = routeModel(config, "volcengine/doubao-seed-2-1-pro-260628"); const request = createOpenAIChatAdapter(route.provider).buildRequest({ modelId: route.modelId, context: { From 04bcd1e51e247c1a326b31bc07edb7f6ba873645 Mon Sep 17 00:00:00 2001 From: yrooogerg Date: Tue, 28 Jul 2026 17:31:07 +0800 Subject: [PATCH 3/5] fix(gui): localize Volcengine provider labels --- .../provider-workspace/ProviderDetails.tsx | 2 +- .../ProviderOverviewDashboard.tsx | 6 ++--- .../provider-workspace/ProviderRail.tsx | 2 +- .../ProviderWorkspaceShell.tsx | 8 +++---- gui/src/i18n/de.ts | 3 +++ gui/src/i18n/en.ts | 3 +++ gui/src/i18n/ja.ts | 3 +++ gui/src/i18n/ko.ts | 3 +++ gui/src/i18n/ru.ts | 3 +++ gui/src/i18n/zh.ts | 3 +++ gui/src/pages/Providers.tsx | 4 ++-- gui/src/pages/providers-page-utils.ts | 4 +++- gui/src/provider-icons.ts | 22 ++++++++++++++----- tests/provider-workspace-data.test.ts | 14 +++++++----- tests/tencent-siliconflow-providers.test.ts | 8 +++++-- tests/volcengine-providers.test.ts | 10 ++++++--- 16 files changed, 71 insertions(+), 27 deletions(-) diff --git a/gui/src/components/provider-workspace/ProviderDetails.tsx b/gui/src/components/provider-workspace/ProviderDetails.tsx index e825dcee6..61ad0d096 100644 --- a/gui/src/components/provider-workspace/ProviderDetails.tsx +++ b/gui/src/components/provider-workspace/ProviderDetails.tsx @@ -149,7 +149,7 @@ export default function ProviderDetails({

- {formatProviderDisplayName(item.name)} + {formatProviderDisplayName(item.name, t)} {local && {t("modal.badge.local")}} {!local && free && {t("modal.badge.free")}}

diff --git a/gui/src/components/provider-workspace/ProviderOverviewDashboard.tsx b/gui/src/components/provider-workspace/ProviderOverviewDashboard.tsx index 393d43abe..8205bd8a8 100644 --- a/gui/src/components/provider-workspace/ProviderOverviewDashboard.tsx +++ b/gui/src/components/provider-workspace/ProviderOverviewDashboard.tsx @@ -121,7 +121,7 @@ export default function ProviderOverviewDashboard({ >
- {formatProviderDisplayName(item.name)} + {formatProviderDisplayName(item.name, t)} {localizeAttentionReason(item.reason)}