feat(provider): enhance Claude provider configuration to support environment variable fallback
This commit is contained in:
+31
-8
@@ -143,15 +143,19 @@ struct ClaudeSettings {
|
||||
env: Option<ClaudeEnv>,
|
||||
}
|
||||
|
||||
/// Read `~/.claude/settings.json` and return a `ProviderConfig` if the file
|
||||
/// contains `ANTHROPIC_BASE_URL` and `ANTHROPIC_API_KEY` in its `env` block.
|
||||
/// Return a `ProviderConfig` for the Claude provider, checking both
|
||||
/// `~/.claude/settings.json` and the process environment.
|
||||
///
|
||||
/// Flow: try the file (`env.ANTHROPIC_BASE_URL` + `env.ANTHROPIC_API_KEY`)
|
||||
/// first → fall back to the `ANTHROPIC_BASE_URL` / `ANTHROPIC_API_KEY` env
|
||||
/// vars → if neither source has both values, return `None`.
|
||||
///
|
||||
/// Why: Claude Code may inject credentials via env vars (OAuth session) rather
|
||||
/// than through its settings file, so reading only the file misses them.
|
||||
fn detect_claude_settings_provider() -> Option<ProviderConfig> {
|
||||
let path = dirs::home_dir()?.join(".claude").join("settings.json");
|
||||
let content = std::fs::read_to_string(&path).ok()?;
|
||||
let settings: ClaudeSettings = serde_json::from_str(&content).ok()?;
|
||||
let env = settings.env?;
|
||||
let base_url = env.anthropic_base_url?;
|
||||
let _ = env.anthropic_api_key?; // presence check — stored as env var, not in config.
|
||||
// Prefer the file, then fall back to env vars.
|
||||
let (base_url, _key) = claude_credentials_from_file()
|
||||
.or_else(claude_credentials_from_env)?;
|
||||
Some(ProviderConfig {
|
||||
api_base: base_url,
|
||||
api_key_env: Some("ANTHROPIC_API_KEY".to_string()),
|
||||
@@ -159,3 +163,22 @@ fn detect_claude_settings_provider() -> Option<ProviderConfig> {
|
||||
default_api_key: None,
|
||||
})
|
||||
}
|
||||
|
||||
/// Try to read Claude credentials from `~/.claude/settings.json`'s `env` block.
|
||||
fn claude_credentials_from_file() -> Option<(String, String)> {
|
||||
let path = dirs::home_dir()?.join(".claude").join("settings.json");
|
||||
let content = std::fs::read_to_string(&path).ok()?;
|
||||
let settings: ClaudeSettings = serde_json::from_str(&content).ok()?;
|
||||
let env = settings.env?;
|
||||
let base_url = env.anthropic_base_url?;
|
||||
let key = env.anthropic_api_key?;
|
||||
Some((base_url, key))
|
||||
}
|
||||
|
||||
/// Try to read Claude credentials from `ANTHROPIC_BASE_URL` /
|
||||
/// `ANTHROPIC_API_KEY` environment variables.
|
||||
fn claude_credentials_from_env() -> Option<(String, String)> {
|
||||
let base_url = std::env::var("ANTHROPIC_BASE_URL").ok()?;
|
||||
let key = std::env::var("ANTHROPIC_API_KEY").ok()?;
|
||||
Some((base_url, key))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user