smos_application/ports/embedding_provider.rs
1//! `EmbeddingProvider` port — text → vector.
2//!
3//! `embed_batch` has a default implementation that loops `embed` per call:
4//! providers with native batch endpoints (a local `llama-server` `/api/embed`,
5//! OpenAI `/v1/embeddings` with `input: []`) override it for fewer
6//! round-trips.
7
8use crate::errors::ProviderError;
9
10/// Embedding model boundary (Jina v5, OpenAI-compatible `llama-server`, …).
11pub trait EmbeddingProvider {
12 /// Embed a single text. `None` is returned when the provider cannot
13 /// produce an embedding (e.g. input is empty after normalisation).
14 async fn embed(&self, text: &str) -> Result<Option<Vec<f32>>, ProviderError>;
15
16 /// Embed many texts. Default loops `embed`; override for batch endpoints.
17 async fn embed_batch(&self, texts: &[&str]) -> Result<Vec<Option<Vec<f32>>>, ProviderError> {
18 let mut out = Vec::with_capacity(texts.len());
19 for text in texts {
20 out.push(self.embed(text).await?);
21 }
22 Ok(out)
23 }
24}