scoring: rebalance consolidation plan using Elo ratings
After health metrics compute the total agent budget, read agent-elo.json and redistribute proportionally to Elo ratings. Higher-rated agent types get more runs. Health determines HOW MUCH work. Elo determines WHAT KIND. Every type gets at least 1 run. If no Elo file exists, falls back to the existing hardcoded allocation. Co-Authored-By: Kent Overstreet <kent.overstreet@linux.dev>
This commit is contained in:
parent
c959b2c964
commit
e9791991a7
1 changed files with 43 additions and 0 deletions
|
|
@ -358,6 +358,49 @@ fn consolidation_plan_inner(store: &Store, detect_interf: bool) -> Consolidation
|
||||||
nodes_per_community));
|
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::<std::collections::HashMap<String, f64>>(&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<f64> = 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<f64> = 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
|
plan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue