From 5094645a82b39536fa2ec50f32275b90a56ed20a Mon Sep 17 00:00:00 2001 From: unknown <> Date: Wed, 1 Jul 2026 03:33:06 +0000 Subject: [PATCH] fix: clear all strategy routers in clear_cache to prevent complexity_router disappearing after model update clear_cache() only cleared auto_routers but not complexity_routers, quality_routers, or adaptive_routers. After a model update, the complexity_router entry was still present so init_complexity_router_deployment raised ValueError("already exists") on re-add; with ignore_invalid_deployments=True the error was silently swallowed and the model vanished from /v2/model/info. Fixes #31694 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../model_management_endpoints.py | 5 +- .../test_model_management_endpoints.py | 62 ++++++++++++++++++- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/litellm/proxy/management_endpoints/model_management_endpoints.py b/litellm/proxy/management_endpoints/model_management_endpoints.py index afe71084a45..ab5e2697bb0 100644 --- a/litellm/proxy/management_endpoints/model_management_endpoints.py +++ b/litellm/proxy/management_endpoints/model_management_endpoints.py @@ -1715,8 +1715,11 @@ async def clear_cache(): for model_id in db_model_ids: llm_router.delete_deployment(id=model_id) - # Clear auto routers + # Clear all strategy routers so they are re-initialized from DB state llm_router.auto_routers.clear() + llm_router.complexity_routers.clear() + llm_router.quality_routers.clear() + llm_router.adaptive_routers.clear() # Reload only DB models await proxy_config.add_deployment(prisma_client=prisma_client, proxy_logging_obj=proxy_logging_obj) diff --git a/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py b/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py index 6a81b1b613b..a7a7f58ffd1 100644 --- a/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py +++ b/tests/test_litellm/proxy/management_endpoints/test_model_management_endpoints.py @@ -7,6 +7,7 @@ from unittest.mock import AsyncMock, MagicMock, patch import pytest from fastapi.testclient import TestClient +import litellm from litellm._uuid import uuid sys.path.insert( @@ -458,6 +459,12 @@ class TestClearCache: mock_router.delete_deployment = MagicMock(return_value=True) mock_router.auto_routers = MagicMock() mock_router.auto_routers.clear = MagicMock() + mock_router.complexity_routers = MagicMock() + mock_router.complexity_routers.clear = MagicMock() + mock_router.quality_routers = MagicMock() + mock_router.quality_routers.clear = MagicMock() + mock_router.adaptive_routers = MagicMock() + mock_router.adaptive_routers.clear = MagicMock() mock_config = MagicMock() mock_config.add_deployment = AsyncMock(return_value=True) @@ -479,8 +486,11 @@ class TestClearCache: mock_router.delete_deployment.assert_any_call(id="db-model-1") mock_router.delete_deployment.assert_any_call(id="db-model-2") - # Should have cleared auto routers + # Should have cleared all strategy routers mock_router.auto_routers.clear.assert_called_once() + mock_router.complexity_routers.clear.assert_called_once() + mock_router.quality_routers.clear.assert_called_once() + mock_router.adaptive_routers.clear.assert_called_once() # Should have called add_deployment to reload DB models mock_config.add_deployment.assert_called_once_with( @@ -488,6 +498,56 @@ class TestClearCache: ) + @pytest.mark.asyncio + async def test_clear_cache_complexity_router_survives_update(self): + """ + Regression test for #31694: after PATCH /model/{id}/update on an + auto_router/complexity_router model, the deployment must reappear + in the router. Before the fix, clear_cache only cleared auto_routers + but not complexity_routers, so init_complexity_router_deployment raised + ValueError("already exists") on re-add and the model silently vanished. + """ + router = litellm.Router( + model_list=[ + { + "model_name": "gpt-4o", + "litellm_params": {"model": "gpt-4o", "api_key": "fake"}, + "model_info": {"id": "dep-gpt4o"}, + }, + { + "model_name": "gpt-4o-mini", + "litellm_params": {"model": "gpt-4o-mini", "api_key": "fake"}, + "model_info": {"id": "dep-gpt4o-mini"}, + }, + ], + ignore_invalid_deployments=True, + ) + + complexity_dep = Deployment( + model_name="my-complexity-model", + litellm_params=LiteLLM_Params( + model="auto_router/complexity_router", + complexity_router_config={ + "tiers": {"SIMPLE": "gpt-4o-mini", "MODERATE": "gpt-4o", "COMPLEX": "gpt-4o"}, + }, + complexity_router_default_model="gpt-4o-mini", + ), + model_info={"id": "dep-complexity", "db_model": True}, + ) + router.add_deployment(deployment=complexity_dep) + + assert "my-complexity-model" in router.complexity_routers + assert router.get_deployment(model_id="dep-complexity") is not None + + router.delete_deployment(id="dep-complexity") + router.complexity_routers.clear() + + re_added = router.add_deployment(deployment=complexity_dep) + assert re_added is not None, "complexity_router deployment must be re-added after clearing" + assert "my-complexity-model" in router.complexity_routers + assert router.get_deployment(model_id="dep-complexity") is not None + + class TestUpdateModel: """ Tests for the update_model (POST /model/update) handler.