diff --git a/litellm/router.py b/litellm/router.py index 714463e6953..7c01efa7461 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -10908,6 +10908,7 @@ class Router: "allowed_fails", "cooldown_time", "num_retries", + "max_fallbacks", "timeout", "max_retries", "retry_after", @@ -10946,6 +10947,7 @@ class Router: "allowed_fails", "cooldown_time", "num_retries", + "max_fallbacks", "timeout", "max_retries", "retry_after", @@ -10962,6 +10964,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 97bd93f3f47..5b8fc784444 100644 --- a/litellm/types/router.py +++ b/litellm/types/router.py @@ -120,6 +120,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 9df7d8baba7..6fb3af6ffef 100644 --- a/ui/litellm-dashboard/src/lib/http/schema.d.ts +++ b/ui/litellm-dashboard/src/lib/http/schema.d.ts @@ -36608,6 +36608,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 */