fix(cost): validate route_down hint against model routes

This commit is contained in:
argenis de la rosa 2026-02-28 23:45:42 -05:00 committed by Argenis
parent 4043056332
commit 4e70abf407

View File

@ -7829,6 +7829,36 @@ impl Config {
if self.cost.enforcement.reserve_percent > 100 {
anyhow::bail!("cost.enforcement.reserve_percent must be between 0 and 100");
}
if matches!(self.cost.enforcement.mode, CostEnforcementMode::RouteDown) {
let route_down_model = self
.cost
.enforcement
.route_down_model
.as_deref()
.map(str::trim)
.filter(|model| !model.is_empty())
.ok_or_else(|| {
anyhow::anyhow!(
"cost.enforcement.route_down_model must be set when mode is route_down"
)
})?;
if let Some(route_hint) = route_down_model
.strip_prefix("hint:")
.map(str::trim)
.filter(|hint| !hint.is_empty())
{
if !self
.model_routes
.iter()
.any(|route| route.hint.trim() == route_hint)
{
anyhow::bail!(
"cost.enforcement.route_down_model uses hint '{route_hint}', but no matching [[model_routes]] entry exists"
);
}
}
}
// Scheduler
if self.scheduler.max_concurrent == 0 {
@ -13848,4 +13878,36 @@ reserve_percent = 15
.expect_err("expected cost.enforcement.reserve_percent validation failure");
assert!(err.to_string().contains("cost.enforcement.reserve_percent"));
}
#[test]
async fn validation_rejects_route_down_hint_without_matching_route() {
let mut config = Config::default();
config.cost.enforcement.mode = CostEnforcementMode::RouteDown;
config.cost.enforcement.route_down_model = Some("hint:fast".to_string());
let err = config
.validate()
.expect_err("route_down hint should require a matching model route");
assert!(err
.to_string()
.contains("cost.enforcement.route_down_model uses hint 'fast'"));
}
#[test]
async fn validation_accepts_route_down_hint_with_matching_route() {
let mut config = Config::default();
config.cost.enforcement.mode = CostEnforcementMode::RouteDown;
config.cost.enforcement.route_down_model = Some("hint:fast".to_string());
config.model_routes = vec![ModelRouteConfig {
hint: "fast".to_string(),
provider: "openrouter".to_string(),
model: "openai/gpt-4.1-mini".to_string(),
api_key: None,
max_tokens: None,
transport: None,
}];
config
.validate()
.expect("matching route_down hint route should validate");
}
}