Skip to main content

relay_knowledge/ports/
embedding.rs

1use std::{error::Error, fmt, future::Future, pin::Pin};
2
3/// Future returned by a configured embedding provider.
4pub type EmbeddingFuture<'a, T> =
5    Pin<Box<dyn Future<Output = Result<T, EmbeddingProviderError>> + Send + 'a>>;
6
7/// Text inputs sent to a remote embedding provider.
8#[derive(Debug, Clone, PartialEq, Eq)]
9pub struct EmbeddingRequest {
10    pub inputs: Vec<String>,
11    pub model: String,
12    pub dimension: u32,
13}
14
15/// One normalized embedding vector returned by a provider.
16#[derive(Debug, Clone, PartialEq)]
17pub struct EmbeddingVector {
18    pub values: Vec<f64>,
19}
20
21/// Provider-neutral remote embedding contract.
22pub trait EmbeddingProvider: Send + Sync {
23    fn embed(&self, request: EmbeddingRequest) -> EmbeddingFuture<'_, Vec<EmbeddingVector>>;
24}
25
26/// Retry category for remote provider failures.
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub enum ProviderRetryClass {
29    Retryable,
30    Permanent,
31}
32
33/// Provider error safe for diagnostics.
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct EmbeddingProviderError {
36    pub retry: ProviderRetryClass,
37    pub status_code: Option<u16>,
38    pub code: String,
39    pub message: String,
40}
41
42impl fmt::Display for EmbeddingProviderError {
43    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
44        match self.status_code {
45            Some(status) => write!(formatter, "{} ({status}): {}", self.code, self.message),
46            None => write!(formatter, "{}: {}", self.code, self.message),
47        }
48    }
49}
50
51impl Error for EmbeddingProviderError {}
52
53#[cfg(test)]
54#[path = "embedding_tests.rs"]
55mod tests;