fix(router): ignore blocked siblings when checking team model cooldown alternatives

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
yassin 2026-09-13 09:35:54 +00:00
parent d0a846c8be
commit 9080f0904a
3 changed files with 25 additions and 3 deletions

View file

@ -1561,7 +1561,9 @@ class Router:
public_model_name: Final = deployment.model_info.team_public_model_name
if team_id is None or public_model_name is None:
return False
return len(self.team_model_to_deployment_indices.get((team_id, public_model_name)) or ()) > 1
sibling_indices: Final = self.team_model_to_deployment_indices.get((team_id, public_model_name)) or ()
routable_siblings: Final = self._filter_blocked_deployments([self.model_list[idx] for idx in sibling_indices])
return len(routable_siblings) > 1
_OVERRIDABLE_ROUTING_STRATEGIES: frozenset[str] = frozenset({"simple-shuffle", *_DEFAULT_SELECTOR_ATTR_BY_STRATEGY})

View file

@ -440,7 +440,7 @@ class TestRoutingGroupCooldownAlternatives:
class TestTeamModelCooldownAlternatives:
def _router(self, team_deployments: int):
def _router(self, team_deployments: int, blocked_ids: frozenset[str] = frozenset()):
from litellm import Router
return Router(
@ -452,6 +452,7 @@ class TestTeamModelCooldownAlternatives:
"id": f"team-deploy-{i}",
"team_id": "team-1",
"team_public_model_name": "team-gpt-4o-mini",
"blocked": f"team-deploy-{i}" in blocked_ids,
},
}
for i in range(team_deployments)
@ -487,3 +488,18 @@ class TestTeamModelCooldownAlternatives:
)
is False
)
def test_429_with_only_a_blocked_sibling_keeps_single_deployment_exemption(self):
from litellm.router_utils.cooldown_handlers import _should_cooldown_deployment
router = self._router(team_deployments=2, blocked_ids=frozenset({"team-deploy-1"}))
assert (
_should_cooldown_deployment(
litellm_router_instance=router,
deployment="team-deploy-0",
exception_status=429,
original_exception=Exception("rate limited"),
requested_model_group="team-gpt-4o-mini",
)
is False
)

View file

@ -897,7 +897,7 @@ def test_arouter_test_team_model():
def test_team_model_has_alternatives():
def team_deployment(deployment_id: str, team_id: str, public_model_name: str):
def team_deployment(deployment_id: str, team_id: str, public_model_name: str, blocked: bool = False):
return {
"model_name": f"model_name_{team_id}_{deployment_id}",
"litellm_params": {"model": "openai/gpt-4o-mini", "api_key": "sk-test"},
@ -905,6 +905,7 @@ def test_team_model_has_alternatives():
"id": deployment_id,
"team_id": team_id,
"team_public_model_name": public_model_name,
"blocked": blocked,
},
}
@ -914,6 +915,8 @@ def test_team_model_has_alternatives():
team_deployment("team-a-2", "team-a", "shared-model"),
team_deployment("team-a-solo", "team-a", "solo-model"),
team_deployment("team-b-1", "team-b", "shared-model"),
team_deployment("team-c-1", "team-c", "paused-sibling-model"),
team_deployment("team-c-paused", "team-c", "paused-sibling-model", blocked=True),
{
"model_name": "plain-model",
"litellm_params": {"model": "openai/gpt-4o-mini", "api_key": "sk-test"},
@ -926,6 +929,7 @@ def test_team_model_has_alternatives():
assert router.team_model_has_alternatives("team-a-2") is True
assert router.team_model_has_alternatives("team-a-solo") is False
assert router.team_model_has_alternatives("team-b-1") is False
assert router.team_model_has_alternatives("team-c-1") is False
assert router.team_model_has_alternatives("plain-1") is False
assert router.team_model_has_alternatives("missing-deployment") is False