agcodex_core/embeddings/
mod.rs

1//! Independent embeddings system - completely separate from chat/LLM models.
2//!
3//! This module provides optional embedding functionality with:
4//! - Multiple provider support (OpenAI, Gemini, Voyage)
5//! - Strict index separation by model and repository
6//! - Zero overhead when disabled
7//! - Independent authentication from chat models
8
9pub mod config;
10pub mod index_manager;
11pub mod manager;
12pub mod providers;
13
14pub use config::EmbeddingsConfig;
15pub use config::ProviderConfig;
16pub use index_manager::EmbeddingIndexManager;
17pub use index_manager::IndexKey;
18pub use index_manager::SearchResult;
19pub use manager::EmbeddingsManager;
20
21use thiserror::Error;
22
23pub type EmbeddingVector = Vec<f32>;
24
25#[derive(Debug, Error)]
26pub enum EmbeddingError {
27    #[error("Embeddings not enabled")]
28    NotEnabled,
29
30    #[error("Provider not available: {0}")]
31    ProviderNotAvailable(String),
32
33    #[error("API error: {0}")]
34    ApiError(String),
35
36    #[error("Dimension mismatch: expected {expected}, got {actual}")]
37    DimensionMismatch { expected: usize, actual: usize },
38
39    #[error("Index error: {0}")]
40    IndexError(#[from] index_manager::IndexError),
41
42    #[error(transparent)]
43    Io(#[from] std::io::Error),
44
45    #[error("Provider error: {0}")]
46    Provider(String),
47}
48
49/// Trait for embedding providers
50#[async_trait::async_trait]
51pub trait EmbeddingProvider: Send + Sync {
52    /// Get the unique model identifier
53    fn model_id(&self) -> String;
54
55    /// Get the actual dimensions for this model
56    fn dimensions(&self) -> usize;
57
58    /// Embed a single text
59    async fn embed(&self, text: &str) -> Result<EmbeddingVector, EmbeddingError>;
60
61    /// Embed multiple texts in batch
62    async fn embed_batch(&self, texts: &[String]) -> Result<Vec<EmbeddingVector>, EmbeddingError>;
63
64    /// Check if this provider is available (has valid API key)
65    fn is_available(&self) -> bool;
66}