use crate::core::Provider;
use crate::types::{ChatRequest, ChatResponse};
use crate::error::LlmConnectorError;
use std::sync::Arc;
#[cfg(feature = "streaming")]
use crate::types::ChatStream;
pub struct LlmClient {
provider: Arc<dyn Provider>,
}
impl LlmClient {
pub fn from_provider(provider: Arc<dyn Provider>) -> Self {
Self { provider }
}
pub fn openai(api_key: &str) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::openai(api_key)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn openai_with_base_url(api_key: &str, base_url: &str) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::openai_with_base_url(api_key, base_url)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn azure_openai(
api_key: &str,
endpoint: &str,
api_version: &str,
) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::azure_openai(api_key, endpoint, api_version)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn aliyun(api_key: &str) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::aliyun(api_key)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn anthropic(api_key: &str) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::anthropic(api_key)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn zhipu(api_key: &str) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::zhipu_default(api_key)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn zhipu_openai_compatible(api_key: &str) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::zhipu_openai_compatible(api_key)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn ollama() -> Result<Self, LlmConnectorError> {
let provider = crate::providers::ollama()?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn ollama_with_url(base_url: &str) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::ollama_with_url(base_url)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn openai_compatible(
api_key: &str,
base_url: &str,
service_name: &str,
) -> Result<Self, LlmConnectorError> {
let provider = crate::providers::openai_compatible(api_key, base_url, service_name)?;
Ok(Self::from_provider(Arc::new(provider)))
}
pub fn provider_name(&self) -> &str {
self.provider.name()
}
pub async fn chat(&self, request: &ChatRequest) -> Result<ChatResponse, LlmConnectorError> {
self.provider.chat(request).await
}
#[cfg(feature = "streaming")]
pub async fn chat_stream(&self, request: &ChatRequest) -> Result<ChatStream, LlmConnectorError> {
self.provider.chat_stream(request).await
}
pub async fn models(&self) -> Result<Vec<String>, LlmConnectorError> {
self.provider.models().await
}
pub fn provider(&self) -> &dyn Provider {
self.provider.as_ref()
}
pub fn as_ollama(&self) -> Option<&crate::providers::OllamaProvider> {
self.provider.as_any().downcast_ref::<crate::providers::OllamaProvider>()
}
}
impl Clone for LlmClient {
fn clone(&self) -> Self {
Self {
provider: Arc::clone(&self.provider),
}
}
}
impl std::fmt::Debug for LlmClient {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("LlmClient")
.field("provider", &self.provider.name())
.finish()
}
}