feagi-api 0.0.8

FEAGI REST API layer with HTTP and ZMQ transport adapters
Documentation
// Copyright 2025 Neuraville Inc.
// SPDX-License-Identifier: Apache-2.0

/*!
 * FEAGI v1 Simulation API
 *
 * Endpoints for simulation control and stimulation
 * Maps to Python: feagi/api/v1/simulation.py
 */

use crate::common::ApiState;
use crate::common::{ApiError, ApiResult, Json, State};
// Removed - using crate::common::State instead
use serde_json::{json, Value};
use std::collections::HashMap;

// ============================================================================
// SIMULATION CONTROL
// ============================================================================

/// Upload a stimulation script for neural activity simulation.
#[utoipa::path(
    post,
    path = "/v1/simulation/upload/string",
    tag = "simulation",
    responses(
        (status = 200, description = "Stimulation script uploaded", body = HashMap<String, String>),
        (status = 500, description = "Internal server error")
    )
)]
pub async fn post_stimulation_upload(
    State(_state): State<ApiState>,
    Json(request): Json<HashMap<String, Value>>,
) -> ApiResult<Json<HashMap<String, String>>> {
    // Validate stimulation script is provided
    let _script = request
        .get("stimulation_script")
        .ok_or_else(|| ApiError::invalid_input("Missing 'stimulation_script' field"))?;

    // TODO: Upload and apply stimulation script
    tracing::info!(target: "feagi-api", "Stimulation script upload requested");

    Ok(Json(HashMap::from([(
        "message".to_string(),
        "Stimulation script uploaded successfully".to_string(),
    )])))
}

/// Reset simulation state to initial conditions.
#[utoipa::path(
    post,
    path = "/v1/simulation/reset",
    tag = "simulation",
    responses(
        (status = 200, description = "Simulation reset", body = HashMap<String, String>),
        (status = 500, description = "Internal server error")
    )
)]
pub async fn post_reset(
    State(_state): State<ApiState>,
) -> ApiResult<Json<HashMap<String, String>>> {
    // TODO: Reset simulation state

    Ok(Json(HashMap::from([(
        "message".to_string(),
        "Simulation reset successfully".to_string(),
    )])))
}

/// Get simulation status including active state and running scripts.
#[utoipa::path(
    get,
    path = "/v1/simulation/status",
    tag = "simulation",
    responses(
        (status = 200, description = "Simulation status", body = HashMap<String, serde_json::Value>),
        (status = 500, description = "Internal server error")
    )
)]
pub async fn get_status(State(_state): State<ApiState>) -> ApiResult<Json<HashMap<String, Value>>> {
    // TODO: Retrieve simulation status
    let mut response = HashMap::new();
    response.insert("active".to_string(), json!(false));
    response.insert("stimulation_running".to_string(), json!(false));

    Ok(Json(response))
}

/// Get simulation statistics including total stimulations and active scripts.
#[utoipa::path(
    get,
    path = "/v1/simulation/stats",
    tag = "simulation",
    responses(
        (status = 200, description = "Simulation statistics", body = HashMap<String, serde_json::Value>),
        (status = 500, description = "Internal server error")
    )
)]
pub async fn get_stats(State(_state): State<ApiState>) -> ApiResult<Json<HashMap<String, Value>>> {
    // TODO: Retrieve simulation statistics
    let mut response = HashMap::new();
    response.insert("total_stimulations".to_string(), json!(0));
    response.insert("active_scripts".to_string(), json!(0));

    Ok(Json(response))
}

/// Configure simulation parameters and behavior settings.
#[utoipa::path(
    post,
    path = "/v1/simulation/config",
    tag = "simulation",
    responses(
        (status = 200, description = "Simulation configured", body = HashMap<String, String>),
        (status = 500, description = "Internal server error")
    )
)]
pub async fn post_config(
    State(_state): State<ApiState>,
    Json(_request): Json<HashMap<String, Value>>,
) -> ApiResult<Json<HashMap<String, String>>> {
    // TODO: Apply simulation configuration

    Ok(Json(HashMap::from([(
        "message".to_string(),
        "Simulation configured successfully".to_string(),
    )])))
}