Memory¶
zeroth.integrations.memory ¶
Memory subsystem for Zeroth agents.
This package provides the building blocks for giving agents persistent memory. It includes governed-protocol connector implementations, models (data shapes), and a registry/resolver (looking up and wrapping connectors by name).
KeyValueMemoryConnector ¶
Simple key-value memory connector.
A general-purpose connector for storing and retrieving data by key.
search
async
¶
Rank entries by token overlap with the query text.
Whole-phrase substring matches outrank token overlap; an empty query
returns everything. Honors query["limit"] (the retrieval node's
top_k). Sentence queries — the shape a RetrievalNode produces —
therefore work against this connector without a vector backend.
RunEphemeralMemoryConnector ¶
Memory that only lasts for a single run and is thrown away afterward.
Use this when an agent needs scratch space during one execution but the data doesn't need to survive after the run finishes.
ThreadMemoryConnector ¶
Memory scoped to a conversation thread.
Use this when data should persist across multiple runs within the same thread (like a conversation) but stay separate between threads.
ConnectorManifest ¶
Bases: BaseModel
Describes how a memory connector is configured.
This is the "ID card" for a connector -- it tells the system what type of connector to use, what scope it operates at, and any extra config.
ResolvedMemoryBinding ¶
Bases: BaseModel
A fully resolved, ready-to-use memory binding.
Combines the connector instance and its manifest (configuration). The connector is already wrapped with ScopedMemoryConnector and (optionally) AuditingMemoryConnector, so callers just call read/write/delete/search directly.
InMemoryConnectorRegistry ¶
A simple lookup table that maps memory ref names to connectors.
You register connectors by name, then look them up later when you need to read or write memory. Raises KeyError if a name isn't found.
MemoryConnectorResolver ¶
MemoryConnectorResolver(
*,
registry: InMemoryConnectorRegistry | None = None,
thread_repository: ThreadRepository | None = None,
audit_emitter: AuditEmitter | None = None,
workflow_name: str = "",
)
Turns memory ref names into fully resolved, ready-to-use bindings.
Given a list of memory reference names, this resolver looks each one up in the registry, wraps the raw connector with AuditingMemoryConnector (if an emitter is provided) and ScopedMemoryConnector, and returns ResolvedMemoryBinding instances.
set_embedding_call_hooks ¶
Wire the shared control plane used by per-resolve campaign wrappers.
consume_embedding_call_costs
async
¶
consume_embedding_call_costs(
*,
tenant_id: str,
run_id: str,
node_id: str,
campaign_id: str,
operation: EmbeddingOperation,
) -> tuple[dict[str, Any], ...]
Consume settled embedding costs once for the owning runtime node.
resolve
async
¶
resolve(
memory_refs: list[str],
*,
thread_id: str | None = None,
runtime_context: Mapping[str, Any] | None = None,
node_id: str | None = None,
effective_capabilities: set[Capability] | None = None,
) -> list[ResolvedMemoryBinding]
Resolve a list of memory ref names into ready-to-use bindings.
For each ref, looks up the connector and builds the wrapper stack
Scoped(TenantScoped(Auditing(raw))): Auditing (innermost, optional)
emits events, TenantScoped rewrites the resolved target into a
tenant-namespaced form, and Scoped (outermost) resolves scope ->
target before either sees it. TenantScoped sits below Scoped on
purpose: Scoped first produces "__shared__" / run_id / thread_id,
then TenantScoped namespaces it — that is what stops SHARED memory from
being cross-tenant readable on a shared backend.
Tenant is read per-call from runtime_context["tenant_id"] and is
fail-closed: an empty/missing tenant raises TenantScopeError (an
explicit "default" sentinel is permitted). The resolver stays a
shared singleton, so tenant must never be stored on __init__.
effective_capabilities (WS-C) is the node's granted capability set.
When it is not None the connector is wrapped with
CapabilityEnforcingMemoryConnector as the OUTERMOST layer, so
MEMORY_READ / MEMORY_WRITE are enforced (fail-closed: an empty
granted set denies) before scope/tenant/audit/raw see the call. When it
is None enforcement is inactive (the policy guard is not wired) and the
stack is left unchanged — the caller, not this method, decides whether
enforcement applies, so None never silently bypasses an active gate.
register_memory_connectors ¶
register_memory_connectors(
registry: InMemoryConnectorRegistry,
settings: Any,
*,
redis_client: Any | None = None,
pg_conninfo: str | None = None,
secret_provider: Any | None = None,
tenant_id: str | None = None,
allow_env_fallback: bool = True,
) -> None
Create and register all configured memory connectors.
Always registers the three in-memory connectors (ephemeral, key_value, thread) for dev/test. Conditionally registers external backend connectors based on settings and available clients.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
registry
|
InMemoryConnectorRegistry
|
The connector registry to populate. |
required |
settings
|
Any
|
Application settings with memory/pgvector/chroma/elasticsearch config. |
required |
redis_client
|
Any | None
|
An async Redis client instance (if Redis is available). |
None
|
pg_conninfo
|
str | None
|
Postgres connection string (if Postgres is available). |
None
|
secret_provider
|
Any | None
|
Optional tenant-aware provider for resolving logical credential references. |
None
|
tenant_id
|
str | None
|
Tenant scope used for secret-provider resolution. |
None
|
allow_env_fallback
|
bool
|
Whether logical references may fall back to the process environment when no secret-provider value is available. |
True
|