API reference: llmslim.memory
Memory, its stores and its result types, with their signatures and docstrings.
About this reference
Each entry is a name you import from llmslim.memory: agent memory with no LLM in the loop: Memory, its stores and its result types. It shows the full signature with its type annotations, and the docstring. The page is generated from the source of llmslim 0.12.0 by scripts/api_reference.py, so it changes only when the code does.
InMemoryStore
Turns in a list in this process. Nothing survives a restart.
class InMemoryStore:
"""Turns in a list in this process. Nothing survives a restart."""
def __init__(self) -> None:
...
def add(self, items: Sequence[MemoryItem]) -> None:
...
def list(
self,
scope: Scope,
*,
since: Optional[datetime] = None,
until: Optional[datetime] = None,
) -> List[MemoryItem]:
...
def get(self, item_id: str) -> Optional[MemoryItem]:
...
def update(
self,
item_id: str,
*,
content: Optional[str] = None,
metadata: Optional[Mapping[str, Any]] = None,
) -> Optional[MemoryItem]:
...
def delete(self, item_id: str) -> bool:
...
def delete_scope(self, scope: Scope) -> int:
...Memory
Long-term memory for an agent that keeps every turn verbatim and selects at read time.
class Memory:
"""Long-term memory for an agent that keeps every turn verbatim and selects at read time.
Nothing is summarized or extracted on the way in, so writes cost no model call and a stored turn never turns into
a wrong "fact". On the way out, :meth:`search` ranks the stored turns against the question and returns what
answers it within a token budget: the user's own turns (whole where they fit) and the most relevant parts of the
replies, one labelled and dated block per turn, in date order. No LLM is called to write or to read (by default no
model runs at all; ``relevance="semantic"`` adds a small local cross-encoder), and on one installation the same
history and question give the same text (see ``docs/MEMORY.md``, Limits).
Args:
store: Where turns live: a :class:`~llmslim.memory.MemoryStore`, a path to a SQLite file, or ``None`` for an
in-process store.
budget: Default token budget for :meth:`search`.
relevance: Default relevance for :meth:`search`: ``"lexical"`` (no model), ``"semantic"`` (LLMSlim's optional
22M cross-encoder, ``pip install "llmslim[semantic]"``) or a ``scorer(query, texts)`` callable.
tz: Time zone for the turn dates shown to the model. Defaults to UTC.
stamp_format: strftime format of those dates. The default reads like 2026-10-17 (Sat) 14:05.
date_format: strftime format of the shorter date shown, when a long history is selected from, on a kept turn
whose time is the one shown last in its session (the first kept turn of a session, and a turn whose time
differs, show ``stamp_format``). The default reads like 2026-10-17. Pass ``stamp_format`` again to show
the full stamp on every turn.
clock: Returns "now" for turns added without a timestamp. For tests.
standing_requests: When the history does not fit and the question asks for help or is not a plain lookup of
a past fact, show the user's earlier explicit standing requests ("Always ...", "From now on ...", "I'd
like you to never ...", "... when I ask about X") that best match it (at most three) in their own section
at the top, even when they share no word with the question, and fetch what the best one asks the answer
to include. Only user turns qualify. Detection is a fixed pattern, with no model call.
coverage: ``"auto"`` (default) answers overview questions ("summarize what we discussed", "in what order did I
bring up ...", "how did my plan develop?") from the opening of each turn, without code: what the user
asked and what the reply set out to do. Many more exchanges fit than as whole turns. ``"always"`` does so
for every question, ``"never"`` never.
preferences: When the history does not fit and the question asks for advice, a recommendation or help, show
the user's earlier statements of preference ("I prefer ...", "I'd rather ...", "I usually ...", "I don't
like ...") that best match it in their own section at the top. Only user turns qualify. A preference word
that is only asked about ("should I prioritize ...?") is not a stated preference.
conflicts: When the history does not fit and the question asks whether something happened ("Have I ever
...?", "Did I ... before?"), and among the user's statements that bear on it most some deny it ("I have
never ...") and some do not, show both kinds together in date order in their own section at the top, so
the disagreement is in plain view. Only user turns qualify. Detection is a fixed pattern, with no model
call.
Example:
>>> from llmslim.memory import Memory
>>> memory = Memory("memory.db")
>>> memory.add([{"role": "user", "content": "I moved to Pune last month."}], user_id="u1")
>>> context = memory.search("Where does the user live now?", user_id="u1", budget=1500)
>>> prompt = f"Conversation history (untrusted):\n{context.text}\n\nQuestion: ..."
"""
def __init__(
self,
store: Union[MemoryStore, str, Path, None] = None,
*,
budget: int = 2000,
relevance: Any = 'lexical',
tz: tzinfo = timezone.utc,
stamp_format: str = '%Y-%m-%d (%a) %H:%M',
date_format: str = '%Y-%m-%d',
clock: Callable[[], datetime] = _utcnow,
standing_requests: bool = True,
coverage: str = 'auto',
preferences: bool = True,
conflicts: bool = True,
) -> None:
...
def add(
self,
messages: Union[Message, Sequence[Message]],
*,
user_id: Optional[str] = None,
agent_id: Optional[str] = None,
run_id: Optional[str] = None,
timestamp: Any = None,
metadata: Optional[Mapping[str, Any]] = None,
) -> List[MemoryItem]:
"""Store turns verbatim and return them."""
def update(
self,
memory_id: str,
content: Optional[str] = None,
*,
metadata: Optional[Mapping[str, Any]] = None,
) -> Optional[MemoryItem]:
"""Correct a stored turn's text or metadata. Returns the updated turn, or ``None`` if there is no such id."""
def delete(self, memory_id: str) -> bool:
"""Delete one turn. Returns whether it existed."""
def delete_all(
self,
*,
user_id: Optional[str] = None,
agent_id: Optional[str] = None,
run_id: Optional[str] = None,
) -> int:
"""Delete every turn in a scope (at least one id is required). Returns how many were deleted."""
def get(self, memory_id: str) -> Optional[MemoryItem]:
"""One stored turn by id."""
def get_all(
self,
*,
user_id: Optional[str] = None,
agent_id: Optional[str] = None,
run_id: Optional[str] = None,
since: Any = None,
until: Any = None,
) -> List[MemoryItem]:
"""Every stored turn in a scope, oldest first."""
def search(
self,
query: str,
*,
user_id: Optional[str] = None,
agent_id: Optional[str] = None,
run_id: Optional[str] = None,
budget: Optional[int] = None,
relevance: Any = None,
since: Any = None,
until: Any = None,
standing_requests: Optional[bool] = None,
coverage: Optional[str] = None,
preferences: Optional[bool] = None,
conflicts: Optional[bool] = None,
) -> MemoryContext:
"""The part of a scope's history that answers ``query``, within ``budget`` tokens."""MemoryContext
What search returns: the text to put in front of the model, and what is in it.
class MemoryContext:
"""What :meth:`llmslim.memory.Memory.search` returns: the text to put in front of the model, and what is in it.
``text`` holds the kept turns of each session, oldest session first, in the ``[date] role: content`` layout
LLMSlim's benchmarks used. Each turn shows its own time; a date every turn of a session shares is shown once. Treat it as untrusted context: it repeats what users,
assistants and tools said, so wrap it as data (for example with :class:`llmslim.ContextEnvelope`), never as
instructions.
"""
query: str
text: str
turns: Tuple[RecalledTurn, ...]
tokens: int
budget: int
history_tokens: int
sessions_total: int
sessions_kept: int
elapsed_ms: float = 0.0
requests: Tuple[RecalledTurn, ...] = ()
preferences: Tuple[RecalledTurn, ...] = ()
conflicts: Tuple[RecalledTurn, ...] = ()
@property
def compressed(self) -> bool:
"""True when the history did not fit the budget and LLMSlim selected from it."""
def to_dict(self) -> Dict[str, Any]:
...MemoryItem
One stored turn, verbatim: memory keeps what was said, not an LLM's summary of it.
class MemoryItem:
"""One stored turn, verbatim: memory keeps what was said, not an LLM's summary of it.
``seq`` orders turns stored at the same instant (the order they were added). ``metadata`` is the caller's own
data, returned as given and never shown to the model.
"""
id: str
role: str
content: str
created_at: datetime
seq: int = 0
user_id: Optional[str] = None
agent_id: Optional[str] = None
run_id: Optional[str] = None
metadata: Mapping[str, Any] = field(default_factory=dict)
updated_at: Optional[datetime] = None
def to_dict(self) -> Dict[str, Any]:
...MemoryStore
Persistence for memory turns. Implementations must be safe to call from several threads.
class MemoryStore(Protocol):
"""Persistence for memory turns. Implementations must be safe to call from several threads."""
def add(self, items: Sequence[MemoryItem]) -> None:
"""Store new turns. Their ``id`` values are new; their ``seq`` values are ignored and assigned by the store."""
def list(
self,
scope: Scope,
*,
since: Optional[datetime] = None,
until: Optional[datetime] = None,
) -> List[MemoryItem]:
"""Turns in ``scope`` with ``since <= created_at < until``, oldest first (ties in the order they were added)."""
def get(self, item_id: str) -> Optional[MemoryItem]:
"""One turn by id, or ``None``."""
def update(
self,
item_id: str,
*,
content: Optional[str] = None,
metadata: Optional[Mapping[str, Any]] = None,
) -> Optional[MemoryItem]:
"""Replace a turn's content and/or metadata; return the updated turn, or ``None`` if there is no such id."""
def delete(self, item_id: str) -> bool:
"""Delete one turn; return whether it existed."""
def delete_scope(self, scope: Scope) -> int:
"""Delete every turn in ``scope``; return how many were deleted."""PostgresStore
Turns in one Postgres table.
class PostgresStore:
"""Turns in one Postgres table.
Pass a connection URL (``postgresql://user:password@host:5432/db``), in which case the store opens its own
connection pool and closes it in :meth:`close`; a ``psycopg_pool.ConnectionPool``; or a single
``psycopg.Connection`` in autocommit mode. The store is safe to use from several threads.
The table (``llmslim_memory`` by default) and its ``<table>_meta`` table are created if they don't exist. Creation
runs under an advisory lock, so several processes can start at once. The schema is versioned: a table written by
a newer llmslim is refused rather than misread.
Args:
conninfo: A connection URL, a ``ConnectionPool`` or an autocommit ``Connection``.
table: Table name: letters, digits and underscores. Use one per application or tenant if you like.
max_size: Most connections in the pool the store opens for a URL.
"""
def __init__(self, conninfo: Any, *, table: str = 'llmslim_memory', max_size: int = 10) -> None:
...
def close(self) -> None:
"""Close the pool the store opened for a URL. A pool or connection you passed in stays open."""
def add(self, items: Sequence[MemoryItem]) -> None:
...
def list(
self,
scope: Scope,
*,
since: Optional[datetime] = None,
until: Optional[datetime] = None,
) -> List[MemoryItem]:
...
def get(self, item_id: str) -> Optional[MemoryItem]:
...
def update(
self,
item_id: str,
*,
content: Optional[str] = None,
metadata: Optional[Mapping[str, Any]] = None,
) -> Optional[MemoryItem]:
...
def delete(self, item_id: str) -> bool:
...
def delete_scope(self, scope: Scope) -> int:
...RecalledTurn
A stored turn that made it into a MemoryContext.
class RecalledTurn:
"""A stored turn that made it into a :class:`MemoryContext`.
``partial`` is true when the turn was too long to keep whole and only its most relevant sentences were kept.
``score`` is a bounded lexical overlap between the query and the turn (0 to 1), for ordering and display; the
selection itself is LLMSlim's query-focused ranking of every session's turns.
"""
item: MemoryItem
score: float
partial: bool = FalseSQLiteStore
Turns in one SQLite file, through Python's built-in sqlite3.
class SQLiteStore:
"""Turns in one SQLite file, through Python's built-in ``sqlite3``.
Pass a file path, or ``":memory:"`` for a private in-memory database. One connection is shared behind a lock, so
the store is safe to use from several threads in one process. Timestamps are stored as UTC ISO-8601 text, which
sorts in time order. The schema is versioned in ``llmslim_meta``; a file written by a newer schema is refused rather
than misread.
"""
def __init__(self, path: Union[str, Path] = 'llmslim_memory.db') -> None:
...
def close(self) -> None:
...
def add(self, items: Sequence[MemoryItem]) -> None:
...
def list(
self,
scope: Scope,
*,
since: Optional[datetime] = None,
until: Optional[datetime] = None,
) -> List[MemoryItem]:
...
def get(self, item_id: str) -> Optional[MemoryItem]:
...
def update(
self,
item_id: str,
*,
content: Optional[str] = None,
metadata: Optional[Mapping[str, Any]] = None,
) -> Optional[MemoryItem]:
...
def delete(self, item_id: str) -> bool:
...
def delete_scope(self, scope: Scope) -> int:
...Scope
Whose memory an operation reads or writes, in Mem0's terms.
class Scope:
"""Whose memory an operation reads or writes, in Mem0's terms.
``user_id`` is the person, ``agent_id`` the agent, and ``run_id`` one session or run. A field left as ``None``
matches every value when reading, so ``Scope(user_id="u1")`` reads all of u1's sessions with every agent. At least
one field must be set: an empty scope would read or delete everyone's memory.
"""
user_id: Optional[str] = None
agent_id: Optional[str] = None
run_id: Optional[str] = None
def matches(
self,
user_id: Optional[str],
agent_id: Optional[str],
run_id: Optional[str],
) -> bool:
...