From 08d08191592b822396ad655b55d5b57a47449244 Mon Sep 17 00:00:00 2001 From: yucheng Date: Fri, 18 Sep 2026 19:39:15 +0000 Subject: [PATCH] fix(proxy): keep the resolved values of config-owned keys across SettingsStore.clear() Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- litellm/proxy/config_resolvers/settings_store.py | 4 +++- .../proxy/config_resolvers/test_settings_store.py | 10 ++++++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/litellm/proxy/config_resolvers/settings_store.py b/litellm/proxy/config_resolvers/settings_store.py index 49f5a833b8f..d4ca0e87d2b 100644 --- a/litellm/proxy/config_resolvers/settings_store.py +++ b/litellm/proxy/config_resolvers/settings_store.py @@ -89,7 +89,9 @@ class SettingsStore(MutableMapping[str, JsonValue]): def clear(self) -> None: self._deleted_runtime_keys = frozenset(key for key in self._keys() if not self.owned_by_config(key)) - self._runtime_values = _EMPTY_VALUES + self._runtime_values = MappingProxyType( + {key: value for key, value in self._runtime_values.items() if self.owned_by_config(key)} + ) def __iter__(self) -> Iterator[str]: return iter( diff --git a/tests/test_litellm/proxy/config_resolvers/test_settings_store.py b/tests/test_litellm/proxy/config_resolvers/test_settings_store.py index d59fb3e5b14..88ec382b013 100644 --- a/tests/test_litellm/proxy/config_resolvers/test_settings_store.py +++ b/tests/test_litellm/proxy/config_resolvers/test_settings_store.py @@ -172,14 +172,15 @@ def test_settings_store_refuses_a_runtime_write_to_a_config_owned_key() -> None: @pytest.mark.timeout(10) def test_settings_store_clear_removes_every_key_the_config_file_does_not_own() -> None: store: Final = SettingsStore("general_settings") - store.load_yaml({"master_key": "sk-config"}) + store.load_yaml({"master_key": "os.environ/MASTER_KEY"}) store.apply_db_row("general_settings", {"max_parallel_requests": 3, "alerting": ["slack"]}) + store.apply_runtime_values({"master_key": "sk-resolved", "alerting": ["slack"]}) store["allow_requests_on_db_unavailable"] = True del store["alerting"] store.clear() - assert dict(store) == {"master_key": "sk-config"} + assert dict(store) == {"master_key": "sk-resolved"} assert "alerting" not in store with pytest.raises(KeyError): store["max_parallel_requests"] @@ -203,13 +204,14 @@ def test_settings_store_clear_then_refill_matches_a_plain_dict() -> None: @pytest.mark.parametrize("clear", (False, True)) def test_settings_store_survives_a_patch_dict_round_trip_when_the_config_file_owns_a_key(clear: bool) -> None: store: Final = SettingsStore("general_settings") - store.load_yaml({"master_key": "sk-config"}) + store.load_yaml({"master_key": "os.environ/MASTER_KEY"}) store.apply_db_row("general_settings", {"max_parallel_requests": 3}) + store.apply_runtime_values({"master_key": "sk-resolved", "max_parallel_requests": 3}) before: Final = dict(store) with patch.dict(store, {"allow_requests_on_db_unavailable": True}, clear=clear): assert store["allow_requests_on_db_unavailable"] is True - assert store["master_key"] == "sk-config" + assert store["master_key"] == "sk-resolved" assert ("max_parallel_requests" in store) is not clear assert dict(store) == before