Skip to content

feat(caching): add valkey-semantic cache backend and fix semantic cache scope keys#30675

Merged
yassin-berriai merged 1 commit into
litellm_internal_stagingfrom
litellm_valkey_semantic_cache
Jun 20, 2026
Merged

feat(caching): add valkey-semantic cache backend and fix semantic cache scope keys#30675
yassin-berriai merged 1 commit into
litellm_internal_stagingfrom
litellm_valkey_semantic_cache

Conversation

@yassin-berriai

@yassin-berriai yassin-berriai commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Relevant issues

Resolves #29121
Docs: BerriAI/litellm-docs#377

Linear ticket

Resolves LIT-3760
Addresses LIT-3860 (semantic cache scope fix; redis/qdrant rollout tracked there)

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have added meaningful tests
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible; it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

Screenshots / Proof of Fix

Run against a live proxy talking to a real Valkey instance with the valkey-search vector module and real OpenAI APIs.

Valkey (valkey-search bundled):

docker run -d --name litfix-valkey -p 6385:6379 valkey/valkey-bundle:8.1
docker exec litfix-valkey valkey-cli MODULE LIST   # shows the "search" module loaded

Proxy config (litellm_settings.cache_params):

litellm_settings:
  cache: true
  cache_params:
    type: valkey-semantic
    host: "127.0.0.1"
    port: 6385
    similarity_threshold: 0.8
    valkey_semantic_cache_embedding_model: text-embedding-3-small
    valkey_semantic_cache_index_name: litellm_proxy_valkey_demo

Before this change, configuring type: valkey-semantic is unrecognized; the Cache builds no backend and the proxy crashes on startup:

File ".../litellm/proxy/proxy_server.py", line 3655, in _init_cache
    litellm.cache.cache, (RedisCache, RedisClusterCache)
AttributeError: 'Cache' object has no attribute 'cache'

After this change the proxy starts, builds the vector index on valkey-search, and serves a semantic cache hit. Sending the same request twice returns the same response id; the second call is served from Valkey with no new LLM call:

$ curl -s localhost:4000/v1/chat/completions -H "Authorization: Bearer $KEY" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"In exactly one sentence, describe the color of a clear daytime sky."}],"temperature":0}'
id: chatcmpl-DrpVbGn9QkpxyaYNVcIT3M5bqDaR7
answer: The color of a clear daytime sky is a vibrant, serene blue ...

$ curl -s localhost:4000/v1/chat/completions -H "Authorization: Bearer $KEY" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"In exactly one sentence, describe the color of a clear daytime sky."}],"temperature":0}'
id: chatcmpl-DrpVbGn9QkpxyaYNVcIT3M5bqDaR7
answer: The color of a clear daytime sky is a vibrant, serene blue ...

The data landed in valkey-search under the scoped index:

$ docker exec litfix-valkey valkey-cli FT._LIST
litellm_proxy_valkey_demo
$ docker exec litfix-valkey valkey-cli KEYS 'litellm_proxy_valkey_demo:*'
litellm_proxy_valkey_demo:99c85b81...:b5a3f3b5-...

E2E Testing in K8s

Elasticache
Screenshot 2026-06-19 at 1 26 10 PM
Proxy Config
Screenshot 2026-06-19 at 1 26 34 PM

