Skip to content

MemoryCache & configuration

MemoryCache

memory_reuse.core.MemoryCache

MemoryCache(config: CacheConfig | None = None, **kwargs: Any)

High-level cache client for AI agent workloads.

MemoryCache is the primary public interface. It wires together a storage backend, the exact-match LLM cache, the TTL-backed tool cache, and statistics tracking.

Parameters:

Name Type Description Default
config CacheConfig | None

Cache configuration. When omitted a default :class:~memory_reuse.config.CacheConfig is used (in-memory backend, 1-hour TTL, global scope).

None
**kwargs Any

Keyword arguments forwarded to :class:CacheConfig when config is None. Allows quick construction::

cache = MemoryCache(backend="redis",
                    redis_url=os.environ["REDIS_URL"])
{}

Example::

from memory_reuse import MemoryCache, CacheConfig

cache = MemoryCache(CacheConfig(backend="memory", default_ttl=600))
cache.set_context(user_id="alice")

result = await cache.exact.get(["my-prompt"], scope="user",
                                scope_id="alice")

stats property

stats: CacheStats

Current cache statistics snapshot.

Returns:

Name Type Description
A CacheStats

class:~memory_reuse.stats.CacheStats dataclass.

Example::

print(cache.stats.hit_rate)

analytics property

analytics: AnalyticsSnapshot

Current savings-analytics snapshot (Phase 5).

Returns an immutable :class:~memory_reuse.analytics.AnalyticsSnapshot with the current hit rate (read from the same counters as :attr:stats), plus tokens, cost, and latency saved. On a fresh cache — and whenever enable_stats is False — the snapshot is fully zeroed. Adding this accessor does not change :attr:stats or :class:~memory_reuse.stats.CacheStats.

Returns:

Name Type Description
An AnalyticsSnapshot

class:~memory_reuse.analytics.AnalyticsSnapshot.

Example::

print(cache.analytics.tokens_saved, cache.analytics.cost_saved)

from_env classmethod

from_env() -> MemoryCache

Create a :class:MemoryCache from MEMORY_REUSE_* environment variables.

See :meth:~memory_reuse.config.CacheConfig.from_env for the full list of recognised variables.

Returns:

Type Description
MemoryCache

A configured :class:MemoryCache instance.

Example::

import os
os.environ["MEMORY_REUSE_BACKEND"] = "redis"
os.environ["MEMORY_REUSE_REDIS_URL"] = "redis://localhost:6379/0"
cache = MemoryCache.from_env()

set_context

set_context(*, user_id: str | None = None, session_id: str | None = None, tenant_id: str | None = None) -> None

Set the user/session context for scoped cache keys.

Context values are used by the LangGraph decorators when no explicit scope ID is passed. They do not affect calls that provide their own scope_id argument.

The context is stored in a :class:contextvars.ContextVar, so a value set in one asyncio task (or thread) is not visible to a concurrently running task. This prevents one request's user_id from leaking into another request handled on the same shared :class:MemoryCache. Only the arguments you pass are updated; others are preserved.

Parameters:

Name Type Description Default
user_id str | None

Identifier for the current user.

None
session_id str | None

Identifier for the current session.

None
tenant_id str | None

Identifier for the current tenant (future use).

None

Example::

cache.set_context(user_id="alice", session_id="sess-123")

clear_context

clear_context() -> None

Reset all context values to None for the current context.

Call this between requests in a shared server context to avoid leaking one user's context into another request. Because the context lives in a :class:contextvars.ContextVar, this only clears the calling task's view.

context

context(*, user_id: str | None = None, session_id: str | None = None, tenant_id: str | None = None) -> Iterator[None]

Temporarily set the request context, restoring it on exit.

Unlike :meth:set_context, this scopes the change to a with block and always restores the previous context afterwards — including when the body raises — so nested or concurrent request handling cannot leave a stale user_id behind.

Example::

with cache.context(user_id="alice"):
    await do_work()   # sees user_id="alice"
# previous context restored here, even on exception

