use crate::error::{APIError, APIResult};
use crate::events::{LoopType, MemoryTier};
use crate::runtime::OmegaRuntime;
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use uuid::Uuid;
pub struct OmegaAPI {
runtime: Arc<OmegaRuntime>,
}
impl OmegaAPI {
pub fn new(runtime: Arc<OmegaRuntime>) -> Self {
Self { runtime }
}
pub async fn store_memory(
&self,
content: &str,
tier: MemoryTier,
) -> APIResult<Uuid> {
if !self.runtime.is_running() {
return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
}
let id = Uuid::new_v4();
tracing::debug!(
"Storing memory {} in tier {:?}: {}",
id,
tier,
content
);
Ok(id)
}
pub async fn query_memory(
&self,
query: &str,
tier: Option<MemoryTier>,
) -> APIResult<Vec<Memory>> {
if !self.runtime.is_running() {
return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
}
tracing::debug!(
"Querying memory with query '{}' in tier {:?}",
query,
tier
);
Ok(Vec::new())
}
pub async fn create_intelligence(
&self,
spec: IntelligenceSpec,
) -> APIResult<Intelligence> {
if !self.runtime.is_running() {
return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
}
let intelligence = Intelligence {
id: Uuid::new_v4(),
architecture_id: Uuid::new_v4(),
name: spec.name,
description: spec.description,
fitness: 0.0,
generation: 0,
created_at: chrono::Utc::now(),
};
tracing::info!(
"Created intelligence {} with architecture {}",
intelligence.id,
intelligence.architecture_id
);
Ok(intelligence)
}
pub async fn evolve_architecture(
&self,
id: Uuid,
) -> APIResult<Architecture> {
if !self.runtime.is_running() {
return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
}
let architecture = Architecture {
id,
fitness: 0.5,
generation: 1,
parameters: serde_json::json!({}),
created_at: chrono::Utc::now(),
};
tracing::info!("Evolved architecture {}", id);
Ok(architecture)
}
pub async fn trigger_loop(
&self,
loop_type: LoopType,
_input: CycleInput,
) -> APIResult<CycleOutput> {
if !self.runtime.is_running() {
return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
}
let output = CycleOutput {
cycle_id: Uuid::new_v4(),
loop_type,
result: serde_json::json!({}),
duration: std::time::Duration::from_millis(100),
};
tracing::debug!("Triggered {:?} loop cycle {}", loop_type, output.cycle_id);
Ok(output)
}
pub async fn get_loop_status(&self) -> APIResult<LoopStatus> {
if !self.runtime.is_running() {
return Err(APIError::Runtime(crate::error::RuntimeError::NotRunning));
}
Ok(LoopStatus {
conscious: LoopInfo {
enabled: true,
cycles_completed: 0,
average_duration_ms: 0,
},
subconscious: LoopInfo {
enabled: true,
cycles_completed: 0,
average_duration_ms: 0,
},
meta: LoopInfo {
enabled: true,
cycles_completed: 0,
average_duration_ms: 0,
},
unconscious: LoopInfo {
enabled: true,
cycles_completed: 0,
average_duration_ms: 0,
},
})
}
pub async fn get_metrics(&self) -> APIResult<RuntimeMetrics> {
let health = self.runtime.health().await;
Ok(RuntimeMetrics {
state: format!("{:?}", health.state),
is_healthy: health.is_healthy(),
event_count: self.runtime.event_history().len(),
agent_count: 0,
memory_usage_bytes: 0,
loop_cycles_total: 0,
})
}
pub fn get_config(&self) -> &crate::config::OmegaConfig {
self.runtime.config()
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Memory {
pub id: Uuid,
pub content: String,
pub tier: MemoryTier,
pub created_at: chrono::DateTime<chrono::Utc>,
pub accessed_at: chrono::DateTime<chrono::Utc>,
pub access_count: usize,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IntelligenceSpec {
pub name: String,
pub description: String,
pub initial_parameters: Option<serde_json::Value>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Intelligence {
pub id: Uuid,
pub architecture_id: Uuid,
pub name: String,
pub description: String,
pub fitness: f64,
pub generation: usize,
pub created_at: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Architecture {
pub id: Uuid,
pub fitness: f64,
pub generation: usize,
pub parameters: serde_json::Value,
pub created_at: chrono::DateTime<chrono::Utc>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CycleInput {
pub data: serde_json::Value,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CycleOutput {
pub cycle_id: Uuid,
pub loop_type: LoopType,
pub result: serde_json::Value,
pub duration: std::time::Duration,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoopInfo {
pub enabled: bool,
pub cycles_completed: u64,
pub average_duration_ms: u64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LoopStatus {
pub conscious: LoopInfo,
pub subconscious: LoopInfo,
pub meta: LoopInfo,
pub unconscious: LoopInfo,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RuntimeMetrics {
pub state: String,
pub is_healthy: bool,
pub event_count: usize,
pub agent_count: usize,
pub memory_usage_bytes: usize,
pub loop_cycles_total: u64,
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::OmegaConfig;
#[tokio::test]
async fn test_api_creation() {
let config = OmegaConfig::minimal();
let runtime = Arc::new(OmegaRuntime::new(config).await.unwrap());
let api = OmegaAPI::new(runtime);
assert!(api.get_config().validate().is_ok());
}
#[tokio::test]
async fn test_api_requires_running_runtime() {
let config = OmegaConfig::minimal();
let runtime = Arc::new(OmegaRuntime::new(config).await.unwrap());
let api = OmegaAPI::new(runtime);
let result = api.store_memory("test", MemoryTier::Working).await;
assert!(result.is_err());
}
#[tokio::test]
async fn test_create_intelligence() {
let config = OmegaConfig::minimal();
let runtime = Arc::new(OmegaRuntime::new(config).await.unwrap());
runtime.start().await.unwrap();
let api = OmegaAPI::new(runtime.clone());
let spec = IntelligenceSpec {
name: "TestIntelligence".to_string(),
description: "A test intelligence".to_string(),
initial_parameters: None,
};
let intelligence = api.create_intelligence(spec).await.unwrap();
assert_eq!(intelligence.name, "TestIntelligence");
assert_eq!(intelligence.generation, 0);
}
#[tokio::test]
async fn test_get_metrics() {
let config = OmegaConfig::minimal();
let runtime = Arc::new(OmegaRuntime::new(config).await.unwrap());
runtime.start().await.unwrap();
let api = OmegaAPI::new(runtime.clone());
let metrics = api.get_metrics().await.unwrap();
assert_eq!(metrics.state, "Running");
}
}