diff --git a/litellm/router_strategy/complexity_router/config.py b/litellm/router_strategy/complexity_router/config.py index fc1ad739903..7c47bac68da 100644 --- a/litellm/router_strategy/complexity_router/config.py +++ b/litellm/router_strategy/complexity_router/config.py @@ -616,7 +616,7 @@ class CapabilityCalibrationConfig(BaseModel): class CapabilityClassifierConfig(BaseModel): """Switchyard-compatible probability threshold policy for two model tiers.""" - model_config = ConfigDict(frozen=True) + model_config = ConfigDict(extra="forbid", frozen=True) efficient_tier: str = Field( description="Tier used when the efficient model's forecasted solve probability meets the adjusted threshold", diff --git a/tests/test_litellm/router_strategy/test_complexity_router.py b/tests/test_litellm/router_strategy/test_complexity_router.py index 8dbd36087b5..38411ef52ea 100644 --- a/tests/test_litellm/router_strategy/test_complexity_router.py +++ b/tests/test_litellm/router_strategy/test_complexity_router.py @@ -2500,6 +2500,17 @@ class TestCapabilityClassifierConfig: with pytest.raises(ValidationError, match="requires classifier_type 'capability'"): ComplexityRouterConfig(**config) + def test_rejects_misspelled_optional_policy_instead_of_using_defaults(self) -> None: + with pytest.raises(ValidationError, match="threshold_steps"): + CapabilityClassifierConfig.model_validate( + { + "efficient_tier": "SIMPLE", + "capable_tier": "REASONING", + "base_threshold": 0.5, + "threshold_steps": 0.2, + } + ) + def test_threshold_defaults_match_switchyard(self): config = CapabilityClassifierConfig(efficient_tier=" SIMPLE ", capable_tier=" REASONING ", base_threshold=0.5) assert config.efficient_tier == "SIMPLE"