reset_stats

reset_stats() -> None

Reset all hit/miss/error counters to zero.

record_hit_event

record_hit_event(event: CacheHitEvent) -> None

Record the savings a cache hit avoided (Phase 5).

Attribution is caller-supplied — the core caches do not know an operation's token/cost/latency — so integrations or application code call this on a hit to feed the analytics layer. Recording is best-effort and never fatal, and is a no-op when enable_stats is False.

Parameters:

Name Type Description Default
event CacheHitEvent

The :class:~memory_reuse.analytics.CacheHitEvent describing the tokens, cost, and/or latency the hit avoided.

required

Example::

cache.record_hit_event(CacheHitEvent(
    tokens_in=1200, tokens_out=400, latency_saved=0.4,
    operation="search_confluence"))

lookup async

lookup(key_parts: list, query_text: str, *, scope: str, scope_id: str | None, exact_only: bool = False, threshold: float | None = None, serializer: Callable[[Any], Any] | None = None, deserializer: Callable[[Any], Any] | None = None, operation: str | None = None) -> Any | None

Look up a cached value, trying the exact cache before the semantic cache.

The combined flow tries the fastest, cheapest path first: an exact hash-match is attempted before any embedding is computed. Only when the exact cache misses — and semantic caching is enabled and not disabled for this call — is the query embedded and matched by similarity.

Parameters:

Name Type Description Default
key_parts list

Ordered list of values identifying the exact-cache entry.

required
query_text str

The natural-language query used for semantic matching.

required
scope str

Cache scope — "global", "user", or "session".

required
scope_id str | None

User or session identifier for non-global scopes.

required
exact_only bool

When True, the semantic cache is never consulted, forcing Phase 1 exact-only behaviour for this call site (for example a tool with side effects).

False
threshold float | None

Optional per-call similarity threshold overriding :attr:~memory_reuse.config.CacheConfig.similarity_threshold.

None
serializer Callable[[Any], Any] | None

Optional per-call serializer override used when promoting a semantic hit to the exact cache. Falls back to the configured serializer when None. Used by wrap_graph's automatic codec; most callers leave it None.

None
deserializer Callable[[Any], Any] | None

Optional per-call deserializer override applied to the exact-cache read. Falls back to the configured deserializer when None.

None
operation str | None

Optional operation identifier (tool/node/graph name) that isolates the semantic search to that operation's own similarity space. The decorators pass their stable operation identity so a reworded match can only come from the same tool/node/graph, never an unrelated one with similar query text. When None (the default) the semantic namespace is scoped only by scope/version, matching the pre-isolation behaviour — so a caller managing its own keys can still match purely on query_text within a scope.

None

Returns:

Name Type Description
Any | None

The cached value on an exact or semantic hit, or None on a miss.

Note Any | None

a cache miss and a stored None value both return None

Any | None

here. The decorators use the internal :meth:_lookup, which returns

Any | None

a sentinel on a miss, so a cached false-like value is served as a hit

Any | None

and not recomputed.

Raises:

Type Description
ScopeViolationError

If scope requires a scope_id but none is provided.

store async

store(key_parts: list, query_text: str, value: Any, *, scope: str, scope_id: str | None, ttl: int | None = None, exact_only: bool = False, serializer: Callable[[Any], Any] | None = None, operation: str | None = None) -> None

Store a value in the exact cache and, when enabled, the semantic cache.

The exact-match entry is always written so a subsequent identical request hits the faster exact path. When semantic caching is enabled and not disabled for this call, the query's embedding is also stored so reworded but equivalent requests can match later.

Parameters:

Name Type Description Default
key_parts list

Ordered list of values identifying the exact-cache entry.

required
query_text str

The natural-language query whose embedding is stored.

required
value Any

The value to cache. Must be JSON-serialisable.

required
scope str

Cache scope — "global", "user", or "session".

required
scope_id str | None

User or session identifier for non-global scopes.

required
ttl int | None

Time-to-live in seconds. Falls back to :attr:~memory_reuse.config.CacheConfig.default_ttl when None.

