From a3ec7ee0813977f9955f208ea3e684f426c25724 Mon Sep 17 00:00:00 2001 From: sh940701 Date: Wed, 23 Sep 2026 09:15:56 +0900 Subject: [PATCH 1/3] feat(claude): describe routed models instead of "From gateway" Claude Code 2.1.257+ shows a discovered model's `description` under its /model picker row and falls back to the generic "From gateway" without one. The readable (CLI) /v1/models rows now carry "Routed by OpenCodex to /" ("native " for native rows), the 1M and Fast siblings inherit it, and the gateway-model cache pre-write passes it through. Desktop 3P rows keep their ModelInfo shape. --- .../src/content/docs/fr/guides/claude-code.md | 2 ++ .../src/content/docs/guides/claude-code.md | 6 ++-- .../src/content/docs/ja/guides/claude-code.md | 2 ++ .../src/content/docs/ko/guides/claude-code.md | 3 ++ .../src/content/docs/ru/guides/claude-code.md | 2 ++ .../src/content/docs/tr/guides/claude-code.md | 2 ++ .../content/docs/zh-cn/guides/claude-code.md | 3 ++ .../content/docs/zh-tw/guides/claude-code.md | 2 ++ src/claude/gateway-cache.ts | 11 ++++++-- src/claude/model-info.ts | 14 ++++++++-- .../claude-gateway-cache.test.ts | 27 ++++++++++++++++++ .../claude-model-info.test.ts | 28 +++++++++++++++++++ 12 files changed, 95 insertions(+), 7 deletions(-) diff --git a/docs-site/src/content/docs/fr/guides/claude-code.md b/docs-site/src/content/docs/fr/guides/claude-code.md index 45851d1fc0d..3a6c8103d5f 100644 --- a/docs-site/src/content/docs/fr/guides/claude-code.md +++ b/docs-site/src/content/docs/fr/guides/claude-code.md @@ -299,6 +299,8 @@ pas les copies externes ; révoquez-la séparément sur le hub si nécessaire. ## Le sélecteur /model (« Depuis la passerelle ») +Depuis Claude Code 2.1.257, chaque ligne affiche aussi sa `description` ; opencodex envoie `Routed by OpenCodex to /` pour chaque ligne du CLI Claude Code, qui montre donc l'itinéraire au lieu du libellé « From gateway ». + Claude Code 2.1.129+ découvre les modèles de passerelle via `GET /v1/models?limit=1000` et les répertorie dans le sélecteur natif `/model` intitulé « Depuis la passerelle ». Comme ce sélecteur n'accepte que les identifiants commençant par `claude` ou `anthropic`, opencodex expose les modèles routés sous forme d'alias stables et réversibles : diff --git a/docs-site/src/content/docs/guides/claude-code.md b/docs-site/src/content/docs/guides/claude-code.md index c1b06b27f82..36b064e4d0a 100644 --- a/docs-site/src/content/docs/guides/claude-code.md +++ b/docs-site/src/content/docs/guides/claude-code.md @@ -363,8 +363,10 @@ arbitrary external copies; revoke separately on the hub if desired. ## The /model picker ("From gateway") Claude Code 2.1.129+ discovers gateway models via `GET /v1/models?limit=1000` and lists them in -the native `/model` picker labeled "From gateway". Because the picker only accepts ids beginning -with `claude` or `anthropic`, opencodex exposes routed models as stable, reversible aliases: +the native `/model` picker. A row without a `description` reads "From gateway"; opencodex sends one +for every Claude Code CLI row (`Routed by OpenCodex to /`), which Claude Code +2.1.257+ shows in its place. Because the picker only accepts ids beginning with `claude` or +`anthropic`, opencodex exposes routed models as stable, reversible aliases: | Surface | Format | Example | | --- | --- | --- | diff --git a/docs-site/src/content/docs/ja/guides/claude-code.md b/docs-site/src/content/docs/ja/guides/claude-code.md index 390fbccd054..0ac4e059773 100644 --- a/docs-site/src/content/docs/ja/guides/claude-code.md +++ b/docs-site/src/content/docs/ja/guides/claude-code.md @@ -173,6 +173,8 @@ Claude Code CLI 互換性は英語版ドキュメントを参照してくださ ## /model ピッカー("From gateway") +Claude Code 2.1.257 以降は各行の `description` も表示します。opencodex は Claude Code CLI 向けの各行に `Routed by OpenCodex to /` を送るため、その行には "From gateway" の代わりにルートが表示されます。 + Claude Code 2.1.129 以降は `GET /v1/models?limit=1000` でゲートウェイモデルを探し、デフォルトの `/model` ピッカーの "From gateway" 項目に表示します。ピッカーは `claude` または `anthropic` で始まる ID のみ 受け付けるため、opencodex はルーティングモデルを安定で元に戻せるエイリアスとして公開します。 diff --git a/docs-site/src/content/docs/ko/guides/claude-code.md b/docs-site/src/content/docs/ko/guides/claude-code.md index 27759bbc709..4c8761c007f 100644 --- a/docs-site/src/content/docs/ko/guides/claude-code.md +++ b/docs-site/src/content/docs/ko/guides/claude-code.md @@ -196,6 +196,9 @@ import/export는 로컬 설정만 다뤄요. 허브 프로필을 바꾸지 않 않아요. 폐기가 필요하면 허브에서 별도로 처리하세요. ## /model 선택기("From gateway") + +Claude Code 2.1.257부터는 각 항목의 `description`도 함께 보여줘요. opencodex는 Claude Code CLI용 항목마다 `Routed by OpenCodex to /`을 보내므로, 그 항목에는 "From gateway" 대신 라우팅 경로가 표시돼요. + 각 항목은 `gemini-3-pro (gemini)` 같은 정직한 표시 이름과 함께, 공식 ModelInfo 형태의 모델 능력 정보(추론 강도 사다리, thinking 타입)를 실어 보냅니다 — Claude Desktop의 서드파티 게이트웨이 모드가 추론 강도 선택 UI를 열 수 있게 하기 위해서입니다. 실제 Anthropic 모델은 diff --git a/docs-site/src/content/docs/ru/guides/claude-code.md b/docs-site/src/content/docs/ru/guides/claude-code.md index f82e2e007e4..a73220f9ef3 100644 --- a/docs-site/src/content/docs/ru/guides/claude-code.md +++ b/docs-site/src/content/docs/ru/guides/claude-code.md @@ -161,6 +161,8 @@ Claude Desktop: работающий процесс может хранить п ## Селектор /model («From gateway») +Начиная с Claude Code 2.1.257 у каждой строки показывается её `description`; opencodex отправляет для строк Claude Code CLI `Routed by OpenCodex to /`, поэтому вместо «From gateway» там виден маршрут. + Claude Code 2.1.129+ обнаруживает модели шлюза через `GET /v1/models?limit=1000` и показывает их в нативном селекторе `/model` в разделе «From gateway». Поскольку селектор принимает только id, начинающиеся с `claude` или `anthropic`, opencodex публикует маршрутизируемые модели как diff --git a/docs-site/src/content/docs/tr/guides/claude-code.md b/docs-site/src/content/docs/tr/guides/claude-code.md index d6f5496db14..7868ec5f69e 100644 --- a/docs-site/src/content/docs/tr/guides/claude-code.md +++ b/docs-site/src/content/docs/tr/guides/claude-code.md @@ -311,6 +311,8 @@ gerekirse anahtarı hub'da ayrıca iptal edin. ## /model seçici ("From gateway") +Claude Code 2.1.257 ve sonrası her satırın `description` alanını da gösterir; opencodex, Claude Code CLI satırları için `Routed by OpenCodex to /` gönderdiğinden bu satırlarda "From gateway" yerine rota görünür. + Claude Code 2.1.129+, `GET /v1/models?limit=1000` aracılığıyla ağ geçidi modellerini keşfeder ve bunları yerel `/model` seçicisinde "From gateway" etiketiyle listeler. Seçici yalnızca `claude` veya `anthropic` ile başlayan diff --git a/docs-site/src/content/docs/zh-cn/guides/claude-code.md b/docs-site/src/content/docs/zh-cn/guides/claude-code.md index 746eeba39f4..8bed801f46a 100644 --- a/docs-site/src/content/docs/zh-cn/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-cn/guides/claude-code.md @@ -136,6 +136,9 @@ apply、轮换/恢复或直接 disconnect 均可处理,无需新参数或事 删除外部副本;如有需要,请另行在 hub 撤销。 ## /model 选择器(“From gateway”) + +自 Claude Code 2.1.257 起,每一行还会显示其 `description`;opencodex 会为 Claude Code CLI 的每一行发送 `Routed by OpenCodex to /`,因此这些行显示路由,而不是“From gateway”。 + 每个条目带有诚实的显示名(如 `gemini-3-pro (gemini)`),并以官方 ModelInfo 形态附带模型能力 信息(推理强度梯度、thinking 类型),使 Claude Desktop 的第三方网关模式能够启用推理强度选择 UI。真实 Anthropic 模型保留其原始 id。合成的 2026 日期是内部槽位,不是发布日期。旧版哈希 diff --git a/docs-site/src/content/docs/zh-tw/guides/claude-code.md b/docs-site/src/content/docs/zh-tw/guides/claude-code.md index fc35c52b399..5f4b9df7ef9 100644 --- a/docs-site/src/content/docs/zh-tw/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-tw/guides/claude-code.md @@ -221,6 +221,8 @@ apply、輪換/復原或直接 disconnect 均可處理,無須新參數或事 ## /model 選擇器(“From gateway”) +自 Claude Code 2.1.257 起,每一列也會顯示其 `description`;opencodex 會為 Claude Code CLI 的每一列送出 `Routed by OpenCodex to /`,因此這些列會顯示路由,而不是“From gateway”。 + Claude Code 2.1.129+ 透過 `GET /v1/models?limit=1000` 發現閘道器模型,並在原生 `/model` 選擇器中以“From gateway”標籤列出。由於選擇器只接受以 `claude` 或 `anthropic` 開頭的 ID, opencodex 會將已路由模型公開為穩定且可逆的別名: diff --git a/src/claude/gateway-cache.ts b/src/claude/gateway-cache.ts index 366017a04ba..c0000b2a938 100644 --- a/src/claude/gateway-cache.ts +++ b/src/claude/gateway-cache.ts @@ -6,9 +6,10 @@ * subscription-preserving launch deliberately sets no token, so the CLI can never * refresh its picker list itself — it reads whatever cache exists. We therefore * pre-write the cache in the exact on-disk schema the CLI uses: - * { baseUrl, fetchedAt, models: [{ id, display_name? }] } (mode 0600) + * { baseUrl, fetchedAt, models: [{ id, display_name?, description? }] } (mode 0600) * mirroring its `/^(claude|anthropic)/i` usable-id filter. The picker validates * only `baseUrl === ANTHROPIC_BASE_URL`, so a foreign base URL is simply ignored. + * `description` replaces the picker's generic "From gateway" line (Claude Code >= 2.1.257). */ import { mkdirSync, writeFileSync } from "node:fs"; import { homedir } from "node:os"; @@ -19,6 +20,7 @@ import type { OcxConfig } from "../types"; export interface GatewayModelRow { id: string; display_name?: string; + description?: string; } export interface GatewayModelCacheRefreshOptions { @@ -56,7 +58,11 @@ export function writeGatewayModelCache(baseUrl: string, models: readonly Gateway const payload = { baseUrl, fetchedAt: Date.now(), - models: usable.map(m => (m.display_name === undefined ? { id: m.id } : { id: m.id, display_name: m.display_name })), + models: usable.map(m => ({ + id: m.id, + ...(m.display_name === undefined ? {} : { display_name: m.display_name }), + ...(m.description === undefined ? {} : { description: m.description }), + })), }; writeFileSync(path, JSON.stringify(payload), { encoding: "utf8", mode: 0o600 }); return path; @@ -110,6 +116,7 @@ export async function refreshGatewayModelCacheFromProxy( .map(m => ({ id: m.id as string, display_name: typeof m.display_name === "string" ? m.display_name : undefined, + description: typeof m.description === "string" ? m.description : undefined, })); return writeGatewayModelCache(baseUrl, models, options.configDir); } catch { diff --git a/src/claude/model-info.ts b/src/claude/model-info.ts index 665183c651c..37c03dcf7b3 100644 --- a/src/claude/model-info.ts +++ b/src/claude/model-info.ts @@ -80,9 +80,14 @@ export interface AnthropicModelInfo { capabilities: ReturnType; max_input_tokens: number | null; max_tokens: null; + /** + * Claude Code (>= 2.1.257) shows this under the picker row instead of the generic + * "From gateway". Readable (CLI) rows only; Desktop 3P rows keep the ModelInfo shape. + */ + description?: string; } -function modelInfo(id: string, displayName: string, ladder: readonly string[], imageInput: boolean, contextWindow?: number): AnthropicModelInfo { +function modelInfo(id: string, displayName: string, ladder: readonly string[], imageInput: boolean, contextWindow?: number, description?: string): AnthropicModelInfo { return { id, display_name: displayName, @@ -91,6 +96,7 @@ function modelInfo(id: string, displayName: string, ladder: readonly string[], i capabilities: modelCapabilities(ladder, imageInput), max_input_tokens: typeof contextWindow === "number" && contextWindow > 0 ? contextWindow : null, max_tokens: null, + ...(description === undefined ? {} : { description }), }; } @@ -192,7 +198,8 @@ export function buildAnthropicModelInfos( const nativeMaxInput = nativeOpenAiMaxInputTokens(slug, nativeContextCap); // max_input_tokens is an INPUT limit, so it follows the measured input ceiling rather // than the total window whenever the model publishes one. - const info = modelInfo(id, `${slug} (native)`, nativeEffectiveLadder(slug), true, nativeMaxInput ?? nativeWindow); + const description = idStyle === "readable" ? `Routed by OpenCodex to native ${slug}` : undefined; + const info = modelInfo(id, `${slug} (native)`, nativeEffectiveLadder(slug), true, nativeMaxInput ?? nativeWindow, description); out.push(info); push1mVariant(info, nativeWindow, nativeMaxInput); // Natives too, not only routed rows: gpt-5.6-sol is the flagship Fast model, and @@ -225,7 +232,8 @@ export function buildAnthropicModelInfos( ? Math.min(m.maxInputTokens, m.contextWindow) : m.maxInputTokens) : undefined; - const info = modelInfo(id, `${listedModelId} (${m.provider})`, ladder, imageInput, routedMaxInput ?? m.contextWindow); + const description = idStyle === "readable" ? `Routed by OpenCodex to ${m.provider}/${listedModelId}` : undefined; + const info = modelInfo(id, `${listedModelId} (${m.provider})`, ladder, imageInput, routedMaxInput ?? m.contextWindow, description); out.push(info); // Anthropic passthrough guard (audit 021 #3): never auto-widen canonical claude // routes — only a genuine >=1M window earns the variant row there. diff --git a/tests/claude-integration/claude-gateway-cache.test.ts b/tests/claude-integration/claude-gateway-cache.test.ts index f690cda6199..9f8ef4ffdba 100644 --- a/tests/claude-integration/claude-gateway-cache.test.ts +++ b/tests/claude-integration/claude-gateway-cache.test.ts @@ -195,3 +195,30 @@ describe("Claude Code gateway-model cache pre-write (devlog 260712 030)", () => } }); }); + +describe("gateway-model cache carries the picker description", () => { + test("writer keeps description so the picker stops reading \"From gateway\"", () => { + const dir = tempDir(); + const path = writeGatewayModelCache("http://127.0.0.1:10100", [ + { id: "claude-ocx-xai--grok-4.7", display_name: "grok-4.7 (xai)", description: "Routed by OpenCodex to xai/grok-4.7" }, + { id: "claude-ocx-native--gpt-5.5", display_name: "gpt-5.5 (native)" }, + ], dir); + expect(JSON.parse(readFileSync(path!, "utf8")).models).toEqual([ + { id: "claude-ocx-xai--grok-4.7", display_name: "grok-4.7 (xai)", description: "Routed by OpenCodex to xai/grok-4.7" }, + { id: "claude-ocx-native--gpt-5.5", display_name: "gpt-5.5 (native)" }, + ]); + }); + + test("proxy refresh copies description from /v1/models and ignores non-strings", async () => { + const dir = tempDir(); + const fetchImpl = (async () => new Response(JSON.stringify({ data: [ + { id: "claude-ocx-xai--grok-4.7", display_name: "grok-4.7 (xai)", description: "Routed by OpenCodex to xai/grok-4.7" }, + { id: "claude-ocx-p--odd", display_name: "odd (p)", description: 42 }, + ] }), { headers: { "content-type": "application/json" } })) as unknown as typeof fetch; + const path = await refreshGatewayModelCacheFromProxy(10100, { timeoutMs: 1000, configDir: dir, env: {}, fetchImpl }); + expect(JSON.parse(readFileSync(path!, "utf8")).models).toEqual([ + { id: "claude-ocx-xai--grok-4.7", display_name: "grok-4.7 (xai)", description: "Routed by OpenCodex to xai/grok-4.7" }, + { id: "claude-ocx-p--odd", display_name: "odd (p)" }, + ]); + }); +}); diff --git a/tests/claude-integration/claude-model-info.test.ts b/tests/claude-integration/claude-model-info.test.ts index 7794a730299..c2a0fd48333 100644 --- a/tests/claude-integration/claude-model-info.test.ts +++ b/tests/claude-integration/claude-model-info.test.ts @@ -237,3 +237,31 @@ describe("saved picker order changes groups after identity selection", () => { expect(result.map(row => [row.id, row.display_name])).toEqual([["collision", "a (p)"]]); }); }); + +describe("Claude Code picker description (replaces the generic \"From gateway\" line)", () => { + test("readable rows describe the route OpenCodex serves them through", () => { + const infos = buildAnthropicModelInfos(["gpt-5.5"], [ + { provider: "xai", id: "grok-4.7", contextWindow: 500_000 }, + ], undefined, "readable"); + const native = infos.find(i => i.display_name === "gpt-5.5 (native)"); + const routed = infos.find(i => i.display_name === "grok-4.7 (xai)"); + expect(native?.description).toBe("Routed by OpenCodex to native gpt-5.5"); + expect(routed?.description).toBe("Routed by OpenCodex to xai/grok-4.7"); + }); + + test("1M and Fast siblings keep their base row's description", () => { + const infos = buildAnthropicModelInfos([], [ + { provider: "p", id: "big", contextWindow: 1_000_000 }, + ], undefined, "readable", undefined, undefined, false, () => true); + expect(infos.map(i => [i.display_name, i.description])).toEqual([ + ["big (p)", "Routed by OpenCodex to p/big"], + ["big (p) · 1M", "Routed by OpenCodex to p/big"], + ["big (p) · Fast", "Routed by OpenCodex to p/big"], + ]); + }); + + test("Desktop 3P rows stay unchanged (no description field)", () => { + const infos = buildAnthropicModelInfos(["gpt-5.5"], [{ provider: "xai", id: "grok-4.7" }], undefined, "desktop3p"); + for (const info of infos) expect("description" in info).toBe(false); + }); +}); From ee38020a380455ca4ea02fd3433ca6a9f3466c0b Mon Sep 17 00:00:00 2001 From: sh940701 Date: Wed, 23 Sep 2026 09:28:56 +0900 Subject: [PATCH 2/3] fix(claude): name the Fast tier in Fast picker rows; align translated guides MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A Fast sibling selects a different tier or variant, so its description now ends in " · Fast" like its display name; 1M siblings keep the base route. The fr/ja/ko/ru/tr/zh-cn/zh-tw guides now say what the English one says: "From gateway" is the fallback for rows without a description, instead of keeping the old "listed under From gateway" sentence with a note on top. --- docs-site/src/content/docs/fr/guides/claude-code.md | 6 +++--- docs-site/src/content/docs/ja/guides/claude-code.md | 6 +++--- docs-site/src/content/docs/ko/guides/claude-code.md | 7 +++---- docs-site/src/content/docs/ru/guides/claude-code.md | 6 +++--- docs-site/src/content/docs/tr/guides/claude-code.md | 8 ++++---- docs-site/src/content/docs/zh-cn/guides/claude-code.md | 7 +++---- docs-site/src/content/docs/zh-tw/guides/claude-code.md | 6 +++--- src/claude/model-info.ts | 8 +++++++- tests/claude-integration/claude-model-info.test.ts | 6 ++++-- 9 files changed, 33 insertions(+), 27 deletions(-) diff --git a/docs-site/src/content/docs/fr/guides/claude-code.md b/docs-site/src/content/docs/fr/guides/claude-code.md index 3a6c8103d5f..f4675a23484 100644 --- a/docs-site/src/content/docs/fr/guides/claude-code.md +++ b/docs-site/src/content/docs/fr/guides/claude-code.md @@ -299,10 +299,10 @@ pas les copies externes ; révoquez-la séparément sur le hub si nécessaire. ## Le sélecteur /model (« Depuis la passerelle ») -Depuis Claude Code 2.1.257, chaque ligne affiche aussi sa `description` ; opencodex envoie `Routed by OpenCodex to /` pour chaque ligne du CLI Claude Code, qui montre donc l'itinéraire au lieu du libellé « From gateway ». - Claude Code 2.1.129+ découvre les modèles de passerelle via `GET /v1/models?limit=1000` et les répertorie dans -le sélecteur natif `/model` intitulé « Depuis la passerelle ». Comme ce sélecteur n'accepte que les identifiants commençant +le sélecteur natif `/model`. Une ligne sans `description` affiche « From gateway » ; opencodex en envoie une pour +chaque ligne du CLI Claude Code (`Routed by OpenCodex to /`), que Claude Code 2.1.257+ affiche +à la place. Comme ce sélecteur n'accepte que les identifiants commençant par `claude` ou `anthropic`, opencodex expose les modèles routés sous forme d'alias stables et réversibles : | Surface | Format | Exemple | diff --git a/docs-site/src/content/docs/ja/guides/claude-code.md b/docs-site/src/content/docs/ja/guides/claude-code.md index 0ac4e059773..787ebb7ff9b 100644 --- a/docs-site/src/content/docs/ja/guides/claude-code.md +++ b/docs-site/src/content/docs/ja/guides/claude-code.md @@ -173,10 +173,10 @@ Claude Code CLI 互換性は英語版ドキュメントを参照してくださ ## /model ピッカー("From gateway") -Claude Code 2.1.257 以降は各行の `description` も表示します。opencodex は Claude Code CLI 向けの各行に `Routed by OpenCodex to /` を送るため、その行には "From gateway" の代わりにルートが表示されます。 - Claude Code 2.1.129 以降は `GET /v1/models?limit=1000` でゲートウェイモデルを探し、デフォルトの `/model` -ピッカーの "From gateway" 項目に表示します。ピッカーは `claude` または `anthropic` で始まる ID のみ +ピッカーに表示します。`description` のない行は "From gateway" と表示されます。opencodex は Claude Code CLI +向けの各行に `description`(`Routed by OpenCodex to /`)を送り、Claude Code 2.1.257 以降は +その内容を代わりに表示します。ピッカーは `claude` または `anthropic` で始まる ID のみ 受け付けるため、opencodex はルーティングモデルを安定で元に戻せるエイリアスとして公開します。 | 画面 | 形式 | 例 | diff --git a/docs-site/src/content/docs/ko/guides/claude-code.md b/docs-site/src/content/docs/ko/guides/claude-code.md index 4c8761c007f..5e32d63b437 100644 --- a/docs-site/src/content/docs/ko/guides/claude-code.md +++ b/docs-site/src/content/docs/ko/guides/claude-code.md @@ -196,9 +196,6 @@ import/export는 로컬 설정만 다뤄요. 허브 프로필을 바꾸지 않 않아요. 폐기가 필요하면 허브에서 별도로 처리하세요. ## /model 선택기("From gateway") - -Claude Code 2.1.257부터는 각 항목의 `description`도 함께 보여줘요. opencodex는 Claude Code CLI용 항목마다 `Routed by OpenCodex to /`을 보내므로, 그 항목에는 "From gateway" 대신 라우팅 경로가 표시돼요. - 각 항목은 `gemini-3-pro (gemini)` 같은 정직한 표시 이름과 함께, 공식 ModelInfo 형태의 모델 능력 정보(추론 강도 사다리, thinking 타입)를 실어 보냅니다 — Claude Desktop의 서드파티 게이트웨이 모드가 추론 강도 선택 UI를 열 수 있게 하기 위해서입니다. 실제 Anthropic 모델은 @@ -211,7 +208,9 @@ Claude Code 2.1.257부터는 각 항목의 `description`도 함께 보여줘요. 지정하거나 `/model`에 라우팅 id를 직접 입력하세요 (Claude Code는 문자열을 그대로 통과시킵니다). Claude Code 2.1.129 이상은 `GET /v1/models?limit=1000`에서 게이트웨이 모델을 찾아 기본 `/model` -선택기의 "From gateway" 항목에 표시해요. 선택기는 `claude` 또는 `anthropic`으로 시작하는 ID만 +선택기에 표시해요. `description`이 없는 항목은 "From gateway"로 보이는데, opencodex는 Claude Code CLI용 +항목마다 `description`(`Routed by OpenCodex to /`)을 보내고 Claude Code 2.1.257 이상은 +그 내용을 대신 보여줘요. 선택기는 `claude` 또는 `anthropic`으로 시작하는 ID만 받으므로, opencodex는 라우팅 모델을 안정적이고 되돌릴 수 있는 별칭으로 노출해요. | 화면 | 형식 | 예시 | diff --git a/docs-site/src/content/docs/ru/guides/claude-code.md b/docs-site/src/content/docs/ru/guides/claude-code.md index a73220f9ef3..1175a93aef2 100644 --- a/docs-site/src/content/docs/ru/guides/claude-code.md +++ b/docs-site/src/content/docs/ru/guides/claude-code.md @@ -161,10 +161,10 @@ Claude Desktop: работающий процесс может хранить п ## Селектор /model («From gateway») -Начиная с Claude Code 2.1.257 у каждой строки показывается её `description`; opencodex отправляет для строк Claude Code CLI `Routed by OpenCodex to /`, поэтому вместо «From gateway» там виден маршрут. - Claude Code 2.1.129+ обнаруживает модели шлюза через `GET /v1/models?limit=1000` и показывает их -в нативном селекторе `/model` в разделе «From gateway». Поскольку селектор принимает только id, +в нативном селекторе `/model`. Строка без `description` подписана «From gateway»; opencodex отправляет +её для каждой строки Claude Code CLI (`Routed by OpenCodex to /`), и Claude Code 2.1.257+ +показывает этот текст вместо подписи. Поскольку селектор принимает только id, начинающиеся с `claude` или `anthropic`, opencodex публикует маршрутизируемые модели как стабильные обратимые алиасы: diff --git a/docs-site/src/content/docs/tr/guides/claude-code.md b/docs-site/src/content/docs/tr/guides/claude-code.md index 7868ec5f69e..4a4ed948e76 100644 --- a/docs-site/src/content/docs/tr/guides/claude-code.md +++ b/docs-site/src/content/docs/tr/guides/claude-code.md @@ -311,11 +311,11 @@ gerekirse anahtarı hub'da ayrıca iptal edin. ## /model seçici ("From gateway") -Claude Code 2.1.257 ve sonrası her satırın `description` alanını da gösterir; opencodex, Claude Code CLI satırları için `Routed by OpenCodex to /` gönderdiğinden bu satırlarda "From gateway" yerine rota görünür. - Claude Code 2.1.129+, `GET /v1/models?limit=1000` aracılığıyla ağ geçidi -modellerini keşfeder ve bunları yerel `/model` seçicisinde "From gateway" -etiketiyle listeler. Seçici yalnızca `claude` veya `anthropic` ile başlayan +modellerini keşfeder ve bunları yerel `/model` seçicisinde listeler. `description` +alanı olmayan bir satır "From gateway" olarak görünür; opencodex her Claude Code CLI +satırı için bir tane gönderir (`Routed by OpenCodex to /`) ve Claude Code +2.1.257+ onun yerine bunu gösterir. Seçici yalnızca `claude` veya `anthropic` ile başlayan kimlikleri kabul ettiğinden, opencodex yönlendirilen modelleri kararlı, tersine çevrilebilir takma adlar olarak sunar: diff --git a/docs-site/src/content/docs/zh-cn/guides/claude-code.md b/docs-site/src/content/docs/zh-cn/guides/claude-code.md index 8bed801f46a..4925f4bd780 100644 --- a/docs-site/src/content/docs/zh-cn/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-cn/guides/claude-code.md @@ -136,9 +136,6 @@ apply、轮换/恢复或直接 disconnect 均可处理,无需新参数或事 删除外部副本;如有需要,请另行在 hub 撤销。 ## /model 选择器(“From gateway”) - -自 Claude Code 2.1.257 起,每一行还会显示其 `description`;opencodex 会为 Claude Code CLI 的每一行发送 `Routed by OpenCodex to /`,因此这些行显示路由,而不是“From gateway”。 - 每个条目带有诚实的显示名(如 `gemini-3-pro (gemini)`),并以官方 ModelInfo 形态附带模型能力 信息(推理强度梯度、thinking 类型),使 Claude Desktop 的第三方网关模式能够启用推理强度选择 UI。真实 Anthropic 模型保留其原始 id。合成的 2026 日期是内部槽位,不是发布日期。旧版哈希 @@ -149,7 +146,9 @@ UI。真实 Anthropic 模型保留其原始 id。合成的 2026 日期是内部 中输入任意路由 id(Claude Code 会原样传递字符串)。 Claude Code 2.1.129+ 通过 `GET /v1/models?limit=1000` 发现网关模型,并在原生 `/model` -选择器中以“From gateway”标签列出。由于选择器只接受以 `claude` 或 `anthropic` 开头的 ID, +选择器中列出。没有 `description` 的行显示为“From gateway”;opencodex 会为 Claude Code CLI 的每一行发送 +`description`(`Routed by OpenCodex to /`),Claude Code 2.1.257+ 会改为显示它。 +由于选择器只接受以 `claude` 或 `anthropic` 开头的 ID, opencodex 会将已路由模型公开为稳定且可逆的别名: | 界面 | 格式 | 示例 | diff --git a/docs-site/src/content/docs/zh-tw/guides/claude-code.md b/docs-site/src/content/docs/zh-tw/guides/claude-code.md index 5f4b9df7ef9..e82e7c27136 100644 --- a/docs-site/src/content/docs/zh-tw/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-tw/guides/claude-code.md @@ -221,10 +221,10 @@ apply、輪換/復原或直接 disconnect 均可處理,無須新參數或事 ## /model 選擇器(“From gateway”) -自 Claude Code 2.1.257 起,每一列也會顯示其 `description`;opencodex 會為 Claude Code CLI 的每一列送出 `Routed by OpenCodex to /`,因此這些列會顯示路由,而不是“From gateway”。 - Claude Code 2.1.129+ 透過 `GET /v1/models?limit=1000` 發現閘道器模型,並在原生 `/model` -選擇器中以“From gateway”標籤列出。由於選擇器只接受以 `claude` 或 `anthropic` 開頭的 ID, +選擇器中列出。沒有 `description` 的列會顯示為“From gateway”;opencodex 會為 Claude Code CLI 的每一列送出 +`description`(`Routed by OpenCodex to /`),Claude Code 2.1.257+ 會改為顯示它。 +由於選擇器只接受以 `claude` 或 `anthropic` 開頭的 ID, opencodex 會將已路由模型公開為穩定且可逆的別名: | 介面 | 格式 | 示例 | diff --git a/src/claude/model-info.ts b/src/claude/model-info.ts index 37c03dcf7b3..7f5fe0f7266 100644 --- a/src/claude/model-info.ts +++ b/src/claude/model-info.ts @@ -188,7 +188,13 @@ export function buildAnthropicModelInfos( // A real model always wins its own id, whatever the iteration order. if (realDiscoveryIds.has(id) || seen.has(id)) return; seen.add(id); - out.push({ ...base, id, display_name: `${base.display_name} · Fast` }); + out.push({ + ...base, + id, + display_name: `${base.display_name} · Fast`, + // Fast picks a different tier/variant, so the picker line says so like the name does. + ...(base.description === undefined ? {} : { description: `${base.description} · Fast` }), + }); }; for (const slug of nativeSlugs) { const id = idStyle === "readable" ? claudeCodeNativeAlias(slug) : aliasForRoute("native", slug); diff --git a/tests/claude-integration/claude-model-info.test.ts b/tests/claude-integration/claude-model-info.test.ts index c2a0fd48333..5d7189b8e2e 100644 --- a/tests/claude-integration/claude-model-info.test.ts +++ b/tests/claude-integration/claude-model-info.test.ts @@ -249,14 +249,16 @@ describe("Claude Code picker description (replaces the generic \"From gateway\" expect(routed?.description).toBe("Routed by OpenCodex to xai/grok-4.7"); }); - test("1M and Fast siblings keep their base row's description", () => { + // A 1M row is the same route with a larger window; a Fast row selects a different tier or + // variant, so its description says so the way its display name does. + test("1M siblings keep the base description and Fast siblings name the Fast tier", () => { const infos = buildAnthropicModelInfos([], [ { provider: "p", id: "big", contextWindow: 1_000_000 }, ], undefined, "readable", undefined, undefined, false, () => true); expect(infos.map(i => [i.display_name, i.description])).toEqual([ ["big (p)", "Routed by OpenCodex to p/big"], ["big (p) · 1M", "Routed by OpenCodex to p/big"], - ["big (p) · Fast", "Routed by OpenCodex to p/big"], + ["big (p) · Fast", "Routed by OpenCodex to p/big · Fast"], ]); }); From c0d6fcc79e83f815bd5745fd3dfa7e8ab061d358 Mon Sep 17 00:00:00 2001 From: sh940701 Date: Wed, 23 Sep 2026 10:37:55 +0900 Subject: [PATCH 3/3] docs(claude): spell out native, Fast and 1M picker descriptions --- docs-site/src/content/docs/fr/guides/claude-code.md | 2 +- docs-site/src/content/docs/guides/claude-code.md | 2 +- docs-site/src/content/docs/ja/guides/claude-code.md | 2 +- docs-site/src/content/docs/ko/guides/claude-code.md | 2 +- docs-site/src/content/docs/ru/guides/claude-code.md | 2 +- docs-site/src/content/docs/tr/guides/claude-code.md | 2 +- docs-site/src/content/docs/zh-cn/guides/claude-code.md | 2 +- docs-site/src/content/docs/zh-tw/guides/claude-code.md | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs-site/src/content/docs/fr/guides/claude-code.md b/docs-site/src/content/docs/fr/guides/claude-code.md index f4675a23484..0ad9eaac5ff 100644 --- a/docs-site/src/content/docs/fr/guides/claude-code.md +++ b/docs-site/src/content/docs/fr/guides/claude-code.md @@ -301,7 +301,7 @@ pas les copies externes ; révoquez-la séparément sur le hub si nécessaire. Claude Code 2.1.129+ découvre les modèles de passerelle via `GET /v1/models?limit=1000` et les répertorie dans le sélecteur natif `/model`. Une ligne sans `description` affiche « From gateway » ; opencodex en envoie une pour -chaque ligne du CLI Claude Code (`Routed by OpenCodex to /`), que Claude Code 2.1.257+ affiche +chaque ligne du CLI Claude Code (`Routed by OpenCodex to /` ; lignes natives : `Routed by OpenCodex to native ` ; les lignes Fast ajoutent ` · Fast` et les lignes 1M gardent la description de base), que Claude Code 2.1.257+ affiche à la place. Comme ce sélecteur n'accepte que les identifiants commençant par `claude` ou `anthropic`, opencodex expose les modèles routés sous forme d'alias stables et réversibles : diff --git a/docs-site/src/content/docs/guides/claude-code.md b/docs-site/src/content/docs/guides/claude-code.md index 36b064e4d0a..65e16011c22 100644 --- a/docs-site/src/content/docs/guides/claude-code.md +++ b/docs-site/src/content/docs/guides/claude-code.md @@ -364,7 +364,7 @@ arbitrary external copies; revoke separately on the hub if desired. Claude Code 2.1.129+ discovers gateway models via `GET /v1/models?limit=1000` and lists them in the native `/model` picker. A row without a `description` reads "From gateway"; opencodex sends one -for every Claude Code CLI row (`Routed by OpenCodex to /`), which Claude Code +for every Claude Code CLI row (`Routed by OpenCodex to /`; native rows use `Routed by OpenCodex to native `, Fast rows append ` · Fast`, and 1M rows keep the base description), which Claude Code 2.1.257+ shows in its place. Because the picker only accepts ids beginning with `claude` or `anthropic`, opencodex exposes routed models as stable, reversible aliases: diff --git a/docs-site/src/content/docs/ja/guides/claude-code.md b/docs-site/src/content/docs/ja/guides/claude-code.md index 787ebb7ff9b..3a91eda2226 100644 --- a/docs-site/src/content/docs/ja/guides/claude-code.md +++ b/docs-site/src/content/docs/ja/guides/claude-code.md @@ -175,7 +175,7 @@ Claude Code CLI 互換性は英語版ドキュメントを参照してくださ Claude Code 2.1.129 以降は `GET /v1/models?limit=1000` でゲートウェイモデルを探し、デフォルトの `/model` ピッカーに表示します。`description` のない行は "From gateway" と表示されます。opencodex は Claude Code CLI -向けの各行に `description`(`Routed by OpenCodex to /`)を送り、Claude Code 2.1.257 以降は +向けの各行に `description`(`Routed by OpenCodex to /`、ネイティブ行は `Routed by OpenCodex to native `、Fast 行は末尾に ` · Fast`、1M 行は元の説明のまま)を送り、Claude Code 2.1.257 以降は その内容を代わりに表示します。ピッカーは `claude` または `anthropic` で始まる ID のみ 受け付けるため、opencodex はルーティングモデルを安定で元に戻せるエイリアスとして公開します。 diff --git a/docs-site/src/content/docs/ko/guides/claude-code.md b/docs-site/src/content/docs/ko/guides/claude-code.md index 5e32d63b437..5a3863cd808 100644 --- a/docs-site/src/content/docs/ko/guides/claude-code.md +++ b/docs-site/src/content/docs/ko/guides/claude-code.md @@ -209,7 +209,7 @@ import/export는 로컬 설정만 다뤄요. 허브 프로필을 바꾸지 않 Claude Code 2.1.129 이상은 `GET /v1/models?limit=1000`에서 게이트웨이 모델을 찾아 기본 `/model` 선택기에 표시해요. `description`이 없는 항목은 "From gateway"로 보이는데, opencodex는 Claude Code CLI용 -항목마다 `description`(`Routed by OpenCodex to /`)을 보내고 Claude Code 2.1.257 이상은 +항목마다 `description`(`Routed by OpenCodex to /`, 네이티브 항목은 `Routed by OpenCodex to native `, Fast 항목은 끝에 ` · Fast`, 1M 항목은 기본 설명 그대로)을 보내고 Claude Code 2.1.257 이상은 그 내용을 대신 보여줘요. 선택기는 `claude` 또는 `anthropic`으로 시작하는 ID만 받으므로, opencodex는 라우팅 모델을 안정적이고 되돌릴 수 있는 별칭으로 노출해요. diff --git a/docs-site/src/content/docs/ru/guides/claude-code.md b/docs-site/src/content/docs/ru/guides/claude-code.md index 1175a93aef2..a95fbc4496c 100644 --- a/docs-site/src/content/docs/ru/guides/claude-code.md +++ b/docs-site/src/content/docs/ru/guides/claude-code.md @@ -163,7 +163,7 @@ Claude Desktop: работающий процесс может хранить п Claude Code 2.1.129+ обнаруживает модели шлюза через `GET /v1/models?limit=1000` и показывает их в нативном селекторе `/model`. Строка без `description` подписана «From gateway»; opencodex отправляет -её для каждой строки Claude Code CLI (`Routed by OpenCodex to /`), и Claude Code 2.1.257+ +её для каждой строки Claude Code CLI (`Routed by OpenCodex to /`; для нативных строк — `Routed by OpenCodex to native `, строки Fast добавляют ` · Fast`, строки 1M сохраняют базовое описание), и Claude Code 2.1.257+ показывает этот текст вместо подписи. Поскольку селектор принимает только id, начинающиеся с `claude` или `anthropic`, opencodex публикует маршрутизируемые модели как стабильные обратимые алиасы: diff --git a/docs-site/src/content/docs/tr/guides/claude-code.md b/docs-site/src/content/docs/tr/guides/claude-code.md index 4a4ed948e76..e4b5c8b6e2f 100644 --- a/docs-site/src/content/docs/tr/guides/claude-code.md +++ b/docs-site/src/content/docs/tr/guides/claude-code.md @@ -314,7 +314,7 @@ gerekirse anahtarı hub'da ayrıca iptal edin. Claude Code 2.1.129+, `GET /v1/models?limit=1000` aracılığıyla ağ geçidi modellerini keşfeder ve bunları yerel `/model` seçicisinde listeler. `description` alanı olmayan bir satır "From gateway" olarak görünür; opencodex her Claude Code CLI -satırı için bir tane gönderir (`Routed by OpenCodex to /`) ve Claude Code +satırı için bir tane gönderir (`Routed by OpenCodex to /`; yerel satırlarda `Routed by OpenCodex to native `, Fast satırları sona ` · Fast` ekler, 1M satırları temel açıklamayı korur) ve Claude Code 2.1.257+ onun yerine bunu gösterir. Seçici yalnızca `claude` veya `anthropic` ile başlayan kimlikleri kabul ettiğinden, opencodex yönlendirilen modelleri kararlı, tersine çevrilebilir takma adlar olarak sunar: diff --git a/docs-site/src/content/docs/zh-cn/guides/claude-code.md b/docs-site/src/content/docs/zh-cn/guides/claude-code.md index 4925f4bd780..fdb4e50125f 100644 --- a/docs-site/src/content/docs/zh-cn/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-cn/guides/claude-code.md @@ -147,7 +147,7 @@ UI。真实 Anthropic 模型保留其原始 id。合成的 2026 日期是内部 Claude Code 2.1.129+ 通过 `GET /v1/models?limit=1000` 发现网关模型,并在原生 `/model` 选择器中列出。没有 `description` 的行显示为“From gateway”;opencodex 会为 Claude Code CLI 的每一行发送 -`description`(`Routed by OpenCodex to /`),Claude Code 2.1.257+ 会改为显示它。 +`description`(`Routed by OpenCodex to /`;原生行为 `Routed by OpenCodex to native `,Fast 行末尾加 ` · Fast`,1M 行沿用基础描述),Claude Code 2.1.257+ 会改为显示它。 由于选择器只接受以 `claude` 或 `anthropic` 开头的 ID, opencodex 会将已路由模型公开为稳定且可逆的别名: diff --git a/docs-site/src/content/docs/zh-tw/guides/claude-code.md b/docs-site/src/content/docs/zh-tw/guides/claude-code.md index e82e7c27136..be440122ec8 100644 --- a/docs-site/src/content/docs/zh-tw/guides/claude-code.md +++ b/docs-site/src/content/docs/zh-tw/guides/claude-code.md @@ -223,7 +223,7 @@ apply、輪換/復原或直接 disconnect 均可處理,無須新參數或事 Claude Code 2.1.129+ 透過 `GET /v1/models?limit=1000` 發現閘道器模型,並在原生 `/model` 選擇器中列出。沒有 `description` 的列會顯示為“From gateway”;opencodex 會為 Claude Code CLI 的每一列送出 -`description`(`Routed by OpenCodex to /`),Claude Code 2.1.257+ 會改為顯示它。 +`description`(`Routed by OpenCodex to /`;原生列為 `Routed by OpenCodex to native `,Fast 列末尾加上 ` · Fast`,1M 列沿用基礎描述),Claude Code 2.1.257+ 會改為顯示它。 由於選擇器只接受以 `claude` 或 `anthropic` 開頭的 ID, opencodex 會將已路由模型公開為穩定且可逆的別名: