mem01
Self-hosted long-term memory for AI agents.
mem01 extracts durable facts from conversation, stores them as beliefs with an explicit lifecycle (ADD / UPDATE / SUPERSEDE / INVALIDATE / MERGE), and retrieves a token-budgeted, conflict-filtered context block on each turn. Writes may call an LLM once per batch; reads do not call an LLM.
| Deploy | Self-hosted (your infrastructure) |
| Store | PostgreSQL + pgvector |
| Interfaces | HTTP API, Python SDK |
| Requirements | Docker (recommended), OpenAI-compatible API key for extraction/embeddings |
Product intent and constraints: PRODUCT.md.
Architecture
Agents / apps
│ HTTP or Python SDK
▼
┌──────────────────┐ ┌─────────────────────────┐
│ mem01 API │─────▶│ PostgreSQL + pgvector │
│ (FastAPI) │ │ beliefs + embeddings │
└──────────────────┘ └─────────────────────────┘
| Path | Behavior |
|---|---|
Write (remember) |
Messages → LLM extraction → belief ops → embed → Postgres |
Read (recall) |
Embed query → vector search + scope filters → conflict rules → token packer → context string |
Default model stack (configurable): gpt-5.6-sol for OpenAI extraction,
text-embedding-3-small (1536-d) for vectors. Anthropic is supported for
extraction; embeddings still need an embedding provider.
Quick start
1. Configure
cp .env.example .env
Set at least:
OPENAI_API_KEY=sk-...
MEM01_LLM_MODEL=gpt-5.6-sol
MEM01_LLM_MODEL is passed into the API container by Docker Compose and selected
by the API at startup. gpt-5.6-sol is the default for both the API and the
embedded Mem01Session runtime.
Docker Compose sets DATABASE_URL for the API container. Host-side Python tools should use:
DATABASE_URL=postgresql://mem01:mem01@localhost:5433/mem01
2. Run the stack
docker compose up -d --build
| Service | Address |
|---|---|
| API | http://localhost:8080 |
| OpenAPI | http://localhost:8080/docs |
| Health | http://localhost:8080/health |
| PostgreSQL | localhost:5433 (user / password / db: mem01) |
3. Call the API
curl -s http://localhost:8080/v1/remember \
-H 'Content-Type: application/json' \
-d '{
"user_id": "user_1",
"messages": [{"role": "user", "content": "I live in San Francisco."}]
}'
curl -s http://localhost:8080/v1/recall \
-H 'Content-Type: application/json' \
-d '{
"user_id": "user_1",
"query": "Where does the user live?",
"max_memory_tokens": 800
}'
Stop:
docker compose down
HTTP API
| Method | Path | Description |
|---|---|---|
GET |
/health |
Process liveness |
POST |
/v1/remember |
Ingest messages; extract and apply belief operations |
POST |
/v1/recall |
Retrieve a budgeted memory block for a query (include_history optional) |
POST |
/v1/history |
Full belief timeline (active + superseded + invalidated) |
POST |
/v1/correct |
Supersede a belief by id with a corrected value |
POST |
/v1/forget |
Invalidate a belief by id |
Request shapes
POST /v1/remember
{
"user_id": "user_1",
"project_id": "optional",
"messages": [
{"role": "user", "content": "..."},
{"role": "assistant", "content": "..."}
]
}
POST /v1/recall
{
"user_id": "user_1",
"query": "Where does the user live?",
"max_memory_tokens": 800,
"k": 20,
"include_history": false
}
- Default (
include_history: false): active only — single current truth for the agent. include_history: true: also returns superseded/invalidated, labeled as[active]/[superseded]so temporal questions (“before SF?”) work without polluting every turn.
POST /v1/history
{
"user_id": "user_1",
"include_invalidated": true,
"limit": 100
}
Chronological audit timeline (no vector search). Use for admin UI, medical-style charts, or “show me what changed.”
POST /v1/correct
{
"memory_id": "bel_...",
"new_value": "User lives in Oakland",
"confidence": 0.95
}
POST /v1/forget
{
"memory_id": "bel_...",
"reason": "optional"
}
Interactive schema: http://localhost:8080/docs
Python SDK
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev,openai]"
Ensure Postgres is running (docker compose up -d or your own instance) and DATABASE_URL is set in .env.
from mem01 import MemoryClient, create_belief_store
from mem01.embeddings.openai_embedder import OpenAIEmbedder
from mem01.llm.openai_compat import OpenAICompatLLM
store = create_belief_store() # requires DATABASE_URL → Postgres + pgvector
client = MemoryClient(
store=store,
embedder=OpenAIEmbedder(),
llm=OpenAICompatLLM(),
)
client.remember(
[{"role": "user", "content": "I prefer TypeScript."}],
user_id="user_1",
)
block = client.recall("language preference", user_id="user_1", max_memory_tokens=800)
print(block.text, block.tokens_used, block.latency_ms)
| Method | Description |
|---|---|
remember(messages, user_id=...) |
Extract ops and persist |
recall(query, user_id=..., max_memory_tokens=800) |
Retrieve packed context |
correct(memory_id, new_value) |
Supersede by id |
forget(memory_id) |
Invalidate by id |
Configuration
| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
For real extract/embed | OpenAI (or compatible) API key |
DATABASE_URL |
For API / SDK | postgresql://... (Docker host: port 5433) |
MEM01_EMBEDDING_DIM |
No (default 1536) |
Must match embedding model dimensions |
MEM01_LLM_MODEL |
No (default gpt-5.6-sol) |
OpenAI extraction model used by the API and embedded runtime |
MEM01_EMBEDDING_MODEL |
No (default text-embedding-3-small) |
OpenAI embedding model name |
Neon: use a Neon connection string as DATABASE_URL (include sslmode=require). No application code changes.
Belief model (summary)
Stored units are beliefs, not raw chat chunks. Operations:
| Op | Effect |
|---|---|
ADD |
Insert active belief |
UPDATE |
Revise content/confidence in place |
SUPERSEDE |
New active belief; previous marked superseded |
INVALIDATE |
Soft-delete (excluded from default recall) |
MERGE |
Collapse duplicates into one canonical belief |
Scopes: user, project, agent, session. Default sharing is user- and project-level.
Full design: PRODUCT.md.
Development
# Stack
docker compose up -d --build
# Tests (unit tests use an in-process store; Postgres tests need DATABASE_URL)
source .venv/bin/activate
pip install -e ".[dev,openai]"
pytest
# Postgres integration tests
export DATABASE_URL=postgresql://mem01:mem01@localhost:5433/mem01
pytest tests/test_postgres_store.py
Repository layout:
| Path | Role |
|---|---|
src/mem01/ |
Library and API |
src/mem01/api/app.py |
FastAPI application |
src/mem01/store/postgres_store.py |
Postgres + pgvector backend |
docker-compose.yml |
API + database |
examples/basic_usage.py |
CLI walkthrough |
Status
| Component | Status |
|---|---|
| Belief store + ops | Implemented |
| Write path (extract → apply) | Implemented |
| Read path (search → conflict → pack) | Implemented |
| HTTP API + Docker Compose | Implemented |
| MCP server | Not yet |
| Background consolidation | Not yet |
| Multi-tenant hosted SaaS | Out of scope for v1 |
License
See repository license file when published.
Release files for mem01-engine 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mem01_engine-0.1.0.tar.gz | 70.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mem01_engine-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 118.0 kB
Release files / mem01_engine-0.1.0.tar.gz
| Download URL | mem01_engine-0.1.0.tar.gz |
|---|---|
| Size | 70.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7bfda2c2688e733c43896ead0655cb43361687bddd01a262f00b9e7448ba7359
|
|
BLAKE2b-256 checksum How to use checksums |
1a2ac30fab27ce78388398bffec3fcb5474873791af04239bb064e3c5c2ab7db
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / mem01_engine-0.1.0-py3-none-any.whl
| Download URL | mem01_engine-0.1.0-py3-none-any.whl |
|---|---|
| Size | 47.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b33eb4a86d05610dc42797791c767b192e711e42f58dc0956deeb2a52c10f3c6
|
|
BLAKE2b-256 checksum How to use checksums |
a1e021bab0fbbef32ab520455ac68da345cbd26ddbd09251eddf152709ff168a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|