None
exact_only bool

When True, only the exact-match entry is written and the semantic cache is left untouched.

False
serializer Callable[[Any], Any] | None

Optional per-call serializer override. Falls back to the configured serializer when None. Used by wrap_graph's automatic codec; most callers leave it None.

None
operation str | None

Optional operation identifier isolating the stored semantic vector to that operation's namespace so it can only be matched by a later lookup for the same operation. Must match the operation passed to :meth:lookup. None (the default) stores in the scope/version-only namespace.

None

Raises:

Type Description
ScopeViolationError

If scope requires a scope_id but none is provided.

get_or_compute async

get_or_compute(key_parts: list, compute: Callable[[], Any], *, scope: str, scope_id: str | None, ttl: int | None = None, query_text: str = '', exact_only: bool = False) -> Any

Look up a value, computing it at most once across concurrent callers.

On a hit the stored value is returned without running compute. On a miss, when single_flight is enabled, concurrent calls for the same key coalesce so compute runs exactly once and its result is shared with every waiter (Phase 6, Req 1); otherwise this is a plain miss→compute→store. The computed value is stored via the combined :meth:store flow (exact, plus semantic when query_text is supplied and semantic is enabled).

Parameters:

Name Type Description Default
key_parts list

Ordered list of values identifying the entry.

required
compute Callable[[], Any]

A zero-argument callable (sync or async) producing the value on a miss.

required
scope str

Cache scope — "global", "user", or "session".

required
scope_id str | None

User or session identifier for non-global scopes.

required
ttl int | None

Time-to-live in seconds for the stored result.

None
query_text str

Optional natural-language query enabling semantic storage of the computed value.

''
exact_only bool

When True, never consult or write the semantic cache.

False

Returns:

Type Description
Any

The cached value on a hit, or the freshly computed value on a miss.

Raises:

Type Description
ScopeViolationError

If scope requires a scope_id but none is provided.

record_operation

record_operation(operation: str, *, hit: bool, cost_saved: float | None = None, latency_saved: float | None = None, input_hash: str | None = None, cached: bool = False, volatile: bool = False) -> None

Record a per-operation observation for the effectiveness analyzer (Phase 6).

Best-effort and never fatal; a no-op when enable_stats is False. The cached and volatile flags are caller-supplied signals the recommendation rules use — the analyzer cannot infer a tool's caching status or data-freshness on its own.

Parameters:

Name Type Description Default
operation str

Label identifying the operation (tool/node/graph name).

required
hit bool

True when served from cache, False on a miss.

required
cost_saved float | None

Optional attributed cost for this observation.

None
latency_saved float | None

Optional attributed latency (seconds).

None
input_hash str | None

Optional stable fingerprint of the inputs, used to estimate the repeat ratio.

None
cached bool

Whether the operation is already configured to be cached.

False
volatile bool

Whether the operation returns rapidly-changing data.

False

analyze

analyze() -> EffectivenessReport

Return per-operation statistics and advisory cache recommendations (Phase 6).

The recommendations are advisory only — reading them never changes cache behaviour. On a cache with no recorded observations this returns an empty report rather than raising.

Returns:

Name Type Description
An EffectivenessReport

class:~memory_reuse.optimizer.EffectivenessReport.

wrap_graph

wrap_graph(graph: Any, *, semantic: bool = False, similarity_threshold: float | None = None, ttl: int | None = None, scope: Literal['global', 'user', 'session'] | None = None, key_fields: list[str] | None = None, exact_only: bool = False, graph_id: str | None = None, serialize_messages: str | bool = 'auto') -> CachedGraph

Wrap a compiled LangGraph graph so entire runs can be served from cache.

On invoke the wrapper checks a graph-level cache keyed on the initial input state; on a hit it returns the stored final result without running any node, and on a miss it runs the real graph and stores the result.

LangGraph is imported lazily here; the core package imports fine without it (Req 7).

Parameters:

Name Type Description Default
graph Any

