1use crate::error::{APIError, APIResult};
4use crate::events::{LoopType, MemoryTier};
5use crate::runtime::OmegaRuntime;
6use serde::{Deserialize, Serialize};
7use std::sync::Arc;
8use uuid::Uuid;
9
10pub struct OmegaAPI {
12 runtime: Arc<OmegaRuntime>,
13}
14
15impl OmegaAPI {
16 pub fn new(runtime: Arc<OmegaRuntime>) -> Self {
18 Self { runtime }
19 }
20
21 pub async fn store_memory(
23 &self,
24 content: &str,
25 tier: MemoryTier,
26 ) -> APIResult<Uuid> {
27 if !self.runtime.is_running() {
28 return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
29 }
30
31 let id = Uuid::new_v4();
32
33 tracing::debug!(
35 "Storing memory {} in tier {:?}: {}",
36 id,
37 tier,
38 content
39 );
40
41 Ok(id)
42 }
43
44 pub async fn query_memory(
46 &self,
47 query: &str,
48 tier: Option<MemoryTier>,
49 ) -> APIResult<Vec<Memory>> {
50 if !self.runtime.is_running() {
51 return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
52 }
53
54 tracing::debug!(
56 "Querying memory with query '{}' in tier {:?}",
57 query,
58 tier
59 );
60
61 Ok(Vec::new())
62 }
63
64 pub async fn create_intelligence(
66 &self,
67 spec: IntelligenceSpec,
68 ) -> APIResult<Intelligence> {
69 if !self.runtime.is_running() {
70 return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
71 }
72
73 let intelligence = Intelligence {
74 id: Uuid::new_v4(),
75 architecture_id: Uuid::new_v4(),
76 name: spec.name,
77 description: spec.description,
78 fitness: 0.0,
79 generation: 0,
80 created_at: chrono::Utc::now(),
81 };
82
83 tracing::info!(
84 "Created intelligence {} with architecture {}",
85 intelligence.id,
86 intelligence.architecture_id
87 );
88
89 Ok(intelligence)
90 }
91
92 pub async fn evolve_architecture(
94 &self,
95 id: Uuid,
96 ) -> APIResult<Architecture> {
97 if !self.runtime.is_running() {
98 return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
99 }
100
101 let architecture = Architecture {
103 id,
104 fitness: 0.5,
105 generation: 1,
106 parameters: serde_json::json!({}),
107 created_at: chrono::Utc::now(),
108 };
109
110 tracing::info!("Evolved architecture {}", id);
111
112 Ok(architecture)
113 }
114
115 pub async fn trigger_loop(
117 &self,
118 loop_type: LoopType,
119 input: CycleInput,
120 ) -> APIResult<CycleOutput> {
121 if !self.runtime.is_running() {
122 return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
123 }
124
125 let output = CycleOutput {
127 cycle_id: Uuid::new_v4(),
128 loop_type,
129 result: serde_json::json!({}),
130 duration: std::time::Duration::from_millis(100),
131 };
132
133 tracing::debug!("Triggered {:?} loop cycle {}", loop_type, output.cycle_id);
134
135 Ok(output)
136 }
137
138 pub async fn get_loop_status(&self) -> APIResult<LoopStatus> {
140 if !self.runtime.is_running() {
141 return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
142 }
143
144 Ok(LoopStatus {
146 conscious: LoopInfo {
147 enabled: true,
148 cycles_completed: 0,
149 average_duration_ms: 0,
150 },
151 subconscious: LoopInfo {
152 enabled: true,
153 cycles_completed: 0,
154 average_duration_ms: 0,
155 },
156 meta: LoopInfo {
157 enabled: true,
158 cycles_completed: 0,
159 average_duration_ms: 0,
160 },
161 unconscious: LoopInfo {
162 enabled: true,
163 cycles_completed: 0,
164 average_duration_ms: 0,
165 },
166 })
167 }
168
169 pub async fn get_metrics(&self) -> APIResult<RuntimeMetrics> {
171 let health = self.runtime.health().await;
172
173 Ok(RuntimeMetrics {
174 state: format!("{:?}", health.state),
175 is_healthy: health.is_healthy(),
176 event_count: self.runtime.event_history().len(),
177 agent_count: 0,
179 memory_usage_bytes: 0,
180 loop_cycles_total: 0,
181 })
182 }
183
184 pub fn get_config(&self) -> &crate::config::OmegaConfig {
186 self.runtime.config()
187 }
188}
189
190#[derive(Debug, Clone, Serialize, Deserialize)]
192pub struct Memory {
193 pub id: Uuid,
194 pub content: String,
195 pub tier: MemoryTier,
196 pub created_at: chrono::DateTime<chrono::Utc>,
197 pub accessed_at: chrono::DateTime<chrono::Utc>,
198 pub access_count: usize,
199}
200
201#[derive(Debug, Clone, Serialize, Deserialize)]
203pub struct IntelligenceSpec {
204 pub name: String,
205 pub description: String,
206 pub initial_parameters: Option<serde_json::Value>,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize)]
211pub struct Intelligence {
212 pub id: Uuid,
213 pub architecture_id: Uuid,
214 pub name: String,
215 pub description: String,
216 pub fitness: f64,
217 pub generation: usize,
218 pub created_at: chrono::DateTime<chrono::Utc>,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize)]
223pub struct Architecture {
224 pub id: Uuid,
225 pub fitness: f64,
226 pub generation: usize,
227 pub parameters: serde_json::Value,
228 pub created_at: chrono::DateTime<chrono::Utc>,
229}
230
231#[derive(Debug, Clone, Serialize, Deserialize)]
233pub struct CycleInput {
234 pub data: serde_json::Value,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct CycleOutput {
240 pub cycle_id: Uuid,
241 pub loop_type: LoopType,
242 pub result: serde_json::Value,
243 pub duration: std::time::Duration,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
248pub struct LoopInfo {
249 pub enabled: bool,
250 pub cycles_completed: u64,
251 pub average_duration_ms: u64,
252}
253
254#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct LoopStatus {
257 pub conscious: LoopInfo,
258 pub subconscious: LoopInfo,
259 pub meta: LoopInfo,
260 pub unconscious: LoopInfo,
261}
262
263#[derive(Debug, Clone, Serialize, Deserialize)]
265pub struct RuntimeMetrics {
266 pub state: String,
267 pub is_healthy: bool,
268 pub event_count: usize,
269 pub agent_count: usize,
270 pub memory_usage_bytes: usize,
271 pub loop_cycles_total: u64,
272}
273
274#[cfg(test)]
275mod tests {
276 use super::*;
277 use crate::config::OmegaConfig;
278
279 #[tokio::test]
280 async fn test_api_creation() {
281 let config = OmegaConfig::minimal();
282 let runtime = Arc::new(OmegaRuntime::new(config).await.unwrap());
283 let api = OmegaAPI::new(runtime);
284
285 assert!(api.get_config().validate().is_ok());
287 }
288
289 #[tokio::test]
290 async fn test_api_requires_running_runtime() {
291 let config = OmegaConfig::minimal();
292 let runtime = Arc::new(OmegaRuntime::new(config).await.unwrap());
293 let api = OmegaAPI::new(runtime);
294
295 let result = api.store_memory("test", MemoryTier::Working).await;
297 assert!(result.is_err());
298 }
299
300 #[tokio::test]
301 async fn test_create_intelligence() {
302 let config = OmegaConfig::minimal();
303 let runtime = Arc::new(OmegaRuntime::new(config).await.unwrap());
304 runtime.start().await.unwrap();
305
306 let api = OmegaAPI::new(runtime.clone());
307
308 let spec = IntelligenceSpec {
309 name: "TestIntelligence".to_string(),
310 description: "A test intelligence".to_string(),
311 initial_parameters: None,
312 };
313
314 let intelligence = api.create_intelligence(spec).await.unwrap();
315 assert_eq!(intelligence.name, "TestIntelligence");
316 assert_eq!(intelligence.generation, 0);
317 }
318
319 #[tokio::test]
320 async fn test_get_metrics() {
321 let config = OmegaConfig::minimal();
322 let runtime = Arc::new(OmegaRuntime::new(config).await.unwrap());
323 runtime.start().await.unwrap();
324
325 let api = OmegaAPI::new(runtime.clone());
326
327 let metrics = api.get_metrics().await.unwrap();
328 assert_eq!(metrics.state, "Running");
329 }
330}