use crate::provider::ProviderRegistry;
use crate::session::delegation::DelegationState;
use crate::session::delegation_skills;
use crate::session::relevance::{Bucket, Dependency, Difficulty, ToolUse};
pub const ROLE_PLANNER: &str = "ralph_planner";
pub const ROLE_CODER: &str = "ralph_coder";
pub const ROLE_REVIEWER: &str = "ralph_reviewer";
pub const ROLE_TESTER: &str = "ralph_tester";
pub fn choose_provider_for_role(
registry: &ProviderRegistry,
state: &DelegationState,
role: &str,
default_provider: &str,
default_model: &str,
) -> (String, String) {
if !state.enabled() {
return (default_provider.to_string(), default_model.to_string());
}
let skill = skill_for_role(role);
let bucket = Bucket {
difficulty: difficulty_for_role(role),
dependency: Dependency::Isolated,
tool_use: tool_use_for_role(role),
};
let providers = registry.list();
let picked = state.rank_candidates(&providers, skill, bucket);
match picked {
Some(p) => {
tracing::info!(provider = %p, role = %role, "LCB selected provider for relay role");
(p.to_string(), default_model.to_string())
}
None => (default_provider.to_string(), default_model.to_string()),
}
}
fn skill_for_role(role: &str) -> &'static str {
match role {
"auto-coder" => ROLE_CODER,
"auto-reviewer" => ROLE_REVIEWER,
"auto-tester" => ROLE_TESTER,
_ => delegation_skills::MODEL_CALL,
}
}
fn difficulty_for_role(role: &str) -> Difficulty {
if role.contains("planner") || role.contains("reviewer") {
Difficulty::Medium
} else if role.contains("coder") {
Difficulty::Hard
} else {
Difficulty::Easy
}
}
fn tool_use_for_role(role: &str) -> ToolUse {
if role.contains("coder") || role.contains("tester") {
ToolUse::Yes
} else {
ToolUse::No
}
}