API reference¶
Agent factories¶
deep_memory_agent.agents ¶
Factories for the two memory agents.
The package deliberately ships two agents instead of one. Recall and curation pull in opposite directions: recall wants a narrow, read-only surface it cannot corrupt, while curation needs write access and a prompt about supersession and consolidation. Splitting them also keeps a single writer over the tree, which is what makes a file-based memory safe to share between agents.
Both factories take either memory_dir — the default on-disk wiring — or a
ready-made backend, never both.
READ_ONLY_MEMORY_PERMISSIONS
module-attribute
¶
READ_ONLY_MEMORY_PERMISSIONS = [
FilesystemPermission(
operations=["write"],
paths=[f"{MEMORY_ROOT}**", MEMORY_ROOT.rstrip("/")],
mode="deny",
)
]
Backend-level guard that makes the memory tree read-only.
Withholding the write tools is not enough on its own: the built-in write_file,
edit_file and delete tools would still reach /memory/. This rule denies
them at the filesystem middleware, so recall stays read-only even if a caller
adds tools of their own.
create_memory_search_agent ¶
create_memory_search_agent(
model: str | BaseChatModel,
*,
memory_dir: str | Path | None = None,
backend: BackendProtocol | None = None,
system_prompt: str | None = None,
tools: Sequence[BaseTool] = (),
name: str = "memory_search_agent",
**kwargs: Any,
) -> CompiledStateGraph
Build a read-only agent that answers from memory.
The agent gets memory_index, memory_search and memory_read, and is
denied every write on /memory/ at the backend level. It is the safe agent
to expose to callers who should be able to consult memory but never change
it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str | BaseChatModel
|
Chat model, or an identifier resolvable by deepagents. |
required |
memory_dir
|
str | Path | None
|
Host directory holding the memory tree. Mutually exclusive
with |
None
|
backend
|
BackendProtocol | None
|
A ready-made backend serving |
None
|
system_prompt
|
str | None
|
Overrides the built-in recall prompt. Pass one only if you also restate the layout rules the built-in prompt carries. |
None
|
tools
|
Sequence[BaseTool]
|
Extra tools to expose alongside the recall tools. |
()
|
name
|
str
|
Name of the compiled graph. |
'memory_search_agent'
|
**kwargs
|
Any
|
Forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
CompiledStateGraph
|
The compiled agent. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both |
create_memory_manager_agent ¶
create_memory_manager_agent(
model: str | BaseChatModel,
*,
memory_dir: str | Path | None = None,
backend: BackendProtocol | None = None,
system_prompt: str | None = None,
tools: Sequence[BaseTool] = (),
consolidation_model: str | BaseChatModel | None = None,
name: str = "memory_manager_agent",
**kwargs: Any,
) -> CompiledStateGraph
Build the agent that curates memory.
It gets the recall tools plus memory_write, memory_update and
memory_consolidate, and is meant to be the single writer of the tree:
concurrent writers on plain markdown files lose data, and nothing here
locks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
str | BaseChatModel
|
Chat model, or an identifier resolvable by deepagents. |
required |
memory_dir
|
str | Path | None
|
Host directory holding the memory tree. Mutually exclusive
with |
None
|
backend
|
BackendProtocol | None
|
A ready-made backend serving |
None
|
system_prompt
|
str | None
|
Overrides the built-in curation prompt. Pass one only if you also restate the layout rules the built-in prompt carries. |
None
|
tools
|
Sequence[BaseTool]
|
Extra tools to expose alongside the memory tools. |
()
|
consolidation_model
|
str | BaseChatModel | None
|
Model used by |
None
|
name
|
str
|
Name of the compiled graph. |
'memory_manager_agent'
|
**kwargs
|
Any
|
Forwarded to |
{}
|
Returns:
| Type | Description |
|---|---|
CompiledStateGraph
|
The compiled agent. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both |
Store¶
deep_memory_agent.store ¶
Read and write operations over the memory tree.
MemoryStore is the single place that
knows how memory is laid out on the virtual filesystem: which file an entry
belongs in, how frontmatter is appended, how a superseded entry is retired and
how the router indexes are kept in step. The agent tools in
deep_memory_agent.tools are thin wrappers over it, which keeps the file
format testable without spinning up a model.
Every operation goes through the deepagents backend. Nothing in this module opens a host path.
MemoryHit
dataclass
¶
An entry found by a search, with the file it lives in.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
str
|
Absolute virtual path of the file holding the entry. |
entry |
MemoryEntry
|
The entry itself. |
MemoryStore ¶
File-backed store for episodic, semantic and procedural memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
BackendProtocol
|
Backend serving the |
required |
ensure_tree ¶
Create any missing file of the memory tree.
Returns:
| Type | Description |
|---|---|
list[str]
|
The paths that were created. |
read_file ¶
Read a memory file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
str
|
Absolute virtual path, which must sit under |
required |
offset
|
int
|
First line to read, 0-indexed. |
0
|
limit
|
int
|
Maximum number of lines to read. |
2000
|
Returns:
| Type | Description |
|---|---|
str
|
The file's content. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the path escapes the memory tree or cannot be read. |
write ¶
write(
category: MemoryCategory,
body: str,
*,
summary: str = "",
tags: tuple[str, ...] = (),
source: str = "agent",
confidence: Confidence = MEDIUM,
supersedes: str | None = None,
title: str | None = None,
when: datetime | None = None,
) -> MemoryHit
Append an entry to the file its category maps to.
The target file is created with a heading if it does not exist yet, the
router index of the owning kind is updated, and — when supersedes is
given — the replaced entry is retired in place.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
category
|
MemoryCategory
|
Which file family the entry belongs to. |
required |
body
|
str
|
Markdown content of the entry. |
required |
summary
|
str
|
One-line description, used in the router index. |
''
|
tags
|
tuple[str, ...]
|
Labels used to narrow later searches. |
()
|
source
|
str
|
Where the information came from. |
'agent'
|
confidence
|
Confidence
|
How much the entry is trusted. |
MEDIUM
|
supersedes
|
str | None
|
Identifier of an entry this one replaces. |
None
|
title
|
str | None
|
Procedure title; required for procedural entries. |
None
|
when
|
datetime | None
|
Instant the entry refers to. Defaults to now, in UTC. |
None
|
Returns:
| Type | Description |
|---|---|
MemoryHit
|
The stored entry and the file it landed in. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the entry cannot be rendered or the write fails. |
get ¶
get(entry_id: str) -> MemoryHit | None
Find an entry by identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entry_id
|
str
|
Identifier to look for. |
required |
Returns:
| Type | Description |
|---|---|
MemoryHit | None
|
The entry and its file, or |
search ¶
search(
query: str = "",
*,
kind: MemoryKind | None = None,
category: MemoryCategory | None = None,
tags: tuple[str, ...] = (),
include_superseded: bool = False,
limit: int = _DEFAULT_SEARCH_LIMIT,
) -> list[MemoryHit]
Search entries lexically, newest first.
Matching is a case-insensitive substring test over summary, body and tags. It is deliberately simple: the frontmatter is what makes a stronger index — BM25, embeddings — addable later without changing the files themselves.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
query
|
str
|
Text to look for. Empty matches everything. |
''
|
kind
|
MemoryKind | None
|
Restrict to one memory kind. |
None
|
category
|
MemoryCategory | None
|
Restrict to one category. |
None
|
tags
|
tuple[str, ...]
|
Only return entries carrying all of these tags. |
()
|
include_superseded
|
bool
|
Whether to return entries a newer one replaced. |
False
|
limit
|
int
|
Maximum number of hits. |
_DEFAULT_SEARCH_LIMIT
|
Returns:
| Type | Description |
|---|---|
list[MemoryHit]
|
Matching entries, most recent first. |
recent_episodes ¶
recent_episodes(
*, since: datetime | None = None, limit: int = 100
) -> list[MemoryHit]
Return recent episodic entries, oldest first.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
since
|
datetime | None
|
Only return entries created at or after this instant. |
None
|
limit
|
int
|
Maximum number of entries. |
100
|
Returns:
| Type | Description |
|---|---|
list[MemoryHit]
|
Episodic entries in chronological order. |
Tools¶
deep_memory_agent.tools ¶
Agent-facing memory tools.
Each tool is a thin wrapper over
MemoryStore, bound to a backend by
closure. That binding is what enforces the core constraint of this package:
tools reach memory only through the deepagents backend, never through the
host filesystem, so the same agent works unchanged against a directory on disk,
thread state, or a remote store.
Tools are split in two sets on purpose. The recall set is read-only and is all the search agent gets; the write set is what makes the manager agent the single writer of the tree.
build_recall_tools ¶
build_recall_tools(store: MemoryStore) -> list[BaseTool]
Build the read-only memory tools.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store
|
MemoryStore
|
Store bound to the backend serving |
required |
Returns:
| Type | Description |
|---|---|
list[BaseTool]
|
The |
build_write_tools ¶
build_write_tools(
store: MemoryStore,
*,
consolidation_model: str | BaseChatModel | None = None,
) -> list[BaseTool]
Build the memory-writing tools.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
store
|
MemoryStore
|
Store bound to the backend serving |
required |
consolidation_model
|
str | BaseChatModel | None
|
Model used by |
None
|
Returns:
| Type | Description |
|---|---|
list[BaseTool]
|
The |
list[BaseTool]
|
when a model was given. |
Consolidation¶
deep_memory_agent.consolidation ¶
Consolidation: promoting episodes into durable knowledge.
Episodic memory on its own is a log. Without a step that reads it and extracts
what turned out to be stable, the agent has to re-read its whole history to
learn anything from it — expensive and unreliable. Consolidation is that step:
it reads recent episodes, asks a model which of them have hardened into facts,
rules or procedures, and writes those as semantic or procedural entries with
source: consolidation.
Episodes are never deleted. Consolidation only ever adds durable knowledge and supersedes semantic entries it contradicts, so the raw history stays auditable.
The function is public and takes a plain backend, so it can be scheduled from
ordinary code — a cron job, a nightly task — without going through a
conversation. The manager agent also exposes it as the memory_consolidate
tool.
ConsolidatedItem ¶
Bases: BaseModel
One piece of durable knowledge proposed by consolidation.
ConsolidationProposal ¶
Bases: BaseModel
What the model proposes to promote out of episodic memory.
ConsolidationResult
dataclass
¶
Outcome of a consolidation run.
Attributes:
| Name | Type | Description |
|---|---|---|
entries |
list[MemoryHit]
|
The durable entries that were written. |
episodes_considered |
int
|
How many episodic entries were read. |
rationale |
str
|
The model's explanation for its choices. |
consolidate_memory ¶
consolidate_memory(
backend: BackendProtocol,
model: str | BaseChatModel,
*,
since: datetime | None = None,
limit: int = _DEFAULT_EPISODE_LIMIT,
) -> ConsolidationResult
Promote stable patterns from episodic into semantic and procedural memory.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
BackendProtocol
|
Backend serving the |
required |
model
|
str | BaseChatModel
|
Chat model, or a model identifier resolvable by
|
required |
since
|
datetime | None
|
Only consider episodes created at or after this instant. |
None
|
limit
|
int
|
Maximum number of episodes to read. |
_DEFAULT_EPISODE_LIMIT
|
Returns:
| Type | Description |
|---|---|
ConsolidationResult
|
The entries written, how many episodes were read, and the model's |
ConsolidationResult
|
rationale. Writing nothing is a normal outcome. |
Backends¶
deep_memory_agent.backends ¶
Backend wiring for the memory filesystem.
The agents in this package never touch the host filesystem: every read and
write goes through a deepagents BackendProtocol, which is what maps the
virtual /memory/ tree onto real storage.
The default wiring is a CompositeBackend that routes /memory/ to a
FilesystemBackend rooted at memory_dir, and leaves everything else on an
ephemeral StateBackend. Memory therefore lands on disk as plain markdown
files — inspectable, diffable, versionable with git — while the agent's scratch
files stay in thread state and disappear with it.
That default only holds inside a deep agent. StateBackend reads and writes
through LangGraph's config keys and raises outside a graph execution, and
CompositeBackend fans unscoped glob/grep calls out to every backend —
so a standalone caller such as consolidate_memory hits the default even
though all of its paths live under /memory/. Pass for_deep_agent=False to
swap the default for an empty scratch directory instead.
build_memory_backend ¶
Build the default backend for a memory directory.
The directory is created if it does not exist. Paths under /memory/ are
served from it; where anything else goes depends on for_deep_agent.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
memory_dir
|
str | Path
|
Host directory that stores the memory tree. |
required |
for_deep_agent
|
bool
|
Whether the backend will be driven by a deep agent.
When |
True
|
Returns:
| Type | Description |
|---|---|
CompositeBackend
|
A composite backend with |
resolve_backend ¶
resolve_backend(
memory_dir: str | Path | None = None,
backend: BackendProtocol | None = None,
) -> BackendProtocol
Resolve the backend an agent factory should use.
Exactly one of memory_dir and backend must be given: memory_dir for
the default on-disk wiring, backend to plug in your own storage. Passing
both would leave it ambiguous which one actually serves /memory/, so it is
rejected rather than silently resolved.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
memory_dir
|
str | Path | None
|
Host directory to build the default backend from. |
None
|
backend
|
BackendProtocol | None
|
A ready-made backend serving the |
None
|
Returns:
| Type | Description |
|---|---|
BackendProtocol
|
The backend to hand to the agent. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both arguments are given, or neither is. |
Layout¶
deep_memory_agent.layout ¶
Layout of the virtual memory filesystem.
Every path in this module is a virtual path inside the deepagents backend,
rooted at MEMORY_ROOT. Nothing here
touches the host filesystem: the mapping from /memory/ to real storage is the
backend's job (see deep_memory_agent.backends).
The tree deliberately departs from a flat events.md / facts.md layout in two
ways:
- Episodic categories are sharded by month so a single file never grows past what fits in a context window.
- Every directory owns an
index.mdthat is a router — one line per file — and never holds memory content itself.
ROOT_INDEX_PATH
module-attribute
¶
Top-level router pointing at the three memory kinds.
PREFERENCES_PATH
module-attribute
¶
Stable user preferences, kept at the root because they cut across kinds.
CATEGORY_KIND
module-attribute
¶
CATEGORY_KIND: dict[MemoryCategory, MemoryKind] = {
MemoryCategory.EVENTS: MemoryKind.EPISODIC,
MemoryCategory.FEEDBACKS: MemoryKind.EPISODIC,
MemoryCategory.ERRORS: MemoryKind.EPISODIC,
MemoryCategory.FACTS: MemoryKind.SEMANTIC,
MemoryCategory.RULES: MemoryKind.SEMANTIC,
MemoryCategory.PREFERENCES: MemoryKind.SEMANTIC,
MemoryCategory.PROCEDURE: MemoryKind.PROCEDURAL,
}
Which kind each category belongs to.
KIND_DIRECTORIES
module-attribute
¶
KIND_DIRECTORIES: dict[MemoryKind, str] = {
MemoryKind.EPISODIC: EPISODIC_DIR,
MemoryKind.SEMANTIC: SEMANTIC_DIR,
MemoryKind.PROCEDURAL: PROCEDURAL_DIR,
}
Directory that holds each kind, including its index.md.
MemoryKind ¶
Bases: StrEnum
The three memory kinds of the CoALA-style taxonomy.
EPISODIC
class-attribute
instance-attribute
¶
What happened: events, feedback and errors, tied to a moment in time.
SEMANTIC
class-attribute
instance-attribute
¶
What is true: facts, rules and preferences, detached from any episode.
PROCEDURAL
class-attribute
instance-attribute
¶
How things are done: repeatable operating procedures.
MemoryCategory ¶
Bases: StrEnum
A concrete file family inside a memory kind.
EVENTS
class-attribute
instance-attribute
¶
Episodic: things that happened during a session.
FEEDBACKS
class-attribute
instance-attribute
¶
Episodic: corrections and judgements received from a user.
ERRORS
class-attribute
instance-attribute
¶
Episodic: mistakes made, so they are not repeated.
FACTS
class-attribute
instance-attribute
¶
Semantic: statements believed to be true right now.
RULES
class-attribute
instance-attribute
¶
Semantic: constraints and policies that govern behaviour.
PREFERENCES
class-attribute
instance-attribute
¶
Semantic: how the user wants the agent to behave.
PROCEDURE
class-attribute
instance-attribute
¶
Procedural: one file per operating procedure.
index_path ¶
index_path(kind: MemoryKind | None = None) -> str
Return the path of a router index.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
kind
|
MemoryKind | None
|
Memory kind whose index is wanted. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Virtual path of the |
category_directory ¶
category_directory(category: MemoryCategory) -> str
Return the directory holding a category's files.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
category
|
MemoryCategory
|
Category to locate. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Virtual directory path, with a trailing slash. |
shard_label ¶
Return the monthly shard label (YYYY-MM) an entry belongs to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
when
|
datetime | None
|
Instant to label. Defaults to now, in UTC. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The shard label, e.g. |
slugify ¶
Turn free text into a filename-safe slug.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Text to slugify, typically a procedure title. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A lowercase, hyphen-separated slug. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
entry_path ¶
entry_path(
category: MemoryCategory,
*,
when: datetime | None = None,
title: str | None = None,
) -> str
Return the file an entry of this category must be written to.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
category
|
MemoryCategory
|
Category of the entry. |
required |
when
|
datetime | None
|
Instant the entry refers to; selects the monthly shard for episodic categories. Defaults to now, in UTC. |
None
|
title
|
str | None
|
Procedure title, required for
|
None
|
Returns:
| Type | Description |
|---|---|
str
|
Virtual path of the target file. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If a procedure is requested without a title. |
Entries¶
deep_memory_agent.entry ¶
Memory entries and their YAML frontmatter.
A memory file is an append-only markdown document made of entries. Each entry carries a YAML frontmatter block so that provenance (when, from where, how sure) travels with the content, and so a newer statement can explicitly supersede an older one instead of silently coexisting with it.
---
id: mem_2026-08-24_9f3a1c
created: 2026-08-24T10:15:00+00:00
type: semantic
category: facts
source: user_message
confidence: high
tags: [pricing, acme]
supersedes: mem_2026-06-01_4b2e77
summary: ACME moved to the Enterprise plan
---
ACME switched from the Team plan to Enterprise on 2026-08-24.
The format stays plain markdown on purpose: readable by a human, diffable by git, and cheap to index later with BM25 or embeddings without changing the source of truth.
Confidence ¶
Bases: StrEnum
How much the agent trusts an entry.
MemoryEntry
dataclass
¶
A single unit of memory, with its provenance.
Attributes:
| Name | Type | Description |
|---|---|---|
entry_id |
str
|
Unique identifier, used by |
created |
datetime
|
Creation instant, always timezone-aware. |
category |
MemoryCategory
|
Which file family the entry belongs to. |
body |
str
|
Markdown content of the entry. |
summary |
str
|
One-line description, used to build router indexes. |
source |
str
|
Where the information came from, e.g. |
confidence |
Confidence
|
How much the entry is trusted. |
tags |
tuple[str, ...]
|
Free-form labels used to narrow searches. |
supersedes |
str | None
|
Identifier of the entry this one replaces, if any. |
superseded_by |
str | None
|
Identifier of the entry that replaced this one, if any. |
replaced_by ¶
replaced_by(entry_id: str) -> MemoryEntry
Return a copy of this entry marked as superseded.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entry_id
|
str
|
Identifier of the entry that replaces this one. |
required |
Returns:
| Type | Description |
|---|---|
MemoryEntry
|
A new entry; the original is left untouched. |
new_entry_id ¶
Mint a unique, sortable-by-day entry identifier.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
when
|
datetime | None
|
Instant the entry was created. Defaults to now, in UTC. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
An identifier such as |
render_entry ¶
render_entry(entry: MemoryEntry) -> str
Render an entry as a frontmatter block followed by its body.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
entry
|
MemoryEntry
|
Entry to render. |
required |
Returns:
| Type | Description |
|---|---|
str
|
Markdown text ending with a trailing newline. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the body contains a line that is exactly |
parse_entries ¶
parse_entries(text: str) -> list[MemoryEntry]
Parse every well-formed entry out of a memory file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Full content of a memory file. |
required |
Returns:
| Type | Description |
|---|---|
list[MemoryEntry]
|
The entries found, in file order. |
split_document ¶
split_document(text: str) -> tuple[str, list[MemoryEntry]]
Split a memory file into its heading preamble and its entries.
Blocks whose frontmatter is unreadable — hand-edited files happen — are skipped rather than raising, so a single malformed entry never blinds the agent to the rest of the file. Skipped blocks are also dropped from the round-trip, so callers that rewrite a file should expect to lose them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Full content of a memory file. |
required |
Returns:
| Type | Description |
|---|---|
str
|
A |
list[MemoryEntry]
|
entry, kept verbatim. |
render_document ¶
render_document(
preamble: str, entries: list[MemoryEntry]
) -> str
Render a whole memory file from its preamble and entries.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
preamble
|
str
|
Heading text to keep above the entries. |
required |
entries
|
list[MemoryEntry]
|
Entries to render, in the order they should appear. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The full file content, ending with a trailing newline. |
Indexes¶
deep_memory_agent.index ¶
Router indexes.
Every memory directory owns an index.md whose only job is to let an agent
decide what to load without loading everything: one row per file, holding a
one-line description, the tags seen in it and the date it last changed — never
the memory content itself.
The index is a markdown table so it stays readable and diffable:
| File | Description | Tags | Updated |
| --- | --- | --- | --- |
| events/2026-08.md | Session events for August 2026 | acme, pricing | 2026-08-24 |
IndexRow
dataclass
¶
One line of a router index.
Attributes:
| Name | Type | Description |
|---|---|---|
path |
str
|
File path, relative to the directory holding the index. |
description |
str
|
One-line summary of what the file contains. |
tags |
tuple[str, ...]
|
Labels seen across the file's entries. |
updated |
str
|
Date of the last write, as |
index_target ¶
index_target(
category: MemoryCategory, file_path: str
) -> tuple[str, str]
Return which index tracks a file, and under which relative path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
category
|
MemoryCategory
|
Category of the entry that was written. |
required |
file_path
|
str
|
Absolute virtual path of the file that was written. |
required |
Returns:
| Type | Description |
|---|---|
tuple[str, str]
|
A |
parse_index ¶
parse_index(text: str) -> tuple[str, dict[str, IndexRow]]
Split index content into its preamble and its rows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
Full content of an |
required |
Returns:
| Type | Description |
|---|---|
str
|
A |
dict[str, IndexRow]
|
The preamble is everything above the table, kept verbatim so a |
tuple[str, dict[str, IndexRow]]
|
hand-written explanation survives updates. |
render_index_table ¶
render_index_table(rows: dict[str, IndexRow]) -> str
Render index rows as a markdown table, sorted by path.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rows
|
dict[str, IndexRow]
|
Rows keyed by relative path. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The table, without a trailing newline. |
read_index_rows ¶
read_index_rows(
backend: BackendProtocol, path: str
) -> dict[str, IndexRow]
Read the rows of an index through the backend.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
BackendProtocol
|
Backend serving the memory tree. |
required |
path
|
str
|
Absolute virtual path of the |
required |
Returns:
| Type | Description |
|---|---|
dict[str, IndexRow]
|
Rows keyed by relative path; empty if the index does not exist yet. |
update_index ¶
update_index(
backend: BackendProtocol,
*,
category: MemoryCategory,
file_path: str,
description: str = "",
tags: tuple[str, ...] = (),
when: datetime | None = None,
) -> str
Record a file in its router index, creating or merging its row.
Tags accumulate across writes so the index keeps working as a lookup table; the description of the most recent write wins, since it is the freshest statement about what the file now holds.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
BackendProtocol
|
Backend serving the memory tree. |
required |
category
|
MemoryCategory
|
Category of the entry that was written. |
required |
file_path
|
str
|
Absolute virtual path of the file that was written. |
required |
description
|
str
|
One-line summary of the entry just written. |
''
|
tags
|
tuple[str, ...]
|
Tags of the entry just written. |
()
|
when
|
datetime | None
|
Instant of the write. Defaults to now, in UTC. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
The absolute virtual path of the index that was updated. |
Scaffolding¶
deep_memory_agent.scaffold ¶
Creation of the memory tree.
Scaffolding runs through the backend like everything else, so pointing an agent
at a StateBackend, a StoreBackend or a directory on disk all behave the
same. It is idempotent: existing files are never overwritten, which is what
makes it safe to call on every agent construction.
PROCEDURE_TEMPLATE
module-attribute
¶
PROCEDURE_TEMPLATE = "# {title}\n\n## When to use\n\n{when_to_use}\n\n## Preconditions\n\n{preconditions}\n\n## Steps\n\n{steps}\n\n## Tools required\n\n{tools}\n\n## Known failures\n\n{known_failures}\n"
Fixed section layout every procedure file follows.
Known failures is where episodic memory feeds back into procedural memory: a
mistake that keeps showing up in errors/ belongs here, so the agent reads the
fix at the moment it is about to repeat the mistake.
MEMORY_DIRECTORIES
module-attribute
¶
Directories the tree is made of, for documentation and tests.
ensure_memory_tree ¶
Create any missing file of the memory tree.
Episodic shards are deliberately not pre-created: they are named after the month they cover and appear the first time something is written to them.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
backend
|
BackendProtocol
|
Backend serving the memory tree. |
required |
Returns:
| Type | Description |
|---|---|
list[str]
|
The paths that were created, in a stable order. Empty when the tree was |
list[str]
|
already complete. |
Prompts¶
deep_memory_agent.prompts ¶
System prompts for the memory agents.
The prompts describe the tree and the rules that govern it — sharding, supersession, indexes as routers — because those rules are what keep a file-based memory from degenerating into an append-only log nobody can query.