diff --git a/crates/g3-config/src/lib.rs b/crates/g3-config/src/lib.rs index c57e7279..4a421d88 100644 --- a/crates/g3-config/src/lib.rs +++ b/crates/g3-config/src/lib.rs @@ -64,6 +64,7 @@ pub struct OpenAIConfig { pub struct AnthropicConfig { pub api_key: String, pub model: String, + pub base_url: Option, pub max_tokens: Option, pub temperature: Option, pub cache_config: Option, diff --git a/crates/g3-core/src/provider_registration.rs b/crates/g3-core/src/provider_registration.rs index 2a2841f4..ea4b0b99 100644 --- a/crates/g3-core/src/provider_registration.rs +++ b/crates/g3-core/src/provider_registration.rs @@ -145,10 +145,15 @@ fn register_anthropic_providers( ) -> Result<()> { for (name, anthropic_config) in &config.providers.anthropic { if should_register(providers_to_register, "anthropic", name) { + debug!( + "Registering Anthropic provider '{}' with base_url: {:?}", + name, anthropic_config.base_url + ); let anthropic_provider = g3_providers::AnthropicProvider::new_with_name( format!("anthropic.{}", name), anthropic_config.api_key.clone(), Some(anthropic_config.model.clone()), + anthropic_config.base_url.clone(), anthropic_config.max_tokens, anthropic_config.temperature, anthropic_config.cache_config.clone(), diff --git a/crates/g3-planner/src/llm.rs b/crates/g3-planner/src/llm.rs index 808f3529..8bad3db3 100644 --- a/crates/g3-planner/src/llm.rs +++ b/crates/g3-planner/src/llm.rs @@ -42,11 +42,12 @@ pub async fn create_planner_provider( let anthropic_config = config .get_anthropic_config(&config_name) .ok_or_else(|| anyhow!("Anthropic config '{}' not found", config_name))?; - + let provider = g3_providers::AnthropicProvider::new_with_name( format!("anthropic.{}", config_name), anthropic_config.api_key.clone(), Some(anthropic_config.model.clone()), + anthropic_config.base_url.clone(), anthropic_config.max_tokens, anthropic_config.temperature, anthropic_config.cache_config.clone(), diff --git a/crates/g3-providers/src/anthropic.rs b/crates/g3-providers/src/anthropic.rs index 9835ed15..85fd6e13 100644 --- a/crates/g3-providers/src/anthropic.rs +++ b/crates/g3-providers/src/anthropic.rs @@ -127,6 +127,7 @@ pub struct AnthropicProvider { name: String, api_key: String, model: String, + base_url: String, max_tokens: u32, temperature: f32, #[allow(dead_code)] @@ -145,33 +146,25 @@ impl AnthropicProvider { enable_1m_context: Option, thinking_budget_tokens: Option, ) -> Result { - let client = Client::builder() - .timeout(Duration::from_secs(300)) - .build() - .map_err(|e| anyhow!("Failed to create HTTP client: {}", e))?; - - let model = model.unwrap_or_else(|| "claude-3-5-sonnet-20241022".to_string()); - - debug!("Initialized Anthropic provider with model: {}", model); - - Ok(Self { - client, - name: "anthropic".to_string(), + Self::new_with_name( + "anthropic".to_string(), api_key, model, - max_tokens: max_tokens.unwrap_or(32768), - temperature: temperature.unwrap_or(0.1), + None, // Use default Anthropic URL + max_tokens, + temperature, cache_config, - enable_1m_context: enable_1m_context.unwrap_or(false), + enable_1m_context, thinking_budget_tokens, - }) + ) } - /// Create a new AnthropicProvider with a custom name (e.g., "anthropic.default") + /// Create a new AnthropicProvider with a custom name and base_url pub fn new_with_name( name: String, api_key: String, model: Option, + base_url: Option, max_tokens: Option, temperature: Option, cache_config: Option, @@ -184,10 +177,11 @@ impl AnthropicProvider { .map_err(|e| anyhow!("Failed to create HTTP client: {}", e))?; let model = model.unwrap_or_else(|| "claude-3-5-sonnet-20241022".to_string()); + let base_url = base_url.unwrap_or_else(|| ANTHROPIC_API_URL.to_string()); debug!( - "Initialized Anthropic provider '{}' with model: {}", - name, model + "Initialized Anthropic provider '{}' with model: {}, base_url: {}", + name, model, base_url ); Ok(Self { @@ -195,6 +189,7 @@ impl AnthropicProvider { name, api_key, model, + base_url, max_tokens: max_tokens.unwrap_or(32768), temperature: temperature.unwrap_or(0.1), cache_config, @@ -206,7 +201,7 @@ impl AnthropicProvider { fn create_request_builder(&self, streaming: bool) -> RequestBuilder { let mut builder = self .client - .post(ANTHROPIC_API_URL) + .post(&self.base_url) .header("x-api-key", &self.api_key) .header("anthropic-version", ANTHROPIC_VERSION) .header("content-type", "application/json"); diff --git a/crates/g3-providers/src/lib.rs b/crates/g3-providers/src/lib.rs index f34860bc..269fbabc 100644 --- a/crates/g3-providers/src/lib.rs +++ b/crates/g3-providers/src/lib.rs @@ -103,7 +103,7 @@ pub struct Message { pub cache_control: Option, } -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] pub enum MessageRole { System,