1pub mod compaction;
44pub mod embedding;
45pub mod manager;
46pub mod markdown_memory;
47pub mod token_counter;
48pub mod types;
49pub mod vector_db;
50pub mod vector_db_factory;
51#[cfg(feature = "vector-lancedb")]
52pub mod vector_db_lance;
53pub mod vector_db_trait;
54
55pub use types::{
57 AccessLevel, AgentContext, ContextError, ContextId, ContextPersistence, ContextQuery,
58 FilePersistenceConfig, HierarchicalMemory, Knowledge, KnowledgeBase, KnowledgeId,
59 KnowledgeItem, KnowledgeSource, KnowledgeType, MemoryItem, MemoryType, QueryType,
60 RetentionPolicy, SessionId, StorageStats, VectorBatchItem, VectorBatchOperation,
61 VectorContentType, VectorId, VectorMetadata, VectorOperationType, VectorSearchResult,
62};
63
64pub use manager::{ContextManager, ContextManagerConfig, FilePersistence, StandardContextManager};
65
66pub use markdown_memory::MarkdownMemoryStore;
67
68pub use embedding::{
69 create_embedding_service, create_embedding_service_from_env, EmbeddingConfig,
70 EmbeddingProvider, OllamaEmbeddingService, OpenAiEmbeddingService,
71};
72
73pub use vector_db::{
74 EmbeddingService, MockEmbeddingService, NoOpVectorDatabase, QdrantConfig, QdrantDistance,
75 TfIdfEmbeddingService, VectorDatabase, VectorDatabaseStats,
76};
77
78#[cfg(feature = "vector-qdrant")]
79pub use vector_db::QdrantClientWrapper;
80
81pub use compaction::{CompactionConfig, CompactionResult, CompactionTier};
82pub use token_counter::{
83 context_limit_for_model, create_token_counter, HeuristicTokenCounter, TiktokenCounter,
84 TokenCounter,
85};
86pub use vector_db_factory::{create_vector_backend, resolve_vector_config, VectorBackendConfig};
87#[cfg(feature = "vector-lancedb")]
88pub use vector_db_lance::{LanceDbBackend, LanceDbConfig};
89pub use vector_db_trait::{DistanceMetric, VectorDb};
90
91#[cfg(test)]
92mod tests {
93 use super::*;
94 use crate::types::AgentId;
95 use std::time::SystemTime;
96
97 fn test_config() -> (ContextManagerConfig, tempfile::TempDir) {
100 let tmp = tempfile::tempdir().unwrap();
101 let mut config = ContextManagerConfig::default();
102 config.persistence_config.root_data_dir = tmp.path().to_path_buf();
103 (config, tmp)
104 }
105
106 #[tokio::test]
107 async fn test_context_manager_creation() {
108 let (config, _tmp) = test_config();
109 let agent_id = AgentId::new();
110 let manager = StandardContextManager::new(config, &agent_id.to_string())
111 .await
112 .unwrap();
113 assert!(manager.initialize().await.is_ok());
114 }
115
116 #[tokio::test]
117 async fn test_session_creation() {
118 let (config, _tmp) = test_config();
119 let agent_id = AgentId::new();
120 let manager = StandardContextManager::new(config, &agent_id.to_string())
121 .await
122 .unwrap();
123 manager.initialize().await.unwrap();
124
125 let session_id = manager.create_session(agent_id).await.unwrap();
126
127 let context = manager
129 .retrieve_context(agent_id, Some(session_id))
130 .await
131 .unwrap();
132 assert!(context.is_some());
133 assert_eq!(context.unwrap().session_id, session_id);
134 }
135
136 #[tokio::test]
137 async fn test_memory_operations() {
138 let (config, _tmp) = test_config();
139 let agent_id = AgentId::new();
140 let manager = StandardContextManager::new(config, &agent_id.to_string())
141 .await
142 .unwrap();
143 manager.initialize().await.unwrap();
144
145 let _session_id = manager.create_session(agent_id).await.unwrap();
146
147 let memory_updates = vec![types::MemoryUpdate {
149 target: types::MemoryTarget::Working("test_key".to_string()),
150 operation: types::UpdateOperation::Add,
151 data: serde_json::Value::String("test_value".to_string()),
152 }];
153
154 assert!(manager
155 .update_memory(agent_id, memory_updates)
156 .await
157 .is_ok());
158 }
159
160 #[tokio::test]
161 async fn test_knowledge_operations() {
162 let (config, _tmp) = test_config();
163 let agent_id = AgentId::new();
164 let manager = StandardContextManager::new(config, &agent_id.to_string())
165 .await
166 .unwrap();
167 manager.initialize().await.unwrap();
168
169 let _session_id = manager.create_session(agent_id).await.unwrap();
170
171 let fact = types::KnowledgeFact {
173 id: KnowledgeId::new(),
174 subject: "test".to_string(),
175 predicate: "is".to_string(),
176 object: "example".to_string(),
177 confidence: 0.9,
178 source: types::KnowledgeSource::UserProvided,
179 created_at: SystemTime::now(),
180 verified: true,
181 };
182
183 let _knowledge_id = manager
184 .add_knowledge(agent_id, Knowledge::Fact(fact))
185 .await
186 .unwrap();
187
188 let results = manager
190 .search_knowledge(agent_id, "test", 10)
191 .await
192 .unwrap();
193 assert!(!results.is_empty());
194 }
195
196 #[tokio::test]
197 async fn test_context_query() {
198 let (config, _tmp) = test_config();
199 let agent_id = AgentId::new();
200 let manager = StandardContextManager::new(config, &agent_id.to_string())
201 .await
202 .unwrap();
203 manager.initialize().await.unwrap();
204
205 let _session_id = manager.create_session(agent_id).await.unwrap();
206
207 let query = ContextQuery {
209 query_type: QueryType::Semantic,
210 search_terms: vec!["test".to_string()],
211 max_results: 10,
212 time_range: None,
213 memory_types: vec![],
214 relevance_threshold: 0.7,
215 include_embeddings: false,
216 };
217
218 let results = manager.query_context(agent_id, query).await.unwrap();
219 assert!(results.len() <= 10);
221 }
222
223 #[tokio::test]
224 async fn test_context_stats() {
225 let (config, _tmp) = test_config();
226 let agent_id = AgentId::new();
227 let manager = StandardContextManager::new(config, &agent_id.to_string())
228 .await
229 .unwrap();
230 manager.initialize().await.unwrap();
231
232 let _session_id = manager.create_session(agent_id).await.unwrap();
233
234 let stats = manager.get_context_stats(agent_id).await.unwrap();
235 assert_eq!(stats.total_memory_items, 0);
236 assert_eq!(stats.total_knowledge_items, 0);
237 assert_eq!(stats.total_conversations, 0);
238 }
239
240 #[tokio::test]
241 async fn test_secrets_integration() {
242 let (config, _tmp) = test_config();
243 let agent_id = AgentId::new();
244 let manager = StandardContextManager::new(config, &agent_id.to_string())
245 .await
246 .unwrap();
247
248 let _secrets = manager.secrets();
250 }
252}