agent_base/llm/
registry.rs1use 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}