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>,
|
env: Option<ClaudeEnv>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Read `~/.claude/settings.json` and return a `ProviderConfig` if the file
|
/// Return a `ProviderConfig` for the Claude provider, checking both
|
||||||
/// contains `ANTHROPIC_BASE_URL` and `ANTHROPIC_API_KEY` in its `env` block.
|
/// `~/.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> {
|
fn detect_claude_settings_provider() -> Option<ProviderConfig> {
|
||||||
let path = dirs::home_dir()?.join(".claude").join("settings.json");
|
// Prefer the file, then fall back to env vars.
|
||||||
let content = std::fs::read_to_string(&path).ok()?;
|
let (base_url, _key) = claude_credentials_from_file()
|
||||||
let settings: ClaudeSettings = serde_json::from_str(&content).ok()?;
|
.or_else(claude_credentials_from_env)?;
|
||||||
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.
|
|
||||||
Some(ProviderConfig {
|
Some(ProviderConfig {
|
||||||
api_base: base_url,
|
api_base: base_url,
|
||||||
api_key_env: Some("ANTHROPIC_API_KEY".to_string()),
|
api_key_env: Some("ANTHROPIC_API_KEY".to_string()),
|
||||||
@@ -159,3 +163,22 @@ fn detect_claude_settings_provider() -> Option<ProviderConfig> {
|
|||||||
default_api_key: None,
|
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