use super::*;
pub(super) async fn get_brain_weights(state: web::Data<NodeState>) -> HttpResponse {
let Some(soul_db) = &state.soul_db else {
return HttpResponse::ServiceUnavailable().json(serde_json::json!({"error": "no soul"}));
};
let brain = x402_soul::brain::load_brain(soul_db);
HttpResponse::Ok().json(serde_json::json!({
"weights": brain.to_json(),
"train_steps": brain.train_steps,
"param_count": brain.param_count(),
}))
}
#[derive(Deserialize)]
pub(crate) struct MergeDeltaRequest {
delta: String,
merge_rate: Option<f32>,
}
pub(super) async fn merge_brain_delta(
state: web::Data<NodeState>,
body: web::Json<MergeDeltaRequest>,
) -> HttpResponse {
let Some(soul_db) = &state.soul_db else {
return HttpResponse::ServiceUnavailable().json(serde_json::json!({"error": "no soul"}));
};
let delta: x402_soul::brain::WeightDelta = match serde_json::from_str(&body.delta) {
Ok(d) => d,
Err(e) => {
return HttpResponse::BadRequest()
.json(serde_json::json!({"error": format!("invalid delta: {e}")}));
}
};
let merge_rate = body.merge_rate.unwrap_or(0.5);
let mut brain = x402_soul::brain::load_brain(soul_db);
brain.merge_delta(&delta, merge_rate);
x402_soul::brain::save_brain(soul_db, &brain);
HttpResponse::Ok().json(serde_json::json!({
"merged": true,
"train_steps": brain.train_steps,
"source": delta.source_id,
}))
}
pub(super) async fn get_lessons(state: web::Data<NodeState>) -> HttpResponse {
let Some(soul_db) = &state.soul_db else {
return HttpResponse::ServiceUnavailable().json(serde_json::json!({"error": "no soul"}));
};
let outcomes: Vec<serde_json::Value> = soul_db
.get_recent_plan_outcomes(20)
.unwrap_or_default()
.into_iter()
.map(|o| {
serde_json::json!({
"goal": o.goal_description,
"status": o.status,
"error_category": o.error_category,
"lesson": o.lesson,
"steps_succeeded": o.steps_succeeded,
"steps_failed": o.steps_failed,
})
})
.collect();
let profile = x402_soul::capability::compute_profile(soul_db);
let benchmark = x402_soul::benchmark::load_score(soul_db);
let elo = x402_soul::elo::load_rating(soul_db);
let (collective_pass, collective_solved, collective_total) =
x402_soul::benchmark::collective_score(soul_db);
HttpResponse::Ok().json(serde_json::json!({
"outcomes": outcomes,
"capability_profile": serde_json::to_value(&profile).ok(),
"benchmark": {
"pass_at_1": benchmark.as_ref().map(|b| b.pass_at_1).unwrap_or(0.0),
"problems_attempted": benchmark.as_ref().map(|b| b.problems_attempted).unwrap_or(0),
"problems_passed": benchmark.as_ref().map(|b| b.problems_passed).unwrap_or(0),
"elo": elo,
},
"collective": {
"pass_at_1": collective_pass,
"unique_solved": collective_solved,
"total_problems": collective_total,
},
"multiagent": soul_db.get_state("benchmark_multiagent")
.ok().flatten()
.and_then(|s| serde_json::from_str::<serde_json::Value>(&s).ok()),
}))
}
pub(super) async fn set_model_override(
state: web::Data<NodeState>,
body: web::Json<serde_json::Value>,
) -> HttpResponse {
let soul_db = match state.soul_db.as_ref() {
Some(db) => db,
None => {
return HttpResponse::ServiceUnavailable()
.json(serde_json::json!({"error": "soul not active"}))
}
};
let model = body
.get("model")
.and_then(|v| v.as_str())
.map(|s| s.to_string());
match &model {
Some(m) => {
let _ = soul_db.set_state("model_override", m);
tracing::info!(model = %m, "Model override SET — turbo boost active");
}
None => {
let _ = soul_db.set_state("model_override", "");
tracing::info!("Model override CLEARED — back to default");
}
}
HttpResponse::Ok().json(serde_json::json!({
"model_override": model,
"status": if model.is_some() { "turbo" } else { "default" },
}))
}
pub(super) async fn get_model_status(state: web::Data<NodeState>) -> HttpResponse {
let soul_db = match state.soul_db.as_ref() {
Some(db) => db,
None => {
return HttpResponse::ServiceUnavailable()
.json(serde_json::json!({"error": "soul not active"}))
}
};
let override_model = soul_db
.get_state("model_override")
.ok()
.flatten()
.filter(|s| !s.is_empty());
let default_fast = std::env::var("GEMINI_MODEL_FAST")
.unwrap_or_else(|_| "gemini-3.1-flash-lite-preview".to_string());
let default_think =
std::env::var("GEMINI_MODEL_THINK").unwrap_or_else(|_| default_fast.clone());
HttpResponse::Ok().json(serde_json::json!({
"active_model": override_model.as_deref().unwrap_or(&default_fast),
"override": override_model,
"default_fast": default_fast,
"default_think": default_think,
"turbo": override_model.is_some(),
}))
}
pub(super) async fn get_transformer_status(state: web::Data<NodeState>) -> HttpResponse {
let soul_db = match state.soul_db.as_ref() {
Some(db) => db,
None => {
return HttpResponse::ServiceUnavailable()
.json(serde_json::json!({"error": "soul not active"}))
}
};
let status = x402_soul::model::status(soul_db);
HttpResponse::Ok().json(status)
}
pub(super) async fn get_transformer_weights(state: web::Data<NodeState>) -> HttpResponse {
let soul_db = match state.soul_db.as_ref() {
Some(db) => db,
None => {
return HttpResponse::ServiceUnavailable()
.json(serde_json::json!({"error": "soul not active"}))
}
};
let weights_json = x402_soul::model::export_weights(soul_db);
let status = x402_soul::model::status(soul_db);
HttpResponse::Ok().json(serde_json::json!({
"weights": weights_json,
"train_steps": status.train_steps,
"param_count": status.param_count,
}))
}
#[derive(Deserialize)]
pub(crate) struct TransformerMergeRequest {
delta: String,
merge_rate: Option<f32>,
}
pub(super) async fn merge_transformer_delta(
state: web::Data<NodeState>,
body: web::Json<TransformerMergeRequest>,
) -> HttpResponse {
let soul_db = match state.soul_db.as_ref() {
Some(db) => db,
None => {
return HttpResponse::ServiceUnavailable()
.json(serde_json::json!({"error": "soul not active"}))
}
};
let delta: x402_soul::model::TransformerDelta = match serde_json::from_str(&body.delta) {
Ok(d) => d,
Err(e) => {
return HttpResponse::BadRequest()
.json(serde_json::json!({"error": format!("invalid delta: {e}")}));
}
};
let merge_rate = body.merge_rate.unwrap_or(0.5);
x402_soul::model::merge_peer_delta(soul_db, &delta, merge_rate);
let status = x402_soul::model::status(soul_db);
HttpResponse::Ok().json(serde_json::json!({
"merged": true,
"train_steps": status.train_steps,
"source": delta.source_id,
}))
}