Skip to main content

nexus_memory_core/
config.rs

1//! Configuration types for Nexus Memory System
2
3use serde::{Deserialize, Serialize};
4use std::path::PathBuf;
5
6/// Main configuration for Nexus
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Config {
9    /// Database configuration
10    pub database: DatabaseConfig,
11
12    /// Server configuration
13    pub server: ServerConfig,
14
15    /// Embedding configuration
16    pub embedding: EmbeddingConfig,
17
18    /// Sync configuration
19    pub sync: SyncConfig,
20}
21
22impl Default for Config {
23    fn default() -> Self {
24        Self {
25            database: DatabaseConfig::default(),
26            server: ServerConfig::default(),
27            embedding: EmbeddingConfig::default(),
28            sync: SyncConfig::default(),
29        }
30    }
31}
32
33impl Config {
34    /// Load configuration from environment variables
35    pub fn from_env() -> crate::Result<Self> {
36        let mut config = Self::default();
37
38        if let Ok(path) = std::env::var("NEXUS_DATABASE_PATH") {
39            config.database.path = PathBuf::from(path);
40        }
41
42        if let Ok(host) = std::env::var("NEXUS_HOST") {
43            config.server.host = host;
44        }
45
46        if let Ok(port) = std::env::var("NEXUS_PORT") {
47            config.server.port = port.parse().unwrap_or(8768);
48        }
49
50        if let Ok(enabled) = std::env::var("NEXUS_EMBEDDINGS_ENABLED") {
51            config.embedding.enabled = enabled.parse().unwrap_or(true);
52        }
53
54        if let Ok(model) = std::env::var("NEXUS_EMBEDDING_MODEL") {
55            config.embedding.model = model;
56        }
57
58        if let Ok(policy) = std::env::var("NEXUS_SYNC_POLICY") {
59            config.sync.policy = policy;
60        }
61
62        Ok(config)
63    }
64
65    /// Get the database URL
66    pub fn database_url(&self) -> String {
67        format!("sqlite:{}", self.database.path.display())
68    }
69}
70
71/// Database configuration
72#[derive(Debug, Clone, Serialize, Deserialize)]
73pub struct DatabaseConfig {
74    /// Path to SQLite database file
75    pub path: PathBuf,
76
77    /// Enable foreign key constraints
78    pub foreign_keys: bool,
79
80    /// Connection pool size
81    pub pool_size: u32,
82}
83
84impl Default for DatabaseConfig {
85    fn default() -> Self {
86        let home = std::env::var("HOME").unwrap_or_else(|_| ".".to_string());
87        let base_path = PathBuf::from(home).join(".nexus");
88
89        Self {
90            path: base_path.join("nexus.db"),
91            foreign_keys: true,
92            pool_size: 5,
93        }
94    }
95}
96
97/// Server configuration
98#[derive(Debug, Clone, Serialize, Deserialize)]
99pub struct ServerConfig {
100    /// Server host
101    pub host: String,
102
103    /// Server port
104    pub port: u16,
105
106    /// Web dashboard port
107    pub web_port: u16,
108
109    /// Transport type (stdio, http, web)
110    pub transport: String,
111}
112
113impl Default for ServerConfig {
114    fn default() -> Self {
115        Self {
116            host: "127.0.0.1".to_string(),
117            port: 8768,
118            web_port: 8768,
119            transport: "stdio".to_string(),
120        }
121    }
122}
123
124/// Embedding configuration
125#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct EmbeddingConfig {
127    /// Enable embeddings
128    pub enabled: bool,
129
130    /// Embedding model name
131    pub model: String,
132
133    /// Embedding dimension
134    pub dimension: usize,
135}
136
137impl Default for EmbeddingConfig {
138    fn default() -> Self {
139        Self {
140            enabled: true,
141            model: "all-MiniLM-L6-v2".to_string(),
142            dimension: 384,
143        }
144    }
145}
146
147/// Sync configuration for cross-agent synchronization
148#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct SyncConfig {
150    /// Sync policy (manual, auto, aggressive)
151    pub policy: String,
152
153    /// Sync interval in seconds (for auto policy)
154    pub interval_secs: u64,
155}
156
157impl Default for SyncConfig {
158    fn default() -> Self {
159        Self {
160            policy: "manual".to_string(),
161            interval_secs: 300,
162        }
163    }
164}
165
166#[cfg(test)]
167mod tests {
168    use super::*;
169
170    #[test]
171    fn test_default_config() {
172        let config = Config::default();
173        assert!(config.embedding.enabled);
174        assert_eq!(config.embedding.dimension, 384);
175        assert_eq!(config.server.port, 8768);
176    }
177
178    #[test]
179    fn test_database_url() {
180        let config = Config::default();
181        let url = config.database_url();
182        assert!(url.starts_with("sqlite:"));
183    }
184}