Metadata-Version: 2.5
Name: octop-memory
Version: 1.0.0
Summary: Pluggable memory system with hierarchical recall, FTS search, and multiple backend support.
Project-URL: Homepage, https://github.com/TencentCloud/octop-memory
Project-URL: Repository, https://github.com/TencentCloud/octop-memory
Project-URL: Issues, https://github.com/TencentCloud/octop-memory/issues
Project-URL: Changelog, https://github.com/TencentCloud/octop-memory/blob/main/CHANGELOG.md
Author: orcakit
License: MIT
License-File: LICENSE
Keywords: agent,fts,llm,memory,recall,sqlite
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.12
Provides-Extra: chroma
Requires-Dist: chromadb>=0.4; extra == 'chroma'
Provides-Extra: cli
Requires-Dist: click>=8.0; extra == 'cli'
Provides-Extra: dashboard
Requires-Dist: click>=8.0; extra == 'dashboard'
Requires-Dist: fastapi>=0.110; extra == 'dashboard'
Requires-Dist: uvicorn[standard]>=0.29; extra == 'dashboard'
Provides-Extra: embeddings
Requires-Dist: sentence-transformers>=2.2; extra == 'embeddings'
Provides-Extra: langgraph
Requires-Dist: langgraph-checkpoint-sqlite>=2.0; extra == 'langgraph'
Requires-Dist: langgraph-checkpoint>=2.0; extra == 'langgraph'
Provides-Extra: langgraph-postgres
Requires-Dist: langgraph-checkpoint-postgres>=2.0; extra == 'langgraph-postgres'
Requires-Dist: langgraph-checkpoint>=2.0; extra == 'langgraph-postgres'
Requires-Dist: psycopg[binary]>=3.1; extra == 'langgraph-postgres'
Provides-Extra: postgres
Requires-Dist: psycopg[binary]>=3.1; extra == 'postgres'
Provides-Extra: qdrant
Requires-Dist: qdrant-client>=1.7; extra == 'qdrant'
Description-Content-Type: text/markdown

<p align="center">
  <img src="assets/images/banner.jpeg" alt="Octop Memory — a little octopus keeping memories safe" width="880" />
</p>

<p align="center">
  <strong>Help your agent remember what matters.</strong><br />
  Keep preferences, carry context across sessions, and bring your memory to the next agent.
</p>

<p align="center">
  <a href="pyproject.toml"><img alt="Python 3.12+" src="https://img.shields.io/badge/Python-3.12%2B-3776AB?logo=python&amp;logoColor=white" /></a>
  <a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/License-MIT-E85D75" /></a>
  <a href="pyproject.toml"><img alt="Core dependencies: 0" src="https://img.shields.io/badge/Core_dependencies-0-E85D75" /></a>
  <a href="#optional-dependencies"><img alt="Storage: SQLite and PostgreSQL" src="https://img.shields.io/badge/Storage-SQLite_%7C_PostgreSQL-4169E1" /></a>
  <a href="CONTRIBUTING.md"><img alt="Code style: Ruff" src="https://img.shields.io/badge/Code_style-Ruff-261230?logo=ruff&amp;logoColor=white" /></a>
</p>

<p align="center">
  <a href="#highlights">Highlights</a> ·
  <a href="#quick-start">Quick start</a> ·
  <a href="#external-agent-adapters">Integrations</a> ·
  <a href="#cli">CLI</a> ·
  <a href="#code-architecture">Architecture</a> ·
  <a href="CONTRIBUTING.md">Contributing</a>
</p>

<p align="center">
  <b>English</b> · <a href="README_CN.md">中文</a>
</p>

---

**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.

<a id="highlights"></a>

## ✨ 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](docs/integrations.md) for host setup.
Existing installations should read the [rename migration guide](docs/integrations.md#更名与已有安装迁移) before upgrading.

## Quick start

```bash
pip install octop-memory
```

```python
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`.

```python
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.

```bash
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](CONTRIBUTING.md#checkpoint-维护) 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](docs/integrations.md) 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

```text
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

```text
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

```text
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](CONTRIBUTING.md); the [project map](docs/agent/PROJECT_MAP.md) covers architecture and data flow. AI contributors use [AGENTS.md](AGENTS.md), with task clarification and handoff in [HANDOFF.md](docs/agent/HANDOFF.md).

## Development

```bash
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](CONTRIBUTING.md).

## License

[MIT](LICENSE). Report vulnerabilities through the channels in [SECURITY.md](SECURITY.md).
