litellm/tests/unit/caching
devin-ai-integration[bot] 8226b2be9a
fix(otel): report cache hits at zero cost with a cache-hit flag in V1 and V2 spans (#43604)
* fix(litellm): report zero cost and cache-hit attrs on cache-served spans

* fix(litellm): stamp cache-hit marker on HiddenParams carriers and restore probe side effects

gauntlet-mini on ace57d25f verified two live gaps. TextCompletionResponse and
ResponsesAPIResponse carry _hidden_params as a HiddenParams object, so the
dict-gated marker write skipped them and the served hit still stamped the full
price. The marker write is now container-agnostic, which it already was for the
partial-embedding stamp, and a regression test exercises the carrier end to end.
_uncached_response_cost also restores billed_token_rates, zero_cost_warned, and
the response_cost_failure_debug_information key alongside cost_breakdown, so the
probe leaves no pricing state on the call it reads.

* test(caching): cover cache-hit marker on HiddenParams carriers through the caching handler

* fix(logging): keep the uncached price probe's restores to the state it can leak

* fix(otel): emit V2 LLM-call span for cache hits with explicit cache attributes

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(otel): read cache payload fields defensively without casts

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* chore(otel): clarify pyright suppression reason on cache payload reads

Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>

* fix(otel): build the cache-hit view from typing_extensions.TypedDict so import works on Python 3.10 and 3.11

* fix(otel): report cache hits at zero cost everywhere and mark misses

Cache hits now carry a zero cost breakdown and a zero hidden response cost,
the /v1/messages hit cost header follows chat and responses hits, every span
carries litellm.cache_hit, V2 hit spans drop server.address, an async hit keeps
the provider-prefixed model name, and the V2 attribute budget counts preset keys

* fix(otel): send a 0 cost header on cache hits and keep hits out of deployment TPM

Cache hits now send x-litellm-response-cost: 0.0 on chat, responses and
/v1/messages, while a fresh call whose cost is 0 still sends no header.

The async hit path stamps the same model name as main again. Stamping the
provider-prefixed name made a hit's tokens count toward the deployment's
TPM limit, so repeated cached requests hit 429s under usage-based routing.

Drop comments that restated fields and annotate new test values as Final.

* fix(otel): keep the served pricing basis on a cache hit's cost breakdown

A hit's breakdown now keeps service_tier, data_residency, vertex_location, and the discount and margin rates the served call recorded, with every amount at 0, so savings reports still read the basis. The hit header test now drives the live non-streaming header path.

* fix(otel): send zero breakdown headers on a cache hit and give hit spans a fresh call's cost keys

A hit's x-litellm-response-cost-original, -input, and -output headers now read 0.0 instead of going missing or carrying the full price. A hit's cost breakdown now comes from pricing the response as fresh, so every route exports the same keys, pricing basis, and rates with every amount at 0.

* test(integration): assert zero cost and the cache-hit flag on cache-served OTel V1 and V2 spans

* test: wait for the cache entry before the cache-hit request and build cost headers without a route_request double

* test: annotate the new cache-hit unit test locals with Final

---------

Co-authored-by: shrey kharbanda <shreshth@berri.ai>
Co-authored-by: jesus <jesus@berri.ai>
Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
2026-10-17 18:25:32 +00:00
..
__init__.py ci: move caching, proxy-extras, gateway and enterprise tests into tests/unit and run them from litellm-tests (#42902) 2026-09-24 15:49:59 -07:00
test_azure_blob_cache.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_cache_preset_key.py ci: move caching, proxy-extras, gateway and enterprise tests into tests/unit and run them from litellm-tests (#42902) 2026-09-24 15:49:59 -07:00
test_caching.py feat(gemini): allow disabling thought summaries while keeping thinking on (#36460) 2026-10-16 09:01:33 +00:00
test_caching_handler.py fix(otel): report cache hits at zero cost with a cache-hit flag in V1 and V2 spans (#43604) 2026-10-17 18:25:32 +00:00
test_check_and_fix_namespace_none_guard.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_disk_cache.py test: migrate legacy unit dirs and unrun folders into tests/unit, tests/integration and tests/e2e (#45940) 2026-10-11 06:24:57 -07:00
test_dual_cache.py fix(caching): make Redis Cluster commands wait for a pool slot instead of tripping the circuit breaker (#46488) 2026-10-14 15:27:00 -07:00
test_embedding_router.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_evicted_client_closer.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_gcs_cache.py test: migrate legacy unit dirs and unrun folders into tests/unit, tests/integration and tests/e2e (#45940) 2026-10-11 06:24:57 -07:00
test_in_memory_cache.py fix(router): keep the prompt caching affinity pin alive as long as the prefix's cache_control ttl (#46084) 2026-10-14 21:10:09 -07:00
test_llm_caching_handler.py refactor(llms): expose public names for private provider helpers (#45037) 2026-10-07 08:49:25 -07:00
test_llm_client_cache_e2e.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_qdrant_semantic_cache.py refactor(llms): expose public names for private provider helpers (#45037) 2026-10-07 08:49:25 -07:00
test_redis_batch.py fix(otel): nest cache spans under their operation and name service spans by purpose (#44150) 2026-10-03 09:20:27 -07:00
test_redis_cache.py test(caching): baseline breaker metrics from live state after gc (#46652) 2026-10-15 05:53:30 -07:00
test_redis_cluster_cache.py fix(caching): make Redis Cluster commands wait for a pool slot instead of tripping the circuit breaker (#46488) 2026-10-14 15:27:00 -07:00
test_redis_cluster_node_isolation.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_redis_connection_pool.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00
test_redis_semantic_cache.py fix(caching): skip the cache past max_messages and keep tool_result text in semantic prompts (#43878) 2026-10-07 17:32:39 +00:00
test_request_redis_batch_post_call.py refactor(proxy): expose public names for private proxy helpers (#45170) 2026-10-07 18:59:27 -07:00
test_request_redis_batch_pre_call.py fix: cap cold MCP schema workers at usable CPUs and deflake wall-clock unit tests (#45791) 2026-10-15 00:47:59 -07:00
test_responses_stream_cache_keys.py refactor: expose core private helpers under public names (#44871) 2026-10-07 00:05:27 +00:00
test_s3_cache.py test: move routing, caching and callback tests out of local_testing (#45761) 2026-10-10 09:33:09 -07:00
test_unit_test_caching.py refactor: expose core private helpers under public names (#44871) 2026-10-07 00:05:27 +00:00
test_valkey_semantic_cache.py test: move tests/test_litellm core utils, routing, responses, caching and rust_bridge into tests/unit (#43199) 2026-09-25 17:10:13 -07:00