use async_trait::async_trait;
use feagi_evolutionary::RuntimeGenome;
use feagi_services::traits::connectome_service::ConnectomeService;
use feagi_services::types::errors::{ServiceError, ServiceResult};
use feagi_services::types::*;
use feagi_structures::genomic::cortical_area::CorticalID;
use std::collections::HashMap;
use std::sync::Arc;
pub struct WasmConnectomeService {
genome: Arc<RuntimeGenome>,
}
impl WasmConnectomeService {
pub fn new(genome: Arc<RuntimeGenome>) -> Self {
Self { genome }
}
fn area_to_info(
&self,
cortical_id: &CorticalID,
area: &feagi_structures::genomic::cortical_area::CorticalArea,
) -> CorticalAreaInfo {
use feagi_structures::genomic::cortical_area::CorticalArea;
let leak_coefficient = area
.properties
.get("leak_coefficient")
.and_then(|v| v.as_f64())
.unwrap_or(0.1);
let neurons_per_voxel = area
.properties
.get("neurons_per_voxel")
.and_then(|v| v.as_u64())
.map(|u| u as u32)
.unwrap_or(1);
let postsynaptic_current = area
.properties
.get("postsynaptic_current")
.and_then(|v| v.as_f64())
.unwrap_or(0.1);
let area_type_str = area
.properties
.get("area_type")
.and_then(|v| v.as_str())
.map(String::from)
.unwrap_or_else(|| "Custom".to_string());
let cortical_group = match area_type_str.as_str() {
"Sensory" | "IPU" => "IPU".to_string(),
"Motor" | "OPU" => "OPU".to_string(),
"Memory" => "MEMORY".to_string(),
"Custom" => "CUSTOM".to_string(),
_ => "CORE".to_string(),
};
let cortical_type = match cortical_group.as_str() {
"IPU" => "sensory".to_string(),
"OPU" => "motor".to_string(),
"MEMORY" => "memory".to_string(),
"CORE" => "core".to_string(),
_ => "custom".to_string(),
};
let firing_threshold = area
.properties
.get("firing_threshold")
.and_then(|v| v.as_f64())
.unwrap_or(1.0);
let firing_threshold_increment = [
area.properties
.get("firing_threshold_increment_x")
.and_then(|v| v.as_f64())
.unwrap_or(0.0),
area.properties
.get("firing_threshold_increment_y")
.and_then(|v| v.as_f64())
.unwrap_or(0.0),
area.properties
.get("firing_threshold_increment_z")
.and_then(|v| v.as_f64())
.unwrap_or(0.0),
];
let postsynaptic_current_max = area
.properties
.get("postsynaptic_current_max")
.and_then(|v| v.as_f64())
.unwrap_or(postsynaptic_current);
let mp_driven_psp = area
.properties
.get("mp_driven_psp")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let mp_charge_accumulation = area
.properties
.get("mp_charge_accumulation")
.and_then(|v| v.as_bool())
.unwrap_or(false);
let neuron_excitability = area
.properties
.get("neuron_excitability")
.and_then(|v| v.as_f64())
.unwrap_or(0.0);
let init_lifespan = area
.properties
.get("init_lifespan")
.and_then(|v| v.as_u64())
.map(|u| u as u32)
.unwrap_or(0);
let lifespan_growth_rate = area
.properties
.get("lifespan_growth_rate")
.and_then(|v| v.as_f64())
.unwrap_or(0.0);
let longterm_mem_threshold = area
.properties
.get("longterm_mem_threshold")
.and_then(|v| v.as_u64())
.map(|u| u as u32)
.unwrap_or(0);
let temporal_depth = area
.properties
.get("temporal_depth")
.and_then(|v| v.as_u64())
.map(|u| u as u32);
let cid_bytes = cortical_id.as_bytes();
let is_io_area_wasm = cid_bytes.len() == 8
&& (cid_bytes.first().copied() == Some(b'i')
|| cid_bytes.first().copied() == Some(b'o'));
let cortical_subtype_field = if is_io_area_wasm {
String::from_utf8(cid_bytes[0..4].to_vec()).ok()
} else {
None
};
let wasm_subunit_id = if is_io_area_wasm {
cid_bytes.get(6).copied()
} else {
None
};
let wasm_cortical_unit_index = if is_io_area_wasm {
cid_bytes.get(7).copied()
} else {
None
};
CorticalAreaInfo {
cortical_id: cortical_id.to_string(),
cortical_id_s: cortical_id.to_string(), cortical_idx: area.cortical_idx,
name: area.name.clone(),
dimensions: (
area.dimensions.width as usize,
area.dimensions.height as usize,
area.dimensions.depth as usize,
),
position: (area.position.x, area.position.y, area.position.z),
area_type: area_type_str,
cortical_group,
cortical_type,
neuron_count: 0, synapse_count: 0, incoming_synapse_count: 0, outgoing_synapse_count: 0, visible: area
.properties
.get("visible")
.and_then(|v| v.as_bool())
.unwrap_or(true),
sub_group: area
.properties
.get("cortical_sub_group")
.and_then(|v| v.as_str())
.map(String::from),
neurons_per_voxel,
postsynaptic_current,
postsynaptic_current_max,
plasticity_constant: area
.properties
.get("plasticity_constant")
.and_then(|v| v.as_f64())
.unwrap_or(0.0),
degeneration: area
.properties
.get("degeneration")
.and_then(|v| v.as_f64())
.unwrap_or(0.0),
psp_uniform_distribution: area
.properties
.get("psp_uniform_distribution")
.and_then(|v| v.as_bool())
.unwrap_or(false),
mp_driven_psp,
firing_threshold,
firing_threshold_increment,
firing_threshold_limit: area
.properties
.get("firing_threshold_limit")
.and_then(|v| v.as_f64())
.unwrap_or(1.0),
consecutive_fire_count: area
.properties
.get("consecutive_fire_count")
.and_then(|v| v.as_u64())
.map(|u| u as u32)
.unwrap_or(0),
snooze_period: area
.properties
.get("snooze_period")
.and_then(|v| v.as_u64())
.map(|u| u as u32)
.unwrap_or(0),
refractory_period: area
.properties
.get("refractory_period")
.and_then(|v| v.as_u64())
.map(|u| u as u32)
.unwrap_or(0),
leak_coefficient,
leak_variability: area
.properties
.get("leak_variability")
.and_then(|v| v.as_f64())
.unwrap_or(0.0),
mp_charge_accumulation,
neuron_excitability,
burst_engine_active: true, init_lifespan,
lifespan_growth_rate,
longterm_mem_threshold,
temporal_depth,
properties: area.properties.clone(),
cortical_subtype: cortical_subtype_field,
encoding_type: None,
encoding_format: None,
unit_id: wasm_cortical_unit_index,
subunit_id: wasm_subunit_id,
group_id: wasm_cortical_unit_index,
coding_signage: None,
coding_behavior: None,
coding_type: None,
coding_options: None,
parent_region_id: None, dev_count: None,
cortical_dimensions_per_device: None,
visualization_voxel_granularity: None,
}
}
}
#[async_trait]
impl ConnectomeService for WasmConnectomeService {
async fn create_cortical_area(
&self,
_params: CreateCorticalAreaParams,
) -> ServiceResult<CorticalAreaInfo> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn update_cortical_area(
&self,
_cortical_id: &str,
_params: UpdateCorticalAreaParams,
) -> ServiceResult<CorticalAreaInfo> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn delete_cortical_area(&self, _cortical_id: &str) -> ServiceResult<()> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn get_cortical_area(&self, cortical_id: &str) -> ServiceResult<CorticalAreaInfo> {
let cortical_id_parsed = CorticalID::try_from_base_64(cortical_id).map_err(|_| {
ServiceError::InvalidInput(format!("Invalid cortical ID format: {}", cortical_id))
})?;
let area = self
.genome
.cortical_areas
.get(&cortical_id_parsed)
.ok_or_else(|| ServiceError::NotFound {
resource: "cortical_area".to_string(),
id: cortical_id.to_string(),
})?;
Ok(self.area_to_info(&cortical_id_parsed, area))
}
async fn list_cortical_areas(&self) -> ServiceResult<Vec<CorticalAreaInfo>> {
let areas: Vec<CorticalAreaInfo> = self
.genome
.cortical_areas
.iter()
.map(|(id, area)| self.area_to_info(id, area))
.collect();
Ok(areas)
}
async fn get_cortical_area_ids(&self) -> ServiceResult<Vec<String>> {
Ok(self
.genome
.cortical_areas
.keys()
.map(|id| id.to_string())
.collect::<Vec<_>>())
}
async fn cortical_area_exists(&self, cortical_id: &str) -> ServiceResult<bool> {
let cortical_id_parsed = CorticalID::try_from_base_64(cortical_id).map_err(|_| {
ServiceError::InvalidInput(format!("Invalid cortical ID format: {}", cortical_id))
})?;
Ok(self.genome.cortical_areas.contains_key(&cortical_id_parsed))
}
async fn get_cortical_area_properties(
&self,
cortical_id: &str,
) -> ServiceResult<std::collections::HashMap<String, serde_json::Value>> {
let cortical_id_parsed = CorticalID::try_from_base_64(cortical_id).map_err(|_| {
ServiceError::InvalidInput(format!("Invalid cortical ID format: {}", cortical_id))
})?;
let area = self
.genome
.cortical_areas
.get(&cortical_id_parsed)
.ok_or_else(|| ServiceError::NotFound {
resource: "cortical_area".to_string(),
id: cortical_id.to_string(),
})?;
Ok(area.properties.clone())
}
async fn get_all_cortical_area_properties(
&self,
) -> ServiceResult<Vec<std::collections::HashMap<String, serde_json::Value>>> {
Ok(self
.genome
.cortical_areas
.values()
.map(|area| area.properties.clone())
.collect())
}
async fn create_brain_region(
&self,
_params: CreateBrainRegionParams,
) -> ServiceResult<BrainRegionInfo> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn delete_brain_region(&self, _region_id: &str) -> ServiceResult<()> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn update_brain_region(
&self,
_region_id: &str,
_properties: std::collections::HashMap<String, serde_json::Value>,
) -> ServiceResult<BrainRegionInfo> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn get_brain_region(&self, region_id: &str) -> ServiceResult<BrainRegionInfo> {
let _region =
self.genome
.brain_regions
.get(region_id)
.ok_or_else(|| ServiceError::NotFound {
resource: "brain_region".to_string(),
id: region_id.to_string(),
})?;
Err(ServiceError::NotImplemented(
"Brain region conversion not yet implemented".to_string(),
))
}
async fn list_brain_regions(&self) -> ServiceResult<Vec<BrainRegionInfo>> {
Err(ServiceError::NotImplemented(
"Brain region listing not yet implemented".to_string(),
))
}
async fn get_brain_region_ids(&self) -> ServiceResult<Vec<String>> {
Ok(self.genome.brain_regions.keys().cloned().collect())
}
async fn brain_region_exists(&self, region_id: &str) -> ServiceResult<bool> {
Ok(self.genome.brain_regions.contains_key(region_id))
}
async fn get_root_region_id(&self) -> ServiceResult<Option<String>> {
Ok(self.genome.brain_regions_root.clone())
}
async fn get_morphologies(
&self,
) -> ServiceResult<std::collections::HashMap<String, MorphologyInfo>> {
Err(ServiceError::NotImplemented(
"Morphology extraction not yet implemented".to_string(),
))
}
async fn create_morphology(
&self,
_morphology_id: String,
_morphology: feagi_evolutionary::Morphology,
) -> ServiceResult<()> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn update_morphology(
&self,
_morphology_id: String,
_morphology: feagi_evolutionary::Morphology,
) -> ServiceResult<()> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn delete_morphology(&self, _morphology_id: &str) -> ServiceResult<()> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn rename_morphology(&self, _old_id: &str, _new_id: &str) -> ServiceResult<()> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
async fn update_cortical_mapping(
&self,
_src_area_id: String,
_dst_area_id: String,
_mapping_data: Vec<serde_json::Value>,
) -> ServiceResult<usize> {
Err(ServiceError::NotImplemented(
"WASM mode is read-only".to_string(),
))
}
}