A compiled LangGraph graph exposing invoke / ainvoke.

required
semantic bool

Enable semantic (similarity) matching for the whole-run key. Requires semantic_enabled=True on the config to take effect.

False
similarity_threshold float | None

Per-wrapper threshold overriding the config default for graph-level semantic lookups.

None
ttl int | None

TTL for stored final results; falls back to :attr:~memory_reuse.config.CacheConfig.default_ttl.

None
scope Literal['global', 'user', 'session'] | None

"global", "user", or "session"; falls back to :attr:~memory_reuse.config.CacheConfig.default_scope.

None
key_fields list[str] | None

Subset of the initial input state used to derive the key and semantic query text.

None
exact_only bool

Force exact-only matching, never consulting the semantic cache regardless of config.

False
graph_id str | None

Stable identifier for this graph included in the key so different wrapped graphs never collide. Defaults to a value derived from the graph object.

None
serialize_messages str | bool

Controls automatic faithful serialization of the wrapped graph's results so a cache hit replays real LangChain message objects (with .content), identical to a miss — plug-and-play, no codec wiring. "auto" (the default) enables it when langchain-core is importable and silently falls back to the default JSON serialization when it is not. True forces it on (raising a named error if langchain-core is absent). False disables it. When a serializer/deserializer is already configured on the cache, that explicit choice always wins and this option is ignored. The codec applies only to this wrapped graph's store/load, never to the cache's exact/tool/semantic layers for other callers.

'auto'

Returns:

Name Type Description
A CachedGraph

class:~memory_reuse.integrations.langgraph.CachedGraph wrapper.

Raises:

Type Description
BackendNotAvailableError

If LangGraph is not installed, naming the extra to install.

Warning

Graph-level caching replays a full stored result and is unsuitable for runs whose side effects must occur on every invocation. Use bypass_cache=True / no_store=True per call, or leave such graphs unwrapped.

invalidate_node async

invalidate_node(node: Callable | str, state: Any = None, *, scope: Literal['global', 'user', 'session'] = 'global', scope_id: str | None = None, key_fields: list[str] | None = None) -> None

Invalidate a cached node output for a specific node and input state.

Reconstructs the same key parts cached_node uses ([node_qualname, key_data]) and deletes the matching exact entry via :meth:~memory_reuse.cache.exact.ExactCache.invalidate. Completes without error when no entry exists (Req 13.6).

Parameters:

Name Type Description Default
node Callable | str

The decorated node callable (its __qualname__ is used) or an explicit node identifier string.

required
state Any

The node input state used to reconstruct the key. Uses the full state, or the key_fields subset when provided.

None
scope Literal['global', 'user', 'session']

"global", "user", or "session".

'global'
scope_id str | None

Explicit scope identifier. When omitted for a non-global scope it is resolved from state then the cache context.

None
key_fields list[str] | None

Subset of the input state forming the key, matching the node's cached_node configuration.

None

Raises:

Type Description
ScopeViolationError

If a non-global scope cannot be resolved.

ping async

ping() -> bool

Check whether the backend is reachable.

Returns:

Type Description
bool

True if the backend responds successfully.

close async

close() -> None

Close backend connections gracefully.

Should be called on application shutdown to prevent resource leaks, especially when using the Redis backend.

Example::

async with asyncio.timeout(5):
    await cache.close()

flush async

flush() -> None

Flush this cache's entries from the backend (and vector index).

