mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-07-24 12:44:18 +08:00
* Add test for Fable model env key exclusion Add regression test to ensure Fable model env keys are excluded from common config. * Add Fable model to CLAUDE_MODEL_OVERRIDE_ENV_KEYS * Add files via upload * Delete .github/workflows/build-windows-unsigned.yml
This commit is contained in:
@@ -775,6 +775,56 @@ mod tests {
|
||||
assert_eq!(value.get("includeCoAuthoredBy"), Some(&json!(false)));
|
||||
}
|
||||
|
||||
/// Regression for issue #4272: Fable tier env keys must not enter the shared
|
||||
/// Claude common-config snippet (same class as haiku/sonnet/opus model pins).
|
||||
#[test]
|
||||
fn extract_claude_common_config_strips_fable_model_env_keys() {
|
||||
let settings = json!({
|
||||
"env": {
|
||||
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "haiku-mapped",
|
||||
"ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME": "Haiku Mapped",
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL": "sonnet-mapped[1M]",
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL_NAME": "Sonnet Mapped",
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL": "opus-mapped[1M]",
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL_NAME": "Opus Mapped",
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL": "deepseek-v4-flash[1M]",
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME": "deepseek-v4-flash",
|
||||
"ANTHROPIC_MODEL": "default-mapped",
|
||||
"ENABLE_TOOL_SEARCH": "true"
|
||||
},
|
||||
"theme": "dark"
|
||||
});
|
||||
|
||||
let snippet = ProviderService::extract_claude_common_config(&settings)
|
||||
.expect("extract should succeed");
|
||||
let value: Value = serde_json::from_str(&snippet).expect("snippet is valid JSON");
|
||||
let env = value.get("env");
|
||||
|
||||
for stripped in [
|
||||
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
|
||||
"ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME",
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL",
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL_NAME",
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL",
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL_NAME",
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL",
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME",
|
||||
"ANTHROPIC_MODEL",
|
||||
] {
|
||||
assert!(
|
||||
env.and_then(|e| e.get(stripped)).is_none(),
|
||||
"provider-specific model key {stripped} must not enter common config"
|
||||
);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
env.and_then(|e| e.get("ENABLE_TOOL_SEARCH"))
|
||||
.and_then(|v| v.as_str()),
|
||||
Some("true")
|
||||
);
|
||||
assert_eq!(value.get("theme").and_then(|v| v.as_str()), Some("dark"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn validate_provider_settings_rejects_negative_cost_multiplier() {
|
||||
let mut provider = Provider::with_id(
|
||||
@@ -2869,6 +2919,10 @@ impl ProviderService {
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL_NAME",
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL",
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL_NAME",
|
||||
// Fable 是 v3.16.3 新增的第四档模型映射,与 haiku/sonnet/opus 同属供应商专属,
|
||||
// 不得进入通用配置片段,否则会污染其它供应商(issue #4272)。
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL",
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME",
|
||||
"CLAUDE_CODE_SUBAGENT_MODEL",
|
||||
"ANTHROPIC_BASE_URL",
|
||||
];
|
||||
|
||||
@@ -26,7 +26,7 @@ const PROXY_TOKEN_PLACEHOLDER: &str = "PROXY_MANAGED";
|
||||
/// 原因:接管模式下 `*_MODEL` 必须由 CC Switch 写成稳定的 Claude 角色别名,
|
||||
/// 再由本地代理映射到当前供应商真实模型;`*_MODEL_NAME` 也需要同步接管,
|
||||
/// 否则 Claude Code 模型菜单会残留上一个供应商的显示名称。
|
||||
const CLAUDE_MODEL_OVERRIDE_ENV_KEYS: [&str; 10] = [
|
||||
const CLAUDE_MODEL_OVERRIDE_ENV_KEYS: [&str; 12] = [
|
||||
"ANTHROPIC_MODEL",
|
||||
"ANTHROPIC_REASONING_MODEL", // legacy: 已废弃,但旧配置可能残留
|
||||
"ANTHROPIC_DEFAULT_HAIKU_MODEL",
|
||||
@@ -35,6 +35,8 @@ const CLAUDE_MODEL_OVERRIDE_ENV_KEYS: [&str; 10] = [
|
||||
"ANTHROPIC_DEFAULT_SONNET_MODEL_NAME",
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL",
|
||||
"ANTHROPIC_DEFAULT_OPUS_MODEL_NAME",
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL",
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME",
|
||||
"ANTHROPIC_SMALL_FAST_MODEL", // Legacy key (已废弃):历史版本使用该字段区分 small/fast 模型
|
||||
"CLAUDE_CODE_SUBAGENT_MODEL",
|
||||
];
|
||||
@@ -42,6 +44,7 @@ const CLAUDE_MODEL_OVERRIDE_ENV_KEYS: [&str; 10] = [
|
||||
const CLAUDE_TAKEOVER_HAIKU_MODEL: &str = "claude-haiku-4-5";
|
||||
const CLAUDE_TAKEOVER_SONNET_MODEL: &str = "claude-sonnet-4-6";
|
||||
const CLAUDE_TAKEOVER_OPUS_MODEL: &str = "claude-opus-4-8";
|
||||
const CLAUDE_TAKEOVER_FABLE_MODEL: &str = "claude-fable-5";
|
||||
// 写给 Claude Code 时沿用文档示例的大写形式;解析侧大小写不敏感。
|
||||
const CLAUDE_ONE_M_MARKER_FOR_CLIENT: &str = "[1M]";
|
||||
|
||||
@@ -221,10 +224,12 @@ impl ProxyService {
|
||||
let opus_model = Self::claude_env_string(env, "ANTHROPIC_DEFAULT_OPUS_MODEL")
|
||||
.or(default_model)
|
||||
.or(small_fast_model);
|
||||
// Fable 未配置时不写稳定别名;映射侧会 fable→opus 降级(与官方一致)。
|
||||
let fable_model = Self::claude_env_string(env, "ANTHROPIC_DEFAULT_FABLE_MODEL");
|
||||
|
||||
let subagent_model = Self::claude_env_string(env, "CLAUDE_CODE_SUBAGENT_MODEL");
|
||||
|
||||
let mut fields = Vec::with_capacity(7);
|
||||
let mut fields = Vec::with_capacity(9);
|
||||
Self::push_claude_takeover_role_fields(
|
||||
&mut fields,
|
||||
env,
|
||||
@@ -252,6 +257,15 @@ impl ProxyService {
|
||||
true,
|
||||
opus_model,
|
||||
);
|
||||
Self::push_claude_takeover_role_fields(
|
||||
&mut fields,
|
||||
env,
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL",
|
||||
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME",
|
||||
CLAUDE_TAKEOVER_FABLE_MODEL,
|
||||
true,
|
||||
fable_model,
|
||||
);
|
||||
if let Some(subagent_model) = subagent_model {
|
||||
fields.push(("CLAUDE_CODE_SUBAGENT_MODEL", subagent_model.to_string()));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user