codex_memory/application/
dependency_container.rs1use crate::{
2 backup::BackupManager,
3 manager::ServerManager,
4 mcp_server::{MCPServer, MCPServerConfig},
5 memory::{
6 connection::create_pool, silent_harvester::SilentHarvesterService,
7 tier_manager::TierManager,
8 },
9 monitoring::HealthChecker,
10 Config, DatabaseSetup, MemoryRepository, SetupManager, SimpleEmbedder,
11};
12use anyhow::Result;
13use sqlx::PgPool;
14use std::sync::Arc;
15use tracing::info;
16
17pub struct DependencyContainer {
19 pub config: Config,
21
22 pub db_pool: Arc<PgPool>,
24
25 pub memory_repository: Arc<MemoryRepository>,
27
28 pub embedder: Arc<SimpleEmbedder>,
30 pub setup_manager: Arc<SetupManager>,
31 pub database_setup: Arc<DatabaseSetup>,
32 pub backup_manager: Option<Arc<BackupManager>>,
33 pub tier_manager: Option<Arc<TierManager>>,
34 pub harvester_service: Option<Arc<SilentHarvesterService>>,
35
36 pub health_checker: Arc<HealthChecker>,
38 pub mcp_server: Option<Arc<MCPServer>>,
39 pub server_manager: Arc<ServerManager>,
40}
41
42impl DependencyContainer {
43 pub async fn new() -> Result<Self> {
44 info!("🔧 Initializing dependency container...");
45
46 let config = Config::from_env().unwrap_or_else(|_| {
48 info!("⚠️ No configuration found, using defaults");
49 Config::default()
50 });
51
52 let db_pool = Arc::new(
54 create_pool(&config.database_url, config.operational.max_db_connections).await?,
55 );
56
57 let memory_repository = Arc::new(MemoryRepository::with_config(
59 (*db_pool).clone(),
60 config.clone(),
61 ));
62
63 let embedder = Arc::new(Self::create_embedder(&config)?);
65 let setup_manager = Arc::new(SetupManager::new(config.clone()));
66 let database_setup = Arc::new(DatabaseSetup::new(config.database_url.clone()));
67
68 let health_checker = Arc::new(HealthChecker::new(db_pool.clone()));
70 let server_manager = Arc::new(ServerManager::new());
71
72 let backup_manager = if config.backup.enabled {
74 let backup_config = crate::backup::BackupConfig::default(); Some(Arc::new(BackupManager::new(backup_config, db_pool.clone())))
76 } else {
77 None
78 };
79
80 let tier_manager = if config.tier_manager.enabled {
81 Some(Arc::new(TierManager::new(
82 memory_repository.clone(),
83 config.tier_manager.clone(),
84 )?))
85 } else {
86 None
87 };
88
89 let harvester_service = None;
92 info!("✅ Dependency container initialized successfully");
101
102 Ok(Self {
103 config,
104 db_pool,
105 memory_repository,
106 embedder,
107 setup_manager,
108 database_setup,
109 backup_manager,
110 tier_manager,
111 harvester_service,
112 health_checker,
113 mcp_server: None, server_manager,
115 })
116 }
117
118 fn create_embedder(config: &Config) -> Result<SimpleEmbedder> {
119 match config.embedding.provider.as_str() {
120 "openai" => Ok(SimpleEmbedder::new(config.embedding.api_key.clone())
121 .with_model(config.embedding.model.clone())
122 .with_base_url(config.embedding.base_url.clone())),
123 "ollama" => Ok(SimpleEmbedder::new_ollama(
124 config.embedding.base_url.clone(),
125 config.embedding.model.clone(),
126 )),
127 "mock" => Ok(SimpleEmbedder::new_mock()),
128 _ => Err(anyhow::anyhow!(
129 "Unsupported embedding provider: {}",
130 config.embedding.provider
131 )),
132 }
133 }
134
135 pub async fn create_mcp_server(&self) -> Result<MCPServer> {
136 let mcp_config = MCPServerConfig::default();
137
138 let server = MCPServer::new(
139 self.memory_repository.clone(),
140 self.embedder.clone(),
141 mcp_config,
142 )?;
143
144 Ok(server)
145 }
146
147 pub async fn health_check(&self) -> Result<bool> {
148 match self.database_setup.health_check().await {
150 Ok(health) => Ok(health.is_healthy()),
151 Err(_) => Ok(false),
152 }
153 }
154}