use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "lowercase")]
#[non_exhaustive]
pub enum ProviderConfig {
OpenAI {
api_key_env: String,
#[serde(default = "default_openai_base")]
api_base: String,
default_model: String,
},
Azure {
#[serde(default = "default_azure_api_key_env")]
api_key_env: String,
#[serde(default = "default_azure_base_url_env")]
base_url_env: String,
#[serde(default = "default_azure_default_model")]
default_model: String,
},
Anthropic {
#[serde(default = "default_anthropic_api_key_env")]
api_key_env: String,
#[serde(default = "default_anthropic_default_model")]
default_model: String,
},
Bedrock {
#[serde(default = "default_bedrock_api_key_env")]
api_key_env: String,
#[serde(default = "default_bedrock_region_env")]
region_env: String,
#[serde(default = "default_bedrock_default_model")]
default_model: String,
},
Ollama {
#[serde(default = "default_ollama_api_key_env")]
api_key_env: String,
#[serde(default = "default_ollama_base_url")]
base_url: String,
#[serde(default = "default_ollama_default_model")]
default_model: String,
},
}
impl ProviderConfig {
pub fn type_name(&self) -> &'static str {
match self {
ProviderConfig::OpenAI { .. } => "openai",
ProviderConfig::Azure { .. } => "azure",
ProviderConfig::Anthropic { .. } => "anthropic",
ProviderConfig::Bedrock { .. } => "bedrock",
ProviderConfig::Ollama { .. } => "ollama",
}
}
}
impl std::str::FromStr for ProviderConfig {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim().to_lowercase().as_str() {
"openai" | "nvidia" => Ok(ProviderConfig::OpenAI {
api_key_env: default_nvidia_api_key_env(),
api_base: default_nvidia_api_base(),
default_model: default_nvidia_default_model(),
}),
"azure" => Ok(ProviderConfig::Azure {
api_key_env: default_azure_api_key_env(),
base_url_env: default_azure_base_url_env(),
default_model: default_azure_default_model(),
}),
"anthropic" => Ok(ProviderConfig::Anthropic {
api_key_env: default_anthropic_api_key_env(),
default_model: default_anthropic_default_model(),
}),
"bedrock" => Ok(ProviderConfig::Bedrock {
api_key_env: default_bedrock_api_key_env(),
region_env: default_bedrock_region_env(),
default_model: default_bedrock_default_model(),
}),
"ollama" => Ok(ProviderConfig::Ollama {
api_key_env: default_ollama_api_key_env(),
base_url: default_ollama_base_url(),
default_model: default_ollama_default_model(),
}),
other => Err(format!(
"Unknown provider type: {other}. Use: openai (or nvidia), azure, anthropic, bedrock, ollama"
)),
}
}
}
fn default_openai_base() -> String {
"https://api.openai.com/v1".to_string()
}
fn default_nvidia_api_key_env() -> String {
"NVIDIA_API_KEY".to_string()
}
fn default_nvidia_api_base() -> String {
"https://integrate.api.nvidia.com/v1".to_string()
}
fn default_nvidia_default_model() -> String {
"nvidia/nemotron-3-ultra-550b-a55b".to_string()
}
fn default_azure_api_key_env() -> String {
"AZURE_FOUNDRY_API_KEY".to_string()
}
fn default_azure_base_url_env() -> String {
"AZURE_FOUNDRY_BASE_URL".to_string()
}
fn default_azure_default_model() -> String {
"DeepSeek-V4-Flash".to_string()
}
fn default_anthropic_api_key_env() -> String {
"ANTHROPIC_API_KEY".to_string()
}
fn default_anthropic_default_model() -> String {
"claude-3-5-sonnet-20241022".to_string()
}
fn default_bedrock_api_key_env() -> String {
"AWS_BEARER_TOKEN_BEDROCK".to_string()
}
fn default_bedrock_region_env() -> String {
"AWS_REGION".to_string()
}
fn default_bedrock_default_model() -> String {
"us.anthropic.claude-haiku-4-5-20251001-v1:0".to_string()
}
fn default_ollama_api_key_env() -> String {
"OLLAMA_API_KEY".to_string()
}
fn default_ollama_base_url() -> String {
"http://localhost:11434".to_string()
}
fn default_ollama_default_model() -> String {
"ministral-3:3b".to_string()
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ModelConfig {
pub provider: String,
pub model: String,
#[serde(default = "default_temperature")]
pub temperature: f32,
#[serde(default = "default_model_max_tokens")]
pub max_tokens: u32,
}
fn default_temperature() -> f32 {
0.7
}
fn default_model_max_tokens() -> u32 {
512
}