#[cfg(feature = "google")]
mod google_gemini;
mod openai_compat;
#[cfg(feature = "zhipu")]
mod zhipu;
use async_trait::async_trait;
use std::time::Duration;
use crate::client::HttpClient;
use crate::config::Provider;
use crate::config::ProviderConfig;
use crate::error::{Error, Result};
const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
#[async_trait]
pub trait EmbedProvider: Send + Sync {
async fn encode(&self, text: &str) -> Result<Vec<f32>>;
async fn encode_batch(&self, texts: &[&str]) -> Result<Vec<Vec<f32>>>;
fn dimension(&self) -> usize;
}
fn http_client(config: &ProviderConfig) -> Result<HttpClient> {
HttpClient::new(config.timeout.unwrap_or(DEFAULT_TIMEOUT))
}
pub(crate) fn create(config: &ProviderConfig) -> Result<Box<dyn EmbedProvider>> {
let dimension = config.dimension.ok_or(Error::MissingConfig("dimension"))?;
match config.provider {
#[cfg(feature = "openai")]
Provider::OpenAI => Ok(Box::new(openai_compat::OpenaiCompatEmbed::new(
config,
dimension,
http_client(config)?,
))),
#[cfg(not(feature = "openai"))]
Provider::OpenAI => Err(Error::ProviderDisabled("openai".to_string())),
#[cfg(feature = "aliyun")]
Provider::Aliyun => Ok(Box::new(openai_compat::OpenaiCompatEmbed::new(
config,
dimension,
http_client(config)?,
))),
#[cfg(not(feature = "aliyun"))]
Provider::Aliyun => Err(Error::ProviderDisabled("aliyun".to_string())),
#[cfg(feature = "ollama")]
Provider::Ollama => Ok(Box::new(openai_compat::OpenaiCompatEmbed::new(
config,
dimension,
http_client(config)?,
))),
#[cfg(not(feature = "ollama"))]
Provider::Ollama => Err(Error::ProviderDisabled("ollama".to_string())),
#[cfg(feature = "zhipu")]
Provider::Zhipu => Ok(Box::new(zhipu::ZhipuEmbed::new(
config,
dimension,
http_client(config)?,
))),
#[cfg(not(feature = "zhipu"))]
Provider::Zhipu => Err(Error::ProviderDisabled("zhipu".to_string())),
#[cfg(feature = "anthropic")]
Provider::Anthropic => Err(Error::Unsupported {
provider: config.provider.to_string(),
capability: "embed",
}),
#[cfg(not(feature = "anthropic"))]
Provider::Anthropic => Err(Error::ProviderDisabled("anthropic".to_string())),
#[cfg(feature = "google")]
Provider::Google => Ok(Box::new(google_gemini::GoogleGeminiEmbed::new(
config,
dimension,
http_client(config)?,
))),
#[cfg(not(feature = "google"))]
Provider::Google => Err(Error::ProviderDisabled("google".to_string())),
}
}