Merge PR #2928 from hongchen1993: prefer dispatcher-provided API key over saved root key

When the CLI dispatcher forwards --api-key with DEEPSEEK_API_KEY_SOURCE=cli, that explicit override now wins over the saved root key for DeepSeek providers.
This commit is contained in:
Hunter Bown
2026-06-09 20:07:59 -07:00
committed by GitHub
+40 -1
View File
@@ -2572,6 +2572,20 @@ impl Config {
// 0. DeepSeek compatibility slot. The legacy top-level `api_key`
// belongs to DeepSeek only; provider-specific keys below must win for
// NIM/OpenRouter/etc. so a stale DeepSeek key is not sent elsewhere.
//
// However, when the CLI dispatcher forwards an explicit `--api-key`
// through `DEEPSEEK_API_KEY` with the dispatcher source marker, that
// intentional override must win over the saved root key. This is
// essential for DeepSeek-compatible subscription endpoints where the
// user runs something like:
// codewhale --provider deepseek --api-key ark-... --base-url ... --model auto
if matches!(provider, ApiProvider::Deepseek | ApiProvider::DeepseekCN)
&& std::env::var("DEEPSEEK_API_KEY_SOURCE").as_deref() == Ok("cli")
&& let Some(env_key) = codewhale_secrets::env_for("deepseek")
&& !env_key.trim().is_empty()
{
return Ok(env_key);
}
if matches!(provider, ApiProvider::Deepseek | ApiProvider::DeepseekCN)
&& let Some(configured) = self.api_key.as_ref()
&& !configured.trim().is_empty()
@@ -7130,7 +7144,7 @@ action = "session.compact"
// Env var path.
let env_cfg = Config::default();
unsafe {
std::env::set_var("DEEPSEEK_API_KEY", "sk-test-from-env");
std::env::set_var("DEEPSEEK_API_KEY", "env-key");
}
assert!(
has_api_key(&env_cfg),
@@ -7142,6 +7156,31 @@ action = "session.compact"
Ok(())
}
#[test]
fn deepseek_dispatcher_env_key_overrides_config_key() -> Result<()> {
let _lock = lock_test_env();
let prev_source = std::env::var_os("DEEPSEEK_API_KEY_SOURCE");
unsafe {
std::env::set_var("DEEPSEEK_API_KEY", "ark-dispatcher-key");
std::env::set_var("DEEPSEEK_API_KEY_SOURCE", "cli");
}
let config = Config {
api_key: Some("saved-deepseek-key".to_string()),
..Default::default()
};
assert_eq!(config.deepseek_api_key()?, "ark-dispatcher-key");
unsafe {
std::env::remove_var("DEEPSEEK_API_KEY");
match prev_source {
Some(value) => std::env::set_var("DEEPSEEK_API_KEY_SOURCE", value),
None => std::env::remove_var("DEEPSEEK_API_KEY_SOURCE"),
}
}
Ok(())
}
fn config_with_provider_scoped_key(provider: &str, api_key: &str) -> Config {
let mut providers = ProvidersConfig::default();
match provider {