Live semantic scope fix on the managed ElastiCache endpoint, deployed image litellm-pr-30675-c0198c0 (Valkey 9.0 over rediss://): a long prompt, then the same prompt with one word changed (meticulous -> careful). The reworded request returns the same response id in a fraction of the time, and the valkey-search index num_docs is unchanged across it, so it is a cache hit rather than a new store. Pre-fix this same reworded request missed with a new id, full latency, and a new document.

$ curl -s localhost:4000/v1/chat/completions -H "Authorization: Bearer $KEY" \
  -d '{"model":"gpt-5.4-mini","messages":[{"role":"user","content":"You are a meticulous technical writer. ... when running it in production."}]}'
"id":"chatcmpl-DscHT8ujqQjDEiLFepg6Jpg41jK3p"
HTTP 200  total=3.369638s

$ curl -s localhost:4000/v1/chat/completions -H "Authorization: Bearer $KEY" \
  -d '{"model":"gpt-5.4-mini","messages":[{"role":"user","content":"You are a careful technical writer. ... when running it in production."}]}'
"id":"chatcmpl-DscHT8ujqQjDEiLFepg6Jpg41jK3p"
HTTP 200  total=0.387151s

# FT.INFO litellm_proxy_valkey_demo -> num_docs 6 both before and after the reworded request

Semantic scope fix: reworded prompt now hits on all three backends

The scope fix lives in get_cache_key(), which every semantic backend filters on, so the same change fixes all three. It was verified end to end against each backend's real engine and real OpenAI, by sending a long prompt then the same prompt with one word changed (meticulous -> careful). In every case the reworded request returns the same response id in a fraction of the time with no new entry stored, a real cache hit. Pre-fix each of these produced a new id, full latency, and a new stored entry.

Backend Engine req2 paraphrase result
valkey-semantic local valkey/valkey-bundle and managed ElastiCache for Valkey 9.0 same id, served from cache hit, index doc count unchanged
redis-semantic redis-stack (RediSearch) same id, served from cache hit, doc count unchanged
qdrant-semantic qdrant/qdrant same id, served from cache hit, points count unchanged

Representative local run (valkey-semantic against valkey/valkey-bundle); the managed ElastiCache run is in the E2E Testing in K8s section above:

$ curl -s localhost:4001/v1/chat/completions -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"You are a meticulous technical writer. ... when running it in production."}]}'
"id":"chatcmpl-Dsc22r6wv8srgL4Cnybz9jQwj9GMp"
HTTP 200  total=3.454095s

$ curl -s localhost:4001/v1/chat/completions -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"You are a careful technical writer. ... when running it in production."}]}'
"id":"chatcmpl-Dsc22r6wv8srgL4Cnybz9jQwj9GMp"
HTTP 200  total=0.414303s

Cross-tenant isolation (two keys do not share a bucket) is covered by test_semantic_cache_key_isolates_tenants.

Type

🆕 New Feature

Changes

Adds a valkey-semantic cache type for semantic prompt caching on Valkey clusters running the valkey-search module, which is what AWS ElastiCache for Valkey exposes.

The existing redis-semantic backend cannot be pointed at valkey-search. It is built on RedisVL, which gates the connection on a RediSearch module version that valkey-search does not report, and whose SemanticCache index declares the prompt as a TEXT field that valkey-search does not implement. Both were confirmed against valkey/valkey-bundle: RedisVL raises RedisModuleVersionError on connect, and forcing past it fails index creation with Invalid field type for field 'prompt': Unknown argument 'TEXT'.

ValkeySemanticCache talks to valkey-search directly over redis-py instead. It creates the index from the field types valkey-search supports, a TAG field for caller scope and a VECTOR field (HNSW, cosine) for the prompt embedding, stores each entry as a hash, and retrieves with a KNN query filtered to the caller's scope. Prompt extraction, embedding generation, and cached-response parsing are inherited from RedisSemanticCache. The scope tag is a sha256 of the litellm cache key so it is always a valid, exact-match TAG token regardless of the key contents. The redis dependency is imported lazily in the cache dispatch, so import litellm still works on a base install without redis.

