mod hdc_text;
mod projection;
#[cfg(feature = "embed-fastembed")]
mod fastembed;
#[cfg(feature = "embed-openai")]
mod remote_openai;
#[cfg(feature = "embed-voyage")]
mod remote_voyage;
pub use hdc_text::HdcTextProvider;
pub use projection::{Projection, ProjectionConfig};
#[cfg(feature = "embed-fastembed")]
pub use fastembed::FastEmbedProvider;
#[cfg(feature = "embed-openai")]
pub use remote_openai::OpenAiProvider;
#[cfg(feature = "embed-voyage")]
pub use remote_voyage::VoyageProvider;
use crate::error::Result;
use crate::hyperdim::HVec10240;
#[async_trait::async_trait]
pub trait EmbeddingProvider: Send + Sync {
fn name(&self) -> &str;
fn native_dim(&self) -> usize;
async fn embed(&self, text: &str) -> Result<Vec<f32>>;
async fn embed_batch(&self, texts: &[&str]) -> Result<Vec<Vec<f32>>>;
fn project(&self, vec: &[f32], projection: &Projection) -> HVec10240 {
projection.project(vec)
}
}
pub fn get_provider(name: &str) -> Result<std::sync::Arc<dyn EmbeddingProvider>> {
let parts: Vec<&str> = name.splitn(2, ':').collect();
let provider_name = parts[0];
let _model_name = parts.get(1).copied();
match provider_name {
"hdc-text" | "hdc" => Ok(std::sync::Arc::new(HdcTextProvider::new())),
"fastembed" => {
#[cfg(feature = "embed-fastembed")]
{
if let Some(model) = _model_name {
Ok(std::sync::Arc::new(FastEmbedProvider::with_model(model)?))
} else {
Ok(std::sync::Arc::new(FastEmbedProvider::new()?))
}
}
#[cfg(not(feature = "embed-fastembed"))]
Err(crate::error::MemoryError::Config(
"embed-fastembed feature not enabled".into(),
))
}
"openai" => {
#[cfg(feature = "embed-openai")]
{
let mut provider = OpenAiProvider::from_env()?;
if let Some(model) = _model_name {
provider = provider.with_model(model);
}
Ok(std::sync::Arc::new(provider))
}
#[cfg(not(feature = "embed-openai"))]
Err(crate::error::MemoryError::Config(
"embed-openai feature not enabled".into(),
))
}
"voyage" => {
#[cfg(feature = "embed-voyage")]
{
let mut provider = VoyageProvider::from_env()?;
if let Some(model) = _model_name {
provider = provider.with_model(model);
}
Ok(std::sync::Arc::new(provider))
}
#[cfg(not(feature = "embed-voyage"))]
Err(crate::error::MemoryError::Config(
"embed-voyage feature not enabled".into(),
))
}
_ => Err(crate::error::MemoryError::Config(format!(
"unknown embedding provider: {provider_name}"
))),
}
}