Imported from delightful-ai/leaven (
crates/leaven-lm-cache/AGENTS.md). Install upstream withnpx skills add delightful-ai/leaven --skill leaven-lm-cache. Copyright stays with the author.
Boundary
This crate owns Leaven's provider-neutral LM response cache: cache policy,
cache key, cache entry, cache-store trait, in-memory backend, durable SQLite
backend, and CachedLm.
It wraps impl Lm; it is not a provider crate and it is not the engine
evaluation cache.
Map
LmCachePolicydecides read/write behavior around an inner LM call.LmCacheKeyis built from provider fingerprint plus canonicalLmRequestcontent: model, messages, sampling, output mode, and provider hints.LmContinuationis intentionally not key material. This is only safe becauseLmRequest.messagesremains the canonical full conversation.LmCacheEntrystores the provider-neutral response and original usage; a cache hit returns zero metered cost while preserving stored usage.LmCacheStoreis the cache backend capability; concrete persistent stores can grow from this trait without changing provider crates.- Durable product runs should use the SQLite backend described in
docs/specs/default_cache_storage.md;open_run_dirscopes cache reuse to one durable run directory, whileopen_workspacescopes cache reuse to the workspace-level.leaven/lm-cache.sqlitedatabase.InMemoryLmCacheremains the cheap test/ephemeral backend. CachedLm::id()andCachedLm::fingerprint()delegate to the inner provider. Cache policy and backend are wrapper/runtime composition, not provider identity. Role-level resume identity belongs above this crate.
Route Away
- Raw provider clients stay in
leaven-lm-openaior future provider crates. Providers do not depend on this cache to be valid providers. - Engine assessment/evaluation caching stays in
leaven-engine; it deduplicates scored candidate evaluations, not raw LM responses. - Provider-side prompt caching stays in the provider leaf. OpenAI prompt cache
hints may affect
ProviderHints, but this crate only decides whether Leaven skips the provider call. - Ordinary solver/reflector/judge cache policy belongs in
leaven-runor a runtime-role composition root. This crate may expose the advanced wrapper and store traits, but product examples should not require users to stack wrappers manually.
Proof Anchors
crates/leaven-lm-cache/tests/cache_contract.rsproves each cache policy, zero-cost cache hits, backend error lifting, and that continuation response IDs are ignored by cache keys.docs/specs/lm_runtime_and_response_cache.mdis the local spec for key ingredients and response-cache boundaries.docs/specs/default_cache_storage.mdowns the durable product default and SQLite storage expectations.- Run
cargo test -p leaven-lm-cacheto prove response-cache behavior. - If
LmRequest,ProviderHints,SamplingOptions, orOutputModechanges, pair this withcargo test -p leaven-lm; those types define the key material this crate serializes.
Local Bait
- Do not include API keys, bearer tokens, wall-clock time, backend paths, or
provider response IDs in
LmCacheKey; they are transport or environment facts, not canonical response identity. - Do not include
LmContinuationinLmCacheKeyas a quick fix for provider suffix bugs. Fix the provider lowering or canonical messages instead. ProviderHintscurrently participates in the key. That means OpenAIprompt_cache_key,store, and metadata are treated as behavior/routing inputs for Leaven response reuse.CachedLmis a reusable advanced wrapper, not the ordinary Layer 1 product story. Typical users should eventually configure cache policy through solver/reflector/judge runtime roles inleaven-runor the runtime composition root; keep the wrapper available without teaching wrapper stacking as the default user path.- A cache hit returns zero
Meteredcost but leavesLmResponse.usageintact. Do not "normalize" usage to zero; usage is the original provider accounting, while cost is what this call spent.
Decision Cards
-
when: changing cache-key material do: update the key law in
docs/specs/lm_runtime_and_response_cache.mdand add/adjust acache_contract.rsassertion that distinguishes hit from miss preserve: provider fingerprint plus canonical request content is enough to decide response reuse avoid: using cache backend paths, response IDs, continuation tokens, or clock time as identity verify: runcargo test -p leaven-lm-cache -p leaven-lm -
when: changing cache policy behavior do: keep all five policy laws explicit:
Never,ReadWrite,ReadOnly,CacheOnly, andRefreshpreserve: read misses call the inner LM where the policy says they should, and cache hits do not charge new cost avoid: silently makingReadOnlywrite, or makingRefreshread before the provider call, or makingCacheOnlycall the inner LM on a miss verify: runcargo test -p leaven-lm-cache