Help your agent remember what matters.
Keep preferences, carry context across sessions, and bring your memory to the next agent.
Highlights · Quick start · Integrations · CLI · Architecture · Contributing
English · 中文
Octop Memory is a persistent, portable memory system for LLM agents. Give a personal assistant lasting preferences, keep decisions and project context available across conversations, or move accumulated memory between supported hosts. Start locally with SQLite, then add PostgreSQL or model-assisted extraction as needed.
It powers memory in the Octop ecosystem and also works independently as a Python library, CLI, or JSON-RPC bridge. OpenClaw and Hermes adapters connect their host hooks and tools to the same memory runtime. Your host manages agent execution and model scheduling; Octop Memory handles capture, extraction, recall, storage, and migration.
Memory worth keeping. Context worth bringing along. Save it, recall it, and carry it between supported agents.
✨ Highlights
| What stands out | What you get | |
|---|---|---|
| 🪶 | Start small, add what you need | Zero core dependencies: Python's standard library + SQLite/FTS5. Manual storage and lexical recall work without a model. |
| 🧠 | Turn conversations into lasting memory | Model-assisted extraction and promotion turn raw events into facts with evidence references; entity pages and episodes organize the context. |
| 🔍 | Recall that fits the prompt | Full-text search, ranking, deduplication, and token budgets select context for the current query. |
| 🧳 | Bring your memory along | Export/import and portable .hmpkg packages move memory between supported hosts, including OpenClaw and Hermes. |
| 🔌 | Connect to your agent | Python MemoryService, a JSON-RPC bridge, and dedicated host plugins share the same runtime. |
| 💾 | Choose your storage | SQLite for a local start; PostgreSQL for server deployments. |
| 🌳 | Keep facts organized | Canonical AtomCard facts, entity pages, and a root → branch → leaf tree make memory easier to navigate; namespaces separate stores within a backend. |
| 🔖 | Resume conversations | Optional LangGraph checkpoints preserve execution state alongside long-term memory, with SQLite and PostgreSQL support. |
Python 3.12+ is required. Automated extraction, promotion checks, and page regeneration use an injected LLMClient;
installing the package alone does not configure a model. See the integration guide for host setup.
Existing installations should read the rename migration guide before upgrading.
Quick start
pip install octop-memory
from octop_memory import Memory, MemoryService
memory = Memory(
namespace="demo",
backend_config={"db_path": "./demo.sqlite"},
)
memory.store("User prefers Python for backend services", topic="preferences")
# Basic fact search returns MemoryNode leaf projections.
for node in memory.recall("Python"):
print(node.content)
# Prompt recall adds source selection, ranking, deduplication, and budgeting.
result = MemoryService(memory).recall("Python")
print(result.rendered)
This creates a local database. Use terms present in the stored text for a minimal FTS example. Memory.search() searches archived conversation messages; it is a separate API from fact recall.
Optional dependencies
| Install | Purpose |
|---|---|
pip install "octop-memory[cli]" |
CLI and OpenClaw setup commands |
pip install "octop-memory[postgres]" |
PostgreSQL memory backend |
pip install "octop-memory[langgraph]" |
SQLite LangGraph checkpointer |
pip install "octop-memory[langgraph-postgres]" |
PostgreSQL LangGraph checkpointer |
Vector search interfaces and Chroma/Qdrant adapters exist in the code, but current tests use fake/mock implementations; real Chroma/Qdrant integration remains unverified. Vector search is not enabled by default and is not yet presented as a fully supported installation option. Using it requires initializing an index and injecting vector_index and embedding_provider into Memory; installing dependencies alone does not enable it. The database backend remains sqlite or postgres.
memory = Memory(
namespace="demo",
backend="postgres",
backend_config={"dsn": "postgresql://user:pass@localhost/octop_memory"},
)
Use deployment configuration for real credentials. SQLite isolates memory with table prefixes; PostgreSQL uses namespace-first keys in the shared octop_memory schema.
CLI
Install [cli]. Global options precede subcommands; use an explicit database and namespace when following examples.
octop-memory --db ./demo.sqlite --namespace demo memory store --content "User prefers Python"
octop-memory --db ./demo.sqlite --namespace demo recall "Python"
octop-memory --db ./demo.sqlite --namespace demo memory tree
octop-memory --help
| Commands | Purpose |
|---|---|
raw, candidate, atom, entity, page |
Inspect and manage memory layers |
episode, digest, journal |
Event summaries and decision records |
memory, recall, thread |
Tree operations, prompt recall, thread state |
export, import, migrate, portable |
Backup and migration |
db, gc, consolidate |
Storage maintenance and lifecycle operations |
config, openclaw, backfill |
Configuration, integration, historical extraction |
Run <command> --help for arguments. db slim FILE previews SQLite checkpoint deduplication; --apply --offline creates a backup and performs it without deleting history. Read checkpoint compatibility and maintenance before migration or reader downgrade.
The dashboard is available from a source checkout with [dashboard] dependencies; its modules are currently excluded from the wheel. Installing octop-memory[dashboard] from PyPI alone does not provide the dashboard command.
External agent adapters
plugins/<host>/ maps external agent hooks, tools, and configuration to the shared Python runtime.
OpenClaw and Hermes adapters are available today. Other agents can integrate through the Python API or JSON-RPC,
with an adapter implementing their host contract.
| Integration | Use case | Entry point |
|---|---|---|
| In-process Python | Custom agents / Python applications | MemoryService.capture_turn() / recall() / search() / get() / extract() |
| JSON-RPC bridge | Cross-language or separate processes | stdio octopmemory-bridge |
| Host plugin | Agent-specific lifecycle and tool interfaces | plugins/<host>/; OpenClaw and Hermes currently implemented |
See the integration guide for installation, configuration, profiles, troubleshooting, and adapter boundaries.
Move memory with octop-memory portable list-sources / pack / adopt / doctor. Exported .hmpkg files contain memory data; keep them out of source control.
Code architecture
src/octop_memory/
├── core.py / types.py # Public Memory API and data structures
├── service.py # MemoryService: Python host entry point
├── application/ # MemoryRuntime, config, host files, path projection
├── pipeline/ # Extraction, promotion, recall, pages, episodes, lifecycle
├── storage/ # SQLite / PostgreSQL, checkpoints, vector indexes
├── ports/ # External capability interfaces, including LLM clients
├── domain/ # Shared alias and time rules
├── adapters/ # JSON-RPC bridge, CLI, source-only dashboard
└── operations/ # Import/export, migration, portable packages
plugins/ # External agent adapters, organized by host
examples/ # Public API example
tests/ / evals/ # Behavior tests / synthetic recall evaluation
docs/agent/ # Harness project map, decisions, and handoff
Adapters call inward through application and pipeline/core/storage layers. MemoryService and Bridge
share MemoryRuntime; pipeline/storage do not depend on adapters, and backend-specific SQL stays in storage.
The source dashboard's direct SQLite access is an existing exception.
Host call flow
Python host → MemoryService ─────────┐
Hermes → in-process Bridge ──────────┤
OpenClaw → JSON-RPC bridge ───────────┴→ MemoryRuntime → pipelines → Memory
CLI → application / operations ────────────────────────────────────┘
├→ SQLite / PostgreSQL
└→ optional vector index
Hermes currently calls Bridge in-process; OpenClaw uses a bridge subprocess. MemoryService.recall() also calls the recall pipeline directly. Facts live in AtomCard; tree leaves reference atoms and project their content. The tree is an organization view, not an additional copy or independent recall source.
Long-term memory flow
RawEvent ──extraction──→ Candidate ──promotion──→ AtomCard ──dirty / regeneration──→ EntityPage
└──episode extraction──→ Episode └──atom_id reference──→ tree leaf
Candidates do not all require human approval. Promotion checks value, evidence, entity resolution,
duplicates, and conflicts; it can promote, merge, or drop candidates automatically, leaving review/conflict
cases for user action. Pages are marked dirty and regenerated when triggered by runtime/CLI/host,
rather than immediately after every write. Episode extraction is a parallel path from raw events.
Manual Memory.store() needs no model and directly creates RawEvent/Candidate/AtomCard plus a leaf reference.
Prompt recall routes atom and raw by default, adds page_headline when an entity is resolved, and adds vector when configured. With the default raw fallback policy, durable hits suppress raw; passing the current session/thread excludes its raw events from prompt injection.
Start with CONTRIBUTING.md; the project map covers architecture and data flow. AI contributors use AGENTS.md, with task clarification and handoff in HANDOFF.md.
Development
make install # uv sync --group dev
make install-hooks # required once per clone
make all # format + lint + strict mypy + tests
uv build # Python wheel + source distribution
Run PostgreSQL behavior tests against a real test server with TEST_POSTGRES_DSN; skipped PG cases do not prove compatibility. OpenClaw has its own npm ci, npm test, and npm run build under plugins/openclaw/octopmemory/.
The repository retains tests, CI, examples, and plugins; the Python sdist contains the sources needed to rebuild the wheel. Development and release procedures live in CONTRIBUTING.md.
License
MIT. Report vulnerabilities through the channels in SECURITY.md.
