diff --git a/poc-memory/src/neuro/scoring.rs b/poc-memory/src/neuro/scoring.rs index 6cd0de6..2307a1b 100644 --- a/poc-memory/src/neuro/scoring.rs +++ b/poc-memory/src/neuro/scoring.rs @@ -358,6 +358,49 @@ fn consolidation_plan_inner(store: &Store, detect_interf: bool) -> Consolidation nodes_per_community)); } + // Rebalance using Elo ratings if available + let elo_path = crate::config::get().data_dir.join("agent-elo.json"); + if let Ok(elo_json) = std::fs::read_to_string(&elo_path) { + if let Ok(ratings) = serde_json::from_str::>(&elo_json) { + let total_budget = plan.replay_count + plan.linker_count + + plan.separator_count + plan.transfer_count + + plan.organize_count + plan.connector_count; + + if total_budget > 0 { + // Convert Elo to weights: subtract min, add 1 to avoid zero + let types = [ + "replay", "linker", "separator", "transfer", + "organize", "connector", + ]; + let elos: Vec = types.iter() + .map(|t| ratings.get(*t).copied().unwrap_or(1000.0)) + .collect(); + let min_elo = elos.iter().copied().fold(f64::MAX, f64::min); + let weights: Vec = elos.iter() + .map(|e| (e - min_elo + 100.0)) // shift so lowest gets 100 + .collect(); + let total_weight: f64 = weights.iter().sum(); + + let allocate = |w: f64| -> usize { + ((w / total_weight * total_budget as f64).round() as usize).max(1) + }; + + plan.replay_count = allocate(weights[0]); + plan.linker_count = allocate(weights[1]); + plan.separator_count = allocate(weights[2]); + plan.transfer_count = allocate(weights[3]); + plan.organize_count = allocate(weights[4]); + plan.connector_count = allocate(weights[5]); + + plan.rationale.push(format!( + "Elo rebalance (budget={}): replay={} linker={} separator={} transfer={} organize={} connector={}", + total_budget, + plan.replay_count, plan.linker_count, plan.separator_count, + plan.transfer_count, plan.organize_count, plan.connector_count)); + } + } + } + plan }