diff --git a/docs-site/src/content/docs/getting-started/quickstart.md b/docs-site/src/content/docs/getting-started/quickstart.md index fa39fef46..1c0d8a4cd 100644 --- a/docs-site/src/content/docs/getting-started/quickstart.md +++ b/docs-site/src/content/docs/getting-started/quickstart.md @@ -13,7 +13,7 @@ ocx init `ocx init` walks you through: -1. **Pick a provider** — choose one of the 69 built-in registry presets or `custom` to type a base +1. **Pick a provider** — choose one of the 70 built-in registry presets or `custom` to type a base URL and adapter. 2. **API key** — paste a key, or reference an environment variable like `${ANTHROPIC_API_KEY}`. 3. **Default model** — for key, local, and custom providers, accept the preset or enter a model id. diff --git a/docs-site/src/content/docs/guides/providers.md b/docs-site/src/content/docs/guides/providers.md index b4a9573ae..4278f6c4e 100644 --- a/docs-site/src/content/docs/guides/providers.md +++ b/docs-site/src/content/docs/guides/providers.md @@ -216,10 +216,9 @@ selectors, then retry. Signing in from a machine with no existing `kiro-cli` ses ## 3. API-key catalog -opencodex ships 69 built-in presets: 58 key-based, seven OAuth, three local, and one default +opencodex ships 70 built-in presets: 58 key-based, eight OAuth, three local, and one default ChatGPT-forward preset. The dashboard's **Add provider** picker opens a key provider's dashboard, -validates the key, and stores it; validation is provider-specific, and Command Code's public -catalog reports keys as unverifiable. Notable entries: +validates the key, and stores it; validation is provider-specific. Notable entries: **ClinePass** uses a Cline API key with the [official subscription catalog](https://docs.cline.bot/getting-started/clinepass) and [Chat Completions endpoint](https://docs.cline.bot/api/chat-completions), operated by Cline Bot Inc. under @@ -301,11 +300,12 @@ slash-containing native model ids, and caps live discovery at 256 KiB and 256 ra serverless text and vision-language chat only; Hyperbolic's separate image, audio, and GPU endpoints are out of scope. Create keys at [Hyperbolic](https://app.hyperbolic.ai). -**Command Code discovery.** The preset reads Command Code's public `/provider/v1/models` list from +**Command Code discovery.** The preset reads Command Code's `/provider/v1/models` list from the fixed Provider API host, preserves provider-native ids, and caps discovery at 256 KiB and 256 raw -rows. The model catalog is unauthenticated, so the CLI login flow reports the key as unverifiable -instead of a false positive. Chat requests use the configured Bearer key; API access requires the -Provider plan, and CLI auth bridging for Go/Pro subscriptions is not yet available. Create keys at +rows. `ocx login command-code` supports OAuth via browser sign-in (with optional local CLI credential +import from `~/.commandcode/auth.json` for existing Command Code CLI users); the model catalog is +account-scoped and comes from the authenticated discovery endpoint after login. Chat requests use the +configured Bearer key. Create keys at [Command Code Studio](https://commandcode.ai/studio/). > **Baseten scope:** The preset covers Baseten's shared [Model APIs](https://docs.baseten.co/inference/model-apis/overview) diff --git a/docs-site/src/content/docs/ja/getting-started/quickstart.md b/docs-site/src/content/docs/ja/getting-started/quickstart.md index 41b7e8343..04a063381 100644 --- a/docs-site/src/content/docs/ja/getting-started/quickstart.md +++ b/docs-site/src/content/docs/ja/getting-started/quickstart.md @@ -13,7 +13,7 @@ ocx init `ocx init` では次の手順を説明します。 -1. **プロバイダーを選択してください** — 69 の組み込みレジストリ プリセットのいずれか、または `custom` を選択してベースを入力します +1. **プロバイダーを選択してください** — 70 の組み込みレジストリ プリセットのいずれか、または `custom` を選択してベースを入力します URLとアダプター。 2. **API キー** — キーを貼り付けるか、`${ANTHROPIC_API_KEY}` のような環境変数を参照します。 3. **デフォルト モデル** — キー、ローカル、カスタム プロバイダーの場合は、プリセットを受け入れるか、モデル ID を入力します。 diff --git a/docs-site/src/content/docs/ja/guides/providers.md b/docs-site/src/content/docs/ja/guides/providers.md index 48f04235c..363f601b8 100644 --- a/docs-site/src/content/docs/ja/guides/providers.md +++ b/docs-site/src/content/docs/ja/guides/providers.md @@ -143,10 +143,9 @@ Kiro のログインには Kiro CLI が必要です。Unix では `curl -fsSL ht ## 3. API キーカタログ -opencodex には組み込みプリセットが 69 個含まれています。キー方式 58、OAuth 7、ローカル 3、 +opencodex には組み込みプリセットが 70 個含まれています。キー方式 58、OAuth 8、ローカル 3、 デフォルト ChatGPT 転送プリセット 1 です。ダッシュボードの **Add provider** ピッカーはキー発行ページを開き、 -入力したキーを検証した後保存します(検証はプロバイダー固有で、Command Code の公開カタログはキーを -検証不能として報告します)。主な項目は以下のとおりです: +入力したキーを検証した後保存します(検証はプロバイダー固有です)。主な項目は以下のとおりです: **ClinePass** は Cline API キーで[公式サブスクリプションカタログ](https://docs.cline.bot/getting-started/clinepass)と [Chat Completions エンドポイント](https://docs.cline.bot/api/chat-completions)に接続します。運営主体は @@ -222,11 +221,12 @@ Volcengine Agent Plan は `openai-responses` アダプターでネイティブ R vision-language chat のみを対象とし、別系統の image、audio、GPU endpoint は対象外です。キーは [Hyperbolic](https://app.hyperbolic.ai) で作成します。 -**Command Code の discovery:** preset は Command Code の公開 `/provider/v1/models` リストを固定の +**Command Code の discovery:** preset は Command Code の `/provider/v1/models` リストを固定の Provider API ホストから読み、スラッシュを含むネイティブモデル ID を保持し、live discovery を -256 KiB と raw 256 行に制限します。モデルカタログは未認証のため、CLI ログインフローはキーを -誤って有効と報告せず、検証不能として報告します。チャットリクエストは設定済みの bearer キーを使います。 -API アクセスには Provider プランが必要で、Go/Pro サブスクリプション向けの CLI 認証ブリッジはまだ利用できません。 +256 KiB と raw 256 行に制限します。`ocx login command-code` はブラウザーでの OAuth サインインを +サポートします(既存の Command Code CLI ユーザー向けに `~/.commandcode/auth.json` からのローカル +CLI 資格情報の取り込みも可能)。モデルカタログはアカウント単位で、ログイン後に認証済みの +discovery エンドポイントから取得します。チャットリクエストは設定済みの bearer キーを使います。 キーは [Command Code Studio](https://commandcode.ai/studio/) で作成します。 > **Baseten の対象範囲:** このプリセットは Baseten の共有 [Model APIs](https://docs.baseten.co/inference/model-apis/overview) diff --git a/docs-site/src/content/docs/ko/getting-started/quickstart.md b/docs-site/src/content/docs/ko/getting-started/quickstart.md index 9692a44e7..6a718c4c1 100644 --- a/docs-site/src/content/docs/ko/getting-started/quickstart.md +++ b/docs-site/src/content/docs/ko/getting-started/quickstart.md @@ -13,7 +13,7 @@ ocx init `ocx init`은 다음 과정을 안내합니다: -1. **프로바이더 선택** — 내장 레지스트리 프리셋 69개 중 하나를 고르거나 `custom`을 선택해 base URL과 adapter를 직접 입력합니다. +1. **프로바이더 선택** — 내장 레지스트리 프리셋 70개 중 하나를 고르거나 `custom`을 선택해 base URL과 adapter를 직접 입력합니다. 2. **API 키** — 키를 붙여넣거나 `${ANTHROPIC_API_KEY}` 같은 환경 변수를 참조합니다. 3. **기본 모델** — 키, 로컬, custom 프로바이더에서는 프리셋을 그대로 쓰거나 모델 ID를 직접 입력합니다. 4. **프록시 포트** — 기본값은 `10100`입니다. diff --git a/docs-site/src/content/docs/ko/guides/providers.md b/docs-site/src/content/docs/ko/guides/providers.md index ae2973499..5314b8666 100644 --- a/docs-site/src/content/docs/ko/guides/providers.md +++ b/docs-site/src/content/docs/ko/guides/providers.md @@ -142,10 +142,9 @@ Kiro 로그인에는 Kiro CLI가 필요합니다. Unix에서는 `curl -fsSL http ## 3. API 키 카탈로그 -opencodex에는 빌트인 프리셋이 69개 들어 있습니다. 키 방식 58개, OAuth 7개, 로컬 3개, +opencodex에는 빌트인 프리셋이 70개 들어 있습니다. 키 방식 58개, OAuth 8개, 로컬 3개, 기본 ChatGPT 포워드 프리셋 1개입니다. 대시보드의 **Add provider** 선택기는 키 발급 페이지를 열고, -입력한 키를 검증한 뒤 저장합니다(검증은 프로바이더별로 다르며, Command Code의 공개 카탈로그는 키를 -검증 불가로 보고합니다). 주요 항목은 다음과 같습니다: +입력한 키를 검증한 뒤 저장합니다(검증은 프로바이더별로 다릅니다). 주요 항목은 다음과 같습니다: **ClinePass**는 Cline API 키로 [공식 구독 카탈로그](https://docs.cline.bot/getting-started/clinepass)와 [Chat Completions 엔드포인트](https://docs.cline.bot/api/chat-completions)에 연결합니다. 운영 주체는 @@ -221,12 +220,12 @@ Bearer API 키를 사용합니다. registry가 소유하는 DeepInfra 모델 목 대상으로 하며 별도 image, audio, GPU 엔드포인트는 범위에서 제외합니다. 키는 [Hyperbolic](https://app.hyperbolic.ai)에서 생성합니다. -**Command Code 검색:** 프리셋은 Command Code의 공개 `/provider/v1/models` 목록을 고정된 Provider API +**Command Code 검색:** 프리셋은 Command Code의 `/provider/v1/models` 목록을 고정된 Provider API 호스트에서 읽고, 슬래시가 포함된 네이티브 모델 ID를 보존하며 live discovery를 256 KiB와 raw 행 -256개로 제한합니다. 모델 카탈로그는 인증이 없으므로 CLI 로그인 흐름은 키를 유효하다고 잘못 보고하지 -않고 검증 불가로 보고합니다. 채팅 요청은 설정된 bearer 키를 사용하며, API 액세스에는 Provider 플랜이 -필요하고 Go/Pro 구독자용 CLI 인증 브리지는 아직 제공되지 않습니다. 키는 -[Command Code Studio](https://commandcode.ai/studio/)에서 생성합니다. +256개로 제한합니다. `ocx login command-code`는 브라우저 OAuth 로그인을 지원하며(기존 Command Code +CLI 사용자는 `~/.commandcode/auth.json`의 로컬 CLI 자격 증명을 가져올 수 있음), 모델 카탈로그는 +계정 단위이며 로그인 후 인증된 discovery 엔드포인트에서 가져옵니다. 채팅 요청은 설정된 bearer +키를 사용합니다. 키는 [Command Code Studio](https://commandcode.ai/studio/)에서 생성합니다. > **Baseten 범위:** 이 프리셋은 Baseten의 공유 [Model APIs](https://docs.baseten.co/inference/model-apis/overview)만 > 지원합니다. 로컬 사용에는 개인 [API 키](https://docs.baseten.co/organization/api-keys)를, 공유/프로덕션 diff --git a/docs-site/src/content/docs/ru/getting-started/quickstart.md b/docs-site/src/content/docs/ru/getting-started/quickstart.md index ee54838ea..73e905f63 100644 --- a/docs-site/src/content/docs/ru/getting-started/quickstart.md +++ b/docs-site/src/content/docs/ru/getting-started/quickstart.md @@ -13,7 +13,7 @@ ocx init `ocx init` проведёт вас по следующим шагам: -1. **Выбор провайдера** — выберите один из 69 встроенных пресетов реестра или `custom`, чтобы +1. **Выбор провайдера** — выберите один из 70 встроенных пресетов реестра или `custom`, чтобы ввести базовый URL и адаптер вручную. 2. **API-ключ** — вставьте ключ или сошлитесь на переменную окружения вида `${ANTHROPIC_API_KEY}`. 3. **Модель по умолчанию** — для провайдеров с ключом, локальных и `custom` примите значение из diff --git a/docs-site/src/content/docs/ru/guides/providers.md b/docs-site/src/content/docs/ru/guides/providers.md index 4f912949a..bcb7c9cbb 100644 --- a/docs-site/src/content/docs/ru/guides/providers.md +++ b/docs-site/src/content/docs/ru/guides/providers.md @@ -153,10 +153,10 @@ OAuth-провайдеры, чьи учётные данные содержат ## 3. Каталог API-ключей -opencodex поставляется с 69 встроенными пресетами: 58 на основе ключей, семь OAuth, три локальных и +opencodex поставляется с 70 встроенными пресетами: 58 на основе ключей, восемь OAuth, три локальных и один пресет ChatGPT-форварда по умолчанию. Селектор **Add provider** в дашборде открывает страницу -выдачи ключей провайдера, проверяет ключ и сохраняет его; проверка зависит от провайдера, а публичный -каталог Command Code сообщает ключ как непроверенный. Наиболее заметные записи: +выдачи ключей провайдера, проверяет ключ и сохраняет его; проверка зависит от провайдера. +Наиболее заметные записи: **ClinePass** подключается с помощью Cline API key к [официальному каталогу подписки](https://docs.cline.bot/getting-started/clinepass) и [Chat Completions endpoint](https://docs.cline.bot/api/chat-completions). Оператор — Cline Bot Inc., указанный в @@ -234,12 +234,13 @@ Volcengine Agent Plan использует нативную конечную т строками. Он охватывает только serverless text и vision-language chat; отдельные image, audio и GPU endpoint в него не входят. Ключи создаются в [Hyperbolic](https://app.hyperbolic.ai). -**Discovery для Command Code.** Пресет читает публичный список `/provider/v1/models` с фиксированного +**Discovery для Command Code.** Пресет читает список `/provider/v1/models` с фиксированного хоста Provider API, сохраняет нативные id моделей со знаком `/` и ограничивает live discovery размером -256 KiB и 256 исходными строками. Каталог моделей не требует аутентификации, поэтому CLI-флоу входа -сообщает ключ как непроверенный, а не как ложноположительно действительный. Запросы чата используют -настроенный bearer-ключ; для доступа к API требуется план Provider, а CLI-мост аутентификации для -подписок Go/Pro пока недоступен. Ключи создаются в [Command Code Studio](https://commandcode.ai/studio/). +256 KiB и 256 исходными строками. `ocx login command-code` поддерживает вход через OAuth в браузере +(с возможностью импорта локальных учётных данных CLI из `~/.commandcode/auth.json` для существующих +пользователей CLI Command Code); каталог моделей привязан к учётной записи и берётся из +аутентифицированного discovery endpoint после входа. Запросы чата используют настроенный bearer-ключ. +Ключи создаются в [Command Code Studio](https://commandcode.ai/studio/). > **Область Baseten:** пресет поддерживает только общие [Model APIs](https://docs.baseten.co/inference/model-apis/overview) > Baseten. Для локальной работы используйте личный [API-ключ](https://docs.baseten.co/organization/api-keys), diff --git a/docs-site/src/content/docs/zh-cn/getting-started/quickstart.md b/docs-site/src/content/docs/zh-cn/getting-started/quickstart.md index 0544b8f63..3f12c45f0 100644 --- a/docs-site/src/content/docs/zh-cn/getting-started/quickstart.md +++ b/docs-site/src/content/docs/zh-cn/getting-started/quickstart.md @@ -13,7 +13,7 @@ ocx init `ocx init` 会引导你完成: -1. **选择 provider** — 从内置 registry 的 69 个预设中选择一个,或选择 `custom` 手动输入 base URL 和 adapter。 +1. **选择 provider** — 从内置 registry 的 70 个预设中选择一个,或选择 `custom` 手动输入 base URL 和 adapter。 2. **API key** — 粘贴一个 key,或引用一个环境变量,例如 `${ANTHROPIC_API_KEY}`。 3. **默认模型** — 对于 key、本地和 custom provider,接受预设值或输入模型 id。 4. **代理端口** — 默认为 `10100`。 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 e8ce7f5d1..6e4926d3a 100644 --- a/docs-site/src/content/docs/zh-cn/guides/providers.md +++ b/docs-site/src/content/docs/zh-cn/guides/providers.md @@ -131,9 +131,9 @@ Kiro 登录需要 Kiro CLI:Unix 使用 `curl -fsSL https://cli.kiro.dev/instal ## 3. API 密钥目录 -opencodex 内置 69 个预设:58 个密钥预设、7 个 OAuth 预设、3 个本地预设,以及 1 个默认的 +opencodex 内置 70 个预设:58 个密钥预设、8 个 OAuth 预设、3 个本地预设,以及 1 个默认的 ChatGPT 转发预设。仪表盘的 **Add provider** 选择器会打开密钥提供商的控制台,验证并保存密钥。 -验证因提供商而异,Command Code 的公开目录会将密钥报告为无法验证。主要条目包括: +验证因提供商而异。主要条目包括: **ClinePass** 使用 Cline API 密钥连接[官方订阅目录](https://docs.cline.bot/getting-started/clinepass)和 [Chat Completions 端点](https://docs.cline.bot/api/chat-completions)。运营主体是 @@ -205,11 +205,11 @@ OpenAI Chat Completions 提供商。registry 固定的 DeepInfra 模型列表 UR 并将实时发现限制为 256 KiB 和 256 条原始记录。它仅覆盖 serverless text 与 vision-language chat;独立的 image、audio 和 GPU 端点不在范围内。密钥可在 [Hyperbolic](https://app.hyperbolic.ai) 创建。 -**Command Code 发现:**该预设从固定的 Provider API 主机读取 Command Code 公开的 +**Command Code 发现:**该预设从固定的 Provider API 主机读取 Command Code 的 `/provider/v1/models` 列表,保留含 `/` 的原生模型 id,并将实时发现限制为 256 KiB 和 256 条原始记录。 -模型目录无需认证,因此 CLI 登录流程会将密钥报告为无法验证,而不是误报为有效。聊天请求使用已配置的 -bearer 密钥;API 访问需要 Provider 套餐,Go/Pro 订阅用户的 CLI 认证桥接尚不可用。 -密钥可在 [Command Code Studio](https://commandcode.ai/studio/) 创建。 +`ocx login command-code` 支持通过浏览器进行 OAuth 登录(现有 Command Code CLI 用户还可选择从 +`~/.commandcode/auth.json` 导入本地 CLI 凭据);模型目录按账户隔离,并在登录后从经过认证的发现 +端点获取。聊天请求使用已配置的 bearer 密钥。密钥可在 [Command Code Studio](https://commandcode.ai/studio/) 创建。 > **Baseten 范围:**该预设仅覆盖 Baseten 的共享 [Model APIs](https://docs.baseten.co/inference/model-apis/overview)。 > 本地使用可选择个人 [API 密钥](https://docs.baseten.co/organization/api-keys);共享或生产用途请使用具备 diff --git a/gui/src/components/combo-workspace-controls.tsx b/gui/src/components/combo-workspace-controls.tsx index 5126df734..8a7277fd4 100644 --- a/gui/src/components/combo-workspace-controls.tsx +++ b/gui/src/components/combo-workspace-controls.tsx @@ -3,6 +3,7 @@ import type { ComboEffort, ComboStrategy, ComboTarget } from "../combo-workspace import { COMBO_EFFORTS, newComboTarget } from "../combo-workspace-data"; import { IconArrowDown, IconArrowUp, IconGrip, IconPlus, IconTrash } from "../icons"; import { useT } from "../i18n/shared"; +import { formatProviderDisplayName } from "../provider-icons"; import type { ModelOption, ProviderOption } from "./combo-workspace-types"; import { clampedNumberInput, enabledProviders, modelsForProvider } from "./combo-workspace-utils"; @@ -199,7 +200,7 @@ export function TargetEditor({ {providerOptions.map((p) => ( ))} diff --git a/gui/src/components/subagents-workspace/SubagentDelegationSection.tsx b/gui/src/components/subagents-workspace/SubagentDelegationSection.tsx index a32b9e3cf..2cf672b93 100644 --- a/gui/src/components/subagents-workspace/SubagentDelegationSection.tsx +++ b/gui/src/components/subagents-workspace/SubagentDelegationSection.tsx @@ -8,6 +8,7 @@ */ import { Select } from "../../ui"; import { useT } from "../../i18n/shared"; +import { formatNamespacedModelId } from "../../provider-icons"; import type { DelegationPatch, DelegationModelOption } from "../../pages/use-subagent-delegation"; export interface SubagentDelegationSectionProps { @@ -45,7 +46,7 @@ export default function SubagentDelegationSection({ value={model} options={[ { value: "", label: t("dash.injectionNone") }, - ...available.map(m => ({ value: m.namespaced, label: `${m.provider} / ${m.model}` })), + ...available.map(m => ({ value: m.namespaced, label: formatNamespacedModelId(`${m.provider}/${m.model}`, t) })), ]} onChange={v => onSave({ model: v || null, effort: effort || null })} disabled={saving} diff --git a/gui/src/i18n/de.ts b/gui/src/i18n/de.ts index 1abe5e37e..a4d633e10 100644 --- a/gui/src/i18n/de.ts +++ b/gui/src/i18n/de.ts @@ -78,6 +78,8 @@ export const de: Record = { "theme.dark": "Dunkel", "theme.system": "System", "lang.label": "Sprache", + "provider.name.commandCodeAuth": "Command Code - Auth", + "provider.name.commandCodeApi": "Command Code - API", "provider.name.volcengine": "Volcengine Ark", "provider.name.volcengineCodingPlan": "Volcengine Ark Coding-Tarif", "provider.name.volcengineAgentPlan": "Volcengine Ark Agent-Tarif", diff --git a/gui/src/i18n/en.ts b/gui/src/i18n/en.ts index 0ad668ca8..df67c7502 100644 --- a/gui/src/i18n/en.ts +++ b/gui/src/i18n/en.ts @@ -45,6 +45,8 @@ export const en = { "theme.dark": "Dark", "theme.system": "System", "lang.label": "Language", + "provider.name.commandCodeAuth": "Command Code - Auth", + "provider.name.commandCodeApi": "Command Code - API", "provider.name.volcengine": "Volcengine Ark", "provider.name.volcengineCodingPlan": "Volcengine Ark Coding Plan", "provider.name.volcengineAgentPlan": "Volcengine Ark Agent Plan", diff --git a/gui/src/i18n/ja.ts b/gui/src/i18n/ja.ts index d64005bb5..eb98a71eb 100644 --- a/gui/src/i18n/ja.ts +++ b/gui/src/i18n/ja.ts @@ -83,6 +83,8 @@ export const ja: Record = { "theme.dark": "ダーク", "theme.system": "システム", "lang.label": "言語", + "provider.name.commandCodeAuth": "Command Code - Auth", + "provider.name.commandCodeApi": "Command Code - API", "provider.name.volcengine": "Volcengine Ark", "provider.name.volcengineCodingPlan": "Volcengine Ark コーディングプラン", "provider.name.volcengineAgentPlan": "Volcengine Ark エージェントプラン", diff --git a/gui/src/i18n/ko.ts b/gui/src/i18n/ko.ts index 2205702c6..339cdbe97 100644 --- a/gui/src/i18n/ko.ts +++ b/gui/src/i18n/ko.ts @@ -78,6 +78,8 @@ export const ko: Record = { "theme.dark": "다크", "theme.system": "시스템", "lang.label": "언어", + "provider.name.commandCodeAuth": "Command Code - Auth", + "provider.name.commandCodeApi": "Command Code - API", "provider.name.volcengine": "Volcengine Ark", "provider.name.volcengineCodingPlan": "Volcengine Ark 코딩 플랜", "provider.name.volcengineAgentPlan": "Volcengine Ark 에이전트 플랜", diff --git a/gui/src/i18n/ru.ts b/gui/src/i18n/ru.ts index 47dd556ea..7904e27c3 100644 --- a/gui/src/i18n/ru.ts +++ b/gui/src/i18n/ru.ts @@ -83,6 +83,8 @@ export const ru: Record = { "theme.dark": "Тёмная", "theme.system": "Системная", "lang.label": "Язык", + "provider.name.commandCodeAuth": "Command Code - Auth", + "provider.name.commandCodeApi": "Command Code - API", "provider.name.volcengine": "Volcengine Ark", "provider.name.volcengineCodingPlan": "Volcengine Ark — тариф Coding", "provider.name.volcengineAgentPlan": "Volcengine Ark — тариф Agent", diff --git a/gui/src/i18n/zh.ts b/gui/src/i18n/zh.ts index e279ddf43..8b16dbe6c 100644 --- a/gui/src/i18n/zh.ts +++ b/gui/src/i18n/zh.ts @@ -78,6 +78,8 @@ export const zh: Record = { "theme.dark": "深色", "theme.system": "跟随系统", "lang.label": "语言", + "provider.name.commandCodeAuth": "Command Code - Auth", + "provider.name.commandCodeApi": "Command Code - API", "provider.name.volcengine": "火山方舟", "provider.name.volcengineCodingPlan": "火山方舟编程套餐", "provider.name.volcengineAgentPlan": "火山方舟智能体套餐", diff --git a/gui/src/pages/ApiKeys.tsx b/gui/src/pages/ApiKeys.tsx index b920fc375..7b2358412 100644 --- a/gui/src/pages/ApiKeys.tsx +++ b/gui/src/pages/ApiKeys.tsx @@ -1,6 +1,7 @@ import { useCallback, useMemo, useRef, useState } from "react"; import { Notice } from "../ui"; import { useI18n, LOCALES } from "../i18n/shared"; +import { formatProviderDisplayName } from "../provider-icons"; import { readJsonIfOk, readJsonOrThrow } from "../fetch-json"; import { classifyExternalModel, @@ -320,7 +321,7 @@ export default function ApiKeys({ apiBase, active = true }: { apiBase: string; a if (model.native) return t("api.sourceNative"); if (model.provider === "combo") return t("api.sourceCombo"); if (model.custom) return t("api.sourceCustom"); - return model.provider; + return formatProviderDisplayName(model.provider, t); }; const protocolLabel = (protocol: GatewayInboundProtocol): string => { diff --git a/gui/src/pages/Logs.tsx b/gui/src/pages/Logs.tsx index b513d754f..b1aa6b867 100644 --- a/gui/src/pages/Logs.tsx +++ b/gui/src/pages/Logs.tsx @@ -1,6 +1,7 @@ import { useCallback, useEffect, useRef, useState } from "react"; import { useVirtualizer } from "@tanstack/react-virtual"; import { useI18n, LOCALES, type TFn } from "../i18n/shared"; +import { formatProviderDisplayName } from "../provider-icons"; import { formatTokens } from "../format-tokens"; import { hashLogConversationQuery, matchesLogConversationId } from "../log-conversation-id"; import { statusCodeInfo } from "../status-codes"; @@ -786,7 +787,7 @@ export default function Logs({ apiBase }: { apiBase: string }) { {reasoningWire && {reasoningWire}} - {log.provider} + {formatProviderDisplayName(log.provider, t)} {log.status} @@ -924,7 +925,7 @@ function LogDetailDialog({ )} {t("logs.col.model")}{modelLabel(detail.resolvedModel ?? detail.model)} - {t("logs.col.provider")}{detail.provider} + {t("logs.col.provider")}{formatProviderDisplayName(detail.provider, t)} {(detail.requestedEffort || detail.effectiveEffort) && ( <>{t("logs.col.effort")}{effortLabel(detail)}{reasoningWire ? ` (${reasoningWire})` : ""} )} @@ -1048,7 +1049,7 @@ function LogDetailDialog({ {attempt.ordinal} - {attempt.provider}
+ {formatProviderDisplayName(attempt.provider, t)}
{attempt.model} {(attempt.requestedEffort || attempt.effectiveEffort) && ( <> diff --git a/gui/src/pages/Models.tsx b/gui/src/pages/Models.tsx index f2ff909c3..8e3cb117d 100644 --- a/gui/src/pages/Models.tsx +++ b/gui/src/pages/Models.tsx @@ -4,6 +4,7 @@ import { IconChevron, IconBoxes, IconInfo, IconShuffle, IconCheck, IconAlert } f import { useT } from "../i18n/shared"; import type { TFn, TKey } from "../i18n/shared"; import { modelLabel } from "../model-display"; +import { formatNamespacedModelId, formatProviderDisplayName, providerDisplaySlug } from "../provider-icons"; import { type ComboItem, parseComboList } from "../combo-workspace-data"; import { readJsonIfOk, readJsonOrThrow } from "../fetch-json"; import { readSessionListCache, writeSessionListCache } from "../session-list-cache"; @@ -170,8 +171,8 @@ export default function Models({ apiBase }: { apiBase: string }) { }, []); const shadowModelOptions = useMemo( - () => activeModelOptions(models, disabled, selectedModels ?? {}), - [models, disabled, selectedModels], + () => activeModelOptions(models, disabled, selectedModels ?? {}, t), + [models, disabled, selectedModels, t], ); const loadShadowCall = useCallback(async () => { @@ -723,7 +724,7 @@ export default function Models({ apiBase }: { apiBase: string }) { style={{ flex: 1, border: 0, background: "transparent", padding: 0, color: "inherit", cursor: "pointer", textAlign: "left" }} > - {provider} + {providerDisplaySlug(provider)} {isNative && {t("models.nativeGroupLabel")}} {discoveryFailure && (
void applyVisibility("models", provider, [{ id: m.id, native: m.native === true }], off)} disabled={busy} label={m.native ? m.id : m.namespaced} /> - {m.native ? modelLabel(m.id) : m.namespaced} + {m.native ? modelLabel(m.id) : formatNamespacedModelId(m.namespaced, t)} {m.custom && ( {t("models.customBadge")} @@ -823,7 +824,7 @@ export default function Models({ apiBase }: { apiBase: string }) { onMouseEnter={keepRowTipOpen} onMouseLeave={onRowLeave} > -
{m.native ? m.id : m.namespaced}
+
{m.native ? m.id : m.namespaced}
{m.displayName &&
{m.displayName}
} {m.custom && ( @@ -832,7 +833,7 @@ export default function Models({ apiBase }: { apiBase: string }) { )}
{t("models.tipProvider")} - {m.provider} + {formatProviderDisplayName(m.provider, t)} {(m.contextWindow || m.contextCap) && ( <> {t("models.tipContext")} @@ -1204,8 +1205,8 @@ export default function Models({ apiBase }: { apiBase: string }) {

{customModalMode === "add" - ? t("models.customAddTitle", { provider: customModalProvider }) - : t("models.customEditTitle", { provider: customModalProvider })} + ? t("models.customAddTitle", { provider: formatProviderDisplayName(customModalProvider, t) }) + : t("models.customEditTitle", { provider: formatProviderDisplayName(customModalProvider, t) })}

); diff --git a/gui/src/pages/Usage.tsx b/gui/src/pages/Usage.tsx index acd0b78de..afca8218f 100644 --- a/gui/src/pages/Usage.tsx +++ b/gui/src/pages/Usage.tsx @@ -1,5 +1,6 @@ import { useCallback, useEffect, useMemo, useRef, useState, type ReactNode } from "react"; import { useI18n, type TFn, type Locale } from "../i18n/shared"; +import { formatProviderDisplayName } from "../provider-icons"; import { formatTokens } from "../format-tokens"; import { formatEstimatedUsdValue as formatUsdEstimate } from "../intl-formatters"; import { readSessionListCache, writeSessionListCache } from "../session-list-cache"; @@ -512,7 +513,7 @@ function UsageModelsTable({ {models.map(model => ( {modelLabel(model.model)} - {model.provider} + {formatProviderDisplayName(model.provider, t)} {model.requests} {model.measuredRequests} {formatTokens(model.totalTokens, locale)} @@ -572,7 +573,7 @@ function UsageProvidersTable({ {providers.map(provider => ( - {provider.provider} + {formatProviderDisplayName(provider.provider, t)} {provider.requests} {provider.measuredRequests} {formatTokens(provider.totalTokens, locale)} diff --git a/gui/src/pages/dashboard-models-section.tsx b/gui/src/pages/dashboard-models-section.tsx index a3d2f1af2..b839828e5 100644 --- a/gui/src/pages/dashboard-models-section.tsx +++ b/gui/src/pages/dashboard-models-section.tsx @@ -2,6 +2,7 @@ import { type Dispatch, type SetStateAction } from "react"; import { IconChevron, IconSearch } from "../icons"; import type { TFn } from "../i18n/shared"; import { EmptyState } from "../ui"; +import { formatProviderDisplayName } from "../provider-icons"; import type { ModelInfo } from "./dashboard-shared"; export function DashboardModelsSection({ @@ -60,7 +61,7 @@ export function DashboardModelsSection({ aria-expanded={open} >