Skip to main content

agent_base/llm/
registry.rs

1use std::sync::Arc;
2
3use super::{AnthropicClient, LlmClient, OpenAiClient};
4
5#[derive(Clone, Debug)]
6pub enum LlmProvider {
7    OpenAi,
8    Anthropic,
9    Custom(String),
10}
11
12impl LlmProvider {
13    #[allow(clippy::should_implement_trait)]
14    pub fn from_str(s: &str) -> Self {
15        match s.to_lowercase().as_str() {
16            "openai" => Self::OpenAi,
17            "anthropic" => Self::Anthropic,
18            other => Self::Custom(other.to_string()),
19        }
20    }
21}
22
23pub struct LlmClientBuilder {
24    provider: LlmProvider,
25    api_key: String,
26    model: String,
27    base_url: Option<String>,
28}
29
30impl LlmClientBuilder {
31    pub fn new(
32        provider: LlmProvider,
33        api_key: impl Into<String>,
34        model: impl Into<String>,
35    ) -> Self {
36        Self {
37            provider,
38            api_key: api_key.into(),
39            model: model.into(),
40            base_url: None,
41        }
42    }
43
44    pub fn from_env() -> Option<Self> {
45        let api_key = std::env::var("LLM_API_KEY").ok()?;
46        let model = std::env::var("LLM_MODEL").unwrap_or_else(|_| "gpt-4o".to_string());
47        let base_url = std::env::var("LLM_BASE_URL").ok();
48        let provider_str = std::env::var("LLM_PROVIDER").unwrap_or_else(|_| "openai".to_string());
49
50        Some(Self {
51            provider: LlmProvider::from_str(&provider_str),
52            api_key,
53            model,
54            base_url,
55        })
56    }
57
58    pub fn base_url(mut self, base_url: impl Into<String>) -> Self {
59        self.base_url = Some(base_url.into());
60        self
61    }
62
63    pub fn build(self) -> Arc<dyn LlmClient> {
64        let base_url = self.base_url;
65        match self.provider {
66            LlmProvider::OpenAi => {
67                let url = base_url.unwrap_or_else(|| "https://api.openai.com/v1".to_string());
68                Arc::new(OpenAiClient::new(self.api_key, self.model, Some(url)))
69            }
70            LlmProvider::Anthropic => {
71                let url = base_url.unwrap_or_else(|| "https://api.anthropic.com".to_string());
72                Arc::new(AnthropicClient::new(self.api_key, self.model, Some(url)))
73            }
74            LlmProvider::Custom(_) => {
75                let url = base_url.unwrap_or_else(|| "https://api.openai.com/v1".to_string());
76                Arc::new(OpenAiClient::new(self.api_key, self.model, Some(url)))
77            }
78        }
79    }
80}