Skip to main content

lumosai_vector_core/
config.rs

1//! Configuration types for the Lumos vector storage system
2
3use std::collections::HashMap;
4use std::time::Duration;
5
6#[cfg(feature = "serde")]
7use serde::{Deserialize, Serialize};
8
9use crate::types::{MetadataValue, SimilarityMetric};
10
11/// Storage backend configuration
12#[derive(Debug, Clone)]
13#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
14pub enum StorageConfig {
15    /// In-memory storage configuration
16    Memory {
17        /// Initial capacity hint
18        initial_capacity: Option<usize>,
19        /// Maximum number of vectors
20        max_vectors: Option<usize>,
21    },
22    
23    /// SQLite storage configuration
24    Sqlite {
25        /// Database file path (":memory:" for in-memory)
26        database_path: String,
27        /// Connection pool size
28        pool_size: Option<usize>,
29        /// Enable WAL mode
30        wal_mode: bool,
31        /// Synchronous mode
32        synchronous: SqliteSynchronous,
33    },
34    
35    /// Qdrant storage configuration
36    Qdrant {
37        /// Qdrant server URL
38        url: String,
39        /// API key for authentication
40        api_key: Option<String>,
41        /// Collection name
42        collection_name: String,
43        /// Connection timeout
44        timeout: Option<Duration>,
45        /// Enable TLS
46        tls: bool,
47    },
48    
49    /// MongoDB storage configuration
50    MongoDB {
51        /// MongoDB connection string
52        connection_string: String,
53        /// Database name
54        database: String,
55        /// Collection name
56        collection: String,
57        /// Connection timeout
58        timeout: Option<Duration>,
59    },
60    
61    /// Custom storage configuration
62    Custom {
63        /// Backend name
64        backend: String,
65        /// Custom configuration options
66        options: HashMap<String, MetadataValue>,
67    },
68}
69
70/// SQLite synchronous mode
71#[derive(Debug, Clone, Copy)]
72#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
73pub enum SqliteSynchronous {
74    Off,
75    Normal,
76    Full,
77    Extra,
78}
79
80impl Default for SqliteSynchronous {
81    fn default() -> Self {
82        SqliteSynchronous::Normal
83    }
84}
85
86/// Embedding model configuration
87#[derive(Debug, Clone)]
88#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
89pub enum EmbeddingConfig {
90    /// OpenAI embedding configuration
91    OpenAI {
92        /// API key
93        api_key: String,
94        /// Model name (e.g., "text-embedding-3-small")
95        model: String,
96        /// API base URL (optional)
97        base_url: Option<String>,
98        /// Organization ID (optional)
99        organization: Option<String>,
100        /// Request timeout
101        timeout: Option<Duration>,
102        /// Max retries
103        max_retries: u32,
104    },
105    
106    /// Ollama embedding configuration
107    Ollama {
108        /// Ollama server URL
109        url: String,
110        /// Model name
111        model: String,
112        /// Request timeout
113        timeout: Option<Duration>,
114    },
115    
116    /// Local model configuration
117    Local {
118        /// Model path or identifier
119        model_path: String,
120        /// Device to run on (cpu, cuda, etc.)
121        device: String,
122        /// Model options
123        options: HashMap<String, MetadataValue>,
124    },
125    
126    /// Custom embedding configuration
127    Custom {
128        /// Provider name
129        provider: String,
130        /// Custom configuration options
131        options: HashMap<String, MetadataValue>,
132    },
133}
134
135/// Index creation configuration
136#[derive(Debug, Clone)]
137#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
138pub struct IndexCreateConfig {
139    /// Index name
140    pub name: String,
141    /// Vector dimension
142    pub dimension: usize,
143    /// Similarity metric
144    pub metric: SimilarityMetric,
145    /// Index-specific options
146    pub options: IndexOptions,
147}
148
149/// Index-specific options
150#[derive(Debug, Clone)]
151#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
152pub struct IndexOptions {
153    /// Enable approximate nearest neighbor search
154    pub approximate: bool,
155    /// Number of trees for approximate search (if supported)
156    pub num_trees: Option<usize>,
157    /// Search accuracy vs speed tradeoff (0.0 to 1.0)
158    pub accuracy: Option<f32>,
159    /// Maximum number of vectors in the index
160    pub max_vectors: Option<usize>,
161    /// Enable compression
162    pub compression: bool,
163    /// Custom backend-specific options
164    pub custom: HashMap<String, MetadataValue>,
165}
166
167impl Default for IndexOptions {
168    fn default() -> Self {
169        Self {
170            approximate: false,
171            num_trees: None,
172            accuracy: None,
173            max_vectors: None,
174            compression: false,
175            custom: HashMap::new(),
176        }
177    }
178}
179
180/// Search configuration
181#[derive(Debug, Clone)]
182#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
183pub struct SearchConfig {
184    /// Search timeout
185    pub timeout: Option<Duration>,
186    /// Enable approximate search
187    pub approximate: bool,
188    /// Search accuracy (for approximate search)
189    pub accuracy: Option<f32>,
190    /// Enable result caching
191    pub cache_results: bool,
192    /// Cache TTL
193    pub cache_ttl: Option<Duration>,
194    /// Custom search options
195    pub custom: HashMap<String, MetadataValue>,
196}
197
198impl Default for SearchConfig {
199    fn default() -> Self {
200        Self {
201            timeout: Some(Duration::from_secs(30)),
202            approximate: false,
203            accuracy: None,
204            cache_results: false,
205            cache_ttl: None,
206            custom: HashMap::new(),
207        }
208    }
209}
210
211/// Complete vector storage system configuration
212#[derive(Debug, Clone)]
213#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
214pub struct VectorSystemConfig {
215    /// Storage backend configuration
216    pub storage: StorageConfig,
217    /// Embedding model configuration (optional)
218    pub embedding: Option<EmbeddingConfig>,
219    /// Default search configuration
220    pub search: SearchConfig,
221    /// System-wide options
222    pub options: HashMap<String, MetadataValue>,
223}
224
225impl VectorSystemConfig {
226    /// Create a new configuration with memory storage
227    pub fn memory() -> Self {
228        Self {
229            storage: StorageConfig::Memory {
230                initial_capacity: None,
231                max_vectors: None,
232            },
233            embedding: None,
234            search: SearchConfig::default(),
235            options: HashMap::new(),
236        }
237    }
238    
239    /// Create a new configuration with SQLite storage
240    pub fn sqlite(database_path: impl Into<String>) -> Self {
241        Self {
242            storage: StorageConfig::Sqlite {
243                database_path: database_path.into(),
244                pool_size: None,
245                wal_mode: true,
246                synchronous: SqliteSynchronous::default(),
247            },
248            embedding: None,
249            search: SearchConfig::default(),
250            options: HashMap::new(),
251        }
252    }
253    
254    /// Create a new configuration with Qdrant storage
255    pub fn qdrant(url: impl Into<String>, collection: impl Into<String>) -> Self {
256        Self {
257            storage: StorageConfig::Qdrant {
258                url: url.into(),
259                api_key: None,
260                collection_name: collection.into(),
261                timeout: None,
262                tls: false,
263            },
264            embedding: None,
265            search: SearchConfig::default(),
266            options: HashMap::new(),
267        }
268    }
269    
270    /// Set the embedding configuration
271    pub fn with_embedding(mut self, embedding: EmbeddingConfig) -> Self {
272        self.embedding = Some(embedding);
273        self
274    }
275    
276    /// Set the search configuration
277    pub fn with_search_config(mut self, search: SearchConfig) -> Self {
278        self.search = search;
279        self
280    }
281    
282    /// Add a system option
283    pub fn with_option(mut self, key: impl Into<String>, value: impl Into<MetadataValue>) -> Self {
284        self.options.insert(key.into(), value.into());
285        self
286    }
287}
288
289/// Builder for creating storage configurations
290pub struct StorageConfigBuilder {
291    config: StorageConfig,
292}
293
294impl StorageConfigBuilder {
295    /// Create a memory storage builder
296    pub fn memory() -> Self {
297        Self {
298            config: StorageConfig::Memory {
299                initial_capacity: None,
300                max_vectors: None,
301            },
302        }
303    }
304    
305    /// Create a SQLite storage builder
306    pub fn sqlite(database_path: impl Into<String>) -> Self {
307        Self {
308            config: StorageConfig::Sqlite {
309                database_path: database_path.into(),
310                pool_size: None,
311                wal_mode: true,
312                synchronous: SqliteSynchronous::default(),
313            },
314        }
315    }
316    
317    /// Create a Qdrant storage builder
318    pub fn qdrant(url: impl Into<String>, collection: impl Into<String>) -> Self {
319        Self {
320            config: StorageConfig::Qdrant {
321                url: url.into(),
322                api_key: None,
323                collection_name: collection.into(),
324                timeout: None,
325                tls: false,
326            },
327        }
328    }
329    
330    /// Set initial capacity for memory storage
331    pub fn with_initial_capacity(mut self, capacity: usize) -> Self {
332        if let StorageConfig::Memory { ref mut initial_capacity, .. } = self.config {
333            *initial_capacity = Some(capacity);
334        }
335        self
336    }
337    
338    /// Set API key for Qdrant
339    pub fn with_api_key(mut self, api_key: impl Into<String>) -> Self {
340        if let StorageConfig::Qdrant { api_key: ref mut key, .. } = self.config {
341            *key = Some(api_key.into());
342        }
343        self
344    }
345    
346    /// Enable TLS for Qdrant
347    pub fn with_tls(mut self, enable: bool) -> Self {
348        if let StorageConfig::Qdrant { ref mut tls, .. } = self.config {
349            *tls = enable;
350        }
351        self
352    }
353    
354    /// Build the configuration
355    pub fn build(self) -> StorageConfig {
356        self.config
357    }
358}