On the Redis backend this clears only keys under the configured key_prefix (and only vectors under the vector index's own prefix) via a batched SCAN sweep, so unrelated application keys and other cache instances sharing the database are never deleted. On the in-memory backend it clears this instance's store.

When semantic caching is enabled the backing vector index is flushed too, so a flush does not leave orphaned semantic entries behind.

Warning

This irreversibly removes every cached entry for this cache. Use only in development or test environments.

CacheConfig

memory_reuse.config.CacheConfig dataclass

CacheConfig(backend: Literal['memory', 'redis', 'agentcore'] = 'memory', redis_url: str | None = None, default_ttl: int | None = 3600, default_scope: Literal['global', 'user', 'session'] = 'global', key_prefix: str = 'memreuse', max_key_size: int = 512, enable_stats: bool = True, semantic_enabled: bool = False, similarity_threshold: float = 0.95, embedding_provider: Literal['openai', 'local', 'litellm'] | None = None, embedding_model: str | None = None, max_vectors_per_namespace: int = 10000, store_exact_on_semantic_hit: bool = True, extract_answer: bool = False, extract_min_similarity: float = 0.5, agentcore_region: str | None = None, agentcore_memory_id: str | None = None, pricing: PricingConfig | None = None, cache_version: str | None = None, single_flight: bool = False, distributed_lock: bool = False, max_tracked_operations: int = 1000, serializer: Callable[[Any], Any] | None = None, deserializer: Callable[[Any], Any] | None = None)

Configuration for the MemoryCache.

All values can be overridden via environment variables when using :meth:MemoryCache.from_env.

Attributes:

Name Type Description
backend Literal['memory', 'redis', 'agentcore']

Storage backend to use. "memory" requires no extra dependencies; "redis" requires pip install memory-reuse[redis]; "agentcore" requires pip install memory-reuse[agentcore].

redis_url str | None

Connection URL for the Redis backend. Should be supplied via the MEMORY_REUSE_REDIS_URL environment variable rather than hardcoded.

agentcore_region str | None

AWS region hosting the AgentCore store. Used only when backend="agentcore".

agentcore_memory_id str | None

AgentCore memory / store resource identifier. Used only when backend="agentcore".

default_ttl int | None

Default time-to-live in seconds for cached entries. None means entries never expire.

default_scope Literal['global', 'user', 'session']

Default cache scope applied when no explicit scope is passed to cache operations.

key_prefix str

String prepended to every cache key for namespacing.

max_key_size int

Maximum allowed cache-key length in bytes. Requests that would produce a longer key raise ValueError.

enable_stats bool

When True, hit/miss/error counts are tracked and accessible via :attr:MemoryCache.stats.

semantic_enabled bool

When True, the semantic (similarity-based) cache is enabled in addition to the exact cache. Off by default so existing behaviour is unchanged; requires embedding_provider.

similarity_threshold float

Minimum cosine similarity (normalised to [0.0, 1.0]) at which two requests are treated as the same and a cached result is reused. Higher values favour precision over recall.

embedding_provider Literal['openai', 'local', 'litellm'] | None

Which embedding provider to use for semantic lookups. None disables provider selection; required when semantic_enabled is True.

embedding_model str | None

Optional model name passed to the embedding provider. None lets the provider pick its default model.

max_vectors_per_namespace int

Maximum number of stored vectors per scope namespace before LRU eviction applies.

store_exact_on_semantic_hit bool

When True, a semantic hit also writes an exact-match entry so the next identical request hits the faster exact path.

extract_answer bool

When True (and the cached value is a string), a semantic hit returns only the sentence(s) of the stored answer that best match the query, rather than the whole answer. This is a purely extractive, embedding-based narrowing — no LLM call and no generation — so it can only return text already present in the stored answer. Off by default; the core cache returns values verbatim.

extract_min_similarity float

Minimum normalised cosine similarity ([0.0, 1.0]) a sentence must reach against the query for :attr:extract_answer to return just that sentence. When no sentence clears this bar the full stored answer is returned, so extraction never yields an empty result.

pricing PricingConfig | None

Optional per-token :class:~memory_reuse.analytics.pricing.PricingConfig used by the analytics layer to compute cost saved from tokens saved. None (the default) means cost is not tracked; token and latency savings are still tracked. Set in code, not via an environment variable.

cache_version str | None

Optional version token folded into every cache key so a redeploy with updated prompts, models, or tools never reuses a result generated by an incompatible older version. None (the default) keeps keys byte-identical to a pre-Phase-6 config, so existing cached entries continue to hit after upgrading. A version change invalidates reuse uniformly across the exact, tool, and semantic layers.

single_flight bool

When True, :meth:MemoryCache.get_or_compute coalesces concurrent misses for the same key so the expensive compute runs once and its result is shared. False (the default) leaves every existing cache operation unchanged.

distributed_lock bool

When True, single-flight coordination extends across processes with a per-key Redis lock (requires the Redis backend). Off by default; enabling it without a Redis backend raises a configuration error at construction.

max_tracked_operations int

Maximum number of distinct operation aggregates the effectiveness analyzer retains, bounding its memory use. Once reached, observations for new operations are dropped.

serializer Callable[[Any], Any] | None

Optional callable converting a value into a JSON-native representation before storage. Paired with deserializer for a faithful round-trip of framework objects (e.g. LangChain messages). None (the default) stores values exactly as before.

deserializer Callable[[Any], Any] | None

Optional callable reconstructing the original value from its JSON-native representation on load. Must be paired with serializer. None (the default) returns parsed JSON as-is.

Example::

config = CacheConfig(
    backend="redis",
    redis_url=os.environ["REDIS_URL"],
    default_ttl=600,
    default_scope="user",
)

__post_init__

__post_init__() -> None

Validate the configuration after initialisation.

from_env classmethod

from_env() -> CacheConfig

Create a :class:CacheConfig from MEMORY_REUSE_* environment variables.

Recognised variables:

  • MEMORY_REUSE_BACKEND — "memory", "redis", or "agentcore"
  • MEMORY_REUSE_REDIS_URL — Redis connection URL
  • MEMORY_REUSE_AGENTCORE_REGION — AWS region hosting the AgentCore store (required when backend="agentcore")
  • MEMORY_REUSE_AGENTCORE_MEMORY_ID — AgentCore memory / store resource identifier (required when backend="agentcore")
  • MEMORY_REUSE_DEFAULT_TTL — integer seconds or "none"
  • MEMORY_REUSE_DEFAULT_SCOPE — "global", "user", or "session"
  • MEMORY_REUSE_KEY_PREFIX — string prefix for all keys
  • MEMORY_REUSE_ENABLE_STATS — "true" / "false"
  • MEMORY_REUSE_SEMANTIC_ENABLED — "true" / "false"
  • MEMORY_REUSE_SIMILARITY_THRESHOLD — float in [0.0, 1.0]
  • MEMORY_REUSE_EMBEDDING_PROVIDER — "openai", "local", or "litellm"
  • MEMORY_REUSE_EMBEDDING_MODEL — embedding model name

Returns:

Name Type Description
A CacheConfig

class:CacheConfig populated from the environment.

Raises:

Type Description
ConfigurationError

If backend="agentcore" is selected but a required AgentCore connection setting (MEMORY_REUSE_AGENTCORE_REGION or MEMORY_REUSE_AGENTCORE_MEMORY_ID) is absent.

Statistics

memory_reuse.stats.CacheStats dataclass

CacheStats(hits: int = 0, exact_hits: int = 0, semantic_hits: int = 0, misses: int = 0, errors: int = 0, total_requests: int = 0)

Snapshot of cache performance counters.

Attributes:

Name Type Description
hits int

Number of successful cache lookups. Always equals exact_hits + semantic_hits.

exact_hits int

Number of hits served by the exact (hash-based) cache.

semantic_hits int

Number of hits served by the semantic (similarity) cache.

misses int

Number of cache lookups that found no entry.

errors int

Number of backend errors encountered during cache operations.

total_requests int

Total number of cache lookup attempts (hits + misses).

Example::

stats = cache.stats
print(f"Hit rate: {stats.hit_rate:.1%}")

hit_rate property

hit_rate: float

Fraction of requests that were cache hits, in the range [0.0, 1.0].

Returns:

Type Description
float

0.0 when no requests have been made yet.

to_dict

to_dict() -> dict

Return a plain-dict representation of the stats snapshot.

Returns:

Type Description
dict

Dictionary with keys hits, exact_hits, semantic_hits,

dict

misses, errors, total_requests, and hit_rate.

memory_reuse.stats.StatsTracker

StatsTracker()

Thread-safe, asyncio-compatible statistics tracker.

Uses an :class:asyncio.Lock to serialise counter updates so that concurrent coroutines always see a consistent view of the counters.

Hits are tracked by type: :meth:record_exact_hit and :meth:record_semantic_hit each also bump the aggregate hits counter, so hits always equals exact_hits + semantic_hits.

Statistics recording is best-effort and never fatal: every record_* method swallows any internal error so a cache operation can always return its result even if recording fails.

Example::

tracker = StatsTracker()
tracker.record_exact_hit()
tracker.record_miss()
print(tracker.get_stats().hit_rate)  # 0.5

record_exact_hit

record_exact_hit() -> None

Record a hit served by the exact cache.

Increments the exact-hit counter, the aggregate hit counter, and the total-request counter. Any internal error is swallowed so recording is never fatal to the caller.

record_semantic_hit

record_semantic_hit() -> None

Record a hit served by the semantic cache.

Increments the semantic-hit counter, the aggregate hit counter, and the total-request counter. Any internal error is swallowed so recording is never fatal to the caller.

record_hit

record_hit() -> None

Record an exact hit. Alias for :meth:record_exact_hit.

Retained for backward compatibility with Phase 1 callers.

record_miss

record_miss() -> None

Increment the miss counter and total-request counter.

Any internal error is swallowed so recording is never fatal.

record_error

record_error() -> None

Increment the error counter (does not affect total_requests).

Any internal error is swallowed so recording is never fatal.

get_stats

get_stats() -> CacheStats

Return an immutable snapshot of the current counters.

Returns:

Name Type Description
A CacheStats

class:CacheStats dataclass with the current values.

reset

reset() -> None

Reset all counters to zero.

Exceptions

memory_reuse.exceptions

Custom exceptions for the memory-reuse package.

AgentMemoryError

Bases: Exception

Base exception for all memory-reuse errors.

All exceptions raised by this library inherit from this class, making it easy to catch any library error with a single handler.

BackendConnectionError

Bases: AgentMemoryError

Raised when the cache backend cannot be reached.

Typically wraps connection failures from Redis or other network backends. Check your redis_url and network connectivity.

ScopeViolationError

Bases: AgentMemoryError

Raised when user-scoped data would be cached under the global scope.

This is a safety guard: if you call a cache operation with scope='user' but no user_id is available in the current context, this exception is raised rather than silently caching data that could be shared across users.

InvalidTTLError

Bases: AgentMemoryError

Raised when a TTL value is not valid.

TTL must be a positive integer (seconds) or None for no expiry.

BackendNotAvailableError

Bases: AgentMemoryError

Raised when the requested backend is not importable or configured.

For example, requesting the redis backend without the redis package installed will raise this exception.

EmbeddingProviderError

Bases: AgentMemoryError

Raised when an embedding provider cannot be used.

Typically raised when the provider's optional dependency is not installed (naming the extra to install, e.g. pip install "memory-reuse[semantic]") or when the provider's backing model or API call fails.

ProviderMismatchError

Bases: AgentMemoryError

Raised when embeddings from different providers or models are mixed.

Vectors are namespaced by provider:model. Comparing vectors from incompatible providers or models is refused rather than silently producing meaningless similarity scores.

ConfigurationError

Bases: AgentMemoryError

Raised when a :class:CacheConfig value is invalid.

For example, a similarity_threshold outside [0.0, 1.0] or enabling semantic_enabled without selecting an embedding_provider.

SerializationError

Bases: AgentMemoryError

Raised when a value cannot be serialised for (or restored from) the cache.

The cache stores values as gzip-compressed JSON. A value containing a type JSON cannot represent (and that no configured serializer converts) raises this rather than being silently coerced to a lossy string — so an unsupported value is never stored as a wrong value. It is also raised when a stored entry cannot be decompressed or parsed back into a Python object.