Honor Claude Code's provider model mapping for Claude sessions - #308
Open
dcdyouget wants to merge 1 commit into
Open
Honor Claude Code's provider model mapping for Claude sessions#308dcdyouget wants to merge 1 commit into
dcdyouget wants to merge 1 commit into
Conversation
cc-switch (and Anthropic-compatible gateways) switch Claude Code's provider
by rewriting the env block of ~/.claude/settings.json:
ANTHROPIC_BASE_URL/AUTH_TOKEN plus ANTHROPIC_DEFAULT_{FABLE,OPUS,SONNET,
HAIKU}_MODEL. Claude Code applies that family mapping only to FAMILY ALIASES
(opus, sonnet, ...); a full model id passed via --model (claude-opus-5) goes
to the provider verbatim. Zeron's curated catalog is exactly those full ids,
so the mapping was bypassed: requests carried the Claude model name and some
providers rejected them with model_not_found (issue zeronsh#305).
Read the user-level settings and resolve the selected id through the family
mapping before passing --model. When a mapping is configured, models() now
surfaces the provider models (deduped by display name) so the picker names
what actually runs; native Anthropic settings are untouched.
Also stop disabling the user settings file for title runs: --setting-sources
"" dropped the provider env, so titles failed with "Not logged in" for
third-party providers. `user` keeps them while still skipping project/local.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
cc-switch (and Anthropic-compatible gateways) switch Claude Code's provider by rewriting the
envblock of~/.claude/settings.json:{ "env": { "ANTHROPIC_BASE_URL": "https://api.deepseek.com/anthropic", "ANTHROPIC_MODEL": "deepseek-v4-flash", "ANTHROPIC_DEFAULT_OPUS_MODEL": "deepseek-v4-flash[1M]", "ANTHROPIC_DEFAULT_SONNET_MODEL": "deepseek-v4-flash[1M]", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "deepseek-v4-flash" } }Claude Code applies the
ANTHROPIC_DEFAULT_*_MODELmapping only to family aliases (fable,opus,sonnet,haiku). A full model id passed via--model(claude-opus-5) is sent to the provider verbatim — verified against a local mock Anthropic endpoint. Zeron's curated catalog is exactly those full ids, so the mapping was bypassed: the model picker kept showing Claude names, requests carried the Claude model name, and providers that validate strictly failed withmodel_not_found(see #305).Refs #305.
Changes
crates/harness/src/claude/settings.rs— reads the user-level Claude settingsenv($CLAUDE_CONFIG_DIRor~/.claude) and exposes the per-family provider mapping plusresolve_request_model().build_command— resolves the selected id through the family mapping before passing--model. When no mapping is configured it keeps the previous behavior (including the[1m]context suffix), so native Anthropic users are unaffected.models()— when a mapping is configured, surfaces the configured provider models instead of the Claude ids they are mapped from.--setting-sources ""dropped the user settings file entirely, so a third-party provider'senv(base URL / token / model) was lost and titles failed with "Not logged in".userkeeps that env while still skipping project/local settings.Design notes
idis the provider model value (deepseek-v4-flash[1M]); Claude Code strips the trailing[...]context suffix, so the request and the displayed model stay identical.ANTHROPIC_DEFAULT_*_MODEL_NAME): cc-switch points all four families at one model, which would otherwise render as four identical rows. Distinct provider models (e.g. opus → A, haiku → B) remain separate rows.Validation
cargo check --locked -p zeron-harness --lib --tests— clean for the changed filescargo test --locked -p zeron-harness --lib claude::— 32 passedcargo test --locked -p zeron-harness --test claude— 10 passedcargo test --locked -p zeron-ui --lib -- --test-threads=1— 778 passed, 0 failed--model claude-opus-5reached the provider asclaude-opus-5before, and as the configured provider model after;--setting-sources ""produced no request,userproduced one.rustfmt --checkon the changed files;git diff --check— cleanNote:
zeron-harness --libhas a pre-existing, environment-dependent failure (shell_env::unix::tests::falls_back_when_interactive_attempt_hangs) that also fails on unmodifiedmain.中文说明
概述
cc-switch(以及各类 Anthropic 兼容网关)是通过改写
~/.claude/settings.json的env块来切换 Claude Code 的供应商的:{ "env": { "ANTHROPIC_BASE_URL": "https://api.deepseek.com/anthropic", "ANTHROPIC_MODEL": "deepseek-v4-flash", "ANTHROPIC_DEFAULT_OPUS_MODEL": "deepseek-v4-flash[1M]", "ANTHROPIC_DEFAULT_SONNET_MODEL": "deepseek-v4-flash[1M]", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "deepseek-v4-flash" } }Claude Code 的
ANTHROPIC_DEFAULT_*_MODEL映射只对 family 别名生效(fable/opus/sonnet/haiku)。通过--model传完整模型 id(claude-opus-5)时,会被原样发给 provider —— 这一点已用一个本地假 Anthropic endpoint 实测确认。而 Zeron 的 catalog 恰好全是完整 id,于是映射被绕过:模型选择器一直显示 Claude 名字,请求里带的也是 Claude 模型名,校验严格的 provider 会直接报model_not_found(见 #305)。引用 #305。
改动
crates/harness/src/claude/settings.rs—— 读取用户级 Claude 配置的env($CLAUDE_CONFIG_DIR或~/.claude),提供 per-family 的 provider 映射以及resolve_request_model()。build_command—— 传--model之前先按 family 映射解析选中的 id。没有配置映射时保持原行为(含[1m]上下文后缀),因此原生 Anthropic 用户不受影响。models()—— 配置了映射时,直接展示 provider 模型,而不是它们所映射自的 Claude id。--setting-sources ""会把用户配置文件整个禁用,第三方 provider 的env(base URL / token / model)随之丢失,标题运行会以 “Not logged in” 失败。改为user后既保留该 env,又仍然跳过 project/local 配置。设计说明
id用 provider 模型值(deepseek-v4-flash[1M]);Claude Code 会剥掉末尾的[...]上下文后缀,因此请求与显示的模型保持一致。ANTHROPIC_DEFAULT_*_MODEL_NAME):cc-switch 通常把四个 family 都指向同一个模型,不去重会渲染成四行一模一样的条目。若确实配了不同的 provider 模型(如 opus → A、haiku → B),仍会分别成行。验证
cargo check --locked -p zeron-harness --lib --tests—— 改动文件无 warningcargo test --locked -p zeron-harness --lib claude::—— 32 passedcargo test --locked -p zeron-harness --test claude—— 10 passedcargo test --locked -p zeron-ui --lib -- --test-threads=1—— 778 passed, 0 failed--model claude-opus-5原样到达 provider,改动后到达的是配置的 provider 模型;--setting-sources ""不产生请求,user会产生请求。rustfmt --check、git diff --check—— 通过说明:
zeron-harness --lib有一个既有的、依赖环境的失败用例(shell_env::unix::tests::falls_back_when_interactive_attempt_hangs),在未改动的main上同样失败。Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.