diff --git a/litellm/router.py b/litellm/router.py index fc9743ff43d..47428a68b9e 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -10890,6 +10890,7 @@ class Router: "allowed_fails", "cooldown_time", "num_retries", + "max_fallbacks", "timeout", "max_retries", "retry_after", @@ -10928,6 +10929,7 @@ class Router: "allowed_fails", "cooldown_time", "num_retries", + "max_fallbacks", "timeout", "max_retries", "retry_after", @@ -10944,6 +10946,7 @@ class Router: _int_settings: Final = [ "timeout", "num_retries", + "max_fallbacks", "retry_after", "allowed_fails", "cooldown_time", diff --git a/litellm/types/router.py b/litellm/types/router.py index d4c735387a5..4a9bda01056 100644 --- a/litellm/types/router.py +++ b/litellm/types/router.py @@ -117,6 +117,7 @@ class UpdateRouterConfig(BaseModel): allowed_fails: int | None = None cooldown_time: float | None = None num_retries: int | None = None + max_fallbacks: int | None = None timeout: float | None = None max_retries: int | None = None retry_after: float | None = None diff --git a/tests/test_litellm/test_router_retry_policy_update.py b/tests/test_litellm/test_router_retry_policy_update.py index 1b98b8c1ae8..ccf378e0650 100644 --- a/tests/test_litellm/test_router_retry_policy_update.py +++ b/tests/test_litellm/test_router_retry_policy_update.py @@ -44,6 +44,13 @@ def test_update_router_config_exposes_retry_policy_field(): assert "retry_policy" in UpdateRouterConfig.model_fields +def test_update_router_config_preserves_max_fallbacks(): + value = 10 + config = UpdateRouterConfig(max_fallbacks=value) + + assert config.model_dump(exclude_none=True)["max_fallbacks"] == value + + def test_update_router_config_accepts_retry_policy_payload(): """The exact payload the Admin UI Model Retry Settings tab sends must round-trip through the schema's ``dict(exclude_none=True)`` form, since @@ -122,6 +129,14 @@ def test_update_settings_persists_retry_policy_dict(): assert router.retry_policy.TimeoutErrorRetries == 3 +def test_update_settings_applies_max_fallbacks(): + router = _build_router() + + router.update_settings(max_fallbacks=10) + + assert router.max_fallbacks == 10 + + def test_update_settings_accepts_retry_policy_object_unchanged(): """A pre-built ``RetryPolicy`` instance must pass through verbatim so callers that already constructed one (e.g. tests or programmatic diff --git a/ui/litellm-dashboard/src/lib/http/schema.d.ts b/ui/litellm-dashboard/src/lib/http/schema.d.ts index 3d657ea53a7..a1b781c1c93 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -35338,6 +35338,8 @@ export interface components { fallbacks?: { [key: string]: unknown; }[] | null; + /** Max Fallbacks */ + max_fallbacks?: number | null; /** Max Retries */ max_retries?: number | null; /** Model Group Affinity Config */