Connections resolve from VALKEY_HOST / VALKEY_PORT / VALKEY_PASSWORD, falling back to REDIS_*, and passwordless clusters are supported for IAM or no-auth setups. A full redis_url (including rediss:// for TLS) can be passed for ElastiCache encryption in transit.

There is no semantic-caching docs page in this repo to extend, so the configuration example lives in this PR for now.

Semantic cache scope fix

This PR also corrects how the semantic cache scope key is built, which previously made semantic caching behave like an exact-match cache. get_cache_key() hashed messages / prompt / input into the litellm_cache_key that all three semantic backends (redis-semantic, qdrant-semantic, valkey-semantic) filter their KNN search on, so a reworded prompt landed in a different bucket and never matched even when vector similarity was well above the threshold. For semantic cache types the prompt-bearing params are now excluded from the scope key and the server-set tenant identity (user_api_key, team, org) is appended instead, so embedding matching works within a tenant while cache entries stay scoped to the authenticated key / team / org. Because the change lives in get_cache_key() and the backends already filter on that key, it fixes redis-semantic and qdrant-semantic as well. Exact caches keep the prompt in their key and are unchanged.

Production configuration (TLS, topology)

Connections support TLS for managed endpoints: pass ssl: true alongside host and port to build a rediss:// URL, or pass a full redis_url. On AWS, vector search requires a node-based ElastiCache for Valkey 8.2+ cluster; a cluster-mode-disabled node group is the supported and recommended target, and a primary with read replicas is fine since only horizontal sharding is unsupported. ElastiCache Serverless does not support vector search. Multi-shard (cluster-mode-enabled) endpoints are rejected with a clear error, since the async client cannot route the FT.* search commands across shards.

@yassin-berriai

Copy link
Copy Markdown
Contributor Author

@greptileai

@CLAassistant

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch from 82b6063 to 6078a55 Compare June 17, 2026 18:49
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

@greptileai please review the latest commit

@codecov

codecov Bot commented Jun 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 86.51163% with 29 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
litellm/caching/valkey_semantic_cache.py 84.65% 29 Missing ⚠️

📢 Thoughts on this report? Let us know!

@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch from 6078a55 to fa04892 Compare June 17, 2026 19:02
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

@greptileai re-review latest commit (modernized type hints, valkey-search index-info override)

@greptile-apps

greptile-apps Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a new valkey-semantic cache backend (ValkeySemanticCache) that drives valkey-search directly over redis-py, bypassing RedisVL which is incompatible with valkey-search. It also changes get_cache_key() to exclude prompt-bearing parameters from the scope key for all semantic cache types and instead appends a tenant identity derived from proxy auth metadata.

  • New backend (valkey_semantic_cache.py): Clean implementation inheriting embedding extraction and response parsing from RedisSemanticCache; creates a HNSW vector index with a TAG scope field, stores entries as hashes, and retrieves with a KNN query filtered to the caller's scope tag. Redis is imported lazily (at dispatch time in caching.py) so the base SDK remains importable without redis installed.
  • Scope-key fix in caching.py: Excludes messages, prompt, and input from the hashed scope key for all three semantic cache types (REDIS_SEMANTIC, QDRANT_SEMANTIC, VALKEY_SEMANTIC) and appends user_api_key / team / org identity instead, so paraphrased prompts share a bucket while tenants remain isolated. This is the correct fix for semantic caching, but it applies retroactively to the two existing backends without a migration path, meaning all warm redis-semantic and qdrant-semantic caches become unreachable on upgrade.
  • Tests: Comprehensive mock-only unit tests covering URL building, dimension mismatch detection, TTL, threshold behaviour, async roundtrip, and the lazy-import invariant.

Confidence Score: 4/5

The new valkey-semantic backend is well-implemented, but the scope-key change in get_cache_key() silently invalidates the entire warm cache for all existing redis-semantic and qdrant-semantic deployments on upgrade.

The get_cache_key() modification removes prompt content from the hash and adds tenant scope for every semantic cache type. Existing redis-semantic and qdrant-semantic users will generate a different key format after upgrading, making all previously stored entries unreachable for the remainder of their TTL. The change is intentional and fixes a real bug, but it has no opt-in flag and no migration guidance, so the cold-cache impact is invisible to the operator upgrading a production system.

litellm/caching/caching.py — the get_cache_key() scope-key change and its reach across existing semantic cache backends.

Important Files Changed

Filename Overview
litellm/caching/caching.py Adds VALKEY_SEMANTIC dispatch to Cache.init and modifies get_cache_key() to exclude prompt params for ALL semantic cache types — a backwards-incompatible change for existing redis-semantic and qdrant-semantic users whose warm caches become unreachable on upgrade.
litellm/caching/valkey_semantic_cache.py New ValkeySemanticCache implementation talking directly to valkey-search over redis-py; clean design with lazy redis imports gated behind the lazy import in caching.py. Two previously-flagged issues (partial-client init path, _index_dim set unconditionally after already-exists) are tracked in prior review threads.
litellm/types/caching.py Adds VALKEY_SEMANTIC = "valkey-semantic" enum value; minimal and correct.
tests/test_litellm/caching/test_caching.py New unit tests for semantic scope-key logic; all use mocked/lazy Redis clients, no real network calls, good coverage of paraphrase bucketing, tenant isolation, model separation, and exact-cache regression.
tests/test_litellm/caching/test_valkey_semantic_cache.py Comprehensive mock-only unit tests for ValkeySemanticCache; covers URL building, dimension mismatch, TTL, threshold, async roundtrip, index info override, and the lazy-import guarantee via subprocess.

Reviews (7): Last reviewed commit: "feat(caching): add valkey-semantic cache..." | Re-trigger Greptile

Comment thread litellm/caching/valkey_semantic_cache.py Outdated
Comment thread litellm/caching/valkey_semantic_cache.py
@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch from fa04892 to 255d845 Compare June 17, 2026 19:23
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

Addressed both P2 findings in the latest commit (255d845):

  1. Partial-client construction: the constructor now resolves a URL only when a client is missing and builds just the absent one, so passing both clients needs no connection info and passing one builds the other from the resolved URL.

  2. Index dimension safety: _ensure_index_sync / _ensure_index_async no longer stamp _index_dim after swallowing "already exists". They read the existing index dimension from FT.INFO and raise a clear ValueError on mismatch (for example after switching embedding models), instead of silently failing later. Added unit tests for the mismatch, matching-dimension, FT.INFO parsing, and partial-client paths.

@greptileai please re-review

@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch from 255d845 to 53a8481 Compare June 17, 2026 19:39
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

Fixed the code-quality failure: _extract_index_dim no longer uses a recursive helper (the recursive_detector flagged it); it now flattens the FT.INFO field descriptors iteratively. Logic is unchanged and covered by the existing parsing test. @greptileai please re-review

@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch from 53a8481 to e4c8ffc Compare June 17, 2026 20:22
yassin-berriai added a commit to BerriAI/litellm-docs that referenced this pull request Jun 17, 2026
Adds setup docs for the new valkey-semantic cache backend (semantic prompt
caching on Valkey clusters running valkey-search, including AWS ElastiCache
for Valkey) to the SDK caching guide and the proxy caching guide, plus a blog
post announcing the feature.

Pairs with BerriAI/litellm#30675
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

Hardened for production deployment in the latest commit: added TLS support (ssl: true -> rediss://, or pass redis_url) and a clear fail-fast error for cluster-mode-enabled (multi-shard) endpoints, since redis-py's async cluster client cannot route FT.* commands. Verified the single-node path end-to-end against valkey-search and the cluster client behavior against a local 3-shard cluster. Note for context: AWS ElastiCache vector search needs node-based Valkey 8.0+ (single-shard supported); Serverless does not support vector search. @greptileai please re-review

@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch 2 times, most recently from aa0951a to bcff127 Compare June 19, 2026 19:36
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

@greptileai

@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch from bcff127 to f91a588 Compare June 19, 2026 19:48
yassin-berriai added a commit to BerriAI/litellm-docs that referenced this pull request Jun 19, 2026
Adds setup docs for the new valkey-semantic cache backend (semantic prompt
caching on Valkey clusters running valkey-search, including AWS ElastiCache
for Valkey) to the SDK caching guide and the proxy caching guide, plus a blog
post announcing the feature.

Pairs with BerriAI/litellm#30675
yassin-berriai added a commit to BerriAI/litellm-docs that referenced this pull request Jun 19, 2026
Adds setup docs for the new valkey-semantic cache backend (semantic prompt
caching on Valkey clusters running valkey-search, including AWS ElastiCache
for Valkey) to the SDK caching guide and the proxy caching guide, plus a blog
post announcing the feature.

Pairs with BerriAI/litellm#30675
@yassin-berriai yassin-berriai marked this pull request as draft June 19, 2026 20:38
@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch from f91a588 to c0198c0 Compare June 19, 2026 22:33
@yassin-berriai yassin-berriai changed the title feat(caching): add valkey-semantic cache backend for valkey-search feat(caching): add valkey-semantic cache backend and fix semantic cache scope keys Jun 19, 2026
@yassin-berriai

Copy link
Copy Markdown
Contributor Author

@greptileai

@yassin-berriai yassin-berriai marked this pull request as ready for review June 19, 2026 22:41
Comment on lines 294 to +377
@@ -293,7 +349,15 @@ def get_cache_key(self, **kwargs) -> str:

combined_kwargs = ModelParamHelper._get_all_llm_api_params()
litellm_param_kwargs = all_litellm_params
is_semantic_cache = self._is_semantic_cache()
scope_excluded_params = (
self._SEMANTIC_CACHE_SCOPE_EXCLUDED_PARAMS
if is_semantic_cache
else frozenset()
)
for param in kwargs:
if param in scope_excluded_params:
continue
if param in combined_kwargs:
param_value: Optional[str] = self._get_param_value(param, kwargs)
if param_value is not None:
@@ -309,6 +373,9 @@ def get_cache_key(self, **kwargs) -> str:
param_value = kwargs[param]
cache_key += f"{str(param)}: {str(param_value)}"

if is_semantic_cache:
cache_key += self._get_semantic_cache_tenant_scope(kwargs)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Breaking scope-key change invalidates all existing redis-semantic and qdrant-semantic entries

get_cache_key() now excludes messages, prompt, and input from the hashed key for every semantic cache type — including the pre-existing redis-semantic and qdrant-semantic backends. Any instance that has been running one of those backends will find that every stored entry becomes permanently unreachable after upgrading: the SHA-256 scope tag changes for every document, so all KNN filter lookups miss indefinitely. Dropping the cache silently on upgrade violates the backwards-compatibility rule; the fix should be opt-in (e.g. litellm.semantic_cache_scope_fix = True) so operators can schedule the cold-start window. New valkey-semantic deployments are unaffected since they have no prior entries to lose.

Rule Used: What: avoid backwards-incompatible changes without... (source)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Intentional, and I think a flag is the wrong call here.

The entries this invalidates were only ever reachable by a byte-identical prompt, because the prompt was baked into the scope key and the KNN filter required an exact key match, so semantic matching never actually ran. The warm cache that goes cold on upgrade therefore only held exact-prompt repeats, which is the single case where a semantic cache adds nothing over a plain exact cache. Keeping the old key format preserves nothing of value.

The impact is also self-healing and bounded. Semantic cache entries are TTL'd and best-effort: an orphaned entry sits until its TTL and expires, and a lookup miss just re-calls the provider, so there is no correctness impact and no data loss, only a one-time cold start for the remainder of the existing TTL. The new key additionally appends the authenticated tenant identity, so it is strictly more isolated than before, never less.

An opt-in flag would default every existing redis-semantic and qdrant-semantic deployment to the broken behavior, so semantic caching keeps silently not working until someone finds the flag, and it adds a second code path and config surface to preserve a cache state with no value. Defaulting to the correct behavior is the better trade. An operator who wants to reclaim the orphaned entries immediately can flush the index or shorten the TTL; otherwise it clears itself within one TTL.

…he scope keys

Adds a "valkey-semantic" cache type so semantic prompt caching can run
against Valkey clusters (for example AWS ElastiCache for Valkey) using the
valkey-search module.

The existing "redis-semantic" backend cannot drive valkey-search. RedisVL
gates the connection on a RediSearch module version that valkey-search does
not report, and its SemanticCache index declares the prompt as a TEXT field,
which valkey-search does not implement. ValkeySemanticCache therefore talks to
valkey-search directly over redis-py: it builds a vector index from the field
types valkey-search supports (TAG for caller scope, VECTOR for the prompt
embedding) and runs KNN queries for retrieval. Prompt extraction, embedding
generation, and cached-response parsing are reused from RedisSemanticCache
since those are backend agnostic. The redis dependency is imported lazily in
the cache dispatch so importing litellm without redis installed still works.

It also fixes semantic-cache scope keys so similarity matching works across
reworded prompts. get_cache_key() hashed messages / prompt / input into the
litellm_cache_key that every semantic backend filters its KNN search on, so a
paraphrase landed in a different bucket and never matched, even far above the
similarity threshold. For semantic cache types the prompt-bearing params are
now excluded from the scope key and the server-set tenant identity
(user_api_key, team, org) is appended instead, restoring embedding matching
within a tenant while keeping cache entries scoped to the authenticated
key / team / org. The three semantic backends share this key, so the same
change fixes redis-semantic and qdrant-semantic.

Connections resolve from VALKEY_HOST / VALKEY_PORT / VALKEY_PASSWORD, falling
back to REDIS_* for drop-in compatibility, and passwordless clusters (IAM or
no-auth) are supported.

Resolves #29121
Fixes #29086
@yassin-berriai yassin-berriai force-pushed the litellm_valkey_semantic_cache branch from c0198c0 to ce7a4cb Compare June 19, 2026 22:57
@yassin-berriai yassin-berriai merged commit 9c3ad1b into litellm_internal_staging Jun 20, 2026
122 checks passed
@yassin-berriai yassin-berriai deleted the litellm_valkey_semantic_cache branch June 20, 2026 00:09
yassin-berriai added a commit to BerriAI/litellm-docs that referenced this pull request Jun 20, 2026
Adds setup docs for the new valkey-semantic cache backend (semantic prompt
caching on Valkey clusters running valkey-search, including AWS ElastiCache
for Valkey) to the SDK caching guide and the proxy caching guide, plus a blog
post announcing the feature.

Pairs with BerriAI/litellm#30675
fzowl pushed a commit to fzowl/litellm that referenced this pull request Jun 24, 2026
…he scope keys (BerriAI#30675)

Adds a "valkey-semantic" cache type so semantic prompt caching can run
against Valkey clusters (for example AWS ElastiCache for Valkey) using the
valkey-search module.

The existing "redis-semantic" backend cannot drive valkey-search. RedisVL
gates the connection on a RediSearch module version that valkey-search does
not report, and its SemanticCache index declares the prompt as a TEXT field,
which valkey-search does not implement. ValkeySemanticCache therefore talks to
valkey-search directly over redis-py: it builds a vector index from the field
types valkey-search supports (TAG for caller scope, VECTOR for the prompt
embedding) and runs KNN queries for retrieval. Prompt extraction, embedding
generation, and cached-response parsing are reused from RedisSemanticCache
since those are backend agnostic. The redis dependency is imported lazily in
the cache dispatch so importing litellm without redis installed still works.

It also fixes semantic-cache scope keys so similarity matching works across
reworded prompts. get_cache_key() hashed messages / prompt / input into the
litellm_cache_key that every semantic backend filters its KNN search on, so a
paraphrase landed in a different bucket and never matched, even far above the
similarity threshold. For semantic cache types the prompt-bearing params are
now excluded from the scope key and the server-set tenant identity
(user_api_key, team, org) is appended instead, restoring embedding matching
within a tenant while keeping cache entries scoped to the authenticated
key / team / org. The three semantic backends share this key, so the same
change fixes redis-semantic and qdrant-semantic.

Connections resolve from VALKEY_HOST / VALKEY_PORT / VALKEY_PASSWORD, falling
back to REDIS_* for drop-in compatibility, and passwordless clusters (IAM or
no-auth) are supported.

Resolves BerriAI#29121
Fixes BerriAI#29086
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Support Valkey for semantic prompt caching (AWS ElastiCache)

3 participants