From b706bf16f83a5c3daccb20b6152c304da2f144d1 Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Tue, 10 Nov 2026 12:11:51 -0800 Subject: [PATCH] revert: drop the LTS-only sync cache read changes This reverts dfc92ba4cd, d94be668d2 and c2ba33609a. Async speech now awaits the bridge, so the proxy reads the cache through the async path, which already honors s-maxage 0 and reads s-max-age first. The sync read goes back to the line's code, which matches main --- litellm/caching/caching.py | 4 +-- tests/unit/caching/test_caching.py | 47 ------------------------------ tests/unit/test_main.py | 1 - 3 files changed, 1 insertion(+), 51 deletions(-) diff --git a/litellm/caching/caching.py b/litellm/caching/caching.py index 8044a5d24e7..5f5b8210096 100644 --- a/litellm/caching/caching.py +++ b/litellm/caching/caching.py @@ -662,9 +662,7 @@ class Cache: cache_key = self.get_cache_key(**kwargs) if cache_key is not None: cache_control_args: Final[DynamicCacheControl] = kwargs.get("cache", {}) - max_age: Final = cache_control_args.get( - "s-max-age", cache_control_args.get("s-maxage", float("inf")) - ) + max_age = cache_control_args.get("s-maxage") or cache_control_args.get("s-max-age") or float("inf") cache_lookup_kwargs: Final = self._get_safe_cache_lookup_kwargs(kwargs) if dynamic_cache_object is not None: cached_result = dynamic_cache_object.get_cache(cache_key, **cache_lookup_kwargs) diff --git a/tests/unit/caching/test_caching.py b/tests/unit/caching/test_caching.py index b0ec0278034..91083921130 100644 --- a/tests/unit/caching/test_caching.py +++ b/tests/unit/caching/test_caching.py @@ -1437,53 +1437,6 @@ async def test_caching_with_cache_controls(monkeypatch: pytest.MonkeyPatch) -> N assert async_ttl_first.id == async_ttl_second.id -@pytest.mark.parametrize("max_age_key", ["s-maxage", "s-max-age"]) -def test_sync_completion_with_zero_s_maxage_skips_the_cached_response( - monkeypatch: pytest.MonkeyPatch, max_age_key: str -) -> None: - monkeypatch.setattr(litellm, "cache", Cache(type=LiteLLMCacheType.LOCAL)) - messages: Final = [{"role": "user", "content": f"zero s-maxage {uuid.uuid4().hex}"}] - first: Final = completion(model="gpt-4o-mini", messages=messages, mock_response="first") - zero_max_age: Final = completion( - model="gpt-4o-mini", messages=messages, cache={max_age_key: 0}, mock_response="second" - ) - open_max_age: Final = completion( - model="gpt-4o-mini", messages=messages, cache={max_age_key: 60}, mock_response="third" - ) - - assert zero_max_age.id != first.id - assert open_max_age.id == zero_max_age.id - - -@pytest.mark.asyncio -@pytest.mark.parametrize( - ("cache_controls", "serves_cached"), - [ - ({"s-maxage": 0, "s-max-age": 60}, True), - ({"s-maxage": 60, "s-max-age": 0}, False), - ({"s-maxage": None, "s-max-age": 0}, False), - ], -) -async def test_sync_and_async_completion_follow_s_max_age_when_both_max_age_keys_are_sent( - monkeypatch: pytest.MonkeyPatch, cache_controls: dict[str, int | None], serves_cached: bool -) -> None: - monkeypatch.setattr(litellm, "cache", Cache(type=LiteLLMCacheType.LOCAL)) - sync_messages: Final = [{"role": "user", "content": f"sync both max-age keys {uuid.uuid4().hex}"}] - sync_first: Final = completion(model="gpt-4o-mini", messages=sync_messages, mock_response="first") - sync_second: Final = completion( - model="gpt-4o-mini", messages=sync_messages, cache=cache_controls, mock_response="second" - ) - async_messages: Final = [{"role": "user", "content": f"async both max-age keys {uuid.uuid4().hex}"}] - async_first: Final = await acompletion(model="gpt-4o-mini", messages=async_messages, mock_response="first") - await asyncio.gather(*_PENDING_CACHE_WRITES) - async_second: Final = await acompletion( - model="gpt-4o-mini", messages=async_messages, cache=cache_controls, mock_response="second" - ) - - assert (sync_second.id == sync_first.id) is serves_cached - assert (async_second.id == async_first.id) is serves_cached - - @pytest.mark.asyncio async def test_embedding_caching_redis_ttl(monkeypatch: pytest.MonkeyPatch, redis_client_without_network: None) -> None: mock_pipeline: Final = AsyncMock() diff --git a/tests/unit/test_main.py b/tests/unit/test_main.py index 367a67dcfa1..ac22723de8f 100644 --- a/tests/unit/test_main.py +++ b/tests/unit/test_main.py @@ -5013,7 +5013,6 @@ async def test_speech_gemini_tts_behind_the_router_waits_as_long_as_the_same_cha [ ({}, {}, 1), ({}, {"cache": {"no-cache": True}}, 2), - ({}, {"cache": {"s-maxage": 0}}, 2), ({"cache": {"no-store": True}}, {}, 2), ({}, {"caching": False}, 2), ({}, {"caching": "yes"}, 2),