use anyhow::Result;
use reqwest::Client;
use std::sync::LazyLock;
use std::time::Duration;
use super::types::{EmbeddingProviderType, InputType};
static HTTP_CLIENT: LazyLock<Client> = LazyLock::new(|| {
Client::builder()
.pool_max_idle_per_host(10)
.pool_idle_timeout(Duration::from_secs(30))
.timeout(Duration::from_secs(120)) .connect_timeout(Duration::from_secs(10))
.build()
.expect("Failed to create HTTP client")
});
#[cfg(feature = "fastembed")]
pub mod fastembed;
#[cfg(feature = "huggingface")]
pub mod huggingface;
pub mod google;
pub mod jina;
pub mod openai;
pub mod voyage;
#[cfg(feature = "fastembed")]
pub use fastembed::{FastEmbedProvider, FastEmbedProviderImpl};
#[cfg(feature = "huggingface")]
pub use huggingface::{HuggingFaceProvider, HuggingFaceProviderImpl};
pub use google::{GoogleProvider, GoogleProviderImpl};
pub use jina::{JinaProvider, JinaProviderImpl};
pub use openai::{OpenAIProvider, OpenAIProviderImpl};
pub use voyage::{VoyageProvider, VoyageProviderImpl};
#[async_trait::async_trait]
pub trait EmbeddingProvider: Send + Sync {
async fn generate_embedding(&self, text: &str) -> Result<Vec<f32>>;
async fn generate_embeddings_batch(
&self,
texts: Vec<String>,
input_type: InputType,
) -> Result<Vec<Vec<f32>>>;
fn get_dimension(&self) -> usize;
fn is_model_supported(&self) -> bool {
true
}
}
pub async fn create_embedding_provider_from_parts(
provider: &EmbeddingProviderType,
model: &str,
) -> Result<Box<dyn EmbeddingProvider>> {
match provider {
EmbeddingProviderType::FastEmbed => {
#[cfg(feature = "fastembed")]
{
Ok(Box::new(FastEmbedProviderImpl::new(model)?))
}
#[cfg(not(feature = "fastembed"))]
{
Err(anyhow::anyhow!("FastEmbed support is not compiled in. Please rebuild with --features fastembed"))
}
}
EmbeddingProviderType::Jina => Ok(Box::new(JinaProviderImpl::new(model)?)),
EmbeddingProviderType::Voyage => Ok(Box::new(VoyageProviderImpl::new(model)?)),
EmbeddingProviderType::Google => Ok(Box::new(GoogleProviderImpl::new(model)?)),
EmbeddingProviderType::OpenAI => Ok(Box::new(OpenAIProviderImpl::new(model)?)),
EmbeddingProviderType::HuggingFace => {
#[cfg(feature = "huggingface")]
{
Ok(Box::new(HuggingFaceProviderImpl::new(model).await?))
}
#[cfg(not(feature = "huggingface"))]
{
Err(anyhow::anyhow!("HuggingFace support is not compiled in. Please rebuild with --features huggingface"))
}
}
}
}
#[cfg(test)]
mod mod_test;