1use crate::traits::SystemService;
12use crate::types::*;
13use async_trait::async_trait;
14use feagi_brain_development::ConnectomeManager;
15use feagi_npu_burst_engine::BurstLoopRunner;
16use parking_lot::RwLock;
17use std::sync::Arc;
18use std::time::SystemTime;
19use tracing::trace;
20
21pub struct SystemServiceImpl {
23 connectome: Arc<RwLock<ConnectomeManager>>,
24 burst_runner: Option<Arc<RwLock<BurstLoopRunner>>>,
25 start_time: SystemTime,
26 version_info: VersionInfo,
27}
28
29impl SystemServiceImpl {
30 pub fn new(
35 connectome: Arc<RwLock<ConnectomeManager>>,
36 burst_runner: Option<Arc<RwLock<BurstLoopRunner>>>,
37 version_info: VersionInfo,
38 ) -> Self {
39 Self {
40 connectome,
41 burst_runner,
42 start_time: SystemTime::now(),
43 version_info,
44 }
45 }
46
47 fn get_uptime_seconds(&self) -> u64 {
49 self.start_time.elapsed().map(|d| d.as_secs()).unwrap_or(0)
50 }
51
52 pub fn get_feagi_session_timestamp(&self) -> i64 {
54 self.start_time
55 .duration_since(SystemTime::UNIX_EPOCH)
56 .map(|d| d.as_millis() as i64)
57 .unwrap_or(0)
58 }
59
60 fn get_timestamp() -> String {
62 chrono::Utc::now().to_rfc3339()
63 }
64}
65
66#[async_trait]
67impl SystemService for SystemServiceImpl {
68 async fn get_health(&self) -> ServiceResult<HealthStatus> {
69 trace!(target: "feagi-services", "Getting system health");
70
71 let mut components = Vec::new();
72
73 let connectome_initialized = self.connectome.read().is_initialized();
75 components.push(ComponentHealth {
76 name: "Connectome".to_string(),
77 status: if connectome_initialized {
78 "healthy".to_string()
79 } else {
80 "degraded".to_string()
81 },
82 message: if connectome_initialized {
83 Some("Genome loaded and brain initialized".to_string())
84 } else {
85 Some("No genome loaded".to_string())
86 },
87 });
88
89 let has_npu = self.connectome.read().has_npu();
91 components.push(ComponentHealth {
92 name: "NPU".to_string(),
93 status: if has_npu {
94 "healthy".to_string()
95 } else {
96 "unhealthy".to_string()
97 },
98 message: if has_npu {
99 Some("NPU connected".to_string())
100 } else {
101 Some("NPU not connected".to_string())
102 },
103 });
104
105 let burst_engine_running = if let Some(ref runner) = self.burst_runner {
107 runner.read().is_running()
108 } else {
109 false
110 };
111 components.push(ComponentHealth {
112 name: "BurstEngine".to_string(),
113 status: if burst_engine_running {
114 "healthy".to_string()
115 } else {
116 "degraded".to_string()
117 },
118 message: if burst_engine_running {
119 Some("Burst engine active".to_string())
120 } else {
121 Some("Burst engine stopped".to_string())
122 },
123 });
124
125 let overall_status = if components.iter().all(|c| c.status == "healthy") {
127 "healthy"
128 } else if components.iter().any(|c| c.status == "unhealthy") {
129 "unhealthy"
130 } else {
131 "degraded"
132 };
133
134 Ok(HealthStatus {
135 overall_status: overall_status.to_string(),
136 components,
137 timestamp: Self::get_timestamp(),
138 })
139 }
140
141 async fn get_status(&self) -> ServiceResult<SystemStatus> {
142 trace!(target: "feagi-services", "Getting system status");
143
144 let manager = self.connectome.read();
145
146 let is_initialized = manager.is_initialized();
147
148 let state_manager_instance = feagi_state_manager::StateManager::instance();
150 let (neuron_count, synapse_count) =
151 if let Some(state_manager) = state_manager_instance.try_read() {
152 let core_state = state_manager.get_core_state();
153 (
154 core_state.get_neuron_count() as usize,
155 core_state.get_synapse_count() as usize,
156 )
157 } else {
158 (manager.get_neuron_count(), manager.get_synapse_count())
160 };
161
162 let cortical_area_count = manager.get_cortical_area_count();
163 let brain_region_count = manager.get_brain_region_ids().len();
164
165 let (burst_engine_running, burst_count, current_burst_rate_hz, avg_burst_time_ms) =
166 if let Some(ref runner) = self.burst_runner {
167 let runner_lock = runner.read();
168 (
169 runner_lock.is_running(),
170 runner_lock.get_burst_count(),
171 0.0, 0.0, )
174 } else {
175 (false, 0, 0.0, 0.0)
176 };
177
178 Ok(SystemStatus {
179 is_initialized,
180 burst_engine_running,
181 burst_count,
182 neuron_count,
183 synapse_count,
184 cortical_area_count,
185 brain_region_count,
186 uptime_seconds: self.get_uptime_seconds(),
187 current_burst_rate_hz,
188 avg_burst_time_ms,
189 })
190 }
191
192 async fn get_version(&self) -> ServiceResult<VersionInfo> {
193 trace!(target: "feagi-services", "Getting version information");
194
195 Ok(self.version_info.clone())
199 }
200
201 async fn is_initialized(&self) -> ServiceResult<bool> {
202 trace!(target: "feagi-services", "Checking if system is initialized");
203 Ok(self.connectome.read().is_initialized())
204 }
205
206 async fn get_burst_count(&self) -> ServiceResult<u64> {
207 trace!(target: "feagi-services", "Getting burst count");
208
209 if let Some(ref runner) = self.burst_runner {
210 Ok(runner.read().get_burst_count())
211 } else {
212 Ok(0)
213 }
214 }
215
216 async fn get_runtime_stats(&self) -> ServiceResult<RuntimeStats> {
217 trace!(target: "feagi-services", "Getting runtime statistics");
218
219 let burst_count = if let Some(ref runner) = self.burst_runner {
220 runner.read().get_burst_count()
221 } else {
222 0
223 };
224
225 Ok(RuntimeStats {
228 total_bursts: burst_count,
229 total_neurons_fired: 0, total_processing_time_ms: 0, avg_burst_time_ms: 0.0, avg_neurons_per_burst: 0.0, current_rate_hz: 0.0, peak_rate_hz: 0.0, uptime_seconds: self.get_uptime_seconds(),
236 })
237 }
238
239 async fn get_memory_usage(&self) -> ServiceResult<MemoryUsage> {
240 trace!(target: "feagi-services", "Getting memory usage");
241
242 let manager = self.connectome.read();
245
246 let state_manager_instance = feagi_state_manager::StateManager::instance();
248 let (neuron_count, synapse_count) =
249 if let Some(state_manager) = state_manager_instance.try_read() {
250 let core_state = state_manager.get_core_state();
251 (
252 core_state.get_neuron_count() as usize,
253 core_state.get_synapse_count() as usize,
254 )
255 } else {
256 (manager.get_neuron_count(), manager.get_synapse_count())
258 };
259
260 let npu_neurons_bytes = neuron_count * 64; let npu_synapses_bytes = synapse_count * 16; let npu_total_bytes = npu_neurons_bytes + npu_synapses_bytes;
264
265 let connectome_metadata_bytes = manager.get_cortical_area_count() * 512 + manager.get_brain_region_ids().len() * 256; let total_allocated_bytes = npu_total_bytes + connectome_metadata_bytes;
269
270 let (system_total_bytes, system_available_bytes) = (0, 0); Ok(MemoryUsage {
274 npu_neurons_bytes,
275 npu_synapses_bytes,
276 npu_total_bytes,
277 connectome_metadata_bytes,
278 total_allocated_bytes,
279 system_total_bytes,
280 system_available_bytes,
281 })
282 }
283
284 async fn get_capacity(&self) -> ServiceResult<CapacityInfo> {
285 trace!(target: "feagi-services", "Getting capacity information");
286
287 let manager = self.connectome.read();
288 let config = manager.get_config();
289
290 let state_manager_instance = feagi_state_manager::StateManager::instance();
292 let (current_neurons, current_synapses) =
293 if let Some(state_manager) = state_manager_instance.try_read() {
294 let core_state = state_manager.get_core_state();
295 (
296 core_state.get_neuron_count() as usize,
297 core_state.get_synapse_count() as usize,
298 )
299 } else {
300 (manager.get_neuron_count(), manager.get_synapse_count())
301 };
302
303 let max_neurons = config.max_neurons;
304 let neuron_utilization_percent = (current_neurons as f64 / max_neurons as f64) * 100.0;
305 let max_synapses = config.max_synapses;
306 let synapse_utilization_percent = (current_synapses as f64 / max_synapses as f64) * 100.0;
307
308 let current_cortical_areas = manager.get_cortical_area_count();
309 let max_cortical_areas = 10000; Ok(CapacityInfo {
312 current_neurons,
313 max_neurons,
314 neuron_utilization_percent,
315 current_synapses,
316 max_synapses,
317 synapse_utilization_percent,
318 current_cortical_areas,
319 max_cortical_areas,
320 })
321 }
322}