mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-13 23:11:40 +00:00
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>
This commit is contained in:
parent
70eb4e5d00
commit
5094645a82
2 changed files with 65 additions and 2 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue