Skip to main content

kyma_memory/
embed.rs

1//! Embedding-backend construction. Memory is the first server-side consumer of
2//! `kyma-embed`; the backend (an ONNX model for fastembed) is built once and
3//! shared process-wide via a `OnceCell` so the model loads at most once.
4
5use std::sync::Arc;
6
7use kyma_embed::{EmbeddingBackend, EmbeddingConfig, EmbeddingProvider};
8use tokio::sync::OnceCell;
9
10use crate::error::{MemoryError, Result};
11
12static SHARED: OnceCell<Arc<dyn EmbeddingBackend>> = OnceCell::const_new();
13
14/// The process-wide embedding backend, lazily built from
15/// [`EmbeddingConfig::from_env`] on first use.
16pub async fn shared_embedding() -> Result<Arc<dyn EmbeddingBackend>> {
17    SHARED
18        .get_or_try_init(|| async { build_embedding_backend(&EmbeddingConfig::from_env()).await })
19        .await
20        .map(|b| b.clone())
21}
22
23/// Construct an embedding backend from config. Only providers whose
24/// `kyma-embed` feature is enabled are available; others return an error.
25pub async fn build_embedding_backend(cfg: &EmbeddingConfig) -> Result<Arc<dyn EmbeddingBackend>> {
26    match &cfg.provider {
27        EmbeddingProvider::Fastembed { id, model_path } => {
28            let b = kyma_embed::FastembedBackend::new(id, model_path.as_deref())
29                .await
30                .map_err(|e| MemoryError::Embed(e.to_string()))?;
31            Ok(Arc::new(b))
32        }
33        other => Err(MemoryError::Embed(format!(
34            "embedding provider not enabled in this build: {other:?}; \
35             rebuild kyma-memory with the matching kyma-embed feature"
36        ))),
37    }
38}