use feagi_api::transports::http::server::{create_http_server, ApiState};
use feagi_brain_development::ConnectomeManager;
use feagi_npu_burst_engine::{BurstLoopRunner, RustNPU};
use feagi_observability::{init_logging, parse_debug_flags};
use feagi_services::impls::{
AnalyticsServiceImpl, ConnectomeServiceImpl, GenomeServiceImpl, NeuronServiceImpl,
RuntimeServiceImpl, SystemServiceImpl,
};
use feagi_services::traits::{
AnalyticsService, ConnectomeService, GenomeService, NeuronService, RuntimeService,
SystemService,
};
use parking_lot::RwLock;
use std::sync::Arc;
#[derive(Debug, Default)]
struct NpuTraceArgs {
enabled: bool,
synapse: bool,
dynamics: bool,
src: Option<String>,
dst: Option<String>,
neuron: Option<String>,
}
fn parse_npu_trace_args() -> NpuTraceArgs {
let mut out = NpuTraceArgs::default();
for arg in std::env::args() {
if arg == "--npu-trace" {
out.enabled = true;
out.synapse = true;
out.dynamics = true;
continue;
}
if arg == "--npu-trace-synapse" {
out.enabled = true;
out.synapse = true;
continue;
}
if arg == "--npu-trace-dynamics" {
out.enabled = true;
out.dynamics = true;
continue;
}
if let Some(v) = arg.strip_prefix("--npu-trace-src=") {
out.enabled = true;
out.src = Some(v.to_string());
continue;
}
if let Some(v) = arg.strip_prefix("--npu-trace-dst=") {
out.enabled = true;
out.dst = Some(v.to_string());
continue;
}
if let Some(v) = arg.strip_prefix("--npu-trace-neuron=") {
out.enabled = true;
out.neuron = Some(v.to_string());
continue;
}
}
out
}
fn apply_npu_trace_env(args: &NpuTraceArgs) {
if !args.enabled {
return;
}
if args.synapse {
std::env::set_var("FEAGI_NPU_TRACE_SYNAPSE", "1");
}
if args.dynamics {
std::env::set_var("FEAGI_NPU_TRACE_DYNAMICS", "1");
}
if let Some(v) = &args.src {
std::env::set_var("FEAGI_NPU_TRACE_SRC", v);
}
if let Some(v) = &args.dst {
std::env::set_var("FEAGI_NPU_TRACE_DST", v);
}
if let Some(v) = &args.neuron {
std::env::set_var("FEAGI_NPU_TRACE_NEURON", v);
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let npu_trace = parse_npu_trace_args();
apply_npu_trace_env(&npu_trace);
let mut debug_flags = parse_debug_flags();
if npu_trace.enabled {
debug_flags
.enabled_crates
.insert("feagi-npu-trace".to_string(), true);
}
let _logging_guard = init_logging(&debug_flags, None, None, None)?;
println!("🚀 FEAGI HTTP API Server - Starting...\n");
println!("📦 Initializing core components...");
let connectome = ConnectomeManager::instance();
println!("✅ Core components initialized\n");
println!("🔧 Creating service layer...");
let _genome_service = Arc::new(GenomeServiceImpl::new(connectome.clone()))
as Arc<dyn GenomeService + Send + Sync>;
let genome_service_impl = Arc::new(GenomeServiceImpl::new(connectome.clone()));
let current_genome = genome_service_impl.get_current_genome_arc();
let genome_service = genome_service_impl as Arc<dyn GenomeService + Send + Sync>;
let connectome_service = Arc::new(ConnectomeServiceImpl::new(
connectome.clone(),
current_genome.clone(),
)) as Arc<dyn ConnectomeService + Send + Sync>;
let neuron_service = Arc::new(NeuronServiceImpl::new(connectome.clone()))
as Arc<dyn NeuronService + Send + Sync>;
let analytics_service = Arc::new(AnalyticsServiceImpl::new(
connectome.clone(),
None, )) as Arc<dyn AnalyticsService + Send + Sync>;
struct DummyViz;
impl feagi_npu_burst_engine::VisualizationPublisher for DummyViz {
fn publish_raw_fire_queue_for_agent(
&self,
_agent_id: &str,
_fire_data: feagi_npu_burst_engine::RawFireQueueSnapshot,
) -> Result<(), String> {
Ok(())
}
}
struct DummyMotor;
impl feagi_npu_burst_engine::MotorPublisher for DummyMotor {
fn publish_motor(&self, _agent_id: &str, _data: &[u8]) -> Result<(), String> {
Ok(())
}
}
use feagi_npu_burst_engine::backend::CPUBackend;
use feagi_npu_burst_engine::{DynamicNPU, TracingMutex};
use feagi_npu_runtime::StdRuntime;
let runtime = StdRuntime;
let backend = CPUBackend::new();
let npu_result = RustNPU::new(runtime, backend, 10, 10, 10).expect("Failed to create NPU");
let npu_for_runtime = Arc::new(TracingMutex::new(DynamicNPU::F32(npu_result), "NPU")); let burst_loop =
BurstLoopRunner::new::<DummyViz, DummyMotor>(npu_for_runtime, None, None, 30.0); let burst_runner_for_runtime = Arc::new(RwLock::new(burst_loop));
let runtime_service = Arc::new(RuntimeServiceImpl::new(burst_runner_for_runtime.clone()))
as Arc<dyn RuntimeService + Send + Sync>;
let mut version_info = feagi_services::types::VersionInfo::default();
version_info
.crates
.insert("example".to_string(), "1.0.0".to_string());
version_info.rust_version = "1.75".to_string();
version_info.build_timestamp = "example build".to_string();
let system_service = Arc::new(SystemServiceImpl::new(
connectome.clone(),
Some(burst_runner_for_runtime.clone()),
version_info,
)) as Arc<dyn SystemService + Send + Sync>;
println!("✅ Service layer created:");
println!(" - GenomeService");
println!(" - ConnectomeService");
println!(" - NeuronService");
println!(" - AnalyticsService");
println!(" - RuntimeService");
println!(" - SystemService\n");
println!("🌐 Creating API state...");
let feagi_session_timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.map(|d| d.as_millis() as i64)
.unwrap_or(0);
let (genome_transition_lock, genome_transition_in_progress) =
ApiState::init_genome_transition_controls();
let api_state = ApiState {
network_connection_info_provider: None,
agent_service: None,
analytics_service,
connectome_service,
genome_service,
neuron_service,
runtime_service,
system_service,
snapshot_service: None,
feagi_session_timestamp,
memory_stats_cache: None,
amalgamation_state: ApiState::init_amalgamation_state(),
genome_transition_lock,
genome_transition_in_progress,
#[cfg(feature = "feagi-agent")]
agent_handler: Some(ApiState::init_agent_registration_handler()),
};
println!(
"✅ API state created (FEAGI session: {})\n",
feagi_session_timestamp
);
let bind_address = "127.0.0.1:8000";
println!("🌐 Starting HTTP server on {}...", bind_address);
let app = create_http_server(api_state);
println!("✅ HTTP server configured\n");
println!("╔═══════════════════════════════════════════════════════════╗");
println!("║ FEAGI API SERVER READY ║");
println!("╠═══════════════════════════════════════════════════════════╣");
println!("║ ║");
println!(
"║ HTTP API: http://{} ║",
bind_address
);
println!(
"║ Swagger UI: http://{}/swagger-ui/ ║",
bind_address
);
println!(
"║ OpenAPI Spec: http://{}/openapi.json ║",
bind_address
);
println!("║ ║");
println!("║ Available Endpoints: ║");
println!("║ - GET /health ║");
println!("║ - GET /v1/genome/file_name ║");
println!("║ - POST /v1/genome/upload/barebones ║");
println!("║ - GET /v1/cortical_area/ipu ║");
println!("║ - GET /v1/cortical_area/cortical_area_id_list ║");
println!("║ - GET /v1/system/health_check ║");
println!("║ - GET /v1/system/readiness_check ║");
println!("║ ...and 50+ more endpoints ║");
println!("║ ║");
println!("╚═══════════════════════════════════════════════════════════╝\n");
let listener = tokio::net::TcpListener::bind(bind_address).await?;
axum::serve(listener, app).await?;
Ok(())
}