Compare commits

..

43 Commits

Author SHA1 Message Date
Saket Aryan fb224083e4 chore(release): promote Python SDK to 2.0.0 and TS SDK to 3.0.0 (#4860) 2026-04-16 17:13:50 +05:30
Chaithanya Kumar 30469aec17 docs: new algorithm migration guides + memory evaluation (#4811)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
Co-authored-by: Saket Aryan <saketaryan2002@gmail.com>
2026-04-16 17:13:13 +05:30
Saket Aryan 50db9e428d chore(release): bump SDK versions to next beta (#4859) 2026-04-16 16:23:50 +05:30
soumil-rathi fb87349664 fix(oss): v3 entity cleanup, filter fixes, and QA hardening (TS + Python) (#4858)
Co-authored-by: Soumil Rathi <soumilrathi@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 12:17:13 +05:30
Saket Aryan 8827553576 fix: adopt new v3 memory endpoints in Python + TS clients (#4856) 2026-04-16 05:28:49 +05:30
Kabir Kohli c8e20a9bb5 fix(docs): resolve duplicate operationIds and expiration_date type in openapi spec (#4854) 2026-04-16 04:09:51 +05:30
Kartik 93a51f4763 test: update integration tests for v1.1 output_format (#4847) 2026-04-16 01:37:51 +05:30
Saket Aryan 86fe275f53 fix(ts): entity store isolation, backward compat, pgvector + redis init fixes (#4841) 2026-04-15 21:01:01 +05:30
Kartik e6d6276bb9 refactor: add entity ID and search param validation, rename textLemmatized field, update tests (#4843) 2026-04-15 20:57:09 +05:30
Chaithanya Kumar 9692726db4 fix(ts-oss): isolate entity store from memory store by default (#4829)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-04-15 14:47:43 +05:30
soumil-rathi d8d776636f fix(v3): migration crashes + entity linking on OSS (#4836)
Co-authored-by: Soumil Rathi <soumilrathi@gmail.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-15 14:46:28 +05:30
Kartik a5a688295e fix: prevent arbitrary code execution via pickle in FAISS vector store (#4833) 2026-04-15 00:02:07 +05:30
Saket Aryan 5d40592e42 chore: version bump to beta1 (#4827) 2026-04-14 18:05:22 +05:30
soumil-rathi a488e19044 feat(oss): port v3 pipeline with hybrid search, entity extraction, and additive scoring (#4805)
Co-authored-by: Soumil Rathi <soumilrathi@gmail.com>
Co-authored-by: Saket Aryan <saketaryan2002@gmail.com>
Co-authored-by: chaithanyak42 <chaithanya.kumar42a@gmail.com>
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-04-14 18:00:58 +05:30
Parteeksachdeva 57f944e18a fix: allow anonymousTelemetryId in openclaw.json config (#4826)
Co-authored-by: parteeksachdeva-123 <parteek.sachdeva@aerchain.io>
2026-04-14 17:31:28 +05:30
Gabriel Stein fe3f7ae618 fix(plugin): remove invalid keys from Claude plugin config (#4821) 2026-04-14 01:13:03 +05:30
shafdev 4a7e166f9a fix(tests): use top_k instead of limit in test_server_params (#4820) 2026-04-14 01:11:31 +05:30
Kartik 85768e78e7 fix(docs): remove chrome extension cookbooks (#4813) 2026-04-13 22:14:00 +05:30
Yunsu 7b395f3bf7 fix(openai): make store opt-in so it stops leaking to non-OpenAI backends (#4757) 2026-04-13 21:53:22 +05:30
HUANG XIAO 4180409b09 fix(s3vectors): handle vector=None in update() to prevent boto3 validation error (#4594) 2026-04-13 21:12:49 +05:30
Joe Wu 649e719ce6 fix: LLM config manager falls back to userConf.url for baseURL (#4715) (#4761) 2026-04-13 20:46:18 +05:30
Kartik 1a53852d93 test: update valkey cluster search test to use top_k parameter (#4815) 2026-04-13 20:44:18 +05:30
Chinnu Abey ac9cdd4840 Fix incorrect use of SentenceTransformer for cross-encoder reranker models (#4806) 2026-04-13 20:14:22 +05:30
Swarnaprakash Udayakumar cf530c4bec feat(valkey): add cluster mode enabled (CME) support (#4759) 2026-04-13 20:07:11 +05:30
Saket Aryan 92b958c1cc chore: bump Python SDK to v2.0.0b0 and Node SDK to v3.0.0-beta.0 (#4810) 2026-04-13 15:51:33 +05:30
Asish Kumar c239d8a483 fix(client): prevent feedback telemetry TypeError (#4795) 2026-04-12 03:06:05 +05:30
Kartik 9d6b79a14e fix(sdk): removing the enable graph flag and switching from snake case to camel case for client ts sdk (#4776)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 02:40:54 +05:30
Kartik e44b46ef2e fix(sdk): removing deprecating param from our sdk and docs changes with it (#4740) 2026-04-12 00:34:58 +05:30
Saket Aryan 3882af7450 fix(cli): persistent anonymous telemetry ID + pass source=CLI in all API calls (#4789) 2026-04-11 21:00:05 +05:30
Saket Aryan d39ebad09f fix(openclaw): persistent anonymous telemetry ID, flush fix, and email resolution (#4790)
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:57:14 +05:30
Gabriel Stein 9d82e2329d refactor(telemetry): sample OSS hot-path events at 10% to reduce PostHog volume (#4771) 2026-04-11 16:25:38 +05:30
szinvas 789cc9d607 docs - replace session_id with run_id (#4742) 2026-04-10 20:06:59 +05:30
Jared Diaz e59e3d5f0c Add deepseek.ts to src/llms with corresponding unit tests. Updates fa… (#4613)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-04-10 20:06:22 +05:30
Kartik d926f3697c fix(docs): eliminate ~222 SEO redirect chains on docs.mem0.ai (#4768) 2026-04-10 19:33:45 +05:30
Kartik c996b0e7fa docs: removing the changelog.mdx file adn replacing it with new changelog system (#4750) 2026-04-10 19:07:43 +05:30
Kartik 78ca85a260 refactor: update OpenClaw plugin config, hook logic, and documentation (#4764) 2026-04-09 17:36:05 +05:30
Kartik 88f696a60a refactor: drop orgId, projectId, enableGraph config options, update CLI prompts, and clean up related code (#4734) 2026-04-09 14:57:33 +05:30
Ignazio De Santis 081eca6d8f fix: guard temp_uuid_mapping lookups against LLM-hallucinated IDs (fixes #3931) (#4674)
Co-authored-by: kartik-mem0 <kartik.labhshetwar@mem0.ai>
2026-04-08 21:55:52 +05:30
Kartik 2434b9d550 docs: add ChatDev integration guide and update integrations list (#4751) 2026-04-08 20:16:04 +05:30
Rakhee Singh 3ffea554bc fix(azure_openai): forward response_format to Azure OpenAI API (#4689) 2026-04-08 19:22:02 +05:30
Rakhee Singh 1ad8a59b0c fix(deepseek): forward response_format to OpenAI-compatible API (#4688) 2026-04-08 19:21:11 +05:30
Saket Aryan a670333d67 feat: add AGENTS.md for AI coding agent instructions (#4726) 2026-04-06 21:32:43 +05:30
Saket Aryan 4c2db3e68b feat(skills): introduce Mem0 skill graph with dedicated CLI and Vercel AI SDK skills (#4725) 2026-04-06 20:41:29 +05:30
373 changed files with 23160 additions and 24512 deletions
+580
View File
@@ -0,0 +1,580 @@
# AGENTS.md
This file provides context for AI coding assistants (Claude Code, Cursor, GitHub Copilot, Codex, etc.) working with the Mem0 repository.
## Project Overview
**Mem0** ("mem-zero") is an intelligent memory layer for AI agents and assistants. It provides persistent, personalized memory via both a hosted platform API and self-hosted open-source SDKs.
- **Repository**: https://github.com/mem0ai/mem0
- **Documentation**: https://docs.mem0.ai
- **License**: Apache-2.0
## Repository Structure
This is a **polyglot monorepo** containing Python and TypeScript packages, CLIs, servers, plugins, documentation, and evaluation tooling.
### Key Directories
| Directory | Description |
|-----------|-------------|
| `mem0/` | Core Python SDK (`mem0ai` on PyPI) — memory, LLMs, embeddings, vector stores, graphs, rerankers |
| `mem0-ts/` | TypeScript SDK (`mem0ai` on npm) — client + OSS memory |
| `cli/python/` | Python CLI (`mem0-cli` on PyPI) — Typer-based, entry point `mem0` |
| `cli/node/` | Node CLI (`@mem0/cli` on npm) — Commander-based, entry point `mem0` |
| `vercel-ai-sdk/` | `@mem0/vercel-ai-provider` — Vercel AI SDK memory provider |
| `openclaw/` | `@mem0/openclaw-mem0` — OpenClaw plugin for Claude Code / AI editors |
| `server/` | FastAPI REST server for self-hosted Mem0 (Docker: FastAPI + PostgreSQL/pgvector + Neo4j) |
| `openmemory/` | Self-hosted memory platform — `api/` (FastAPI + Alembic + MCP server) and `ui/` (Next.js 15 + React 19) |
| `mem0-plugin/` | AI editor plugins (Claude Code, Cursor, Codex) — MCP server connection, lifecycle hooks, skills |
| `skills/` | Claude Code skill definitions — `mem0/`, `mem0-cli/`, `mem0-vercel-ai-sdk/` |
| `docs/` | Documentation site (Mintlify) |
| `tests/` | Python SDK tests (pytest) |
| `evaluation/` | Benchmarking framework — LOCOMO evals, experiment runner, score generation |
| `examples/` | Sample projects — demo apps, Chrome extension, multi-agent patterns |
| `cookbooks/` | Jupyter notebooks — customer support chatbot, AutoGen integration |
| `embedchain/` | Legacy Embedchain RAG framework (maintained separately, Poetry-based) |
| `pr-reviews/` | Pull request review materials |
### Core Package Dependencies
```
mem0 (Python SDK) mem0-ts (TypeScript SDK)
├── mem0/memory/ ├── src/client/ (MemoryClient — hosted)
├── mem0/llms/ └── src/oss/ (Memory — self-hosted)
├── mem0/embeddings/ ├── src/llms/
├── mem0/vector_stores/ ├── src/embeddings/
├── mem0/graphs/ ├── src/vector_stores/
└── mem0/reranker/ └── src/graphs/
cli/python/ ──▶ mem0ai (optional, for OSS mode)
cli/node/ ──▶ mem0ai (npm, for API calls)
vercel-ai-sdk/ ──▶ ai, @ai-sdk/* providers
openclaw/ ──▶ mem0ai (npm)
```
## Development Setup
### Requirements
- **Python**: 3.9+ (3.10+ for CLI)
- **Node.js**: v18+ (v20 or v22 recommended)
- **pnpm**: v10+ (`npm install -g pnpm@10`) — used for all TypeScript packages
- **Hatch**: Python build/environment tool (`pip install hatch`)
- **Docker**: Required for `server/` and `openmemory/` development
### Initial Setup
```bash
# Python SDK
hatch shell dev_py_3_11 # creates environment with all deps
pre-commit install # install git hooks
# TypeScript packages
cd mem0-ts && pnpm install # TS SDK
cd cli/node && pnpm install # Node CLI
cd vercel-ai-sdk && pnpm install # Vercel AI provider
cd openclaw && pnpm install # OpenClaw plugin
```
## Build, Lint, and Test Commands
### Python SDK (`mem0/`)
```bash
# Environment setup (uses Hatch)
hatch shell dev_py_3_11 # or dev_py_3_9, dev_py_3_10, dev_py_3_12
# Linting and formatting
make lint # ruff check
make format # ruff format
make sort # isort mem0/
# Tests
make test # pytest tests/
make test-py-3.9 # test specific Python version (3.9–3.12)
# Build and publish
make build # hatch build
make publish # hatch publish
```
- **Python:** 3.9, 3.10, 3.11, 3.12
- **Linter/formatter:** Ruff (line length **120**)
- **Import sorting:** isort (`profile = "black"`)
- **Test framework:** pytest (with pytest-mock, pytest-asyncio)
- **Pre-commit hooks:** ruff + isort — run `pre-commit install` before committing
### TypeScript SDK (`mem0-ts/`)
```bash
cd mem0-ts
pnpm install
pnpm run build # tsup
pnpm run test # jest (all tests)
pnpm run test:unit # jest --coverage (unit tests only)
pnpm run test:integration # jest (integration tests, needs MEM0_API_KEY)
pnpm run test:ci # jest --coverage --ci (CI mode)
pnpm run test:watch # jest watch mode
```
- **Node:** 20, 22 (CI-tested)
- **Build:** tsup (CJS + ESM)
- **Test:** jest
- **Formatter:** prettier
### Python CLI (`cli/python/`)
```bash
cd cli/python
pip install -e ".[dev]" # dev install with ruff + pytest
ruff check . # lint
ruff format . # format
pytest # test
hatch build # build
```
- **Python:** 3.10+ (not 3.9)
- **Linter/formatter:** Ruff (line length **100** — different from root SDK)
- **Ruff rules:** E, F, I, W, UP, B, SIM, RUF (ignores E501, B008 for Typer patterns, SIM108)
- **Framework:** Typer + Rich + httpx
- **Entry point:** `mem0 = "mem0_cli.app:main"`
- **Source layout:** `src/mem0_cli/`
- **Optional dependency:** `mem0ai` (for OSS mode, via `[oss]` extra)
### Node CLI (`cli/node/`)
```bash
cd cli/node
pnpm install
pnpm run build # tsup
pnpm run lint # biome check src/
pnpm run lint:fix # biome check --write src/
pnpm run typecheck # tsc --noEmit
pnpm run test # vitest run
pnpm run test:watch # vitest (watch mode)
pnpm run dev # tsx src/index.ts (development)
```
- **Node:** 18+ required
- **Build:** tsup (ESM)
- **Linter:** Biome (not ESLint, not Ruff)
- **Test:** vitest (not jest)
- **Framework:** Commander + Chalk + ora + cli-table3
### Vercel AI SDK Provider (`vercel-ai-sdk/`)
```bash
cd vercel-ai-sdk
pnpm install
pnpm run build # tsup
pnpm run lint # eslint
pnpm run type-check # tsc --noEmit
pnpm run prettier-check # prettier --check
pnpm run test # jest
pnpm run test:edge # vitest (edge runtime)
pnpm run test:node # vitest (node runtime)
```
- **Build:** tsup (CJS + ESM)
- **Lint:** ESLint + Prettier
- **Test:** jest + vitest (edge/node configs)
### OpenClaw Plugin (`openclaw/`)
```bash
cd openclaw
pnpm install
pnpm run build # tsup
pnpm run test # vitest run
```
- **Build:** tsup (ESM)
- **Test:** vitest (with Codecov in CI)
- **Plugin manifest:** `openclaw.plugin.json`
### Server (`server/`)
```bash
# Docker production build
cd server
make build # docker build -t mem0-api-server .
make run_local # docker run -p 8000:8000 with .env
# Docker Compose development (FastAPI + PostgreSQL/pgvector + Neo4j)
cd server
docker-compose up # starts all 3 services
# mem0 API: localhost:8888
# PostgreSQL: localhost:8432
# Neo4j HTTP: localhost:8474, Bolt: localhost:8687
```
- **Framework:** FastAPI with uvicorn (auto-reload in dev)
- **Services:** PostgreSQL with pgvector, Neo4j 5.x with APOC plugin
- **Hot reload:** Dev Dockerfile mounts `server/` and `mem0/` for live changes
### OpenMemory (`openmemory/`)
```bash
# Full stack via Docker Compose
cd openmemory
docker-compose up
# Qdrant: localhost:6333
# API (MCP): localhost:8765
# UI: localhost:3000
# Individual development
cd openmemory/api && uvicorn main:app --reload # FastAPI backend
cd openmemory/ui && npm run dev # Next.js frontend
# Tests
cd openmemory/api && pytest tests/ # API tests (e.g., test_mcp_server.py)
```
- **API:** FastAPI + Alembic (DB migrations) + MCP server (Model Context Protocol)
- **UI:** Next.js 15, React 19, Radix UI, Redux Toolkit, TailwindCSS, Recharts
- **Vector store:** Qdrant
### Documentation (`docs/`)
```bash
make docs # or: cd docs && mintlify dev
```
- **Framework:** Mintlify
- **API spec:** `docs/openapi.json`
- **Structure:** `api-reference/`, `open-source/`, `platform/`, `integrations/`, `cookbooks/`, `core-concepts/`
### Evaluation (`evaluation/`)
```bash
cd evaluation
make run-mem0-add # Run mem0 add experiments
make run-mem0-search # Run mem0 search experiments
make run-mem0-plus-add # With graph memory
make run-mem0-plus-search # With graph memory
make run-rag # RAG baseline
make run-full-context # Full context baseline
make run-langmem # LangMem comparison
make run-openai # OpenAI comparison
```
## Core APIs
### Python
| Function / Class | Purpose | Import |
|-----------------|---------|--------|
| `Memory` | Self-hosted memory (sync) | `from mem0 import Memory` |
| `AsyncMemory` | Self-hosted memory (async) | `from mem0 import AsyncMemory` |
| `MemoryClient` | Hosted platform client (sync) | `from mem0 import MemoryClient` |
| `AsyncMemoryClient` | Hosted platform client (async) | `from mem0 import AsyncMemoryClient` |
**Key `Memory` / `MemoryClient` methods:**
| Method | Purpose |
|--------|---------|
| `add(messages, *, user_id, agent_id, run_id, metadata)` | Store a new memory |
| `search(query, *, user_id, agent_id, run_id, limit, filters)` | Search memories |
| `get(memory_id)` | Retrieve a single memory by ID |
| `get_all(*, user_id, agent_id, run_id, limit)` | List all memories |
| `update(memory_id, data)` | Update a memory |
| `delete(memory_id)` | Delete a memory |
| `delete_all(*, user_id, agent_id, run_id)` | Delete all memories |
| `history(memory_id)` | Get change history for a memory |
### TypeScript
| Export | Purpose | Import |
|--------|---------|--------|
| `MemoryClient` | Hosted platform client | `import { MemoryClient } from 'mem0ai'` |
| `Memory` | Self-hosted OSS memory | `import { Memory } from 'mem0ai/oss'` |
## Import Patterns
### Python
| What | Import |
|------|--------|
| Core memory classes | `from mem0 import Memory, AsyncMemory` |
| Platform client | `from mem0 import MemoryClient, AsyncMemoryClient` |
| Configuration | `from mem0.configs.base import MemoryConfig` |
| LLM providers | `from mem0.llms.<provider> import <ProviderLLM>` |
| Embedding providers | `from mem0.embeddings.<provider> import <ProviderEmbedding>` |
| Vector store providers | `from mem0.vector_stores.<provider> import <ProviderVectorStore>` |
### TypeScript
| What | Import |
|------|--------|
| Hosted client | `import { MemoryClient } from 'mem0ai'` |
| OSS memory | `import { Memory } from 'mem0ai/oss'` |
| Specific providers (OSS) | `import { OpenAIEmbedding } from 'mem0ai/oss'` |
## Coding Standards
### File Naming Conventions
- **Python source files:** `snake_case.py` (e.g., `azure_openai.py`, `cohere_reranker.py`)
- **Python test files:** `test_<module>.py` (e.g., `test_memory.py`, `test_main.py`)
- **TypeScript source files:** `snake_case.ts` (e.g., `azure_ai_search.ts`)
- **TypeScript test files:** `<module>.test.ts` (e.g., `memory.test.ts`)
- **Config/manifest files:** `kebab-case` (e.g., `openclaw.plugin.json`, `jest.config.js`)
### Python Conventions
- **Provider pattern:** All providers (LLMs, embeddings, vector stores, graphs, rerankers) inherit from a `base.py` abstract class in their directory. Config classes live in `configs.py`.
- **Pydantic v2** for all data models and configuration.
- **Ruff** is the single linting and formatting tool — no black, no flake8.
- Root SDK: line length **120**
- Python CLI: line length **100** with extended rule set (UP, B, SIM, RUF)
- **isort** with `profile = "black"` for import sorting.
- Ruff excludes `embedchain/` and `openmemory/` from root config.
### TypeScript Conventions
- **Build:** tsup across all packages.
- **Package manager:** pnpm everywhere (no npm, no yarn).
- **TypeScript strict mode** across all packages.
- **Linting varies by package:**
| Package | Linter | Formatter | Test Framework |
|---------|--------|-----------|---------------|
| `mem0-ts/` | — | Prettier | jest |
| `cli/node/` | Biome | Biome | vitest |
| `vercel-ai-sdk/` | ESLint | Prettier | jest + vitest |
| `openclaw/` | — | — | vitest |
### Type Checking
Always run type checking after modifying TypeScript code:
```bash
cd <package> && pnpm run typecheck # or: tsc --noEmit
```
## Architecture
### Provider Pattern
The SDK uses a consistent plugin architecture across 5 categories. Each category has a `base.py` abstract class and concrete provider implementations:
| Category | Count | Examples |
|----------|-------|---------|
| **LLMs** | 24 | OpenAI, Anthropic, AWS Bedrock, Azure OpenAI, Gemini, Groq, Ollama, Together, DeepSeek, vLLM, LiteLLM, LM Studio, xAI |
| **Vector Stores** | 30 | Qdrant, Pinecone, Chroma, Weaviate, Milvus, MongoDB, Redis, Elasticsearch, pgvector, Supabase, Faiss, S3 Vectors |
| **Embeddings** | 15 | OpenAI, Azure OpenAI, Gemini, HuggingFace, FastEmbed, Together, AWS Bedrock, Ollama, Vertex AI |
| **Graph Stores** | 4 | Neo4j, Memgraph, Kuzu, Apache AGE |
| **Rerankers** | 5 | Cohere, HuggingFace, LLM-based, Sentence Transformer, Zero Entropy |
### Two Usage Modes
Self-hosted `Memory` / `AsyncMemory` classes and hosted-platform `MemoryClient` — both in Python and TypeScript.
### Graph Memory
Optional layer on top of vector memory for relationship-aware retrieval. Configured via the `graph` section of `MemoryConfig`.
### MCP Integration
Model Context Protocol support in multiple places:
- **Remote:** MCP server at `mcp.mem0.ai`
- **Local:** MCP server in `openmemory/api/` (FastAPI-based)
- **Plugin:** MCP tools in `mem0-plugin/` — 9 tools: `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities`
### Plugin & Skills System
- `mem0-plugin/` provides integrations for Claude Code, Cursor, and Codex via MCP server connections and lifecycle hooks for automatic memory capture.
- `skills/` contains structured skill definitions for AI agents, covering SDK usage, CLI workflows, and Vercel AI SDK patterns.
### Adding a New Provider
To add a new LLM, embedding, vector store, or reranker provider:
1. Create `mem0/<category>/<provider_name>.py`
2. Inherit from the abstract base class in `mem0/<category>/base.py`
3. Add configuration to `mem0/<category>/configs.py` (if the category uses one)
4. Register the provider in `mem0/<category>/__init__.py`
5. Add tests in `tests/<category>/<provider_name>/`
6. Add any new dependencies to the appropriate optional group in `pyproject.toml` (never to core `dependencies`)
7. Follow the exact pattern of existing providers in the same category — match method signatures, error handling, and config structure
## CI/CD
### CI Workflows (automated testing)
| Workflow | File | Triggers | Tests |
|----------|------|----------|-------|
| Python SDK | `ci.yml` | Push to main, PRs on `mem0/`, `tests/`, `pyproject.toml` | Ruff lint + pytest on Python 3.10, 3.11, 3.12 |
| TypeScript SDK | `ts-sdk-ci.yml` | Push to main, PRs on `mem0-ts/` | Prettier + build + jest on Node 20, 22 |
| Python CLI | `cli-python-ci.yml` | Push to `cli/python/`, PRs, manual | Ruff lint + pytest + hatch build on Python 3.10, 3.11, 3.12 |
| Node CLI | `cli-node-ci.yml` | Push to `cli/node/`, PRs, manual | Biome lint + tsc + vitest + tsup build on Node 20, 22 |
| OpenClaw | `openclaw-checks.yml` | Push to `openclaw/`, PRs, manual | tsc + vitest (with Codecov) + tsup build on Node 20, 22 |
| Embedchain | `ci.yml` (shared) | PRs on `embedchain/` | Ruff + pytest + coverage on Python 3.9–3.12 |
### CD Workflows (automated publishing)
| Workflow | File | Tag Prefix | Target |
|----------|------|------------|--------|
| Python SDK | `cd.yml` | `v*` | PyPI (`mem0ai`) |
| TypeScript SDK | `ts-sdk-cd.yml` | `ts-v*` | npm (`mem0ai`) |
| Python CLI | `cli-python-cd.yml` | `cli-v*` | PyPI (`mem0-cli`) |
| Node CLI | `cli-node-cd.yml` | `cli-node-v*` | npm (`@mem0/cli`) |
| Vercel AI SDK | `vercel-ai-cd.yml` | `vercel-ai-v*` | npm (`@mem0/vercel-ai-provider`) |
| OpenClaw | `openclaw-cd.yml` | `openclaw-v*` | npm (`@mem0/openclaw-mem0`) |
- All publishing uses **OIDC trusted publishing** — no tokens or secrets required.
- First publish of a new npm package must be done manually; OIDC works for subsequent versions.
### Utility Workflows
| Workflow | File | Purpose |
|----------|------|---------|
| Issue Labeler | `issue-labeler.yml` | Automatic issue labeling |
| Stale Bot | `stale.yml` | Marks stale issues and PRs |
## Task Completion Guidelines
These guidelines outline typical artifacts for different task types. Use judgment to adapt based on scope and context.
### Bug Fixes
1. **Unit tests**: Add tests that would fail without the fix (regression tests)
2. **Implementation**: Fix the bug
3. **Manual verification**: Run the relevant test suite to confirm the fix
4. **Lint**: Run the appropriate linter for the package you modified
### New Features
1. **Implementation**: Build the feature following existing patterns
2. **Unit tests**: Comprehensive test coverage for new functionality
3. **Documentation**: Update relevant docs in `docs/` for public APIs
4. **Examples**: Add usage examples if the feature introduces new user-facing behavior
### New Provider (LLM / Embedding / Vector Store / Reranker)
1. **Implementation**: Follow the "Adding a New Provider" steps above
2. **Tests**: Add unit tests matching the pattern of existing providers
3. **Configuration**: Add to the appropriate `configs.py` and `__init__.py`
4. **Dependencies**: Add to the correct optional group in `pyproject.toml`
5. **Documentation**: Add an integration guide in `docs/integrations/`
### Refactoring / Internal Changes
- Unit tests for any changed behavior
- No documentation needed for internal-only changes
- Ensure all existing tests still pass
### When to Deviate
These are guidelines, not rigid rules. Adjust based on:
- **Scope**: Trivial fixes (typos, comments) may not need tests
- **Visibility**: Internal changes may not need documentation
- **Context**: Some changes span multiple categories — use judgment
When uncertain about expected artifacts, ask for clarification.
## Contributing Guidelines
### Workflow
1. Fork and clone the repository.
2. Create a feature branch from `main` (e.g., `feature/my-new-feature`).
3. Make your changes — add tests, docs, and examples as appropriate.
4. Run linting and tests for every package you modified (see commands above).
5. Run `pre-commit install` on first setup — hooks run ruff + isort automatically.
6. Commit with a clear message following [Conventional Commits](https://www.conventionalcommits.org/) (e.g., `feat:`, `fix:`, `docs:`, `refactor:`).
7. Push and open a Pull Request against `main`.
### Pull Request Requirements
Every PR must follow the repo's PR template (`.github/PULL_REQUEST_TEMPLATE.md`):
1. **Linked Issue** — Reference the issue with `Closes #<number>`. If no issue exists, create one first or explain why in the description.
2. **Description** — Explain what the PR does and why it's needed.
3. **Type of Change** — Check the appropriate box:
- Bug fix / New feature / Breaking change / Refactor / Documentation update
4. **Breaking Changes** — If applicable, describe what breaks and the migration path.
5. **Test Coverage** — Check what applies:
- Added/updated unit tests
- Added/updated integration tests
- Tested manually (describe how)
- No tests needed (explain why)
6. **Checklist** — All must be checked before merge:
- [ ] Code follows the project's style guidelines
- [ ] Self-review performed
- [ ] Tests added that prove the fix/feature works
- [ ] New and existing tests pass locally
- [ ] Documentation updated if needed
### PR Description Template
```markdown
## Linked Issue
Closes #<!-- issue number -->
## Description
<!-- What does this PR do? Why is it needed? -->
## Type of Change
- [ ] Bug fix (non-breaking change that fixes an issue)
- [ ] New feature (non-breaking change that adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
- [ ] Refactor (no functional changes)
- [ ] Documentation update
## Breaking Changes
N/A
## Test Coverage
- [ ] I added/updated unit tests
- [ ] I added/updated integration tests
- [ ] I tested manually (describe below)
- [ ] No tests needed (explain why)
## Checklist
- [ ] My code follows the project's style guidelines
- [ ] I have performed a self-review of my code
- [ ] I have added tests that prove my fix/feature works
- [ ] New and existing tests pass locally
- [ ] I have updated documentation if needed
```
### General Rules
- Follow existing code patterns — don't introduce new frameworks or abstractions without discussion.
- Version bumps go in `pyproject.toml` (Python) or `package.json` (TypeScript).
- For `server/` and `openmemory/` work, use Docker Compose for local development.
- Do NOT use `pip` or `conda` for dependency management — use `hatch` (see `docs/contributing/development.mdx`).
### Contributing Guides
| Task | Guide |
|------|-------|
| Code contributions | `docs/contributing/development.mdx` |
| Documentation contributions | `docs/contributing/documentation.mdx` |
| PR template | `.github/PULL_REQUEST_TEMPLATE.md` |
| Bug reports | `.github/ISSUE_TEMPLATE/bug_report.yml` |
| Feature requests | `.github/ISSUE_TEMPLATE/feature_request.yml` |
| Documentation issues | `.github/ISSUE_TEMPLATE/documentation_issue.yml` |
## Do NOT
- Modify CI/CD workflows without explicit approval.
- Add new Python dependencies to the core `dependencies` list in `pyproject.toml` without discussion — use optional dependency groups instead.
- Commit `.env` files, API keys, or credentials.
- Modify `embedchain/` unless specifically working on that package — it has its own build system (Poetry).
- Skip pre-commit hooks.
- Use npm or yarn in TypeScript packages — this repo uses pnpm exclusively.
- Use `require()` for imports in TypeScript — use ES module `import` syntax.
- Mix up linter configs: root Python SDK uses line-length 120, Python CLI uses 100, Node CLI uses Biome (not ESLint/Ruff).
- Modify `openmemory/` database migrations without understanding the Alembic migration chain.
- Change public APIs without updating documentation in `docs/`.
Symlink
+1
View File
@@ -0,0 +1 @@
AGENTS.md
+2 -2
View File
@@ -266,7 +266,7 @@ config = MemoryConfig(
graph_store=GraphStoreConfig(provider="neo4j", config={...}), # optional
history_db_path="~/.mem0/history.db",
version="v1.1",
custom_fact_extraction_prompt="Custom prompt...",
custom_instructions="Custom prompt...",
custom_update_memory_prompt="Custom prompt..."
)
```
@@ -684,7 +684,7 @@ Conversation: {messages}
"""
config = MemoryConfig(
custom_fact_extraction_prompt=custom_extraction_prompt
custom_instructions=custom_extraction_prompt
)
memory = Memory(config)
```
+34 -11
View File
@@ -41,16 +41,30 @@
<p align="center">
<a href="https://mem0.ai/research"><strong>📄 Building Production-Ready AI Agents with Scalable Long-Term Memory →</strong></a>
</p>
<p align="center">
<strong>⚡ +26% Accuracy vs. OpenAI Memory • 🚀 91% Faster • 💰 90% Fewer Tokens</strong>
</p>
> **🎉 mem0ai v1.0.0 is now available!** This major release includes API modernization, improved vector store support, and enhanced GCP integration. [See migration guide →](MIGRATION_GUIDE_v1.0.md)
## New Memory Algorithm (April 2026)
## 🔥 Research Highlights
- **+26% Accuracy** over OpenAI Memory on the LOCOMO benchmark
- **91% Faster Responses** than full-context, ensuring low-latency at scale
- **90% Lower Token Usage** than full-context, cutting costs without compromise
| Benchmark | Old | New | Tokens | Latency p50 |
| --- | --- | --- | --- | --- |
| **LoCoMo** | 71.4 | **91.6** | 7.0K | 0.88s |
| **LongMemEval** | 67.8 | **93.4** | 6.8K | 1.09s |
| **BEAM (1M)** | — | **64.1** | 6.7K | 1.00s |
| **BEAM (10M)** | — | **48.6** | 6.9K | 1.05s |
All benchmarks run on the same production-representative model stack. Single-pass retrieval (one call, no agentic loops).
**What changed:**
- **Single-pass ADD-only extraction** -- one LLM call, no UPDATE/DELETE. Memories accumulate; nothing is overwritten.
- **Agent-generated facts are first-class** -- when an agent confirms an action, that information is now stored with equal weight.
- **Entity linking** -- entities are extracted, embedded, and linked across memories for retrieval boosting.
- **Multi-signal retrieval** -- semantic, BM25 keyword, and entity matching scored in parallel and fused.
See the [migration guide](https://docs.mem0.ai/migration/oss-v2-to-v3) for upgrade instructions. The [evaluation framework](https://github.com/mem0ai/memory-benchmarks) is open-sourced so anyone can reproduce the numbers.
## Research Highlights
- **91.6 on LoCoMo** -- +20 points over the previous algorithm
- **93.4 on LongMemEval** -- +26 points, with +53.6 on assistant memory recall
- **64.1 on BEAM (1M)** -- production-scale memory evaluation at 1M tokens
- [Read the full paper](https://mem0.ai/research)
# Introduction
@@ -88,6 +102,13 @@ Install the sdk via pip:
pip install mem0ai
```
For enhanced hybrid search with BM25 keyword matching and entity extraction, install with NLP support:
```bash
pip install mem0ai[nlp]
python -m spacy download en_core_web_sm
```
Install sdk via npm:
```bash
npm install mem0ai
@@ -109,7 +130,9 @@ See the [CLI documentation](https://docs.mem0.ai/platform/cli) for the full comm
### Basic Usage
Mem0 requires an LLM to function, with `gpt-4.1-nano-2025-04-14 from OpenAI as the default. However, it supports a variety of LLMs; for details, refer to our [Supported LLMs documentation](https://docs.mem0.ai/components/llms/overview).
Mem0 requires an LLM to function, with `gpt-5-mini` from OpenAI as the default. However, it supports a variety of LLMs; for details, refer to our [Supported LLMs documentation](https://docs.mem0.ai/components/llms/overview).
Mem0 uses `text-embedding-3-small` from OpenAI as the default embedding model. For best results with hybrid search (semantic + keyword + entity boosting), we recommend using at least [Qwen 600M](https://huggingface.co/Alibaba-NLP/gte-Qwen2-1.5B-instruct) or a comparable embedding model. See [Supported Embeddings](https://docs.mem0.ai/components/embedders/overview) for configuration details.
First step is to instantiate the memory:
@@ -122,13 +145,13 @@ memory = Memory()
def chat_with_memories(message: str, user_id: str = "default_user") -> str:
# Retrieve relevant memories
relevant_memories = memory.search(query=message, user_id=user_id, limit=3)
relevant_memories = memory.search(query=message, filters={"user_id": user_id}, top_k=3)
memories_str = "\n".join(f"- {entry['memory']}" for entry in relevant_memories["results"])
# Generate Assistant response
system_prompt = f"You are a helpful AI. Answer the question based on query and memories.\nUser Memories:\n{memories_str}"
messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": message}]
response = openai_client.chat.completions.create(model="gpt-4.1-nano-2025-04-14", messages=messages)
response = openai_client.chat.completions.create(model="gpt-5-mini", messages=messages)
assistant_response = response.choices[0].message.content
# Create new memories from the conversation
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@mem0/cli",
"version": "0.2.2",
"version": "0.2.3",
"description": "The official CLI for mem0 — the memory layer for AI agents",
"type": "module",
"bin": {
+12 -9
View File
@@ -116,6 +116,7 @@ export class PlatformBackend implements Backend {
if (opts.expires) payload.expiration_date = opts.expires;
if (opts.categories) payload.categories = opts.categories;
if (opts.enableGraph) payload.enable_graph = true;
payload.source = "CLI";
return (await this._request("POST", "/v1/memories/", {
json: payload,
@@ -176,6 +177,7 @@ export class PlatformBackend implements Backend {
if (opts.keyword) payload.keyword_search = true;
if (opts.fields) payload.fields = opts.fields;
if (opts.enableGraph) payload.enable_graph = true;
payload.source = "CLI";
const result = (await this._request("POST", "/v2/memories/search/", {
json: payload,
@@ -186,10 +188,9 @@ export class PlatformBackend implements Backend {
}
async get(memoryId: string): Promise<Record<string, unknown>> {
return (await this._request("GET", `/v1/memories/${memoryId}/`)) as Record<
string,
unknown
>;
return (await this._request("GET", `/v1/memories/${memoryId}/`, {
params: { source: "CLI" },
})) as Record<string, unknown>;
}
async listMemories(
@@ -227,6 +228,7 @@ export class PlatformBackend implements Backend {
});
if (apiFilters) payload.filters = apiFilters;
if (opts.enableGraph) payload.enable_graph = true;
payload.source = "CLI";
const result = (await this._request("POST", "/v2/memories/", {
json: payload,
@@ -245,6 +247,7 @@ export class PlatformBackend implements Backend {
const payload: Record<string, unknown> = {};
if (content) payload.text = content;
if (metadata) payload.metadata = metadata;
payload.source = "CLI";
return (await this._request("PUT", `/v1/memories/${memoryId}/`, {
json: payload,
})) as Record<string, unknown>;
@@ -255,7 +258,7 @@ export class PlatformBackend implements Backend {
opts: DeleteOptions = {},
): Promise<Record<string, unknown>> {
if (opts.all) {
const params: Record<string, string> = {};
const params: Record<string, string> = { source: "CLI" };
if (opts.userId) params.user_id = opts.userId;
if (opts.agentId) params.agent_id = opts.agentId;
if (opts.appId) params.app_id = opts.appId;
@@ -265,10 +268,9 @@ export class PlatformBackend implements Backend {
})) as Record<string, unknown>;
}
if (memoryId) {
return (await this._request(
"DELETE",
`/v1/memories/${memoryId}/`,
)) as Record<string, unknown>;
return (await this._request("DELETE", `/v1/memories/${memoryId}/`, {
params: { source: "CLI" },
})) as Record<string, unknown>;
}
throw new Error("Either memoryId or --all is required");
}
@@ -291,6 +293,7 @@ export class PlatformBackend implements Backend {
result = (await this._request(
"DELETE",
`/v2/entities/${entityType}/${entityId}/`,
{ params: { source: "CLI" } },
)) as Record<string, unknown>;
}
return result;
+14
View File
@@ -31,10 +31,15 @@ export interface DefaultsConfig {
enableGraph: boolean;
}
export interface TelemetryConfig {
anonymousId: string;
}
export interface Mem0Config {
version: number;
defaults: DefaultsConfig;
platform: PlatformConfig;
telemetry: TelemetryConfig;
}
export function createDefaultConfig(): Mem0Config {
@@ -52,6 +57,9 @@ export function createDefaultConfig(): Mem0Config {
baseUrl: DEFAULT_BASE_URL,
userEmail: "",
},
telemetry: {
anonymousId: "",
},
};
}
@@ -80,6 +88,9 @@ export function loadConfig(): Mem0Config {
config.defaults.appId = defaults.app_id ?? "";
config.defaults.runId = defaults.run_id ?? "";
config.defaults.enableGraph = defaults.enable_graph ?? false;
const telemetry = data.telemetry ?? {};
config.telemetry.anonymousId = telemetry.anonymous_id ?? "";
}
// Environment variable overrides
@@ -119,6 +130,9 @@ export function saveConfig(config: Mem0Config): void {
base_url: config.platform.baseUrl,
user_email: config.platform.userEmail,
},
telemetry: {
anonymous_id: config.telemetry.anonymousId,
},
};
fs.writeFileSync(CONFIG_FILE, JSON.stringify(data, null, 2));
+52 -5
View File
@@ -9,10 +9,10 @@
*/
import { spawn } from "node:child_process";
import { createHash } from "node:crypto";
import { createHash, randomUUID } from "node:crypto";
import path from "node:path";
import { fileURLToPath } from "node:url";
import { CONFIG_FILE, loadConfig } from "./config.js";
import { CONFIG_FILE, loadConfig, saveConfig } from "./config.js";
import { CLI_VERSION } from "./version.js";
const POSTHOG_API_KEY = "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX";
@@ -29,11 +29,34 @@ function isTelemetryEnabled(): boolean {
}
}
/**
* Return a persistent per-machine anonymous ID, generating one if needed.
*
* Stored in ~/.mem0/config.json under `telemetry.anonymous_id` so that
* repeat runs on the same machine share one PostHog identity instead of
* collapsing into a single shared fallback string.
*/
function getOrCreateAnonymousId(): string {
const config = loadConfig();
if (config.telemetry.anonymousId) {
return config.telemetry.anonymousId;
}
const newId = `cli-anon-${randomUUID().replace(/-/g, "")}`;
config.telemetry.anonymousId = newId;
try {
saveConfig(config);
} catch {
/* ignore persistence failure — still return the generated ID */
}
return newId;
}
/**
* Return a stable anonymous identifier for the current user.
*
* Priority: cached user_email (from /v1/ping/) > MD5(api_key) > fallback.
* Matches the SDK pattern in mem0-ts/src/client/mem0.ts.
* Priority: cached user_email (from /v1/ping/) > MD5(api_key) >
* persistent per-machine anonymous ID.
*/
function getDistinctId(): string {
try {
@@ -47,7 +70,11 @@ function getDistinctId(): string {
} catch {
/* ignore */
}
return "anonymous-cli";
try {
return getOrCreateAnonymousId();
} catch {
return `cli-anon-${randomUUID().replace(/-/g, "")}`;
}
}
/**
@@ -69,6 +96,25 @@ export function captureEvent(
const config = loadConfig();
const distinctId = preResolvedEmail || getDistinctId();
// Detect anonymous → identified transition. If a stored anonymous_id
// exists and we just resolved to a real identity, fire a one-shot
// $identify event so PostHog stitches the pre-signup history onto
// the authenticated profile. Clear the stored id so we don't re-alias.
let anonIdToAlias: string | null = null;
if (
distinctId &&
!distinctId.startsWith("cli-anon-") &&
config.telemetry.anonymousId
) {
anonIdToAlias = config.telemetry.anonymousId;
config.telemetry.anonymousId = "";
try {
saveConfig(config);
} catch {
/* ignore — alias may double-fire next run, harmless */
}
}
const payload = {
api_key: POSTHOG_API_KEY,
distinct_id: distinctId,
@@ -92,6 +138,7 @@ export function captureEvent(
mem0ApiKey: config.platform.apiKey || "",
mem0BaseUrl: config.platform.baseUrl || "https://api.mem0.ai",
configPath: CONFIG_FILE,
anonDistinctIdToAlias: anonIdToAlias,
};
const child = spawn(
+21
View File
@@ -94,6 +94,19 @@ async function sendPosthogEvent(posthogHost, payload) {
}
}
async function sendIdentifyEvent(ctx, payload, anonId) {
const identifyPayload = {
api_key: payload.api_key,
event: "$identify",
distinct_id: payload.distinct_id,
properties: {
$anon_distinct_id: anonId,
$lib: (payload.properties && payload.properties.$lib) || "posthog-node",
},
};
await sendPosthogEvent(ctx.posthogHost, identifyPayload);
}
async function main() {
const ctx = JSON.parse(process.argv[2]);
const payload = ctx.payload;
@@ -102,6 +115,14 @@ async function main() {
await resolveAndCacheEmail(ctx, payload);
}
// Fire $identify *after* email resolution so PostHog links the stored
// anonymous id directly to the final identity (email, not the api-key
// hash). The regular event is sent next so it lands under the merged
// profile.
if (ctx.anonDistinctIdToAlias) {
await sendIdentifyEvent(ctx, payload, ctx.anonDistinctIdToAlias);
}
await sendPosthogEvent(ctx.posthogHost, payload);
}
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "mem0-cli"
version = "0.2.2"
version = "0.2.3"
description = "The official CLI for mem0 — the memory layer for AI agents"
readme = "README.md"
license = "Apache-2.0"
+1 -1
View File
@@ -1,3 +1,3 @@
"""mem0 CLI — the command-line interface for the mem0 memory layer."""
__version__ = "0.2.2"
__version__ = "0.2.3"
+10 -4
View File
@@ -93,6 +93,7 @@ class PlatformBackend(Backend):
payload["categories"] = categories
if enable_graph:
payload["enable_graph"] = True
payload["source"] = "CLI"
return self._request("POST", "/v1/memories/", json=payload)
@@ -172,6 +173,7 @@ class PlatformBackend(Backend):
payload["fields"] = fields
if enable_graph:
payload["enable_graph"] = True
payload["source"] = "CLI"
result = self._request("POST", "/v2/memories/search/", json=payload)
return (
@@ -181,7 +183,7 @@ class PlatformBackend(Backend):
)
def get(self, memory_id: str) -> dict:
return self._request("GET", f"/v1/memories/{memory_id}/")
return self._request("GET", f"/v1/memories/{memory_id}/", params={"source": "CLI"})
def list_memories(
self,
@@ -220,6 +222,7 @@ class PlatformBackend(Backend):
payload["filters"] = api_filters
if enable_graph:
payload["enable_graph"] = True
payload["source"] = "CLI"
result = self._request("POST", "/v2/memories/", json=payload, params=params)
return (
@@ -236,6 +239,7 @@ class PlatformBackend(Backend):
payload["text"] = content
if metadata:
payload["metadata"] = metadata
payload["source"] = "CLI"
return self._request("PUT", f"/v1/memories/{memory_id}/", json=payload)
def delete(
@@ -249,7 +253,7 @@ class PlatformBackend(Backend):
run_id: str | None = None,
) -> dict:
if all:
params: dict[str, str] = {}
params: dict[str, str] = {"source": "CLI"}
if user_id:
params["user_id"] = user_id
if agent_id:
@@ -260,7 +264,7 @@ class PlatformBackend(Backend):
params["run_id"] = run_id
return self._request("DELETE", "/v1/memories/", params=params)
elif memory_id:
return self._request("DELETE", f"/v1/memories/{memory_id}/")
return self._request("DELETE", f"/v1/memories/{memory_id}/", params={"source": "CLI"})
else:
raise ValueError("Either memory_id or --all is required")
@@ -285,7 +289,9 @@ class PlatformBackend(Backend):
# Delete each provided entity via the v2 path-based endpoint
result: dict = {}
for entity_type, entity_id in entities.items():
result = self._request("DELETE", f"/v2/entities/{entity_type}/{entity_id}/")
result = self._request(
"DELETE", f"/v2/entities/{entity_type}/{entity_id}/", params={"source": "CLI"}
)
return result
def ping(self, timeout: float | None = None) -> dict:
+12
View File
@@ -39,11 +39,17 @@ class DefaultsConfig:
enable_graph: bool = False
@dataclass
class TelemetryConfig:
anonymous_id: str = ""
@dataclass
class Mem0Config:
version: int = CONFIG_VERSION
defaults: DefaultsConfig = field(default_factory=DefaultsConfig)
platform: PlatformConfig = field(default_factory=PlatformConfig)
telemetry: TelemetryConfig = field(default_factory=TelemetryConfig)
SHORT_KEY_ALIASES: dict[str, str] = {
@@ -87,6 +93,9 @@ def load_config() -> Mem0Config:
config.defaults.run_id = defaults.get("run_id", "")
config.defaults.enable_graph = defaults.get("enable_graph", False)
telemetry = data.get("telemetry", {})
config.telemetry.anonymous_id = telemetry.get("anonymous_id", "")
# Environment variable overrides
env_key = os.environ.get("MEM0_API_KEY")
if env_key:
@@ -137,6 +146,9 @@ def save_config(config: Mem0Config) -> None:
"base_url": config.platform.base_url,
"user_email": config.platform.user_email,
},
"telemetry": {
"anonymous_id": config.telemetry.anonymous_id,
},
}
with open(CONFIG_FILE, "w") as f:
+45 -4
View File
@@ -9,12 +9,14 @@ Disable with: MEM0_TELEMETRY=false
from __future__ import annotations
import contextlib
import hashlib
import json
import os
import platform
import subprocess
import sys
import uuid
from typing import Any
POSTHOG_API_KEY = "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX"
@@ -26,11 +28,31 @@ def _is_telemetry_enabled() -> bool:
return val not in ("false", "0", "no")
def _get_or_create_anonymous_id() -> str:
"""Return a persistent per-machine anonymous ID, generating one if needed.
Stored in ~/.mem0/config.json under `telemetry.anonymous_id` so that
repeat runs on the same machine share one PostHog identity instead of
collapsing into a single shared fallback string.
"""
from mem0_cli.config import load_config, save_config
config = load_config()
if config.telemetry.anonymous_id:
return config.telemetry.anonymous_id
new_id = f"cli-anon-{uuid.uuid4().hex}"
config.telemetry.anonymous_id = new_id
with contextlib.suppress(Exception):
save_config(config)
return new_id
def _get_distinct_id() -> str:
"""Return a stable anonymous identifier for the current user.
Priority: cached user_email (from /v1/ping/) > MD5(api_key) > fallback.
Matches the SDK pattern in mem0/client/main.py.
Priority: cached user_email (from /v1/ping/) > MD5(api_key) >
persistent per-machine anonymous ID.
"""
try:
from mem0_cli.config import load_config
@@ -42,7 +64,10 @@ def _get_distinct_id() -> str:
return hashlib.md5(config.platform.api_key.encode()).hexdigest()
except Exception:
pass
return "anonymous-cli"
try:
return _get_or_create_anonymous_id()
except Exception:
return f"cli-anon-{uuid.uuid4().hex}"
def capture_event(
@@ -61,12 +86,27 @@ def capture_event(
try:
from mem0_cli import __version__
from mem0_cli.config import CONFIG_FILE, load_config
from mem0_cli.config import CONFIG_FILE, load_config, save_config
from mem0_cli.state import is_agent_mode
config = load_config()
distinct_id = pre_resolved_email or _get_distinct_id()
# Detect anonymous → identified transition. If a stored anonymous_id
# exists and we just resolved to a real identity, fire a one-shot
# $identify event so PostHog stitches the pre-signup history onto
# the authenticated profile. Clear the stored id so we don't re-alias.
anon_id_to_alias: str | None = None
if (
distinct_id
and not distinct_id.startswith("cli-anon-")
and config.telemetry.anonymous_id
):
anon_id_to_alias = config.telemetry.anonymous_id
config.telemetry.anonymous_id = ""
with contextlib.suppress(Exception):
save_config(config)
payload = {
"api_key": POSTHOG_API_KEY,
"distinct_id": distinct_id,
@@ -92,6 +132,7 @@ def capture_event(
"mem0_api_key": config.platform.api_key or "",
"mem0_base_url": config.platform.base_url or "https://api.mem0.ai",
"config_path": str(CONFIG_FILE),
"anon_distinct_id_to_alias": anon_id_to_alias,
}
subprocess.Popen(
@@ -27,9 +27,31 @@ def main() -> None:
if ctx.get("needs_email") and ctx.get("mem0_api_key"):
_resolve_and_cache_email(ctx, payload)
# Fire $identify *after* email resolution so PostHog links the stored
# anonymous id directly to the final identity (email, not the api-key
# hash). The regular event is sent next so it lands under the merged
# profile.
anon_id = ctx.get("anon_distinct_id_to_alias")
if anon_id:
_send_identify_event(ctx, payload, anon_id)
_send_posthog_event(ctx["posthog_host"], payload)
def _send_identify_event(ctx: dict, payload: dict, anon_id: str) -> None:
"""Send a PostHog $identify event aliasing anon_id → payload['distinct_id']."""
identify_payload = {
"api_key": payload["api_key"],
"event": "$identify",
"distinct_id": payload["distinct_id"],
"properties": {
"$anon_distinct_id": anon_id,
"$lib": payload.get("properties", {}).get("$lib", "posthog-python"),
},
}
_send_posthog_event(ctx["posthog_host"], identify_payload)
def _resolve_and_cache_email(ctx: dict, payload: dict) -> None:
"""Call /v1/ping/ to get the user's email, update the payload, and cache it."""
try:
+2 -2
View File
@@ -10,7 +10,7 @@ description: "REST APIs for memory management, search, and entity operations"
Mem0 provides a comprehensive REST API for integrating advanced memory capabilities into your applications. Create, search, update, and manage memories across users, agents, and custom entities with simple HTTP requests.
<Info>
**Quick start:** Get your API key from the [Mem0 Dashboard](https://app.mem0.ai/dashboard/api-keys) and make your first memory operation in minutes.
**Quick start:** Get your API key from the <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 Dashboard</a> and make your first memory operation in minutes.
</Info>
---
@@ -87,7 +87,7 @@ All API requests require authentication using Token-based authentication. Includ
Authorization: Token <your-api-key>
```
Get your API key from the [Mem0 Dashboard](https://app.mem0.ai/dashboard/api-keys).
Get your API key from the <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 Dashboard</a>.
<Warning>
**Keep your API key secure.** Never expose it in client-side code or public repositories. Use environment variables and server-side requests only.
@@ -47,8 +47,6 @@ Provide at least one message or direct memory string. Most callers supply `messa
| `messages` | array | No* | Conversation turns for Mem0 to infer memories from. Each object should include `role` and `content`. |
| `metadata` | object | Optional | Custom key/value metadata (e.g., `{"topic": "preferences"}`). |
| `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. |
| `async_mode` | boolean (default `true`) | Optional | Controls asynchronous processing. Most clients leave this enabled. |
| `output_format` | string (default `v1.1`) | Optional | Response format. `v1.1` wraps results in a `results` array. |
> \* Provide at least one `messages` entry to describe what you are storing. For scoped memories, include `user_id`. You can also attach `agent_id`, `app_id`, `run_id`, `project_id`, or `org_id` to refine ownership.
@@ -83,20 +81,3 @@ Successful requests return an array of events queued for processing. Each event
```
</CodeGroup>
## Graph relationships
Add Memories can enrich the knowledge graph on write. Set `enable_graph: true` to create entity nodes and relationships for the stored memory. Use this when you want downstream `get_all` or search calls to traverse connected entities.
<CodeGroup>
```json Graph-aware request
{
"user_id": "alice",
"messages": [
{ "role": "user", "content": "I met with Dr. Lee at General Hospital." }
],
"enable_graph": true
}
```
</CodeGroup>
The response follows the same format, and related entities become available in [Graph Memory](/platform/features/graph-memory) queries.
+1 -2
View File
@@ -62,8 +62,7 @@ To retrieve graph memory relationships between entities, pass `output_format="v1
memories = client.get_all(
filters={
"user_id": "alex"
},
output_format="v1.1"
}
)
```
+4 -11
View File
@@ -32,7 +32,7 @@ Example with the mem0 Python package:
```python
from mem0 import MemoryClient
client = MemoryClient(org_id='YOUR_ORG_ID', project_id='YOUR_PROJECT_ID')
client = MemoryClient(api_key="your-api-key")
```
</Tab>
@@ -41,10 +41,7 @@ client = MemoryClient(org_id='YOUR_ORG_ID', project_id='YOUR_PROJECT_ID')
```javascript
import { MemoryClient } from "mem0ai";
const client = new MemoryClient({
organizationId: "YOUR_ORG_ID",
projectId: "YOUR_PROJECT_ID"
});
const client = new MemoryClient({ apiKey: "your-api-key" });
```
</Tab>
@@ -98,9 +95,6 @@ client.project.update(
custom_instructions="..."
)
# Enable graph memory for the project
client.project.update(enable_graph=True)
# Use the input language for memory storage and retrieval
client.project.update(multilingual=True)
@@ -111,7 +105,6 @@ client.project.update(
{"personal_info": "User personal information and preferences"},
{"work_context": "Professional context and work-related information"}
],
enable_graph=True,
multilingual=True
)
```
@@ -172,11 +165,11 @@ All project methods are available in async mode:
from mem0 import AsyncMemoryClient
async def manage_project():
client = AsyncMemoryClient(org_id='YOUR_ORG_ID', project_id='YOUR_PROJECT_ID')
client = AsyncMemoryClient(api_key="your-api-key")
# All methods support async/await
project_info = await client.project.get()
await client.project.update(enable_graph=True)
await client.project.update(multilingual=True)
members = await client.project.get_members()
# To call the async function properly
+102
View File
@@ -0,0 +1,102 @@
---
title: "Highlights"
description: "Major product launches, headline features, and milestones for Mem0."
mode: "wide"
---
<Update label="2026-04-14" description="Mem0 SDK v2.0.0 / v3.0.0">
**New Memory Algorithm — State-of-the-Art Accuracy at 90% Lower Cost**
Ground-up rewrite of the memory pipeline with 20+ point benchmark improvements:
- **LoCoMo:** 71.4 → **91.6** (+20) — multi-turn conversation recall
- **LongMemEval:** 67.8 → **93.4** (+26) — long-term memory across sessions
- **BEAM (1M tokens):** **64.1** — production-scale memory evaluation
- **Agent memories are first-class** — Previous algorithm: 46% on assistant recall. New: **100%**
- **Temporal reasoning works** — "Where did I live before SF?" Previous: 51%. New: **93%**
- **90% fewer tokens** — Under 7K tokens per retrieval vs 25K+ for full-context approaches
- **ADD-only extraction** — Memories accumulate; nothing is overwritten or deleted
- **Hybrid retrieval** — Semantic + BM25 keyword + entity boost, scored in parallel
- **Entity linking** — Entities extracted, embedded, and linked across memories
Breaking changes: Graph memory removed from OSS, `search()` defaults changed, deprecated params removed. See [migration guide](/migration/oss-v2-to-v3).
</Update>
<Update label="2026-04-06" description="Mem0 Skill Graph">
**Mem0 Skill Graph — In-Context Documentation for AI Agents**
AI coding agents in Claude Code, Cursor, and Codex can now access Mem0 knowledge directly in their workflow — no doc searching required. Three interconnected skills launched:
- **mem0 Core Skill** — Complete Python and TypeScript SDK reference, REST API patterns, and integration guides for LangChain, CrewAI, Autogen, and more
- **mem0-cli Skill** — Terminal command reference, configuration walkthroughs, and CI/CD recipes
- **mem0-vercel-ai-sdk Skill** — Vercel AI SDK provider API, memory-augmented generation patterns, and multi-provider setup
</Update>
<Update label="2026-04-06" description="Mem0 CLI v0.2.2">
**Official Mem0 CLI — Now on PyPI and npm**
A full-featured command-line interface for Mem0, available in both Python and Node.js:
- **Install:** `pip install mem0-cli` or `npm install -g @mem0/cli`
- **Full command suite** — `add`, `search`, `list`, `get`, `update`, `delete`, `import`, `config`, `init`, `status`, `entity`, `event`
- **Interactive setup** — `mem0 init` with email verification or direct API key entry
- **Works everywhere** — Platform (Mem0 Cloud) and self-hosted OSS modes
- **Scriptable** — `--json` flag for CI/CD pipelines and automation
- **Dual SDK** — Same commands, same experience across Python and Node.js
</Update>
<Update label="2026-04-06" description="OpenClaw v1.0.4">
**OpenClaw Plugin — Production-Ready**
The OpenClaw Mem0 plugin went from initial release to production-ready in one week (v1.0.0 → v1.0.4):
- **Skills-based memory architecture** — New extraction pipeline with skill-loader, batched extraction, and domain-aware memory triage
- **Dream gate** — Automatic memory consolidation during idle periods for higher-quality long-term recall
- **Interactive CLI** — `openclaw mem0 init`, `status`, `config`, `import`, and `event` commands
- **Unified tool naming** — `memory_add` and `memory_delete` replace 4 legacy tools, matching the platform API
- **Security hardened** — Path traversal protection, pinned dependencies, 329 tests across 10 files
</Update>
<Update label="2026-04-02" description="Mem0 Plugin for AI Editors">
**Mem0 Plugin for Claude Code, Cursor, and Codex**
Launched a unified Mem0 plugin across three major AI development environments — Claude Code and Cursor first (March 25), then Codex (April 2):
- **9 MCP memory tools** — add, search, get, update, delete, bulk delete, entity management via `mcp.mem0.ai`
- **Lifecycle hooks** — Automatic memory capture at session start, context compaction, task completion, and session end
- **Cloud MCP server** — Managed endpoint replaces local MCP and Smithery setup
- **Streamable HTTP transport** — New MCP transport protocol for real-time streaming
- **Codex-specific skill** — Dedicated skill in `mem0-plugin/skills/mem0-codex` for Codex workflows
</Update>
<Update label="2026-03-21" description="New Providers">
**Apache AGE, Turbopuffer, MiniMax, and pgvector for Node.js**
Major expansion of the provider ecosystem:
- **Apache AGE** — New graph store support, bringing the total to 4 graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE)
- **Turbopuffer** — New vector database provider for Python SDK
- **MiniMax** — New LLM provider with dedicated AWS Bedrock support
- **pgvector for Node.js** — PostgreSQL vector support added to the TypeScript OSS SDK
- **Reasoning models** — `reasoning_effort` parameter for OpenAI o1/o3-style models
</Update>
<Update label="2026-03-14" description="Mem0 Platform Skill">
**Mem0 Platform Skill on skills.sh**
First skill launch — a dedicated Mem0 skill providing platform API reference, quickstart patterns, and integration examples directly inside agent sessions. Available on [skills.sh](https://skills.sh) for any compatible AI coding agent.
</Update>
+199
View File
@@ -0,0 +1,199 @@
---
title: "OpenClaw"
description: "Release notes for the OpenClaw plugin and agent harness."
mode: "wide"
---
<Update label="2026-04-11" description="v1.0.6">
**Bug Fixes:**
- **Telemetry:** Replaced shared `"anonymous-openclaw"` fallback with a persistent per-machine random hash (`openclaw-anon-<uuid>`), so anonymous plugin users are counted individually in PostHog ([#4790](https://github.com/mem0ai/mem0/pull/4790))
- **Telemetry:** Added PostHog `$identify` event on first authenticated run to stitch anonymous history onto the authenticated profile ([#4790](https://github.com/mem0ai/mem0/pull/4790))
- **Telemetry:** Fixed event loss on short-lived CLI invocations — added `beforeExit` handler to flush queued events before the process exits ([#4790](https://github.com/mem0ai/mem0/pull/4790))
- **Telemetry:** Added lazy `/v1/ping/` email resolution so users who configure API key outside `mem0 init` show as their email in PostHog, not an md5 hash ([#4790](https://github.com/mem0ai/mem0/pull/4790))
- **Telemetry:** Unified CLI event prefix from `openclaw.<cmd>` to `openclaw.cli.<cmd>` on the needsSetup branch to match the authenticated branch ([#4790](https://github.com/mem0ai/mem0/pull/4790))
**Improvements:**
- **API:** Added `source: "OPENCLAW"` to all provider calls (`add`, `search`, `getAll`) across tools, CLI commands, recall, and the OSS backend adapter ([#4790](https://github.com/mem0ai/mem0/pull/4790))
</Update>
<Update label="2026-04-07" description="v1.0.5">
**Bug Fixes:**
- **Init interactive choice bug**: Fixed number selection in `openclaw mem0 init` — entering 1/2/3 now correctly selects the corresponding option (was broken by readline prefill concatenating with user input)
- **OSS pgvector crash** ([#4727](https://github.com/mem0ai/mem0/issues/4727)): Fixed "Client has already been connected" cascade when using pgvector in OSS mode. The warmup call swallowed errors leaving a half-initialized pg client; concurrent recall/capture then all hit `client.connect()` on the same client. Fix: let warmup errors propagate (so `initPromise` resets and retries with a fresh Memory + fresh pg client) and build fresh config objects per attempt instead of mutating shared state.
**Removed:**
- **`orgId` / `projectId` config parameters**: Removed from config schema, CLI (`config show/get/set`), init display, and providers. The API key is project-scoped, so separate org/project IDs are unnecessary and could cause access errors if mismatched.
- **`enableGraph` config parameter**: Removed from all config surfaces, providers, backend, and tools. Graph memory is being deprecated — removing the flag avoids unnecessary exposure.
</Update>
<Update label="2026-04-04" description="v1.0.4">
**New Features:**
- **Interactive init flow**: `openclaw mem0 init` with interactive menu (email verification or direct API key). Non-interactive modes: `--api-key`, `--email`, `--email --code`
- **`memory_add` tool**: Replaces `memory_store` — name now matches `mem0` CLI and platform API
- **`memory_delete` tool**: Unified delete — single ID, search-then-delete, bulk, entity cascade. Replaces `memory_forget` and `memory_delete_all`
- **CLI subcommands**: `openclaw mem0 init`, `openclaw mem0 status`, `openclaw mem0 config show`, `openclaw mem0 config set`
- **`import` CLI command**: Bulk-import memories from a JSON file with `--user-id` and `--agent-id` overrides
- **`event list` / `event status` CLI commands**: Monitor background processing events
- **`fs-safe.ts` module**: Isolated filesystem wrappers in a separate entry point
- **`backend/` module**: `PlatformBackend` with direct HTTP API access for CLI commands
- **Plugin manifest**: Added `contracts.tools`, `configSchema`, and `uiHints` to `openclaw.plugin.json`
- **Test suite**: 329 tests across 10 test files
**Changes:**
- **Modular architecture**: Extracted tools into `tools/` directory (6 files) and CLI into `cli/commands.ts`
- **Code splitting**: tsup builds with `splitting: true` and two entry points
- **Skills updated**: All SKILL.md files reference new tool names (`memory_add`, `memory_delete`)
- **Auto-recall timeout**: Recall wrapped in 8-second `Promise.race`
- **Auto-capture fire-and-forget**: `provider.add()` runs in background via `.then()/.catch()`
- **Auto-capture minimum content gate**: Skips extraction when total user content is fewer than 50 chars
**Removed:**
- `memory_store` tool — replaced by `memory_add`
- `memory_forget` tool — replaced by `memory_delete`
- `memory_delete_all` tool — merged into `memory_delete`
- `memory_history` tool and `history` CLI command — deprecated
</Update>
<Update label="2026-04-03" description="v1.0.3">
**Bug Fixes:**
- **Security**: Added `safePath()` containment helper to `readSkillFile` and `readDomainOverlay` in `skill-loader.ts` — prevents directory traversal
- **Noise filter**: Reverted incorrect `After-Compaction` regex rename back to `Post-Compaction`
**Changes:**
- **Supply-chain hardening**: Pinned `mem0ai` dependency to exact `2.3.0` (was `^2.3.0`)
**Tests:**
- 12 new tests covering `safePath`, `readSkillFile`, `readDomainOverlay`, and `loadSkill` with traversal inputs
</Update>
<Update label="2026-04-02" description="v1.0.2">
**Bug Fixes:**
- **Security**: Removed `resolveEnvVars()` and `resolveEnvVarsDeep()` from `config.ts` — plugin-side env resolution was redundant and triggered static analysis warnings ([#4676](https://github.com/mem0ai/mem0/pull/4676))
</Update>
<Update label="2026-04-02" description="v1.0.1">
**New Features:**
- **CD workflow**: Added continuous deployment workflow with OIDC trusted publishing ([#4672](https://github.com/mem0ai/mem0/pull/4672))
- **Plugin configuration manifest**: Added `compat` and `build` metadata to `package.json` ([#4667](https://github.com/mem0ai/mem0/pull/4667))
- **LICENSE**: Added Apache-2.0 license file ([#4667](https://github.com/mem0ai/mem0/pull/4667))
**Bug Fixes:**
- **Dream gate**: Fixed cheap-first ordering, session isolation, and verified completion ([#4666](https://github.com/mem0ai/mem0/pull/4666))
- **Graceful startup**: Plugin now starts gracefully when no API key is configured ([#4669](https://github.com/mem0ai/mem0/pull/4669))
</Update>
<Update label="2026-04-01" description="v1.0.0">
**New Features:**
- **Skills-based memory architecture**: New skill-loader and skill-based extraction pipeline with batched extraction ([#4624](https://github.com/mem0ai/mem0/pull/4624))
- **Dream gate**: Memory consolidation and dream-cycle processing during idle periods
- **Enhanced recall**: New `recall.ts` module with improved recall logic and skill-aware retrieval
- **Memory triage skill**: Domain-aware memory triage with companion domain support and recall protocol
- **Memory dream skill**: Skill for memory consolidation during idle periods
- **Plugin configuration**: Added `openclaw.plugin.json` manifest and `scripts/configure.py` setup helper
**Changes:**
- Extraction pipeline refactored to use skills-based architecture for more contextual and higher quality memory capture
</Update>
<Update label="2026-03-26" description="v0.4.1">
**New Features:**
- **Improved extraction quality**: Enhanced noise filtering, deduplication, and better extraction instructions
**Bug Fixes:**
- **Credential detection**: Improved detection of credentials, API keys, and secrets in extraction instructions (#4552)
- **Standalone timestamps**: Prevented extraction of standalone timestamps as memories (#4550)
</Update>
<Update label="2026-03-16" description="v0.4.0">
**New Features:**
- **Non-interactive trigger filtering**: Skips recall and capture for `cron`, `heartbeat`, `automation`, and `schedule` triggers
- **Subagent hallucination prevention**: Detects ephemeral subagent sessions and routes recall to parent namespace
- **Dynamic recall thresholding**: Memories scoring less than 50% of top result are dropped
- **SQLite resilience**: Init error recovery with automatic retry for OSS mode
- **`disableHistory` config option**: New `oss.disableHistory` flag
- 78 unit tests covering filtering, isolation, trigger filtering, subagent detection, and SQLite resilience
**Changes:**
- Auto-recall threshold raised from 0.5 to 0.6 for stricter precision
- Recall candidate pool increased to `topK * 2` for better filtering headroom
- Relaxed extraction instructions: related facts kept together to preserve context
**Bug Fixes:**
- **Concurrent session race condition**: Lifecycle hooks now use `ctx.sessionKey` directly instead of a shared mutable variable
</Update>
<Update label="2026-03-12" description="v0.3.1">
**New Features:**
- **Message filtering pipeline**: Multi-stage noise removal before extraction
- **Broad recall for new sessions**: Short or new-session prompts trigger secondary broad search
- **Client-side threshold filtering**: Safety net that drops low-relevance results
- **Temporal anchoring**: Extraction instructions now include current date
- 55 unit tests covering filtering and isolation helpers
**Changes:**
- Extraction window expanded from last 10 to last 20 messages
- Rewritten custom extraction instructions for conciseness and deduplication
- Refactored monolithic `index.ts` (1772 lines) into 6 focused modules
</Update>
<Update label="2026-03-10" description="v0.3.0">
**Bug Fixes:**
- Updated `mem0ai` dependency with sqlite3 to better-sqlite3 migration (#4270)
</Update>
<Update label="2026-03-09" description="v0.2.0">
**New Features:**
- Per-agent memory isolation for multi-agent setups via `agentId`
- "Understanding userId" section in docs
**Changes:**
- Updated config examples to use concrete `userId` values instead of placeholders
**Bug Fixes:**
- Migrated platform search to Mem0 v2 API
</Update>
<Update label="2026-02-19" description="v0.1.2">
**New Features:**
- Source field for openclaw memory entries
**Bug Fixes:**
- Auto-recall injection and auto-capture message drop
</Update>
<Update label="2026-02-02" description="v0.1.0">
**New Features:**
- Initial release of the OpenClaw Mem0 plugin
- Platform mode (Mem0 Cloud) and open-source mode support
- Auto-recall: inject relevant memories before each turn
- Auto-capture: store facts after each turn
- Configurable `topK`, `threshold`, and `apiVersion` options
</Update>
+290
View File
@@ -0,0 +1,290 @@
---
title: "Platform"
description: "Release notes for the Mem0 hosted platform — backend, dashboard, billing, and infrastructure changes."
mode: "wide"
---
<Update label="2025-07-23" description="">
**Bug Fixes:**
- **Memory:** Fixed ADD functionality
</Update>
<Update label="2025-07-19" description="">
**New Features:**
- **UI:** Added Settings UI and latency display
- **Performance:** Neo4j query optimization
**Bug Fixes:**
- **OpenMemory:** Fixed OMM raising unnecessary exceptions
</Update>
<Update label="2025-07-18" description="">
**Improvements:**
- **UI:** Updated Event UI
- **Performance:** Fixed N+1 query issue in semantic_search_v2 by optimizing MemorySerializer field selection
**Bug Fixes:**
- **Memory:** Fixed duplicate memory index sentry error
</Update>
<Update label="2025-07-17" description="">
**New Features:**
- **UI:** New Settings Page
- **Memory:** Duplicate memories entities support
**Improvements:**
- **Performance:** Optimized semantic search and get_all APIs by eliminating N+1 queries
</Update>
<Update label="2025-07-16" description="">
**New Features:**
- **Database:** Implemented read replica routing with enhanced logging and app-specific DB routing
**Improvements:**
- **Performance:** Improved query performance in search v2 and get all v2 endpoints
**Bug Fixes:**
- **API:** Fixed pagination for get all API
</Update>
<Update label="2025-07-12" description="">
**Bug Fixes:**
- **Graph:** Fixed social graph bugs and connection issues
</Update>
<Update label="2025-07-11" description="">
**Improvements:**
- **Rate Limiting:** New rate limit for V2 Search
**Bug Fixes:**
- **Slack:** Fixed Slack rate limit error with backend improvements
</Update>
<Update label="2025-07-10" description="">
**Improvements:**
- **Performance:**
- Changed connection pooling time to 5 minutes
- Separated graph lambdas for better performance
</Update>
<Update label="2025-07-09" description="">
**Improvements:**
- **Graph:** Graph Optimizations V2 and memory improvements
</Update>
<Update label="2025-07-08" description="">
**New Features:**
- **Database:** Added read replica support for improved database performance
- **UI:** Implemented UI changes for Users Page
- **Feedback:** Enabled feedback functionality
**Bug Fixes:**
- **Serializer:** Fixed GET ALL Serializer
</Update>
<Update label="2025-07-05" description="">
**New Features:**
- **UI:** User Page Revamp and New Users Page
</Update>
<Update label="2025-07-04" description="">
**New Features:**
- **Users:** New Users Page implementation
- **Tools:** Added script to backfill memory categories
**Bug Fixes:**
- **Filters:** Fixed Filters Get All functionality
</Update>
<Update label="2025-07-03" description="">
**Improvements:**
- **Graph:** Graph Memory optimization
- **Memory:** Fixed exact memories and semantically similar memories retrieval
</Update>
<Update label="2025-07-02" description="">
**Improvements:**
- **Categorization:** Refactored categorization logic to utilize Gemini 2.5 Flash and improve message handling
</Update>
<Update label="2025-07-01" description="">
**Bug Fixes:**
- **Memory:** Fixed old_memory issue in Async memory addition lambda
- **Events:** Fixed missing events
</Update>
<Update label="2025-06-30" description="">
**Improvements:**
- **Graph:** Improvements to graph memory and added user to LTM-STM
</Update>
<Update label="2025-06-28" description="">
**New Features:**
- **Graph:** Added support for SQS in graph memory addition
- **Testing:** Added Locust load testing script and Grafana Dashboard
</Update>
<Update label="2025-06-27" description="">
**Improvements:**
- **Rate Limiting:** Updated rate limiting for ADD API to 1000/min
- **Performance:** Improved Neo4j performance
</Update>
<Update label="2025-06-26" description="">
**New Features:**
- **Memory:** Edit Memory From Drawer functionality
- **API:** Added Topic Suggestions API Endpoint
</Update>
<Update label="2025-06-25" description="">
**New Features:**
- **Group Chat:** Group-Chat v2 with Actor-Aware Memories
- **Memory:** Editable Metadata in Memories
- **UI:** Memory Actions Badges
</Update>
<Update label="2025-06-19" description="">
**New Features:**
- **Rate Limiting:** Implemented comprehensive rate limiting system
**Improvements:**
- **Performance:** Added performance indexes for memory stats query
**Bug Fixes:**
- **Search:** Fixed search events not respecting top-k parameter
</Update>
<Update label="2025-06-18" description="">
**New Features:**
- **Memory Management:** Implemented OpenAI Batch API for Memory Cleaning with fallback
- **Playground:** Added Claude 4 support on Playground
**Improvements:**
- **Memory:** Added ability to update memory metadata
</Update>
<Update label="2025-06-17" description="">
**New Features:**
- **UI:** New Memories Page UI design
</Update>
<Update label="2025-06-16" description="">
**Improvements:**
- **Infrastructure:** Migrated to Application Load Balancer (ALB)
</Update>
<Update label="2025-06-13" description="">
**Improvements:**
- **Memory Management:** Enhanced Memory Management with Cosine Similarity Fallback
</Update>
<Update label="2025-06-11" description="">
**New Features:**
- **OMM:** Added OMM Script and UI functionality
**Improvements:**
- **API:** Added filters validation to semantic_search_v2 endpoint
</Update>
<Update label="2025-06-09" description="">
**New Features:**
- **Intercom:** Set Intercom events for ADD and SEARCH operations
- **OpenMemory:** Added Posthog integration and feedback functionality
- **MCP:** New JavaScript MCP Server with feedback support
**Improvements:**
- **Structured Data:** Enhanced structured data handling in memory management
</Update>
<Update label="2025-06-06" description="">
**New Features:**
- **OAuth:** Added Mem0 OAuth integration
- **OMM:** Added OMM-Mem0 sync for deleted memories
</Update>
<Update label="2025-06-05" description="">
**New Features:**
- **Filters:** Implemented Wildcard Filters and refactored filter logic in V2 Views
</Update>
<Update label="2025-06-02" description="">
**New Features:**
- **OpenMemory Cloud:** Added OpenMemory Cloud support
- **Structured Data:** Added 'structured_attributes' field to Memory model
</Update>
<Update label="2025-05-30" description="">
**New Features:**
- **Projects:** Added version and enable_graph to project views
- **OpenMemory:** Added Postgres support for OpenMemory
</Update>
<Update label="2025-05-19" description="">
**Bug Fixes:**
- **Core:** Fixed unicode error in user_id, agent_id, run_id and app_id
</Update>
+188 -288
View File
@@ -1,14 +1,63 @@
---
title: "Product Updates"
description: "Latest releases, bug fixes, and improvements for the Mem0 Python and TypeScript SDKs."
title: "SDK & Tools"
description: "Release notes for the Mem0 Python SDK, TypeScript SDK, Vercel AI SDK, CLI, and editor plugins."
mode: "wide"
---
<Tabs>
<Tab title="Python">
<Update label="2026-04-04" description="v1.0.11">
<Update label="2026-04-14" description="v2.0.0">
**Major Release** — Python SDK with V3 memory pipeline, ADD-only extraction, and cleaned-up API surface.
**New Features:**
- **Single-Pass Extraction:** Replaced 2-LLM-call pipeline with additive extraction using `ADDITIVE_EXTRACTION_PROMPT`. Memories accumulate via `linked_memory_ids` — no more UPDATE/DELETE events ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Hybrid Search:** Combined semantic + BM25 keyword matching + entity boost with additive scoring. Native `keyword_search()` added to 15 vector store adapters (Qdrant, Elasticsearch, OpenSearch, Azure AI Search, Weaviate, Redis, PGVector, Pinecone, Databricks, MongoDB, Milvus, Baidu, Upstash, Azure MySQL, Vertex AI) ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Entity Extraction & Linking:** spaCy-based entity extraction with second vector collection (`{collection}_entities`) for cross-memory relationship retrieval. Optional dependency: `pip install mem0ai[nlp]` ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Batch Operations:** Batch embedding, batch persist, and batch entity linking (8-phase pipeline) for both sync `Memory` and async `AsyncMemory` at full parity ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Message Persistence:** SQLite-based rolling window (10 messages per session scope) for LLM context ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Valkey Cluster Mode:** Added `cluster_mode` parameter for Valkey Cluster Mode Enabled (CME) deployments ([#4759](https://github.com/mem0ai/mem0/pull/4759))
- **V3 API Endpoints:** `MemoryClient.add()` now posts to `/v3/memories/add/`; `MemoryClient.get_all()` posts to `/v3/memories/` and returns a paginated envelope `{"count": int, "next": str | None, "previous": str | None, "results": [...]}` ([#4856](https://github.com/mem0ai/mem0/pull/4856))
- **Default model:** `gpt-5-mini` is now the default across `OpenAILLM`, `OpenAIStructuredLLM`, `AzureOpenAILLM`, `AzureOpenAIStructuredLLM`, and `LiteLLM` fallback ([#4829](https://github.com/mem0ai/mem0/pull/4829))
**Breaking Changes:**
- **`add()` returns ADD-only events** — No more `"UPDATE"` or `"DELETE"` events. Memories accumulate; nothing is overwritten ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **`search()` default `threshold` is now `0.1`** — Pass `threshold=0.0` for previous behavior ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **`search()` `score` is now a combined multi-signal score** — The top-level `score` fuses semantic similarity, BM25 keyword match, and entity boost into one value. Absolute numbers shift versus the old raw cosine score; retune any hard thresholds against representative queries. Per-signal scores are not exposed on the response ([#4805](https://github.com/mem0ai/mem0/pull/4805), [#4836](https://github.com/mem0ai/mem0/pull/4836))
- **`search()` default `rerank` is now `False`** — Pass `rerank=True` for previous behavior ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **`top_k` default changed 100 → 20** in `Memory.get_all()` and `Memory.search()` (sync + async). Pass `top_k=100` explicitly to restore the old behavior ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **Entity ID validation:** `user_id` / `agent_id` / `run_id` are trimmed; empty-string and whitespace-only values now raise `ValueError` ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **Search params validation:** `threshold` must be a number in `[0, 1]`; `top_k` must be a non-negative integer — invalid inputs raise `ValueError` ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **`messages` in `Memory.add()` rejects invalid types:** Passing `None` or non-`(str | dict | list)` values raises `Mem0ValidationError` (`error_code="VALIDATION_003"`) ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **`qdrant-client>=1.12.0` required** — Upgrade from `>=1.9.1` ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **`org_id` and `project_id` removed** — Removed from `MemoryClient` constructor and all method signatures ([#4740](https://github.com/mem0ai/mem0/pull/4740))
- **Graph Memory Removed (OSS):** `mem0/memory/graph_memory.py`, `memgraph_memory.py`, `kuzu_memory.py`, `apache_age_memory.py`, and `mem0/graphs/` (Neo4j / Memgraph / Kuzu / Apache AGE / Neptune drivers) deleted — ~4,000 lines. Graph memory is no longer supported in the OSS SDK; graph drivers (neo4j, memgraph, kuzu, etc.) can be uninstalled. Use the Platform API for graph features. Remove `enable_graph` and `graph_store` from your config ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **`enable_graph` removed from Client SDK** — Graph memory is now a project-level setting on the Platform. Remove `enable_graph` from `MemoryClient.add()` / `search()` / `get_all()` / `update_project()` calls ([#4776](https://github.com/mem0ai/mem0/pull/4776))
- **`custom_fact_extraction_prompt` renamed to `custom_instructions`** — Update config and memory module references ([#4740](https://github.com/mem0ai/mem0/pull/4740))
- **Typed option classes** — Added Pydantic v2 typed classes: `AddMemoryOptions`, `SearchMemoryOptions`, `GetAllMemoryOptions`, `DeleteAllMemoryOptions`, `UpdateMemoryOptions`, `ProjectUpdateOptions` ([#4740](https://github.com/mem0ai/mem0/pull/4740))
**Security:**
- **FAISS:** Prevent arbitrary code execution via pickle deserialization in `FAISS` vector store ([#4833](https://github.com/mem0ai/mem0/pull/4833))
**Bug Fixes:**
- **V3 migration crashes:** Fixed crashes in the v3 migration path; entity linking on OSS is now functional across Qdrant and Milvus backends ([#4836](https://github.com/mem0ai/mem0/pull/4836))
- **Qdrant entity store:** Entity store now shares the existing Qdrant client when using embedded mode (`path=...`), eliminating RocksDB lock contention between the main and entity collections ([#4836](https://github.com/mem0ai/mem0/pull/4836))
- **Reranker:** Fixed incorrect use of SentenceTransformer for cross-encoder reranker models — switched to CrossEncoder API for proper scoring ([#4806](https://github.com/mem0ai/mem0/pull/4806))
- **S3 Vectors:** Handle `vector=None` in `update()` to prevent boto3 validation error when `event=NONE` ([#4594](https://github.com/mem0ai/mem0/pull/4594))
- **LLMs:** Made OpenAI `store` parameter opt-in to prevent leaking to non-OpenAI backends like Google Gemini ([#4757](https://github.com/mem0ai/mem0/pull/4757))
- **LLMs:** Forward `response_format` to Azure OpenAI API to prevent JSON parsing failures ([#4689](https://github.com/mem0ai/mem0/pull/4689))
- **Core:** Guard `temp_uuid_mapping` lookups against LLM-hallucinated IDs with safe `.get()` and warnings ([#4674](https://github.com/mem0ai/mem0/pull/4674))
- **Client:** Prevent `MemoryClient.feedback()` telemetry TypeError by merging feedback data into single payload ([#4795](https://github.com/mem0ai/mem0/pull/4795))
**Improvements:**
- **Telemetry:** Sample OSS hot-path events at 10% via PostHog `before_send` hook to reduce event volume ([#4771](https://github.com/mem0ai/mem0/pull/4771))
See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-v2) and [Platform migration guide](https://docs.mem0.ai/migration/platform-v2-to-v3) for upgrade instructions.
</Update>
<Update label="2026-04-06" description="v1.0.11">
**New Features & Updates:**
- **SDK:** Added `multilingual` parameter to project update ([#4314](https://github.com/mem0ai/mem0/pull/4314))
@@ -844,8 +893,59 @@ mode: "wide"
</Tab>
<Tab title="TypeScript">
<Update label="2026-04-14" description="v3.0.0">
<Update label="2026-04-04" description="v2.4.6">
**Major Release** — TypeScript SDK with V3 memory pipeline, camelCase parameters, and cleaned-up API surface.
**V3 Memory Pipeline (OSS):**
- **Single-Pass Extraction:** Additive extraction pipeline aligned with Python SDK — memories accumulate, no UPDATE/DELETE events ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Entity Extraction & Linking:** New `entity_extraction.ts` module (720+ lines) with cross-memory relationship retrieval ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Message Persistence:** SQLite-based message history via new `SQLiteManager.ts` with rolling window for LLM context ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Batch Embeddings:** `embedBatch()` support in OpenAI and Azure embedding providers ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **Scoring & Lemmatization:** New `scoring.ts` and `lemmatization.ts` utilities for hybrid search ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **New Prompts:** `prompts/index.ts` (592+ lines) with additive extraction prompt aligned with Python SDK ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **V3 API Endpoints:** `MemoryClient.add()` now posts to `/v3/memories/add/`; `MemoryClient.getAll()` posts to `/v3/memories/` with paginated envelope `{ count, next, previous, results }` ([#4856](https://github.com/mem0ai/mem0/pull/4856))
- **Default model:** `gpt-5-mini` is now the default in `OpenAI`, `OpenAIStructured`, and `Azure` LLM providers ([#4829](https://github.com/mem0ai/mem0/pull/4829))
**Breaking Changes:**
- **Graph Memory Removed (OSS):** `graph_memory.ts` (675 lines), `graphs/tools.ts` (267 lines), `graphs/utils.ts` (116 lines), `graphs/configs.ts` (30 lines) deleted. Graph memory is no longer supported in the OSS SDK — use Platform API for graph features ([#4805](https://github.com/mem0ai/mem0/pull/4805))
- **camelCase Parameters (Client SDK):** All user-facing parameters converted from snake_case to camelCase. Mapping is transparent at API boundary via `camelToSnakeKeys()` / `snakeToCamelKeys()` ([#4776](https://github.com/mem0ai/mem0/pull/4776))
```typescript
// Before
client.add(messages, { user_id: "alice", top_k: 5 });
// After
client.add(messages, { userId: "alice", topK: 5 });
```
- **Per-Method Option Types:** Replaced monolithic `MemoryOptions` with typed interfaces: `AddMemoryOptions`, `SearchMemoryOptions`, `GetAllMemoryOptions`, `DeleteAllMemoryOptions` ([#4740](https://github.com/mem0ai/mem0/pull/4740))
- **Removed Deprecated Parameters:** `org_id`, `project_id`, `api_version`, `output_format`, `async_mode`, `enable_graph`, `limit` removed from client method signatures. `ClientOptions` reduced to `{ apiKey, host }` only ([#4740](https://github.com/mem0ai/mem0/pull/4740))
- **`limit` renamed to `topK` (OSS):** Update all search calls ([#4740](https://github.com/mem0ai/mem0/pull/4740))
- **`topK` default changed 100 → 20** in `Memory.getAll()` and `Memory.search()`. Pass `topK: 100` explicitly to restore the old behavior ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **Entity ID validation:** `userId` / `agentId` / `runId` are trimmed; empty-string and whitespace-only values now throw ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **Search params validation:** `threshold` must be in `[0, 1]`; `topK` must be a non-negative integer — invalid inputs throw ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **`messages` in `Memory.add()` is required:** Passing `undefined` or `null` now throws ([#4843](https://github.com/mem0ai/mem0/pull/4843))
- **`customPrompt` renamed to `customInstructions` (OSS):** Update memory and vector store configurations ([#4740](https://github.com/mem0ai/mem0/pull/4740))
- **`enableGraph` removed (OSS):** Config option removed — graph memory no longer available in OSS ([#4776](https://github.com/mem0ai/mem0/pull/4776))
**New Features:**
- **LLMs:** Added DeepSeek LLM provider with OpenAI-compatible integration using custom baseURL to `api.deepseek.com` ([#4613](https://github.com/mem0ai/mem0/pull/4613))
- **Entity store isolation:** `MemoryVectorStore` now uses a dedicated `_entities.db` file, preventing entity/memory store collisions ([#4829](https://github.com/mem0ai/mem0/pull/4829), [#4841](https://github.com/mem0ai/mem0/pull/4841))
- **Payload backward compatibility:** Legacy camelCase payload keys normalized to snake_case on read ([#4841](https://github.com/mem0ai/mem0/pull/4841))
**Bug Fixes:**
- **V3 migration:** Fixed crashes in the OSS migration path; entity linking works end-to-end ([#4836](https://github.com/mem0ai/mem0/pull/4836))
- **PGVector init race:** `PGVector.initialize()` now memoises the in-flight init promise ([#4841](https://github.com/mem0ai/mem0/pull/4841))
- **Redis module detection:** Handles both node-redis v4+ and legacy `moduleList` response shapes ([#4841](https://github.com/mem0ai/mem0/pull/4841))
- **Config:** Fixed `ConfigManager.mergeConfig()` to only include `graphStore` when explicitly provided by user, preventing default Neo4j connection attempts ([#4776](https://github.com/mem0ai/mem0/pull/4776))
- **LLMs:** Config manager now falls back to `userConf.url` for `baseURL` — prevents custom LLM providers (Ollama, LMStudio) from silently connecting to OpenAI ([#4761](https://github.com/mem0ai/mem0/pull/4761))
**Improvements:**
- **Telemetry:** Sample OSS hot-path events at 10% to reduce PostHog event volume ([#4771](https://github.com/mem0ai/mem0/pull/4771))
See the [TypeScript SDK migration guide](https://docs.mem0.ai/migration/ts-v2-to-v3) for upgrade instructions.
</Update>
<Update label="2026-04-06" description="v2.4.6">
**New Features & Updates:**
- **Client:** Added `multilingual` parameter to project update types ([#4314](https://github.com/mem0ai/mem0/pull/4314))
@@ -1160,352 +1260,152 @@ mode: "wide"
</Tab>
<Tab title="Platform">
<Tab title="CLI">
<Update label="2025-07-23" description="">
<Update label="2026-04-11" description="Python v0.2.3 / Node v0.2.3">
**Bug Fixes:**
- **Memory:** Fixed ADD functionality
- **Telemetry:** Replaced shared `"anonymous-cli"` fallback with a persistent per-machine random hash (`cli-anon-<uuid>`), so anonymous CLI users are counted individually in PostHog instead of collapsing into one identity ([#4789](https://github.com/mem0ai/mem0/pull/4789))
- **Telemetry:** Added PostHog `$identify` event on first authenticated run to stitch pre-signup anonymous history onto the authenticated user profile ([#4789](https://github.com/mem0ai/mem0/pull/4789))
**Improvements:**
- **API:** All API calls now include `source=CLI` in request bodies (POST/PUT) and query params (GET/DELETE) for server-side attribution ([#4789](https://github.com/mem0ai/mem0/pull/4789))
</Update>
<Update label="2025-07-19" description="">
<Update label="2026-04-06" description="Python v0.2.2 / Node v0.2.2">
**New Features:**
- **UI:** Added Settings UI and latency display
- **Performance:** Neo4j query optimization
- **Telemetry:** Added PostHog telemetry and source tracking to both Python and Node CLIs ([#4699](https://github.com/mem0ai/mem0/pull/4699))
- **Validation:** API key validated upfront via `/v1/ping/` on startup — fail-fast with a helpful error instead of cryptic 401s ([#4701](https://github.com/mem0ai/mem0/pull/4701))
**Bug Fixes:**
- **OpenMemory:** Fixed OMM raising unnecessary exceptions
- **CD:** Fixed OIDC trusted publishing with `npx npm@latest` ([#4724](https://github.com/mem0ai/mem0/pull/4724))
- **CD:** Removed npm self-upgrade from CD workflows ([#4723](https://github.com/mem0ai/mem0/pull/4723))
</Update>
<Update label="2025-07-18" description="">
<Update label="2026-04-03" description="Python v0.2.1 / Node v0.2.1">
**Improvements:**
- **UI:** Updated Event UI
- **Performance:** Fixed N+1 query issue in semantic_search_v2 by optimizing MemorySerializer field selection
**New Features:**
- **Docs:** Comprehensive README with installation, usage examples, and purple branding ([#4680](https://github.com/mem0ai/mem0/pull/4680))
**Bug Fixes:**
- **Memory:** Fixed duplicate memory index sentry error
- **npm:** Added `repository` field to Node packages for npm provenance ([#4671](https://github.com/mem0ai/mem0/pull/4671))
- **CD:** Added CD workflows for Node SDK packages with OIDC trusted publishing ([#4670](https://github.com/mem0ai/mem0/pull/4670))
</Update>
<Update label="2025-07-17" description="">
<Update label="2026-04-02" description="Python v0.2.0 / Node v0.1.1">
**New Features:**
- **UI:** New Settings Page
- **Memory:** Duplicate memories entities support
**Improvements:**
- **Performance:** Optimized semantic search and get_all APIs by eliminating N+1 queries
</Update>
<Update label="2025-07-16" description="">
**New Features:**
- **Database:** Implemented read replica routing with enhanced logging and app-specific DB routing
**Improvements:**
- **Performance:** Improved query performance in search v2 and get all v2 endpoints
- **`event` commands:** `mem0 event list` shows recent background processing events in a table; `mem0 event status <id>` shows full detail including nested memory results ([#4649](https://github.com/mem0ai/mem0/pull/4649))
- **`--json` / `--agent` flag:** Root-level flag switches all command output to a structured JSON envelope for programmatic/agent consumption. Envelope format: `{"status", "command", "duration_ms", "scope", "count", "data"}` ([#4649](https://github.com/mem0ai/mem0/pull/4649))
- **Agent output sanitization:** Raw API responses projected to only relevant fields per command (e.g., `add` → `{id, memory, event}`, `search` → `{id, memory, score, created_at, categories}`) ([#4649](https://github.com/mem0ai/mem0/pull/4649))
- **Email login:** Added email verification code login to `mem0 init` ([#4623](https://github.com/mem0ai/mem0/pull/4623))
- **Brand update:** Updated color palette from purple to golden ([#4664](https://github.com/mem0ai/mem0/pull/4664))
- **CI/CD:** Added CI pipelines and CD workflows for both CLIs ([#4640](https://github.com/mem0ai/mem0/pull/4640), [#4653](https://github.com/mem0ai/mem0/pull/4653))
**Bug Fixes:**
- **API:** Fixed pagination for get all API
</Update>
<Update label="2025-07-12" description="">
**Bug Fixes:**
- **Graph:** Fixed social graph bugs and connection issues
</Update>
<Update label="2025-07-11" description="">
- **Node:** Fixed critical `MODULE_NOT_FOUND` crash on `status`, `import`, and all commands when installed globally — replaced runtime `createRequire` with build-time version injection ([#4636](https://github.com/mem0ai/mem0/pull/4636))
- **Node:** API errors now show full response detail instead of bare "Bad Request" ([#4636](https://github.com/mem0ai/mem0/pull/4636))
- **Python:** Fixed double error printing on all commands ([#4636](https://github.com/mem0ai/mem0/pull/4636))
- **`status` command:** Replaced heavyweight `/v1/entities/` check with dedicated `GET /v1/ping/` endpoint ([#4649](https://github.com/mem0ai/mem0/pull/4649))
- **`add` command:** Deduplicated PENDING results from API; changed misleading count message ([#4649](https://github.com/mem0ai/mem0/pull/4649))
- **`init` command:** Partial flags now work in non-TTY; warns before overwriting existing config; added `--force` flag ([#4649](https://github.com/mem0ai/mem0/pull/4649))
- **`delete` command:** Fixed entity delete via v2 API for all entity types ([#4649](https://github.com/mem0ai/mem0/pull/4649))
**Improvements:**
- **Rate Limiting:** New rate limit for V2 Search
**Bug Fixes:**
- **Slack:** Fixed Slack rate limit error with backend improvements
- Tables now show full UUIDs (was truncated to 8 chars, making `mem0 get <id>` fail) ([#4636](https://github.com/mem0ai/mem0/pull/4636))
- Search table includes Score column ([#4636](https://github.com/mem0ai/mem0/pull/4636))
- `config get api_key` short-form aliases added ([#4636](https://github.com/mem0ai/mem0/pull/4636))
- Client-side validation for `--expires`, `--page-size`, `--page`, `--top-k`, `--threshold`, and empty content ([#4636](https://github.com/mem0ai/mem0/pull/4636))
- `printInfo` / `printScope` moved to stderr to avoid contaminating JSON piping ([#4636](https://github.com/mem0ai/mem0/pull/4636))
</Update>
<Update label="2025-07-10" description="">
<Update label="2026-03-26" description="Python v0.1.0 / Node v0.1.0">
**Improvements:**
- **Performance:**
- Changed connection pooling time to 5 minutes
- Separated graph lambdas for better performance
**Initial Release — Official Mem0 CLI**
</Update>
A full-featured command-line interface for Mem0, available in both Python and Node.js:
<Update label="2025-07-09" description="">
**Improvements:**
- **Graph:** Graph Optimizations V2 and memory improvements
</Update>
<Update label="2025-07-08" description="">
**New Features:**
- **Database:** Added read replica support for improved database performance
- **UI:** Implemented UI changes for Users Page
- **Feedback:** Enabled feedback functionality
**Bug Fixes:**
- **Serializer:** Fixed GET ALL Serializer
</Update>
<Update label="2025-07-05" description="">
**New Features:**
- **UI:** User Page Revamp and New Users Page
</Update>
<Update label="2025-07-04" description="">
**New Features:**
- **Users:** New Users Page implementation
- **Tools:** Added script to backfill memory categories
**Bug Fixes:**
- **Filters:** Fixed Filters Get All functionality
</Update>
<Update label="2025-07-03" description="">
**Improvements:**
- **Graph:** Graph Memory optimization
- **Memory:** Fixed exact memories and semantically similar memories retrieval
</Update>
<Update label="2025-07-02" description="">
**Improvements:**
- **Categorization:** Refactored categorization logic to utilize Gemini 2.5 Flash and improve message handling
</Update>
<Update label="2025-07-01" description="">
**Bug Fixes:**
- **Memory:** Fixed old_memory issue in Async memory addition lambda
- **Events:** Fixed missing events
</Update>
<Update label="2025-06-30" description="">
**Improvements:**
- **Graph:** Improvements to graph memory and added user to LTM-STM
</Update>
<Update label="2025-06-28" description="">
**New Features:**
- **Graph:** Added support for SQS in graph memory addition
- **Testing:** Added Locust load testing script and Grafana Dashboard
</Update>
<Update label="2025-06-27" description="">
**Improvements:**
- **Rate Limiting:** Updated rate limiting for ADD API to 1000/min
- **Performance:** Improved Neo4j performance
</Update>
<Update label="2025-06-26" description="">
**New Features:**
- **Memory:** Edit Memory From Drawer functionality
- **API:** Added Topic Suggestions API Endpoint
</Update>
<Update label="2025-06-25" description="">
**New Features:**
- **Group Chat:** Group-Chat v2 with Actor-Aware Memories
- **Memory:** Editable Metadata in Memories
- **UI:** Memory Actions Badges
</Update>
<Update label="2025-06-19" description="">
**New Features:**
- **Rate Limiting:** Implemented comprehensive rate limiting system
**Improvements:**
- **Performance:** Added performance indexes for memory stats query
**Bug Fixes:**
- **Search:** Fixed search events not respecting top-k parameter
</Update>
<Update label="2025-06-18" description="">
**New Features:**
- **Memory Management:** Implemented OpenAI Batch API for Memory Cleaning with fallback
- **Playground:** Added Claude 4 support on Playground
**Improvements:**
- **Memory:** Added ability to update memory metadata
</Update>
<Update label="2025-06-17" description="">
**New Features:**
- **UI:** New Memories Page UI design
</Update>
<Update label="2025-06-16" description="">
**Improvements:**
- **Infrastructure:** Migrated to Application Load Balancer (ALB)
</Update>
<Update label="2025-06-13" description="">
**Improvements:**
- **Memory Management:** Enhanced Memory Management with Cosine Similarity Fallback
</Update>
<Update label="2025-06-11" description="">
**New Features:**
- **OMM:** Added OMM Script and UI functionality
**Improvements:**
- **API:** Added filters validation to semantic_search_v2 endpoint
</Update>
<Update label="2025-06-09" description="">
**New Features:**
- **Intercom:** Set Intercom events for ADD and SEARCH operations
- **OpenMemory:** Added Posthog integration and feedback functionality
- **MCP:** New JavaScript MCP Server with feedback support
**Improvements:**
- **Structured Data:** Enhanced structured data handling in memory management
</Update>
<Update label="2025-06-06" description="">
**New Features:**
- **OAuth:** Added Mem0 OAuth integration
- **OMM:** Added OMM-Mem0 sync for deleted memories
</Update>
<Update label="2025-06-05" description="">
**New Features:**
- **Filters:** Implemented Wildcard Filters and refactored filter logic in V2 Views
</Update>
<Update label="2025-06-02" description="">
**New Features:**
- **OpenMemory Cloud:** Added OpenMemory Cloud support
- **Structured Data:** Added 'structured_attributes' field to Memory model
</Update>
<Update label="2025-05-30" description="">
**New Features:**
- **Projects:** Added version and enable_graph to project views
- **OpenMemory:** Added Postgres support for OpenMemory
</Update>
<Update label="2025-05-19" description="">
**Bug Fixes:**
- **Core:** Fixed unicode error in user_id, agent_id, run_id and app_id
- **Install:** `pip install mem0-cli` (Python) or `npm install -g @mem0/cli` (Node.js)
- **Full command suite:** `add`, `search`, `list`, `get`, `update`, `delete`, `import`, `config`, `init`, `status`, `entity`
- **Interactive setup:** `mem0 init` with API key entry and user ID configuration
- **Works everywhere:** Platform (Mem0 Cloud) and self-hosted OSS modes
- **Scriptable:** `-o json` flag for CI/CD pipelines and automation
- **Dual SDK:** Same commands, same experience across Python and Node.js
- **Shared spec:** Both implementations driven by a single `cli-spec.json` ensuring identical behavior ([#4575](https://github.com/mem0ai/mem0/pull/4575))
</Update>
</Tab>
<Tab title="Vercel AI SDK">
<Tab title="Plugins">
<Update label="2025-12-26" description="v2.0.5">
<Update label="2026-04-02" description="mem0-plugin v1.0.0">
**Mem0 Plugin for Claude Code, Cursor, and Codex**
The unified Mem0 plugin for AI development environments:
- **9 MCP memory tools:** `add_memory`, `search_memories`, `get_memories`, `get_memory`, `update_memory`, `delete_memory`, `delete_all_memories`, `delete_entities`, `list_entities` — all via `mcp.mem0.ai`
- **Lifecycle hooks:** Automatic memory capture at session start, context compaction, task completion, and session end
- **Cloud MCP server:** Managed endpoint replaces local MCP and Smithery setup
- **Streamable HTTP transport:** New MCP transport protocol for real-time streaming
- **Codex-specific skill:** Dedicated skill in `mem0-plugin/skills/mem0-codex` for Codex workflows
- **Supported editors:** Claude Code, Claude Cowork, Cursor, Codex
</Update>
<Update label="2025-12-26" description="Vercel AI SDK v2.0.5">
**Bug Fix:**
- **Vercel AI SDK:** Removed unnecessary dependencies to make the package lighter.
- Removed unnecessary dependencies to make the package lighter.
</Update>
<Update label="2025-09-25" description="v2.0.4">
<Update label="2025-09-25" description="Vercel AI SDK v2.0.3 – v2.0.4">
**New Features:**
- Added file support for multimodal capabilities with memory context (v2.0.3)
**Bug Fix:**
- **Vercel AI SDK:** Fixed version parameter in the AI SDK to use V2 for addition.
- Fixed version parameter to use V2 for addition (v2.0.4)
</Update>
<Update label="2025-09-25" description="v2.0.3">
**New Features:**
- **Vercel AI SDK:** Added file support for multimodal capabilities with memory context
</Update>
<Update label="2025-09-03" description="v2.0.2">
<Update label="2025-09-03" description="Vercel AI SDK v2.0.2">
**Bug Fix:**
- **Vercel AI SDK:** Fixed streaming response in the AI SDK.
- Fixed streaming response in the AI SDK.
</Update>
<Update label="2025-08-05" description="v2.0.1">
<Update label="2025-08-05" description="Vercel AI SDK v2.0.0 – v2.0.1">
**New Features:**
- **Vercel AI SDK:** Added a new param `host` to the config.
- Migration to AI SDK V5 (v2.0.0)
- Added `host` param to the config (v2.0.1)
</Update>
<Update label="2025-08-05" description="v2.0.0">
<Update label="2025-06-15" description="Vercel AI SDK v1.0.6">
**New Features:**
- **Vercel AI SDK:** Migration to AI SDK V5.
- Added `filter_memories` param.
</Update>
<Update label="2025-06-15" description="v1.0.6">
<Update label="2025-05-23" description="Vercel AI SDK v1.0.5">
**New Features:**
- **Vercel AI SDK:** Added param `filter_memories`.
- Added support for Google provider.
</Update>
<Update label="2025-05-23" description="v1.0.5">
<Update label="2025-05-10" description="Vercel AI SDK v1.0.3 – v1.0.4">
**New Features:**
- **Vercel AI SDK:** Added support for Google provider.
</Update>
- Added support for `output_format` param (v1.0.4)
<Update label="2025-05-10" description="v1.0.4">
**New Features:**
- **Vercel AI SDK:** Added support for new param `output_format`.
</Update>
<Update label="2025-05-08" description="v1.0.3">
**Improvements:**
- **Vercel AI SDK:** Added support for graceful failure in cases services are down.
- Added graceful failure handling when services are down (v1.0.3)
</Update>
<Update label="2025-05-01" description="v1.0.1">
<Update label="2025-05-01" description="Vercel AI SDK v1.0.1">
**New Features:**
- **Vercel AI SDK:** Added support for graph memories
- Added support for graph memories.
</Update>
</Tab>
</Tabs>
+1 -1
View File
@@ -21,7 +21,7 @@ os.environ["OPENAI_API_KEY"] = "your-api-key"
# Initialize a LangChain model directly
openai_model = ChatOpenAI(
model="gpt-4.1-nano-2025-04-14",
model="gpt-5-mini",
temperature=0.2,
max_tokens=2000
)
+1 -1
View File
@@ -16,7 +16,7 @@ config = {
"llm": {
"provider": "litellm",
"config": {
"model": "gpt-4.1-nano-2025-04-14",
"model": "gpt-5-mini",
"temperature": 0.2,
"max_tokens": 2000,
}
+2 -2
View File
@@ -20,7 +20,7 @@ config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4.1-nano-2025-04-14",
"model": "gpt-5-mini",
"temperature": 0.2,
"max_tokens": 2000,
}
@@ -86,7 +86,7 @@ config = {
"llm": {
"provider": "openai_structured",
"config": {
"model": "gpt-4.1-nano-2025-04-14",
"model": "gpt-5-mini",
"temperature": 0.0,
}
}
+1 -1
View File
@@ -91,7 +91,7 @@ config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4.1-nano-2025-04-14"
"model": "gpt-5-mini"
}
},
"reranker": {
+1 -1
View File
@@ -189,7 +189,7 @@ for i, prompt in enumerate(prompts):
config["reranker"]["config"]["scoring_prompt"] = prompt
memory = Memory.from_config(config)
results = memory.search("test query", user_id="test_user")
results = memory.search("test query", filters={"user_id": "test_user"})
print(f"Prompt {i+1} results: {results}")
```
+2 -2
View File
@@ -35,7 +35,7 @@ config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4.1-nano-2025-04-14"
"model": "gpt-5-mini"
}
},
"reranker": {
@@ -95,7 +95,7 @@ messages = [
memory.add(messages, user_id="bob")
# Search with reranking
results = memory.search("What is the user's profession?", user_id="bob")
results = memory.search("What is the user's profession?", filters={"user_id": "bob"})
for result in results['results']:
print(f"Memory: {result['memory']}")
@@ -175,7 +175,7 @@ queries = [
results = []
for query in queries:
result = m.search(query, user_id="alice", rerank=True)
result = m.search(query, filters={"user_id": "alice"}, rerank=True)
results.append(result)
```
+1 -1
View File
@@ -111,7 +111,7 @@ messages = [
memory.add(messages, user_id="david")
# Search with LLM reranking
results = memory.search("What programming topics is the user studying?", user_id="david")
results = memory.search("What programming topics is the user studying?", filters={"user_id": "david"})
for result in results['results']:
print(f"Memory: {result['memory']}")
@@ -283,12 +283,12 @@ for result in results["results"]:
def safe_llm_rerank_search(query, user_id, max_retries=3):
for attempt in range(max_retries):
try:
return m.search(query, user_id=user_id, rerank=True)
return m.search(query, filters={"user_id": user_id}, rerank=True)
except Exception as e:
print(f"Attempt {attempt + 1} failed: {e}")
if attempt == max_retries - 1:
# Fall back to vector search
return m.search(query, user_id=user_id, rerank=False)
return m.search(query, filters={"user_id": user_id}, rerank=False)
# Use the safe function
results = safe_llm_rerank_search("What are my preferences?", "alice")
@@ -376,19 +376,19 @@ class RobustLLMReranker:
# Try primary LLM reranker
for attempt in range(max_retries):
try:
return self.primary.search(query, user_id=user_id, rerank=True)
return self.primary.search(query, filters={"user_id": user_id}, rerank=True)
except Exception as e:
print(f"Primary reranker attempt {attempt + 1} failed: {e}")
# Try fallback reranker
if self.fallback:
try:
return self.fallback.search(query, user_id=user_id, rerank=True)
return self.fallback.search(query, filters={"user_id": user_id}, rerank=True)
except Exception as e:
print(f"Fallback reranker failed: {e}")
# Final fallback: vector search only
return self.primary.search(query, user_id=user_id, rerank=False)
return self.primary.search(query, filters={"user_id": user_id}, rerank=False)
# Usage
primary_config = {
@@ -101,7 +101,7 @@ messages = [
memory.add(messages, user_id="charlie")
# Search with local reranking
results = memory.search("What books does the user like?", user_id="charlie")
results = memory.search("What books does the user like?", filters={"user_id": "charlie"})
for result in results['results']:
print(f"Memory: {result['memory']}")
@@ -86,7 +86,7 @@ messages = [
memory.add(messages, user_id="alice")
# Search with reranking
results = memory.search("What Italian food does the user like?", user_id="alice")
results = memory.search("What Italian food does the user like?", filters={"user_id": "alice"})
for result in results['results']:
print(f"Memory: {result['memory']}")
+2 -2
View File
@@ -153,7 +153,7 @@ def measure_reranker_performance(config, queries, user_id):
latencies = []
for query in queries:
start_time = time.time()
results = memory.search(query, user_id=user_id)
results = memory.search(query, filters={"user_id": user_id})
latency = time.time() - start_time
latencies.append(latency)
@@ -191,7 +191,7 @@ class CachedReranker:
@lru_cache(maxsize=1000)
def search_cached(self, query_hash, user_id):
return self.memory.search(query, user_id=user_id)
return self.memory.search(query, filters={"user_id": user_id})
def search(self, query, user_id):
query_hash = hashlib.md5(f"{query}_{user_id}".encode()).hexdigest()
+1 -1
View File
@@ -15,7 +15,7 @@ Mem0 supports LangChain as a provider for vector store integration. LangChain pr
```python Python
import os
from mem0 import Memory
from langchain_community.vectorstores import Chroma
from langchain_chroma import Chroma
from langchain_openai import OpenAIEmbeddings
# Initialize a LangChain vector store
+1 -1
View File
@@ -72,7 +72,7 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
### Search Memories
```python
results = m.search("What kind of movies does Alice like?", user_id="alice")
results = m.search("What kind of movies does Alice like?", filters={"user_id": "alice"})
```
### Features
@@ -36,7 +36,7 @@ messages = [
m.add(messages, user_id="alice", metadata={"category": "movies"})
# Search memories
results = m.search(query="sci-fi recommendations", user_id="alice")
results = m.search(query="sci-fi recommendations", filters={"user_id": "alice"})
```
### Config
+21
View File
@@ -50,4 +50,25 @@ Here are the parameters available for configuring Valkey:
| `hnsw_m` | Number of bi-directional links for HNSW | `16` |
| `hnsw_ef_construction` | Size of dynamic candidate list for HNSW | `200` |
| `hnsw_ef_runtime` | Size of dynamic candidate list for search | `10` |
| `cluster_mode` | Enable cluster mode for Valkey cluster (CME) deployments | `false` |
| `distance_metric` | Distance metric for vector similarity | `cosine` |
## Cluster Mode
To use Valkey with cluster mode enabled (CME), set `cluster_mode` to `true`:
```python
config = {
"vector_store": {
"provider": "valkey",
"config": {
"collection_name": "memories",
"valkey_url": "valkey://cluster-endpoint:6379",
"embedding_model_dims": 1536,
"cluster_mode": True
}
}
}
```
When cluster mode is enabled, the connector uses `ValkeyCluster` instead of the standalone client, which handles `MOVED`/`ASK` redirections automatically. Search queries are coordinated across all shards by the valkey-search module's built-in coordinator. See the [valkey-search documentation](https://github.com/valkey-io/valkey-search) for details on cluster mode behavior.
+2 -2
View File
@@ -60,7 +60,7 @@ class PersonalAITutor:
"""
# Start a streaming response request to the AI
response = self.client.responses.create(
model="gpt-4.1-nano-2025-04-14",
model="gpt-5-mini",
instructions="You are a personal AI Tutor.",
input=question,
stream=True
@@ -81,7 +81,7 @@ class PersonalAITutor:
:param user_id: Optional user ID to filter memories.
:return: List of memories.
"""
return self.memory.get_all(user_id=user_id)
return self.memory.get_all(filters={"user_id": user_id})
# Instantiate the PersonalAITutor
ai_tutor = PersonalAITutor()
@@ -57,7 +57,7 @@ m = Memory.from_config(config)
m.add("I'm visiting Paris", user_id="john")
# Retrieve memories
memories = m.get_all(user_id="john")
memories = m.get_all(filters={"user_id": "john"})
```
## Key Points
@@ -47,7 +47,7 @@ ${memoriesStr}`;
];
const response = await openaiClient.chat.completions.create({
model: "gpt-4.1-nano-2025-04-14",
model: "gpt-5-mini",
messages: messages
});
@@ -45,7 +45,7 @@ Before you begin, follow these steps to set up the demo application:
OPENAI_API_KEY=your_openai_api_key
MEM0_API_KEY=your_mem0_api_key
```
You can obtain your `MEM0_API_KEY` by signing up at [Mem0 API Dashboard](https://app.mem0.ai/dashboard/api-keys).
You can obtain your `MEM0_API_KEY` by signing up at <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 API Dashboard</a>.
5. Start the development server:
```bash
@@ -36,7 +36,7 @@ config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4.1-nano-2025-04-14",
"model": "gpt-5-mini",
"temperature": 0.1,
"max_tokens": 2000,
}
@@ -77,7 +77,7 @@ class PersonalTravelAssistant:
# Generate response using Responses API
response = self.client.responses.create(
model="gpt-4.1-nano-2025-04-14",
model="gpt-5-mini",
input=prompt
)
@@ -89,11 +89,11 @@ class PersonalTravelAssistant:
return answer
def get_memories(self, user_id):
memories = self.memory.get_all(user_id=user_id)
memories = self.memory.get_all(filters={"user_id": user_id})
return [m['memory'] for m in memories['results']]
def search_memories(self, query, user_id):
memories = self.memory.search(query, user_id=user_id)
memories = self.memory.search(query, filters={"user_id": user_id})
return [m['memory'] for m in memories['results']]
# Usage example
@@ -143,7 +143,7 @@ class PersonalTravelAssistant:
# Generate response using gpt-4.1-nano
response = self.client.chat.completions.create(
model="gpt-4.1-nano-2025-04-14"2025-04-14",
model="gpt-5-mini",
messages=self.messages
)
answer = response.choices[0].message.content
@@ -126,16 +126,15 @@ async def search_memories(
print(f"Finding memories related to: {query}")
results = await mem0_client.search(
query,
user_id=USER_ID,
limit=5,
filters={"user_id": USER_ID},
top_k=5,
threshold=0.7, # Higher threshold for more relevant results
)
# Format and return the results
if not results.get('results', []):
return "I don't have any relevant memories about this topic."
memories = [f"• {result['memory']}" for result in results.get('results', [])]
return "Here's what I remember that might be relevant:\n" + "\n".join(memories)
```
@@ -161,7 +160,7 @@ def create_memory_voice_agent():
Use the search_memories tool when you need context from past conversations or user asks you to recall something.
""",
),
model="gpt-4.1-nano-2025-04-14",
model="gpt-5-mini",
tools=[save_memories, search_memories],
)
@@ -342,16 +341,15 @@ async def search_memories(
print(f"Finding memories related to: {query}")
results = await mem0_client.search(
query,
user_id=USER_ID,
limit=5,
filters={"user_id": USER_ID},
top_k=5,
threshold=0.7, # Higher threshold for more relevant results
)
# Format and return the results
if not results.get('results', []):
return "I don't have any relevant memories about this topic."
memories = [f"• {result['memory']}" for result in results.get('results', [])]
return "Here's what I remember that might be relevant:\n" + "\n".join(memories)
@@ -368,7 +366,7 @@ def create_memory_voice_agent():
Use the search_memories tool when you need context from past conversations or user asks you to recall something.
""",
),
model="gpt-4.1-nano-2025-04-14",
model="gpt-5-mini",
tools=[save_memories, search_memories],
)
@@ -62,7 +62,7 @@ mem0_client = MemoryClient(api_key="your-mem0-key")
def chat(user_input, user_id):
# Retrieve relevant memories
memories = mem0_client.search(user_input, user_id=user_id, limit=5)
memories = mem0_client.search(user_input, filters={"user_id": user_id}, top_k=5)
context = "\\n".join(m["memory"] for m in memories["results"])
# Call LLM with memory context
@@ -123,7 +123,7 @@ ollama_chat = OpenAI(base_url=f"{OLLAMA_URL}/v1", api_key="ollama")
def chat(user_input, user_id):
# Retrieve relevant memories
memories = memory.search(user_input, user_id=user_id, limit=5)
memories = memory.search(user_input, filters={"user_id": user_id}, top_k=5)
context = "\n".join(m["memory"] for m in memories["results"])
# Call LLM with memory context (Ollama via OpenAI-compatible API)
@@ -319,7 +319,7 @@ print([m["memory"] for m in memories["results"]])
</Tab>
<Tab title="Open Source">
```python
memories = memory.get_all(user_id="max")
memories = memory.get_all(filters={"user_id": "max"})
print([m["memory"] for m in memories["results"]])
# Output: ["Max wants to run marathon under 4 hours", "hey", "lol ok", "cool thanks", "gtg bye"]
```
@@ -397,7 +397,7 @@ print([m["memory"] for m in memories["results"]])
chat("hey how's it going", user_id="max")
chat("I prefer trail running over roads", user_id="max")
memories = memory.get_all(user_id="max")
memories = memory.get_all(filters={"user_id": "max"})
print([m["memory"] for m in memories["results"]])
# Output: ["Max wants to run marathon under 4 hours", "Max prefers trail running over roads"]
```
@@ -446,7 +446,7 @@ Retrieve agent style alongside user memories:
<Tab title="Platform">
```python
# Get coach personality
agent_memories = mem0_client.search("coaching style", agent_id="ray_coach")
agent_memories = mem0_client.search("coaching style", filters={"agent_id": "ray_coach"})
# Output: ["Max wants direct, data-driven feedback. Skip motivational language."]
# Store conversations with agent_id
@@ -459,7 +459,7 @@ mem0_client.add([
<Tab title="Open Source">
```python
# Get coach personality
agent_memories = memory.search("coaching style", agent_id="ray_coach")
agent_memories = memory.search("coaching style", filters={"agent_id": "ray_coach"})
# Output: ["Max wants direct, data-driven feedback. Skip motivational language."]
# Store conversations with agent_id
@@ -706,13 +706,13 @@ memory.add(
<Tabs>
<Tab title="Platform">
```python
memories = mem0_client.search("training plan", user_id="max", limit=5)
memories = mem0_client.search("training plan", filters={"user_id": "max"}, top_k=5)
# Gets: marathon goal, trail preference, ankle injury (if still valid)
```
</Tab>
<Tab title="Open Source">
```python
memories = memory.search("training plan", user_id="max", limit=5)
memories = memory.search("training plan", filters={"user_id": "max"}, top_k=5)
# Gets: marathon goal, trail preference, ankle injury (if still valid / not pruned)
```
</Tab>
@@ -806,7 +806,7 @@ mem0_client.update(goal_memory["id"], "Max wants to run sub-3:45 marathon")
<Tab title="Open Source">
```python
# Find the old memory
memories = memory.get_all(user_id="max")
memories = memory.get_all(filters={"user_id": "max"})
goal_memory = [m for m in memories["results"] if "sub-4" in m["memory"]][0]
# Update it
@@ -38,7 +38,7 @@ client = MemoryClient(api_key="your-api-key")
```
<Note>
Replace `your-api-key` with your actual Mem0 API key from the [dashboard](https://app.mem0.ai). Without proper API authentication, memory operations will fail.
Replace `your-api-key` with your actual Mem0 API key from the <a href="https://app.mem0.ai" rel="nofollow">dashboard</a>. Without proper API authentication, memory operations will fail.
</Note>
---
@@ -17,7 +17,7 @@ from mem0 import MemoryClient
client = MemoryClient(api_key="m0-...")
```
Grab an API key from the <Link href="https://app.mem0.ai/">Mem0 dashboard</Link> to get started.
Grab an API key from the <a href="https://app.mem0.ai/" rel="nofollow">Mem0 dashboard</a> to get started.
## Store and Retrieve Scoped Memories
@@ -20,7 +20,7 @@ client = MemoryClient(api_key="your-api-key")
```
<Note>
Your API key needs export permissions to download memory data. Check your project settings on the [dashboard](https://app.mem0.ai) if export operations fail with authentication errors.
Your API key needs export permissions to download memory data. Check your project settings on the <a href="https://app.mem0.ai" rel="nofollow">dashboard</a> if export operations fail with authentication errors.
</Note>
Let's add some sample memories to work with:
@@ -1,70 +0,0 @@
---
title: Browser Extension Memory
description: "Add Mem0's universal memory layer to Chrome chat surfaces."
---
Enhance your AI interactions with Mem0, a Chrome extension that introduces a universal memory layer across platforms like ChatGPT, Claude, and Perplexity. Mem0 ensures seamless context sharing, making your AI experiences more personalized and efficient.
<Note>
We now support Grok! The Mem0 Chrome Extension has been updated to work with Grok, bringing the same powerful memory capabilities to your Grok conversations.
</Note>
## Features
- **Universal Memory Layer**: Share context seamlessly across ChatGPT, Claude, Perplexity, and Grok.
- **Smart Context Detection**: Automatically captures relevant information from your conversations.
- **Intelligent Memory Retrieval**: Surfaces pertinent memories at the right time.
- **One-Click Sync**: Easily synchronize with existing ChatGPT memories.
- **Memory Dashboard**: Manage all your memories in one centralized location.
## Installation
You can install the Mem0 Chrome Extension using one of the following methods:
### Method 1: Chrome Web Store Installation
1. **Download the Extension**: Open Google Chrome and navigate to the [Mem0 Chrome Extension page](https://chromewebstore.google.com/detail/mem0/onihkkbipkfeijkadecaafbgagkhglop?hl=en).
2. **Add to Chrome**: Click on the "Add to Chrome" button.
3. **Confirm Installation**: In the pop-up dialog, click "Add extension" to confirm. The Mem0 icon should now appear in your Chrome toolbar.
### Method 2: Manual Installation
1. **Download the Extension**: Clone or download the extension files from the [Mem0 Chrome Extension GitHub repository](https://github.com/mem0ai/mem0-chrome-extension).
2. **Access Chrome Extensions**: Open Google Chrome and navigate to `chrome://extensions`.
3. **Enable Developer Mode**: Toggle the "Developer mode" switch in the top right corner.
4. **Load Unpacked Extension**: Click "Load unpacked" and select the directory containing the extension files.
5. **Confirm Installation**: The Mem0 Chrome Extension should now appear in your Chrome toolbar.
## Usage
1. **Locate the Mem0 Icon**: After installation, find the Mem0 icon in your Chrome toolbar.
2. **Sign In**: Click the icon and sign in with your Google account.
3. **Interact with AI Assistants**:
- **ChatGPT and Perplexity**: Continue your conversations as usual; Mem0 operates seamlessly in the background.
- **Claude**: Click the Mem0 button or use the shortcut `Ctrl + M` to activate memory functions.
## Configuration
- **API Key**: Obtain your API key from the Mem0 Dashboard to connect the extension to the Mem0 API.
- **User ID**: This is your unique identifier in the Mem0 system. If not provided, it defaults to `chrome-extension-user`.
## Demo Video
<iframe width="700" height="400" src="https://www.youtube.com/embed/dqenCMMlfwQ?si=zhGVrkq6IS_0Jwyj" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
## Privacy and Data Security
Your messages are sent to the Mem0 API for extracting and retrieving memories. Mem0 is committed to ensuring your data's privacy and security.
---
<CardGroup cols={2}>
<Card title="Build a Mem0 Companion" icon="users" href="/cookbooks/essentials/building-ai-companion">
Learn the foundations of memory-powered assistants that work across platforms.
</Card>
<Card title="Multimodal Support" icon="image" href="/platform/features/multimodal-support">
Extend your browser interactions with vision and audio memory.
</Card>
</CardGroup>
@@ -55,7 +55,7 @@ GEMINI_API_KEY=your-gemini-api-key-here
```
<Note>
Ensure you have your Mem0 API key from the [Mem0 Dashboard](https://app.mem0.ai) and your Gemini API key from the [Google AI Studio](https://ai.studio/app/api-keys).
Ensure you have your Mem0 API key from the <a href="https://app.mem0.ai" rel="nofollow">Mem0 Dashboard</a> and your Gemini API key from the [Google AI Studio](https://ai.studio/app/api-keys).
</Note>
## Gemini Memory Agent
@@ -41,7 +41,7 @@ Set up your environment variables:
- `MEM0_API_KEY`: Your Mem0 Platform API key
- `OPENAI_API_KEY`: Your OpenAI API key
You can obtain your Mem0 Platform API key from the [Mem0 Platform](https://app.mem0.ai).
You can obtain your Mem0 Platform API key from the <a href="https://app.mem0.ai" rel="nofollow">Mem0 Platform</a>.
## Complete Implementation
@@ -83,7 +83,7 @@ class MultiAgentLearningSystem:
def __init__(self, student_id: str):
self.student_id = student_id
self.llm = OpenAI(model="gpt-4.1-nano-2025-04-14", temperature=0.2)
self.llm = OpenAI(model="gpt-5-mini", temperature=0.2)
# Memory context for this student
self.memory_context = {"user_id": student_id, "app": "learning_assistant"}
@@ -357,7 +357,7 @@ Based on our previous session, I remember we covered Vision Language Models and
## Help & Resources
- [LlamaIndex Agent Workflows](https://docs.llamaindex.ai/en/stable/use_cases/agents/)
- [Mem0 Platform](https://app.mem0.ai/)
- <a href="https://app.mem0.ai/" rel="nofollow">Mem0 Platform</a>
---
@@ -22,10 +22,10 @@ import os
from llama_index.llms.openai import OpenAI
os.environ["OPENAI_API_KEY"] = "<your-openai-api-key>"
llm = OpenAI(model="gpt-4.1-nano-2025-04-14")
llm = OpenAI(model="gpt-5-mini")
```
Initialize the Mem0 client. You can find your API key [here](https://app.mem0.ai/dashboard/api-keys). Read about Mem0 [Open Source](https://docs.mem0.ai/open-source/overview).
Initialize the Mem0 client. You can find your API key <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">here</a>. Read about Mem0 [Open Source](https://docs.mem0.ai/open-source/overview).
```python
os.environ["MEM0_API_KEY"] = "<your-mem0-api-key>"
@@ -1,766 +0,0 @@
---
title: MiroFish Swarm Memory
description: "Build a multi-agent swarm simulation with graph-powered memory using Mem0 and MiroFish patterns."
---
<Snippet file="blank-notif.mdx" />
Build a multi-agent swarm simulation with graph-powered memory using Mem0 OSS and [MiroFish](https://github.com/666ghj/MiroFish) patterns. MiroFish is a graph-centric system — it extracts entities and relationships from documents, builds a knowledge graph, and queries it throughout its pipeline. Mem0's Graph Memory is a natural replacement for its Zep Cloud integration.
<Note>
This cookbook demonstrates the **core memory patterns** using a simplified simulation. MiroFish's actual architecture uses a factory pattern (`memory_factory.py`) with abstract providers, batch buffering with retries in `ZepGraphMemoryUpdater`, and IPC-based agent interviews. This cookbook focuses on the Mem0 API integration points — wrap these calls in your own retry/batch logic for production use.
</Note>
## Overview
This cookbook implements a **Housing Policy Prediction Simulation** following MiroFish's five-stage workflow:
1. **Graph Building** — Ingest seed documents, extract entities and relationships
2. **Environment Setup** — Query the knowledge graph to enrich agent profiles
3. **Simulation** — Track agent interactions with per-agent memory isolation
4. **Report Generation** — Semantic search + graph traversal for analysis
5. **Deep Interaction** — Query post-simulation memory and relationships (MiroFish also supports live agent interviews via IPC — not covered here)
Three agents debate a housing policy reform:
- **Mayor Chen** — Policy advocate pushing for zoning reform
- **Wang (Homeowner)** — Opposition leader organizing resistance
- **Professor Li** — Academic providing data-driven analysis
## Prerequisites
```bash
pip install "mem0ai[graph]"
```
You need a graph backend. Choose one:
| Backend | Setup | Best for |
|---|---|---|
| **Neo4j Aura** (free tier) | [Sign up](https://neo4j.com/product/auradb/), get Bolt URI | Production, closest to Zep |
| **Neo4j Docker** | `docker run -p 7687:7687 -e NEO4J_AUTH=neo4j/password neo4j:5` | Local development |
| **Kuzu** (embedded) | No setup needed — runs in-process | Quick testing, zero dependencies |
```bash
export OPENAI_API_KEY="sk-..."
# Option A: Neo4j Docker (local development)
docker run -p 7687:7687 -e NEO4J_AUTH=neo4j/password neo4j:5
export NEO4J_URL="neo4j://localhost:7687"
export NEO4J_USERNAME="neo4j"
export NEO4J_PASSWORD="password"
# Option B: Neo4j Aura (production — free tier available)
export NEO4J_URL="neo4j+s://<your-instance>.databases.neo4j.io"
export NEO4J_USERNAME="neo4j"
export NEO4J_PASSWORD="your-aura-password"
# Option C: Kuzu (zero setup — auto-detected when NEO4J_URL is not set)
# No exports needed
```
## Complete Implementation
```python
"""
MiroFish Swarm Prediction Simulation with Mem0 Graph Memory
MiroFish uses Zep Cloud as its knowledge graph backend. This implementation
replaces Zep with Mem0 OSS Graph Memory, which provides:
- Automatic entity extraction from text
- Relationship mining (source → relationship → destination triples)
- Combined vector + graph search returning memories AND relations
- Per-agent isolation via run_id
- Self-hosted with no node caps
Follows MiroFish's 5-stage pipeline:
1. Graph Building - Ingest seed documents, extract entities
2. Environment Setup - Query graph to enrich agent profiles
3. Simulation - Track agent actions with per-agent isolation
4. Report Generation - Semantic + graph search for analysis
5. Deep Interaction - Query post-simulation knowledge graph
Run:
export OPENAI_API_KEY="sk-..."
export NEO4J_URL="neo4j://localhost:7687"
export NEO4J_USERNAME="neo4j"
export NEO4J_PASSWORD="password"
python mirofish_swarm_memory.py
"""
import os
import time
from mem0 import Memory
# ======================================================================
# MiroFish Agent Action Types (matches OASIS simulation output)
# ======================================================================
# Twitter actions
TWITTER_ACTIONS = [
"CREATE_POST", "LIKE_POST", "REPOST", "FOLLOW",
"DO_NOTHING", "QUOTE_POST",
]
# Reddit actions (superset — includes moderation + discovery)
REDDIT_ACTIONS = [
"LIKE_POST", "DISLIKE_POST", "CREATE_POST", "CREATE_COMMENT",
"LIKE_COMMENT", "DISLIKE_COMMENT", "SEARCH_POSTS", "SEARCH_USER",
"TREND", "REFRESH", "DO_NOTHING", "FOLLOW", "MUTE",
]
# Combined (DO_NOTHING is skipped during memory storage)
MIROFISH_ACTIONS = list(set(TWITTER_ACTIONS + REDDIT_ACTIONS) - {"DO_NOTHING"})
# ======================================================================
# Graph Memory Configuration
# ======================================================================
def build_config():
"""Build Mem0 config with Graph Memory.
Uses Neo4j if credentials are set, otherwise falls back to Kuzu (embedded).
"""
neo4j_url = os.environ.get("NEO4J_URL")
# Shared config for LLM, embedder, and vector store
base = {
"llm": {
"provider": "openai",
"config": {"model": "gpt-4o-mini", "temperature": 0.1}
},
"embedder": {
"provider": "openai",
"config": {"model": "text-embedding-3-small", "embedding_dims": 1536}
},
"vector_store": {
"provider": "qdrant",
"config": {
"collection_name": "mirofish",
"embedding_model_dims": 1536,
}
},
}
custom_prompt = (
"Extract all people, organizations, policies, locations, "
"and their relationships. Capture support/opposition stances, "
"affiliations, and quantitative claims."
)
if neo4j_url:
base["graph_store"] = {
"provider": "neo4j",
"config": {
"url": neo4j_url,
"username": os.environ.get("NEO4J_USERNAME", "neo4j"),
"password": os.environ.get("NEO4J_PASSWORD", "password"),
},
"custom_prompt": custom_prompt,
}
else:
# Fallback: Kuzu embedded (no external services needed)
print(" NEO4J_URL not set — using Kuzu (embedded) graph store")
base["graph_store"] = {
"provider": "kuzu",
"config": {"db": "/tmp/mirofish_graph.kuzu"},
"custom_prompt": custom_prompt,
}
return base
# ======================================================================
# Simulation Engine
# ======================================================================
class MiroFishSimulation:
"""
Multi-agent simulation with graph-powered memory.
Uses Mem0 Graph Memory to replace MiroFish's Zep Cloud integration:
- Entities and relationships are extracted automatically from text
- search() returns both semantic memories AND graph relations
- Per-agent isolation via run_id
- Project isolation via user_id
"""
def __init__(self, project_id: str, config: dict):
self.project_id = project_id
self.memory = Memory.from_config(config)
self.stats = {
"documents_ingested": 0,
"activities_recorded": 0,
"rounds_completed": 0,
}
# ------------------------------------------------------------------
# Stage 1: Graph Building — Seed Document Ingestion
# ------------------------------------------------------------------
def ingest_documents(self, documents: list[str]):
"""Ingest seed documents and extract entities + relationships.
MiroFish equivalent: GraphBuilderService.build_graph()
Zep equivalent: graph.add_batch() with episode polling
With Mem0 Graph Memory, each document is processed by the LLM
to extract entities (people, orgs, policies) and relationships
(supports, opposes, filed). These become nodes and edges in the
graph store, alongside vector embeddings for semantic search.
"""
print(" Ingesting documents and building knowledge graph...")
for i, doc in enumerate(documents):
result = self.memory.add(
[{"role": "user", "content": doc}],
user_id=self.project_id,
metadata={"stage": "graph_building", "source": "seed_document", "chunk_index": i}
)
# Graph Memory returns extracted relations
relations = result.get("relations", {})
added = relations.get("added_entities", [])
if added:
print(f" Doc {i}: extracted {len(added)} entities/relations")
self.stats["documents_ingested"] = len(documents)
print(f" Ingested {len(documents)} documents")
# ------------------------------------------------------------------
# Stage 2: Environment Setup — Agent Profile Enrichment
# ------------------------------------------------------------------
def enrich_agent_profile(self, agent_name: str, persona_query: str) -> dict:
"""Search memory + graph for context relevant to an agent's persona.
MiroFish equivalent: OasisProfileGenerator using graph.search()
Returns both semantic memories and graph relations that can be
injected into the agent's system prompt.
"""
results = self.memory.search(
persona_query,
user_id=self.project_id,
limit=10
)
facts = [r["memory"] for r in results.get("results", [])]
relations = results.get("relations", [])
print(f" {agent_name}: {len(facts)} facts, {len(relations)} relations")
return {"facts": facts, "relations": relations}
# ------------------------------------------------------------------
# Stage 3: Simulation — Agent Activity Tracking
# ------------------------------------------------------------------
def record_action(self, agent_id: str, agent_name: str,
action_type: str, content: str,
platform: str, round_num: int):
"""Record a single agent action as a memory with graph extraction.
MiroFish equivalent: ZepGraphMemoryUpdater.add_activity()
Zep equivalent: graph.add(type="text", data=episode_text)
Agent memories use run_id to group by agent (no assistant
memories involved). Graph Memory extracts entities/relationships
from the action content automatically.
"""
formatted = f"{agent_name} [{action_type}]: {content}"
self.memory.add(
[{"role": "user", "content": formatted}],
run_id=agent_id,
metadata={
"action_type": action_type,
"platform": platform,
"round": round_num,
"agent_name": agent_name,
}
)
self.stats["activities_recorded"] += 1
def run_round(self, round_num: int, activities: list[tuple]):
"""Execute one simulation round."""
print(f" Round {round_num}: {len(activities)} actions")
for agent_id, agent_name, action_type, content, platform in activities:
self.record_action(agent_id, agent_name, action_type, content, platform, round_num)
self.stats["rounds_completed"] = max(self.stats["rounds_completed"], round_num)
def recall_agent_memory(self, agent_id: str, query: str) -> dict:
"""Agent recalls its own memories mid-simulation.
Searches by run_id to match the scope used during add().
"""
results = self.memory.search(
query,
run_id=agent_id,
limit=5
)
return {
"memories": [r["memory"] for r in results.get("results", [])],
"relations": results.get("relations", []),
}
# ------------------------------------------------------------------
# Stage 4: Report Generation — Semantic + Graph Retrieval
# ------------------------------------------------------------------
def quick_search(self, query: str, limit: int = 10) -> dict:
"""Semantic search + graph relations across all agents.
MiroFish equivalent: ZepToolsService.quick_search()
Returns both vector-matched memories and related graph triples.
"""
results = self.memory.search(
query,
user_id=self.project_id,
limit=limit
)
return {
"memories": [r["memory"] for r in results.get("results", [])],
"relations": results.get("relations", []),
}
def panorama_search(self) -> dict:
"""Retrieve all memories + all graph relations.
MiroFish equivalent: ZepToolsService.panorama_search()
Returns the complete knowledge state for report generation.
"""
results = self.memory.get_all(user_id=self.project_id)
return {
"memories": [r["memory"] for r in results.get("results", [])],
"relations": results.get("relations", []),
}
def agent_search(self, agent_id: str, query: str, limit: int = 10) -> dict:
"""Search within a single agent's memory space."""
results = self.memory.search(
query,
run_id=agent_id,
limit=limit
)
return {
"memories": [r["memory"] for r in results.get("results", [])],
"relations": results.get("relations", []),
}
# ------------------------------------------------------------------
# Cleanup
# ------------------------------------------------------------------
def cleanup(self):
"""Delete all memories and graph data for this simulation."""
self.memory.delete_all(user_id=self.project_id)
print(f" Cleaned up all memories for {self.project_id}")
# ======================================================================
# Run the full 5-stage pipeline
# ======================================================================
def main():
project_id = f"mirofish_housing_{int(time.time())}"
config = build_config()
sim = MiroFishSimulation(project_id=project_id, config=config)
# ==================================================================
# STAGE 1: Graph Building — Ingest seed documents
# ==================================================================
print("=" * 60)
print("STAGE 1: Graph Building")
print("=" * 60)
sim.ingest_documents([
"The city council proposed a new zoning reform allowing higher "
"density housing in suburban areas. Mayor Chen expressed strong "
"support, citing a 40% housing shortage affecting young professionals. "
"The reform would allow buildings up to 8 stories in previously "
"restricted 3-story zones.",
"Local homeowners association president Wang opposes the reform, "
"arguing it will decrease property values by 15-20%. The association "
"represents 5,000 homeowners in the affected districts. Wang has "
"organized three community meetings and collected 2,000 signatures.",
"Professor Li from Beijing University published research showing "
"similar reforms in Shenzhen led to 15% price drops in existing "
"homes but created 30% more affordable housing units within 3 years. "
"The study covered 12 districts and 50,000 housing units.",
])
# ==================================================================
# STAGE 2: Environment Setup — Enrich agent profiles
# ==================================================================
print("\n" + "=" * 60)
print("STAGE 2: Environment Setup")
print("=" * 60)
mayor_context = sim.enrich_agent_profile(
"Mayor Chen",
"Mayor Chen housing reform zoning policy"
)
wang_context = sim.enrich_agent_profile(
"Wang",
"Wang homeowner opposition property values petition"
)
li_context = sim.enrich_agent_profile(
"Professor Li",
"Professor Li research housing data Shenzhen"
)
print("\n Example profile context for Mayor Chen:")
for fact in mayor_context["facts"][:3]:
print(f" Fact: {fact}")
for rel in mayor_context["relations"][:3]:
src = rel.get("source", "?")
edge = rel.get("relationship", "?")
dst = rel.get("destination", rel.get("target", "?"))
print(f" Relation: {src} --[{edge}]--> {dst}")
# ==================================================================
# STAGE 3: Simulation — Run agent interactions
# ==================================================================
print("\n" + "=" * 60)
print("STAGE 3: Simulation")
print("=" * 60)
# Round 1: Opening statements
sim.run_round(1, [
("mayor_chen", "Mayor Chen", "CREATE_POST",
"This reform will create 10,000 new housing units by 2028. "
"Young families deserve affordable homes. #HousingForAll",
"twitter"),
("wang_homeowner", "Wang", "CREATE_POST",
"Our property values will plummet! The council ignores the "
"voices of 5,000 homeowners. #StopTheReform",
"twitter"),
("prof_li", "Professor Li", "CREATE_POST",
"New analysis: Shenzhen zoning data shows net positive outcomes "
"after 3 years. Short-term pain, long-term gain for housing equity.",
"twitter"),
])
# Round 2: Debate and interaction
sim.run_round(2, [
("wang_homeowner", "Wang", "CREATE_COMMENT",
"Replied to Professor Li: 'Shenzhen is a tier-1 city with "
"completely different dynamics. Your comparison is misleading.'",
"twitter"),
("mayor_chen", "Mayor Chen", "LIKE_POST",
"Liked Professor Li's post about Shenzhen housing data.",
"twitter"),
("prof_li", "Professor Li", "CREATE_COMMENT",
"Replied to Wang: 'The methodology controls for city tier "
"and population density. I invite you to review the full dataset.'",
"twitter"),
("mayor_chen", "Mayor Chen", "CREATE_POST",
"Data from @ProfLi confirms what we've been saying: zoning "
"reform works. Let's move forward with evidence, not fear.",
"twitter"),
])
# Round 3: Escalation and platform expansion
sim.run_round(3, [
("wang_homeowner", "Wang", "CREATE_POST",
"Filing formal petition with 3,000 signatures against the "
"zoning reform. Council meeting next Tuesday. All homeowners "
"must attend!",
"reddit"),
("mayor_chen", "Mayor Chen", "CREATE_POST",
"Announcing public town hall on zoning reform this Saturday. "
"All voices welcome. Data-driven decisions benefit everyone.",
"twitter"),
("prof_li", "Professor Li", "CREATE_POST",
"Published full dataset and methodology on my university page. "
"Transparency is essential for informed public debate.",
"twitter"),
("wang_homeowner", "Wang", "FOLLOW",
"Followed @MayorChen to monitor policy updates.",
"twitter"),
])
# Mid-simulation: agent recalls own memory + graph
print("\n Mid-simulation recall for Mayor Chen:")
mayor_recall = sim.recall_agent_memory(
"mayor_chen",
"What positions have I taken on housing reform?"
)
for mem in mayor_recall["memories"]:
print(f" Memory: {mem}")
for rel in mayor_recall["relations"][:3]:
src = rel.get("source", "?")
edge = rel.get("relationship", "?")
dst = rel.get("destination", rel.get("target", "?"))
print(f" Relation: {src} --[{edge}]--> {dst}")
# ==================================================================
# STAGE 4: Report Generation — Retrieve memories + graph for analysis
# ==================================================================
print("\n" + "=" * 60)
print("STAGE 4: Report Generation")
print("=" * 60)
# Quick search: targeted query
print("\n Quick Search: 'opposition to housing reform'")
opposition = sim.quick_search("opposition to housing reform", limit=5)
for mem in opposition["memories"]:
print(f" Memory: {mem}")
for rel in opposition["relations"][:3]:
src = rel.get("source", "?")
edge = rel.get("relationship", "?")
dst = rel.get("destination", rel.get("target", "?"))
print(f" Relation: {src} --[{edge}]--> {dst}")
# Agent-specific search
print("\n Agent Search: Wang's activities")
wang_activities = sim.agent_search("wang_homeowner", "all actions and statements")
for mem in wang_activities["memories"]:
print(f" Memory: {mem}")
# Panorama: full overview
print("\n Panorama Search: all memories + relations")
panorama = sim.panorama_search()
print(f" Total memories: {len(panorama['memories'])}")
print(f" Total relations: {len(panorama['relations'])}")
for mem in panorama["memories"][:5]:
print(f" Memory: {mem}")
if len(panorama["memories"]) > 5:
print(f" ... and {len(panorama['memories']) - 5} more")
for rel in panorama["relations"][:5]:
src = rel.get("source", "?")
edge = rel.get("relationship", "?")
dst = rel.get("destination", rel.get("target", "?"))
print(f" Relation: {src} --[{edge}]--> {dst}")
# ==================================================================
# STAGE 5: Deep Interaction — Post-simulation queries
# ==================================================================
print("\n" + "=" * 60)
print("STAGE 5: Deep Interaction")
print("=" * 60)
queries = [
"How did the debate evolve across the three rounds?",
"What evidence was cited by each side?",
"Who supports and who opposes the reform?",
]
for query in queries:
print(f"\n Query: '{query}'")
results = sim.quick_search(query, limit=3)
for mem in results["memories"][:2]:
print(f" Memory: {mem}")
for rel in results["relations"][:2]:
src = rel.get("source", rel.get("source_node", "?"))
edge = rel.get("relationship", rel.get("relation", "?"))
dst = rel.get("destination", rel.get("destination_node", "?"))
print(f" Relation: {src} --[{edge}]--> {dst}")
# ==================================================================
# Summary
# ==================================================================
print("\n" + "=" * 60)
print("SIMULATION COMPLETE")
print("=" * 60)
print(f" Project ID: {project_id}")
print(f" Documents ingested: {sim.stats['documents_ingested']}")
print(f" Activities tracked: {sim.stats['activities_recorded']}")
print(f" Rounds completed: {sim.stats['rounds_completed']}")
print(f" Total memories: {len(panorama['memories'])}")
print(f" Total relations: {len(panorama['relations'])}")
# Cleanup (uncomment to delete all memories + graph data)
# sim.cleanup()
if __name__ == "__main__":
print("MiroFish Swarm Prediction Simulation powered by Mem0 Graph Memory\n")
main()
```
## How It Works
### Graph Memory: The Right Fit for MiroFish
MiroFish's entire pipeline revolves around a **knowledge graph** — it extracts entities from documents, builds relationships, and queries the graph throughout simulation and reporting. Mem0's Graph Memory provides the same capabilities:
| MiroFish needs | Zep Cloud | Mem0 Graph Memory |
|---|---|---|
| **Entity extraction** | Built-in via Zep API | Automatic via LLM extraction |
| **Relationship mining** | Graph edges | `(source) --[relationship]--> (destination)` triples |
| **Semantic + keyword search** | Semantic + BM25 | Vector similarity + graph relation retrieval |
| **Graph traversal** | Node/edge queries | `relations` array in search results |
| **Per-agent isolation** | Single shared graph in MiroFish | Native `run_id` scoping |
| **Self-hosting** | No (cloud only) | Yes — Neo4j, Memgraph, Kuzu, Neptune |
| **Node/memory limits** | Capped on free tier | Unlimited (self-hosted) |
### How search() Returns Both Memories and Relations
When Graph Memory is enabled, every `search()` call returns two arrays:
```python
results = memory.search("housing reform", user_id="my_sim")
# Vector-matched memories (ordered by similarity)
results["results"] # [{"memory": "...", "score": 0.85, ...}, ...]
# Graph relations connected to query entities
results["relations"] # [{"source": "mayor_chen", "relationship": "supports", "destination": "zoning_reform"}, ...]
```
This is what makes Mem0 Graph Memory a natural replacement for Zep — you get semantic search AND structured graph data in a single call.
### Per-Agent Memory Isolation
`user_id` scopes the simulation project. `run_id` tags individual agent actions at storage time (we use `run_id` instead of `agent_id` since no assistant memories are involved). Searches use `user_id` for project-wide retrieval:
```python
# Store project-level memories (seed documents)
memory.add(
[{"role": "user", "content": "Mayor Chen supports the zoning reform."}],
user_id="my_sim"
)
# Store agent-specific memories (simulation actions)
memory.add(
[{"role": "user", "content": "Mayor Chen [CREATE_POST]: Reform works!"}],
run_id="mayor_chen"
)
# Search project-level memories (seed docs)
memory.search("housing reform", user_id="my_sim")
# Search agent-specific memories (actions stored with run_id)
memory.search("housing reform", run_id="mayor_chen")
# Get all project-level memories + graph relations
memory.get_all(user_id="my_sim")
```
<Note>
Use `user_id` for project-level data (seed documents) and `run_id` for agent actions — both for `add()` and `search()`. Always match the scope: if you `add()` with `run_id`, `search()` with `run_id`. Use the message list format `[{"role": "user", "content": "..."}]` for all `add()` calls — it works on both OSS and Cloud.
</Note>
### Stage Mapping
| MiroFish Stage | What Happens | Mem0 Graph Memory Call |
|---|---|---|
| **1. Graph Building** | Ingest docs, extract entities | `memory.add(doc, user_id=project)` — entities/relations extracted automatically |
| **2. Environment Setup** | Enrich agent personas from graph | `memory.search(query, user_id=project)` — returns facts + relations |
| **3. Simulation** | Track per-agent actions | `memory.add(messages, run_id=agent)` |
| **3. Simulation** | Mid-round recall | `memory.search(query, run_id=agent)` |
| **4. Report Generation** | Targeted analysis | `memory.search(query, user_id=project)` — memories + graph |
| **4. Report Generation** | Full overview | `memory.get_all(user_id=project)` — all memories + all relations |
| **5. Deep Interaction** | Follow-up queries | `memory.search(query, user_id=project)` |
### Zep-to-Mem0 Migration Reference
For developers replacing MiroFish's Zep integration. Note that Mem0 Graph Memory covers the core graph operations but some Zep features have no direct equivalent — see caveats below.
| MiroFish Service | Zep Call | Mem0 Graph Memory Equivalent | Caveat |
|---|---|---|---|
| GraphBuilderService | `client.graph.create()` | Implicit on first `memory.add()` | |
| GraphBuilderService | `client.graph.set_ontology()` | `custom_prompt` in graph_store config | Freeform text, not a typed schema like Zep's `EntityModel`/`EdgeModel` |
| GraphBuilderService | `client.graph.add_batch(episodes)` | `memory.add()` per chunk | No batch API — call per chunk |
| GraphBuilderService | `client.graph.episode.get(uuid)` | Not needed (add is synchronous in OSS) | |
| GraphBuilderService | `client.graph.delete(id)` | `memory.delete_all(user_id=...)` | |
| ZepEntityReader | `client.graph.node.get_by_graph_id()` | `memory.get_all(user_id=...)` → `relations` | |
| ZepEntityReader | `client.graph.node.get(uuid)` | `memory.search(entity_name, user_id=...)` | Semantic search, not exact ID lookup |
| ZepEntityReader | `client.graph.node.get_entity_edges()` | `memory.search(entity_name, user_id=...)` → `relations` | Returns all matching relations, not edges for a specific node |
| ZepGraphMemoryUpdater | `client.graph.add(type="text")` | `memory.add(messages, run_id=...)` | No batch buffering or retry — implement in your wrapper |
| ZepToolsService | `search_graph(query, scope)` | `memory.search(query, user_id=...)` → memories + relations | |
| ZepToolsService | `get_entities()` | `memory.get_all(user_id=...)` → `relations` | |
| ZepToolsService | Panorama (all nodes + edges) | `memory.get_all(user_id=...)` | No temporal fact separation (active vs historical) |
| ZepToolsService | InsightForge (multi-query decomposition) | Not available | Implement LLM-driven sub-query decomposition in your own ReportAgent |
| OasisProfileGenerator | `client.graph.search()` | `memory.search(query, user_id=...)` | |
<Note>
**What Mem0 Graph Memory does not cover**: Zep's typed ontology schemas (`EntityModel`, `EdgeModel`), temporal fact lifecycle (`valid_at`/`invalid_at`/`expired_at`), single-node-by-ID lookup, and InsightForge's multi-query decomposition. For InsightForge-like functionality, implement sub-query logic in your own ReportAgent using `memory.search()` as the retrieval primitive.
</Note>
### Custom Extraction Prompts
Guide what entities and relationships Mem0 extracts — analogous to (but less structured than) Zep's `set_ontology()`:
```python
config = {
"graph_store": {
"provider": "neo4j",
"config": {"url": "...", "username": "...", "password": "..."},
"custom_prompt": (
"Extract all people, organizations, policies, locations, "
"and their relationships. Capture support/opposition stances, "
"affiliations, and quantitative claims."
),
}
}
```
### Action Types
MiroFish's OASIS engine produces these agent action types. Format them as natural language when storing. Skip `DO_NOTHING` actions (no memory value). `TREND` and `REFRESH` are Reddit-only discovery actions — store if you want to track browsing behavior.
| Action Type | Platform | Example Memory Content |
|---|---|---|
| `CREATE_POST` | Both | `"Mayor Chen [CREATE_POST]: This reform will create 10,000 units"` |
| `CREATE_COMMENT` | Reddit | `"Wang [CREATE_COMMENT]: Replied to Prof Li: 'Your data is misleading'"` |
| `LIKE_POST` | Both | `"Mayor Chen [LIKE_POST]: Liked Prof Li's post about Shenzhen data"` |
| `REPOST` | Twitter | `"Prof Li [REPOST]: Reposted Mayor Chen's town hall announcement"` |
| `FOLLOW` | Both | `"Wang [FOLLOW]: Followed @MayorChen"` |
| `QUOTE_POST` | Twitter | `"Mayor Chen [QUOTE_POST]: 'Data confirms reform works' quoting Prof Li"` |
| `DISLIKE_POST` | Reddit | `"Wang [DISLIKE_POST]: Downvoted Mayor Chen's reform post"` |
| `TREND` | Reddit | `"Prof Li [TREND]: Browsed trending topics"` |
| `DO_NOTHING` | Both | Skip — no memory value |
## Running the Example
```bash
# Option A: Neo4j (production)
export OPENAI_API_KEY="sk-..."
export NEO4J_URL="neo4j://localhost:7687"
export NEO4J_USERNAME="neo4j"
export NEO4J_PASSWORD="password"
python mirofish_swarm_memory.py
# Option B: Kuzu (zero dependencies, just need OpenAI key)
export OPENAI_API_KEY="sk-..."
python mirofish_swarm_memory.py # auto-detects missing NEO4J_URL, uses Kuzu
```
<Note>
Exact output varies as Mem0 automatically extracts and deduplicates entities. The specific relations and memory counts depend on LLM extraction quality.
</Note>
## Best Practices
1. **Unique `user_id` per simulation** — Use timestamps or UUIDs (e.g., `mirofish_housing_1742198400`) to prevent memory collisions between runs
2. **Always set `run_id` for agent actions** — Per-agent isolation prevents memory cross-contamination between agents
3. **Use `custom_prompt`** — Guide entity extraction to capture domain-specific relationships (people, policies, stances)
4. **Format actions as natural language** — `"Mayor Chen [CREATE_POST]: content"` extracts better entities than raw JSON
5. **Query relations for reports** — The `relations` array in search results gives structured `(source, relationship, destination)` triples for building analytical reports
6. **Cleanup old simulations** — Call `delete_all(user_id=...)` when a simulation run is no longer needed
## Resources
- [MiroFish GitHub](https://github.com/666ghj/MiroFish) — Source code and setup guide
- [MiroFish Documentation](https://deepwiki.com/666ghj/MiroFish) — Full framework docs
- [Mem0 Graph Memory](/open-source/features/graph-memory) — Graph Memory documentation
- [Mem0 Documentation](https://docs.mem0.ai/) — Full API reference
<CardGroup cols={2}>
<Card title="Graph Memory" icon="network-wired" href="/open-source/features/graph-memory">
Full Graph Memory documentation with provider setup.
</Card>
<Card title="MiroFish GitHub" icon="fish" href="https://github.com/666ghj/MiroFish">
MiroFish source code and setup guide.
</Card>
</CardGroup>
@@ -112,7 +112,7 @@ async def search_memory(
query: The search query.
"""
user_id = context.context.user_id or "default_user"
memories = await client.search(query, user_id=user_id)
memories = await client.search(query, filters={"user_id": user_id})
results = '\n'.join([result["memory"] for result in memories["results"]])
return str(results)
```
@@ -222,8 +222,8 @@ context = Mem0Context(user_id="user123")
## Resources
- [Mem0 Documentation](https://docs.mem0.ai)
- [Mem0 Dashboard](https://app.mem0.ai/dashboard)
- [Mem0 Documentation](https://docs.mem0.ai/introduction)
- <a href="https://app.mem0.ai/dashboard" rel="nofollow">Mem0 Dashboard</a>
- [API Reference](https://docs.mem0.ai/api-reference)
---
+8 -20
View File
@@ -1,17 +1,17 @@
---
title: Bedrock with Persistent Memory
description: "Pair Mem0 with AWS Bedrock, OpenSearch, and Neptune for a managed stack."
description: "Pair Mem0 with AWS Bedrock and OpenSearch for a managed stack."
---
This example demonstrates how to configure and use the `mem0ai` SDK with **AWS Bedrock**, **OpenSearch Service (AOSS)**, and **AWS Neptune Analytics** for persistent memory capabilities in Python.
This example demonstrates how to configure and use the `mem0ai` SDK with **AWS Bedrock** and **OpenSearch Service (AOSS)** for persistent memory capabilities in Python.
## Installation
Install the required dependencies to include the Amazon data stack, including **boto3**, **opensearch-py**, and **langchain-aws**:
```bash
pip install "mem0ai[graph,extras]"
pip install "mem0ai[extras]"
```
## Environment Setup
@@ -38,7 +38,6 @@ This sets up Mem0 with:
- [AWS Bedrock for LLM](https://docs.mem0.ai/components/llms/models/aws_bedrock)
- [AWS Bedrock for embeddings](https://docs.mem0.ai/components/embedders/models/aws_bedrock#aws-bedrock)
- [OpenSearch as the vector store](https://docs.mem0.ai/components/vectordbs/dbs/opensearch)
- [Graph Memory guide](https://docs.mem0.ai/open-source/features/graph-memory)
```python
import boto3
@@ -79,12 +78,6 @@ config = {
"embedding_model_dims": 1024,
}
},
"graph_store": {
"provider": "neptune",
"config": {
"endpoint": f"neptune-graph://my-graph-identifier",
},
},
}
# Initialize the memory system
@@ -93,8 +86,6 @@ m = Memory.from_config(config)
## Usage
Reference [Notebook example](https://github.com/mem0ai/mem0/blob/main/examples/graph-db-demo/neptune-example.ipynb)
### Add a memory
```python
@@ -112,13 +103,13 @@ result = m.add(messages, user_id="alice", metadata={"category": "movie_recommend
### Search a memory
```python
relevant_memories = m.search(query, user_id="alice")
relevant_memories = m.search(query, filters={"user_id": "alice"})
```
### Get all memories
```python
all_memories = m.get_all(user_id="alice")
all_memories = m.get_all(filters={"user_id": "alice"})
```
### Get a specific memory
@@ -129,15 +120,12 @@ memory = m.get(memory_id)
## Conclusion
With Mem0 and AWS services like Bedrock, OpenSearch, and Neptune Analytics, you can build intelligent AI companions that remember, adapt, and personalize their responses over time. This makes them ideal for long-term assistants, tutors, or support bots with persistent memory and natural conversation abilities.
With Mem0 and AWS services like Bedrock and OpenSearch, you can build intelligent AI companions that remember, adapt, and personalize their responses over time. This makes them ideal for long-term assistants, tutors, or support bots with persistent memory and natural conversation abilities.
---
<CardGroup cols={2}>
<Card title="Neptune Analytics with Mem0" icon="database" href="/cookbooks/integrations/neptune-analytics">
Explore graph-based memory storage with AWS Neptune Analytics.
</Card>
<Card title="Graph Memory Features" icon="sitemap" href="/platform/features/graph-memory">
Learn how to leverage knowledge graphs for entity relationships.
<Card title="Memory Evaluation" icon="chart-line" href="/core-concepts/memory-evaluation">
Understand how Mem0's memory system is benchmarked and evaluated.
</Card>
</CardGroup>
@@ -1,133 +0,0 @@
---
title: Graph Memory on Neptune
description: "Combine Mem0 graph memory with AWS Neptune Analytics and Bedrock."
---
This example demonstrates how to configure and use the `mem0ai` SDK with **AWS Bedrock** and **AWS Neptune Analytics** for persistent memory capabilities in Python.
## Installation
Install the required dependencies to include the Amazon data stack, including **boto3** and **langchain-aws**:
```bash
pip install "mem0ai[graph,extras]"
```
## Environment Setup
Set your AWS environment variables:
```python
import os
# Set these in your environment or notebook
os.environ['AWS_REGION'] = 'us-west-2'
os.environ['AWS_ACCESS_KEY_ID'] = 'AK00000000000000000'
os.environ['AWS_SECRET_ACCESS_KEY'] = 'AS00000000000000000'
# Confirm they are set
print(os.environ['AWS_REGION'])
print(os.environ['AWS_ACCESS_KEY_ID'])
print(os.environ['AWS_SECRET_ACCESS_KEY'])
```
## Configuration and Usage
This sets up Mem0 with:
- [AWS Bedrock for LLM](https://docs.mem0.ai/components/llms/models/aws_bedrock)
- [AWS Bedrock for embeddings](https://docs.mem0.ai/components/embedders/models/aws_bedrock#aws-bedrock)
- [Neptune Analytics as the vector store](https://docs.mem0.ai/components/vectordbs/dbs/neptune_analytics)
- [Graph Memory guide](https://docs.mem0.ai/open-source/features/graph-memory).
```python
import boto3
from mem0.memory.main import Memory
region = 'us-west-2'
neptune_analytics_endpoint = 'neptune-graph://my-graph-identifier'
config = {
"embedder": {
"provider": "aws_bedrock",
"config": {
"model": "amazon.titan-embed-text-v2:0"
}
},
"llm": {
"provider": "aws_bedrock",
"config": {
"model": "us.anthropic.claude-3-7-sonnet-20250219-v1:0",
"temperature": 0.1,
"max_tokens": 2000
}
},
"vector_store": {
"provider": "neptune",
"config": {
"collection_name": "mem0",
"endpoint": neptune_analytics_endpoint,
},
},
"graph_store": {
"provider": "neptune",
"config": {
"endpoint": neptune_analytics_endpoint,
},
},
}
# Initialize the memory system
m = Memory.from_config(config)
```
## Usage
Reference [Notebook example](https://github.com/mem0ai/mem0/blob/main/examples/graph-db-demo/neptune-example.ipynb)
#### Add a memory:
```python
messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
{"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
]
# Store inferred memories (default behavior)
result = m.add(messages, user_id="alice", metadata={"category": "movie_recommendations"})
```
#### Search a memory:
```python
relevant_memories = m.search(query, user_id="alice")
```
#### Get all memories:
```python
all_memories = m.get_all(user_id="alice")
```
#### Get a specific memory:
```python
memory = m.get(memory_id)
```
---
## Conclusion
With Mem0 and AWS services like Bedrock and Neptune Analytics, you can build intelligent AI companions that remember, adapt, and personalize their responses over time. This makes them ideal for long-term assistants, tutors, or support bots with persistent memory and natural conversation abilities.
---
<CardGroup cols={2}>
<Card title="AWS Bedrock with Mem0" icon="aws" href="/cookbooks/integrations/aws-bedrock">
Combine Neptune Analytics with AWS Bedrock for complete AWS stack.
</Card>
<Card title="Graph Memory Architecture" icon="sitemap" href="/cookbooks/essentials/choosing-memory-architecture-vector-vs-graph">
Understand when to use graph vs vector memory for your use case.
</Card>
</CardGroup>
@@ -23,7 +23,7 @@ MEM0_API_KEY=your_mem0_api_key
OPENAI_API_KEY=your_openai_api_key
```
Get your Mem0 API key from the [Mem0 Dashboard](https://app.mem0.ai/dashboard/api-keys).
Get your Mem0 API key from the <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 Dashboard</a>.
### Configuration
@@ -121,7 +121,7 @@ const carRecommendationTool = zodResponsesFunction({
// Use the tool in your OpenAI request
const response = await openAIClient.responses.create({
model: "gpt-4.1-nano-2025-04-14",
model: "gpt-5-mini",
tools: [{ type: "web_search_preview" }, carRecommendationTool],
input: `${getMemoryString(relevantMemories)}\n${userInput}`,
});
@@ -133,7 +133,7 @@ Combine memory with web search for up-to-date recommendations:
```javascript
const response = await openAIClient.responses.create({
model: "gpt-4.1-nano-2025-04-14",
model: "gpt-5-mini",
tools: [{ type: "web_search_preview" }, carRecommendationTool],
input: `${getMemoryString(relevantMemories)}\n${userInput}`,
});
@@ -204,7 +204,7 @@ async function main(memory = false) {
}
const response = await openAIClient.responses.create({
model: "gpt-4.1-nano-2025-04-14",
model: "gpt-5-mini",
tools: [{ type: "web_search_preview" }, tool],
input: `${getMemoryString(relevantMemories)}\n${input}`,
});
@@ -308,8 +308,8 @@ run().catch(console.error);
## Resources
- [Mem0 Documentation](https://docs.mem0.ai)
- [Mem0 Dashboard](https://app.mem0.ai/dashboard)
- [Mem0 Documentation](https://docs.mem0.ai/introduction)
- <a href="https://app.mem0.ai/dashboard" rel="nofollow">Mem0 Dashboard</a>
- [API Reference](https://docs.mem0.ai/api-reference)
- [OpenAI Documentation](https://platform.openai.com/docs)
@@ -202,7 +202,7 @@ Preferences:
]
response = openai.chat.completions.create(
model="gpt-4.1-nano-2025-04-14",
model="gpt-5-mini",
messages=messages
)
clean_response = response.choices[0].message.content.strip()
+1 -1
View File
@@ -79,7 +79,7 @@ class CustomerSupportAIAgent:
:param user_id: Optional user ID to filter memories.
:return: List of memories.
"""
return self.memory.get_all(user_id=user_id)
return self.memory.get_all(filters={"user_id": user_id})
# Instantiate the CustomerSupportAIAgent
support_agent = CustomerSupportAIAgent()
@@ -45,7 +45,7 @@ class CollaborativeAgent:
def brainstorm(self, prompt):
# Get recent messages for context
memories = self.mem.search(prompt, run_id=self.run_id, limit=5)["results"]
memories = self.mem.search(prompt, filters={"run_id": self.run_id}, top_k=5)["results"]
context = "\n".join(f"- {m['memory']} (by {m.get('actor_id', 'Unknown')})" for m in memories)
client = OpenAI()
messages = [
@@ -53,14 +53,14 @@ class CollaborativeAgent:
{"role": "user", "content": f"Prompt: {prompt}\nContext:\n{context}"}
]
reply = client.chat.completions.create(
model="gpt-4.1-nano-2025-04-14",
model="gpt-5-mini",
messages=messages
).choices[0].message.content.strip()
self.add_message("assistant", "assistant", reply)
return reply
def get_all_messages(self):
return self.mem.get_all(run_id=self.run_id)["results"]
return self.mem.get_all(filters={"run_id": self.run_id})["results"]
def print_sorted_by_time(self):
messages = self.get_all_messages()
+1 -4
View File
@@ -201,10 +201,7 @@ Here are some examples of how Mem0 can be integrated into various applications:
>
Persistent personality for Eliza agents.
</Card>
<Card title="Browser Extension Memory" icon="globe" href="/cookbooks/frameworks/chrome-extension">
Universal memory layer for Chrome.
</Card>
</CardGroup>
</CardGroup>
---
+354
View File
@@ -0,0 +1,354 @@
---
title: "Memory Evaluation"
description: "Understand how Mem0's memory system is evaluated, benchmark results, and how to run evaluations on your own data."
icon: "chart-bar"
iconType: "solid"
---
## Why Memory Evaluation Matters
Most AI agent memory systems retrieve information by maximizing context window size. That works on benchmarks but not in production, where every token adds cost. **Token efficiency** — achieving high accuracy with less context per query — is what separates benchmark performance from production viability.
The new Mem0 algorithm achieves competitive accuracy on LoCoMo, LongMemEval, and BEAM while averaging **under 7,000 tokens per retrieval call**. Full-context approaches on the same benchmarks routinely consume 25,000+ tokens per query.
Evaluating a memory system at scale comes down to three parameters: **accuracy** (what the benchmarks measure), **cost** (context tokens per query), and **performance** (latency). Optimizing one is easy. Balancing all three at scale is the actual problem.
Some benchmarks today — particularly smaller ones like LoCoMo and LongMemEval — can be materially improved by aggressive retrieval strategies, larger context windows, or frontier models. That does not necessarily mean the underlying memory system has gotten better. We evaluate under constraints that reflect how memory systems actually run in production: limited context windows and practical token budgets.
## Architecture Overview
Mem0's memory system operates across two phases — **extraction** (writing) and **retrieval** (reading) — with an entity linking layer connecting them.
### Memory Extraction (Distillation)
When new conversations arrive, the extraction pipeline processes them through five stages:
1. **Store New Memories** — Conversation enters the pipeline asynchronously (after the agent responds)
2. **Context Lookup** — Find related existing memories to avoid duplicates
3. **Distill Memories** — Single-pass LLM extraction produces ADD-only facts from input + context
4. **Deduplicate + Embed** — Hash-based deduplication, then vectorize new memories
5. **Entity Linking** — Identify entities (proper nouns, quoted text, compound noun phrases) and link them across memories
Memories are distributed across three storage layers, each tuned for a specific retrieval pattern:
| Store | Contents | Purpose |
|---|---|---|
| **Vector Database** | Memory text, embeddings, metadata (timestamps, hash, categories, attributed_to) | Primary fact storage + semantic retrieval |
| **Entity Store** | Entities + embeddings + linked memory IDs | Entity-based retrieval boost |
| **SQL Database** | History log (ADD events) + rolling message window | Audit trail + extraction dedup context |
<Info>
The key architectural decision is **ADD-only extraction**. New facts are stored alongside old ones — nothing is overwritten or deleted. When information changes, both the old and new facts survive. This preserves temporal context and eliminates information loss from premature consolidation.
</Info>
### Multi-Signal Retrieval
When a query arrives, the retrieval pipeline scores candidates across three signals in parallel:
1. **Semantic Search** — Vector similarity scoring against memory embeddings
2. **Keyword Search** — Normalized term matching via BM25 with verb-form lemmatization
3. **Entity Search** — Entity graph matching boosts memories linked to query entities
Results are fused via rank scoring into a final top-K set. Different query types lean on different signals:
| Query Type | Primary Signal | Example |
|---|---|---|
| Conceptual | Semantic | "What does the user think about remote work?" |
| Factual/exact | BM25 keyword | "What meetings did I attend last week?" |
| Entity-centric | Entity matching | "What do we know about Alice?" |
| Temporal | Semantic + keyword | "When did the user first mention the project?" |
The combined score outperformed every individual signal across every category tested.
## Benchmarks
### LoCoMo
[LoCoMo](https://github.com/snap-stanford/locomo) tests single-hop, multi-hop, open-domain, and temporal memory recall across conversational sessions.
| Category | Old Algorithm | New Algorithm | Delta |
|---|---|---|---|
| **Overall** | **71.4** | **91.6** | **+20.2** |
| Single-hop | 76.6 | 92.3 | +15.7 |
| Multi-hop | 70.2 | 93.3 | +23.1 |
| Open-domain | 57.3 | 76.0 | +18.7 |
| Temporal | 63.2 | 92.8 | +29.6 |
*Mean tokens: 6,956*
The two largest gains are **temporal queries (+29.6)** and **multi-hop reasoning (+23.1)**. Both categories directly test the ADD-only architecture (preserving temporal context) and entity linking (connecting facts across memories).
### LongMemEval
[LongMemEval](https://github.com/xiaowu0162/LongMemEval) evaluates memory across single-session and multi-session contexts, including knowledge updates and temporal reasoning.
| Category | Old Algorithm | New Algorithm | Delta |
|---|---|---|---|
| **Overall** | **67.8** | **93.4** | **+25.6** |
| Single-session (user) | 94.3 | 97.1 | +2.8 |
| Single-session (assistant) | 46.4 | 100.0 | +53.6 |
| Single-session (preference) | 76.7 | 96.7 | +20.0 |
| Knowledge update | 79.5 | 96.2 | +16.7 |
| Temporal reasoning | 51.1 | 93.2 | +42.1 |
| Multi-session | 70.7 | 86.5 | +15.8 |
*Mean tokens: 6,787*
The biggest gain is **single-session assistant (+53.6)** — the previous algorithm had a blind spot for agent-generated facts. The new algorithm treats them as first-class memories.
The **+42.1 on temporal reasoning** reflects the ADD-only architecture preserving chronological context that the previous UPDATE/DELETE model would destroy.
### BEAM
[BEAM](https://github.com/mem0ai/memory-benchmarks) evaluates memory systems at 1M and 10M token scales across ten task categories. It is the only public benchmark that operates at context volumes production AI agents actually encounter.
| Category | 1M | 10M |
|---|---|---|
| **Overall** | **64.1** | **48.6** |
| preference_following | 88.3 | 90.4 |
| instruction_following | 85.2 | 82.5 |
| information_extraction | 70.0 | 56.3 |
| knowledge_update | 65.0 | 75.0 |
| multi_session_reasoning | 65.2 | 26.1 |
| summarization | 63.5 | 46.9 |
| temporal_reasoning | 61.8 | 16.3 |
| event_ordering | 53.6 | 20.2 |
| abstention | 52.5 | 40.0 |
| contradiction_resolution | 35.7 | 32.5 |
*Mean tokens (1M): 6,719. Mean tokens (10M): 6,914.*
<Info>
**BEAM is the most relevant benchmark here.** It operates at 1M and 10M token scales and cannot be solved by simply expanding the context window. The results at 10M reflect where memory systems actually stand at production context volumes. The system holds up well on preference following, instruction following, and knowledge updates at both scales. Weaker categories at 10M (temporal reasoning, event ordering, multi-session reasoning) are open problems across the field — they require higher-order representations of how events relate to each other across time, which is a primary focus of our ongoing research.
</Info>
### Performance Summary
All results use a single-pass retrieval setup: one retrieval call, one answer, no agentic loops.
| Benchmark | Old Algorithm | New Algorithm | Average tokens / query |
|---|---|---|---|
| **LoCoMo** | 71.4 | **91.6** | 6,956 |
| **LongMemEval** | 67.8 | **93.4** | 6,787 |
| **BEAM (1M)** | — | **64.1** | 6,719 |
| **BEAM (10M)** | — | **48.6** | 6,914 |
<Info>
Scores reflect Mem0's managed platform, which includes proprietary optimizations not available in the open-source SDK. Open-source users should expect directionally similar gains but not identical numbers.
</Info>
All benchmarks run on the same production-representative model stack. Scores carry a ±1 point confidence interval due to judge inconsistency.
## Running Evaluations
The full evaluation framework is [open-sourced](https://github.com/mem0ai/memory-benchmarks) so anyone can reproduce the numbers independently. It supports both Mem0 Cloud and self-hosted OSS backends.
### Setup
<Tabs>
<Tab title="Mem0 Cloud">
```bash
git clone https://github.com/mem0ai/memory-benchmarks.git
cd memory-benchmarks
pip install -r requirements.txt
# Set your API keys
export MEM0_API_KEY=m0-your-key
export OPENAI_API_KEY=sk-your-key
```
</Tab>
<Tab title="Mem0 OSS (Docker)">
```bash
git clone https://github.com/mem0ai/memory-benchmarks.git
cd memory-benchmarks
pip install -r requirements.txt
# Copy and configure environment
cp .env.example .env
# Edit .env to add OPENAI_API_KEY
# Start local Mem0 server + Qdrant
docker compose up -d
# Mem0 server: http://localhost:8888
# Qdrant: http://localhost:6333
```
</Tab>
</Tabs>
### Running a Benchmark
Each benchmark is a Python module with its own runner ([source code](https://github.com/mem0ai/memory-benchmarks/tree/main/benchmarks)). All share common CLI options:
| Option | Default | Description |
|---|---|---|
| `--project-name` | (required) | Run identifier for tracking results |
| `--backend` | `oss` | `oss` (self-hosted) or `cloud` (Mem0 Platform) |
| `--mem0-api-key` | — | Mem0 API key (required for `cloud` backend) |
| `--mem0-host` | `http://localhost:8888` | Mem0 server URL (for `oss` backend) |
| `--top-k` | `200` | Number of memories to retrieve per query |
| `--top-k-cutoffs` | `10,20,50,200` | Evaluate accuracy at multiple retrieval depths (BEAM default: `100`) |
| `--answerer-model` | *(varies)* | LLM for generating answers from retrieved memories |
| `--judge-model` | *(varies)* | LLM for judging answer correctness |
| `--provider` | `openai` | LLM provider: `openai`, `anthropic`, `azure` |
| `--judge-provider` | (same as `--provider`) | Override provider for the judge model |
| `--max-workers` | `10` | Parallel workers for evaluation |
| `--predict-only` | — | Stop after search, skip answer + judge phases |
| `--evaluate-only` | — | Skip ingest + search, evaluate existing results |
| `--resume` | — | Resume from checkpoint (BEAM and LongMemEval; on by default for LongMemEval) |
<CodeGroup>
```bash LoCoMo
# ~300 questions across 10 conversations (fastest benchmark)
python -m benchmarks.locomo.run \
--project-name my-eval \
--backend cloud \
--mem0-api-key $MEM0_API_KEY \
--top-k 200
# Self-hosted
python -m benchmarks.locomo.run \
--project-name my-eval \
--top-k 200
```
```bash LongMemEval
# 500 questions across 6 categories
python -m benchmarks.longmemeval.run \
--project-name my-eval \
--backend cloud \
--mem0-api-key $MEM0_API_KEY \
--all-questions \
--top-k 200
# Self-hosted
python -m benchmarks.longmemeval.run \
--project-name my-eval \
--all-questions \
--top-k 200
```
```bash BEAM
# 1M token scale (100 conversations)
python -m benchmarks.beam.run \
--project-name my-eval \
--backend cloud \
--mem0-api-key $MEM0_API_KEY \
--chat-sizes 1M \
--conversations 0-99 \
--top-k 200
# 10M token scale
python -m benchmarks.beam.run \
--project-name my-eval \
--backend cloud \
--mem0-api-key $MEM0_API_KEY \
--chat-sizes 10M \
--conversations 0-99 \
--top-k 200
```
</CodeGroup>
### Custom Model Configuration
To run evaluations with custom models (Azure OpenAI, Ollama, etc.), copy one of the provided configs:
```bash
# Available configs: openai.yaml, azure-openai.yaml, ollama.yaml
cp configs/azure-openai.yaml mem0-config.yaml
# Edit mem0-config.yaml with your model details
# Uncomment the volume mount in docker-compose.yml, then restart:
docker compose down && docker compose up -d
```
### Viewing Results
Results are saved to `results/[benchmark]/` and can be explored through the built-in web UI:
```bash
npm install
npm run dev -- -p 3001
# Open http://localhost:3001
```
The UI lets you browse per-question results, inspect retrieval details, and compare multiple runs.
### Result Format
Each evaluated question produces a structured result:
```json
{
"id": "locomo_q_001",
"group": "temporal",
"question": "When did the user first mention moving?",
"ground_truth": "During the March 3rd conversation",
"retrieval": {
"search_query": "when did user mention moving",
"search_results": ["..."],
"search_latency_ms": 123.4,
"total_results": 42
},
"generation": {
"generated_answer": "The user first mentioned moving on March 3rd",
"model": "<answerer-model>",
"prompt_tokens": 500,
"completion_tokens": 100
},
"judgment": {
"judgment": "CORRECT",
"score": 0.85,
"reason": "Answer correctly identifies the date",
"model": "<judge-model>"
},
"cutoff_results": {
"top_10": { "score": 0.75, "judgment": "CORRECT" },
"top_50": { "score": 0.85, "judgment": "CORRECT" },
"top_200": { "score": 0.90, "judgment": "CORRECT" }
}
}
```
## Interpreting Results
When evaluating memory systems, keep these considerations in mind:
- **Saturating a small benchmark is not the same as building a memory system that works at scale.** Small benchmarks can be brute-forced with aggressive retrieval and frontier models.
- **Token efficiency matters as much as accuracy.** A system that scores 95% using 25K tokens per query isn't comparable to one scoring 90% using 7K tokens. Report mean tokens per query alongside scores.
- **Compare at equal constraints.** Always compare systems using the same retrieval budget, the same model, and the same latency budget. A frontier model at maximum recall is not comparable to a smaller production-grade model at production-realistic retrieval depth.
- **Watch for score ceiling effects.** Categories like "single-session user" are already near-saturated (97%+). Improvements in these categories are less meaningful than gains in harder categories like temporal reasoning or multi-session.
- **BEAM at 10M is the real test.** Any system can look good at small scale. The 10M-token BEAM benchmark reveals whether the retrieval system actually scales.
## FAQ
<AccordionGroup>
<Accordion title="What judge model is used for evaluation?">
The judge model is configurable via `--judge-model` and `--judge-provider` flags. See the [evaluation repository](https://github.com/mem0ai/memory-benchmarks) for the current defaults. Scores carry a ±1 point confidence interval due to judge inconsistency.
</Accordion>
<Accordion title="Can I evaluate with a different extraction model?">
Yes. For self-hosted, configure the extraction model in your `mem0-config.yaml` (see the `configs/` directory of the evaluation repo for provider-specific examples). For Mem0 Cloud, extraction uses the platform's default. Using a frontier model will likely produce higher scores but at higher cost and latency.
</Accordion>
<Accordion title="Why are BEAM scores lower than LoCoMo/LongMemEval?">
BEAM operates at 1M and 10M token scales — orders of magnitude larger than LoCoMo or LongMemEval. At these scales, similar content appears multiple times across the window, and the memory system must surface the exact correct memory over many close matches. The scores reflect the genuine difficulty of the task, not a regression in the algorithm.
</Accordion>
<Accordion title="How do I contribute a new benchmark?">
Open a pull request to the [memory-benchmarks repository](https://github.com/mem0ai/memory-benchmarks) with your benchmark implementation. See the repository README for the expected interface and format.
</Accordion>
</AccordionGroup>
## Resources
<CardGroup cols={2}>
<Card title="Evaluation Repository" icon="github" href="https://github.com/mem0ai/memory-benchmarks">
Open-source evaluation framework for reproducing all benchmark results
</Card>
<Card title="Research" icon="flask" href="https://mem0.ai/research">
Published research papers and technical reports
</Card>
<Card title="Blog Post" icon="newspaper" href="https://mem0.ai/blog/new-algorithm">
Detailed writeup of the new algorithm design and results
</Card>
<Card title="Platform Migration" icon="arrow-right" href="/migration/platform-v2-to-v3">
Guide for migrating your Platform integration
</Card>
</CardGroup>
+1 -3
View File
@@ -21,7 +21,7 @@ Adding memory is how Mem0 captures useful details from a conversation so your ag
- **Messages** – The ordered list of user/assistant turns you send to `add`.
- **Infer** – Controls whether Mem0 extracts structured memories (`infer=True`, default) or stores raw messages.
- **Metadata** – Optional filters (e.g., `{"category": "movie_recommendations"}`) that improve retrieval later.
- **User / Session identifiers** – `user_id`, `session_id`, or `run_id` that scope the memory for future searches.
- **User / Session identifiers** – `user_id`, `agent_id`, or `run_id` that scope the memory for future searches.
## How does it work?
@@ -85,7 +85,6 @@ const messages = [
await client.add(messages, {
user_id: "alice",
version: "v2",
});
```
</CodeGroup>
@@ -173,7 +172,6 @@ For full list of supported fields, required formats, and advanced options, see t
| Capability | Mem0 Platform | Mem0 OSS |
| --- | --- | --- |
| Conflict resolution | Automatic with dashboard visibility | SDK handles merges locally; you control storage |
| Graph writes | Toggle per request (`enable_graph=True`) | Requires configuring a graph provider |
| Rate limits | Managed quotas per workspace | Limited by your hardware and provider APIs |
| Dashboard visibility | Yes — inspect memories visually | Inspect via CLI, logs, or custom UI |
@@ -120,7 +120,7 @@ import MemoryClient from 'mem0ai';
const client = new MemoryClient({ apiKey: "your-api-key" });
client.deleteAll({ user_id: "alice" })
client.deleteAll({ userId: "alice" })
.then(result => console.log(result))
.catch(error => console.error(error));
```
@@ -162,12 +162,12 @@ import MemoryClient from 'mem0ai';
const client = new MemoryClient({ apiKey: "your-api-key" });
// Delete all memories across every user in the project
client.deleteAll({ user_id: "*" })
client.deleteAll({ userId: "*" })
.then(result => console.log(result))
.catch(error => console.error(error));
// Full project wipe — all four filters must be explicitly set to "*"
client.deleteAll({ user_id: "*", agent_id: "*", app_id: "*", run_id: "*" })
client.deleteAll({ userId: "*", agentId: "*", appId: "*", runId: "*" })
.then(result => console.log(result))
.catch(error => console.error(error));
```
+18 -14
View File
@@ -56,7 +56,7 @@ Search converts your natural language question into a vector embedding, then fin
client.search("What are Alice's hobbies?", filters={"user_id": "alice"})
# OSS
m.search("What are Alice's hobbies?", user_id="alice")
m.search("What are Alice's hobbies?", filters={"user_id": "alice"})
```
<Tip>
@@ -74,7 +74,7 @@ m.search("What are Alice's hobbies?", user_id="alice")
| Capability | Mem0 Platform | Mem0 OSS |
| --- | --- | --- |
| **user_id usage** | In `filters={"user_id": "alice"}` for search/get_all | As parameter `user_id="alice"` for all operations |
| **Entity IDs on search / get_all** | Inside `filters={"user_id": "alice"}` | Inside `filters={"user_id": "alice"}` (aligned with Platform in v3 — top-level kwargs raise `ValueError`) |
| **Filter syntax** | Logical operators (`AND`, `OR`, comparisons) with field-level access | Basic field filters, extend via Python hooks |
| **Reranking** | Toggle `rerank=True` with managed reranker catalog | Requires configuring local or third-party rerankers |
| **Thresholds** | Request-level configuration (`threshold`, `top_k`) | Controlled via SDK parameters |
@@ -125,14 +125,13 @@ from mem0 import Memory
m = Memory()
# Simple search
related_memories = m.search("Should I drink coffee or tea?", user_id="alice")
# Simple search — entity IDs go in `filters`
related_memories = m.search("Should I drink coffee or tea?", filters={"user_id": "alice"})
# Search with filters
# Search with additional metadata filters (combine entity + metadata in the same dict)
memories = m.search(
"food preferences",
user_id="alice",
filters={"categories": {"contains": "diet"}}
filters={"user_id": "alice", "categories": {"contains": "diet"}},
)
```
@@ -141,13 +140,14 @@ import { Memory } from 'mem0ai/oss';
const memory = new Memory();
// Simple search
const relatedMemories = memory.search("Should I drink coffee or tea?", { userId: "alice" });
// Simple search — entity IDs go inside `filters`
const relatedMemories = memory.search("Should I drink coffee or tea?", {
filters: { userId: "alice" },
});
// Search with filters (if supported)
// Combine entity + metadata filters in the same filters object
const memories = memory.search("food preferences", {
userId: "alice",
filters: { categories: { contains: "diet" } }
filters: { userId: "alice", categories: { contains: "diet" } },
});
```
</CodeGroup>
@@ -176,8 +176,12 @@ client.search("query", filters={
*OSS:*
```python
# Get memories from a specific agent session
m.search("query", user_id="alice", agent_id="chatbot", run_id="session-123")
# Get memories from a specific agent session — entity IDs combined in filters
m.search("query", filters={
"user_id": "alice",
"agent_id": "chatbot",
"run_id": "session-123",
})
```
**Filter by Date Range:**
+4 -4
View File
@@ -52,7 +52,7 @@ Mem0 maps these classic categories onto its layered storage so you can decide wh
Mem0 stores each layer separately and merges them when you query:
1. **Capture** – Messages enter the conversation layer while the turn is active.
2. **Promote** – Relevant details persist to session or user memory based on your `user_id`, `session_id`, and metadata.
2. **Promote** – Relevant details persist to session or user memory based on your `user_id`, `run_id`, and metadata.
3. **Retrieve** – The search pipeline pulls from all layers, ranking user memories first, then session notes, then raw history.
```python
@@ -66,19 +66,19 @@ memory = Memory(api_key=os.environ["MEM0_API_KEY"])
memory.add(
["I'm Alex and I prefer boutique hotels."],
user_id="alex",
session_id="trip-planning-2025",
run_id="trip-planning-2025",
)
# Later in the session, pull long-term + session context
results = memory.search(
"Any hotel preferences?",
user_id="alex",
session_id="trip-planning-2025",
run_id="trip-planning-2025",
)
```
<Tip>
Use `session_id` when you want short-term context to expire automatically; rely on `user_id` for lasting personalization.
Use `run_id` when you want short-term context to expire automatically; rely on `user_id` for lasting personalization.
</Tip>
## When should you use each layer?
+84 -33
View File
@@ -12,7 +12,7 @@
"logo": {
"light": "/logo/light.svg",
"dark": "/logo/dark.svg",
"href": "https://app.mem0.ai/"
"href": "https://mem0.ai"
},
"navigation": {
"anchors": [
@@ -55,7 +55,8 @@
"core-concepts/memory-operations/add",
"core-concepts/memory-operations/search",
"core-concepts/memory-operations/update",
"core-concepts/memory-operations/delete"
"core-concepts/memory-operations/delete",
"core-concepts/memory-evaluation"
]
},
{
@@ -70,7 +71,6 @@
"platform/features/v2-memory-filters",
"platform/features/entity-scoped-memory",
"platform/features/async-client",
"platform/features/async-mode-default-change",
"platform/features/multimodal-support",
"platform/features/custom-categories"
]
@@ -79,8 +79,6 @@
"group": "Advanced Features",
"icon": "bolt",
"pages": [
"platform/features/graph-memory",
"platform/features/graph-threshold",
"platform/features/advanced-retrieval",
"platform/advanced-memory-operations",
"platform/features/criteria-retrieval",
@@ -94,8 +92,7 @@
"pages": [
"platform/features/direct-import",
"platform/features/memory-export",
"platform/features/timestamp",
"platform/features/expiration-date"
"platform/features/timestamp"
]
},
{
@@ -121,9 +118,8 @@
"group": "Migration Guide",
"icon": "arrow-right",
"pages": [
"migration/platform-v2-to-v3",
"migration/oss-to-platform",
"migration/v0-to-v1",
"migration/breaking-changes",
"migration/api-changes"
]
},
@@ -133,13 +129,6 @@
"pages": [
"platform/contribute"
]
},
{
"group": "Release Notes",
"icon": "rocket",
"pages": [
"changelog"
]
}
]
},
@@ -174,13 +163,11 @@
"icon": "server",
"pages": [
"open-source/features/overview",
"open-source/features/graph-memory",
"open-source/features/metadata-filtering",
"open-source/features/reranker-search",
"open-source/features/async-memory",
"open-source/features/multimodal-support",
"open-source/features/custom-fact-extraction-prompt",
"open-source/features/custom-update-memory-prompt",
"open-source/features/custom-instructions",
"open-source/features/rest-api",
"open-source/features/openai_compatibility"
]
@@ -307,6 +294,13 @@
}
]
},
{
"group": "Migration",
"icon": "arrow-right",
"pages": [
"migration/oss-v2-to-v3"
]
},
{
"group": "Community & Support",
"icon": "users",
@@ -373,7 +367,6 @@
"cookbooks/integrations/mastra-agent",
"cookbooks/integrations/healthcare-google-adk",
"cookbooks/integrations/aws-bedrock",
"cookbooks/integrations/neptune-analytics",
"cookbooks/integrations/tavily-search"
]
},
@@ -385,9 +378,7 @@
"cookbooks/frameworks/llamaindex-multiagent",
"cookbooks/frameworks/multimodal-retrieval",
"cookbooks/frameworks/eliza-os-character",
"cookbooks/frameworks/chrome-extension",
"cookbooks/frameworks/gemini-3-with-mem0-mcp",
"cookbooks/frameworks/mirofish-swarm-memory"
"cookbooks/frameworks/gemini-3-with-mem0-mcp"
]
}
]
@@ -416,7 +407,8 @@
"integrations/openai-agents-sdk",
"integrations/google-ai-adk",
"integrations/mastra",
"integrations/vercel-ai-sdk"
"integrations/vercel-ai-sdk",
"integrations/chatdev"
]
},
{
@@ -558,6 +550,21 @@
]
}
]
},
{
"tab": "Release Notes",
"groups": [
{
"group": "Release Notes",
"icon": "rocket",
"pages": [
"changelog/highlights",
"changelog/sdk",
"changelog/platform",
"changelog/openclaw"
]
}
]
}
]
}
@@ -608,6 +615,34 @@
]
},
"redirects": [
{
"source": "/migration/breaking-changes",
"destination": "/"
},
{
"source": "/migration/v0-to-v1",
"destination": "/"
},
{
"source": "/platform/features/expiration-date",
"destination": "/"
},
{
"source": "/platform/features/async-mode-default-change",
"destination": "/"
},
{
"source": "/open-source/features/custom-fact-extraction-prompt",
"destination": "/open-source/features/custom-instructions"
},
{
"source": "/platform/features/graph-memory",
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/changelog",
"destination": "/changelog/highlights"
},
{
"source": "/api-reference/memory/v2-search-memories",
"destination": "/api-reference/memory/search-memories"
@@ -702,11 +737,23 @@
},
{
"source": "/examples/aws_neptune_analytics_hybrid_store",
"destination": "/cookbooks/integrations/neptune-analytics"
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/examples/aws_neptune_analytics_hybrid_st",
"destination": "/cookbooks/integrations/neptune-analytics"
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/cookbooks/integrations/neptune-analytics",
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/platform/features/graph-threshold",
"destination": "/migration/platform-v2-to-v3"
},
{
"source": "/open-source/features/custom-update-memory-prompt",
"destination": "/open-source/features/custom-instructions"
},
{
"source": "/examples/personalized-search-tavily-mem0",
@@ -766,7 +813,11 @@
},
{
"source": "/examples/chrome-extension",
"destination": "/cookbooks/frameworks/chrome-extension"
"destination": "/cookbooks/overview"
},
{
"source": "/cookbooks/frameworks/chrome-extension",
"destination": "/cookbooks/overview"
},
{
"source": "/examples",
@@ -774,11 +825,11 @@
},
{
"source": "/open-source/graph_memory/overview",
"destination": "/open-source/features/graph-memory"
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/open-source/graph_memory/features",
"destination": "/open-source/features/graph-memory"
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/v0x/examples/ai_companion_js",
@@ -806,7 +857,7 @@
},
{
"source": "/v0x/examples/chrome-extension",
"destination": "/cookbooks/frameworks/chrome-extension"
"destination": "/cookbooks/overview"
},
{
"source": "/v0x/examples/youtube-assistant",
@@ -874,7 +925,7 @@
},
{
"source": "/v0x/examples/aws_neptune_analytics_hybrid_store",
"destination": "/cookbooks/integrations/neptune-analytics"
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/features/memory-export",
@@ -958,7 +1009,7 @@
},
{
"source": "/features/graph-memory",
"destination": "/platform/features/graph-memory"
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/features/:slug",
@@ -1066,7 +1117,7 @@
},
{
"source": "/open-source/graph-memory",
"destination": "/open-source/features/graph-memory"
"destination": "/migration/oss-v2-to-v3"
},
{
"source": "/cookbooks/customer-support-agent",
+7
View File
@@ -409,4 +409,11 @@ Here are the available integrations for Mem0:
>
Use Mem0 with AWS Bedrock and OpenSearch Service for cloud-native persistent semantic memory storage.
</Card>
<Card
title="ChatDev"
icon="comments"
href="/integrations/chatdev"
>
Add persistent cloud-managed memory to ChatDev multi-agent workflows with zero-code YAML configuration.
</Card>
</CardGroup>
+4 -4
View File
@@ -24,7 +24,7 @@ pip install mem0ai agentops python-dotenv
2. Valid API keys:
- [AgentOps API Key](https://app.agentops.ai/dashboard/api-keys)
- OpenAI API Key (for LLM operations)
- [Mem0 API Key](https://app.mem0.ai/dashboard/api-keys) (optional, for cloud operations)
- <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 API Key</a> (optional, for cloud operations)
## Basic Integration Example
@@ -50,7 +50,7 @@ local_config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4.1-nano-2025-04-14",
"model": "gpt-5-mini",
"temperature": 0.1,
"max_tokens": 2000,
},
@@ -103,7 +103,7 @@ def demonstrate_sync_memory(local_config, sample_messages, sample_preferences, u
]
for query in search_queries:
results = memory.search(query, user_id=user_id)
results = memory.search(query, filters={"user_id": user_id})
if results and "results" in results:
for j, result in enumerate(results['results']):
@@ -111,7 +111,7 @@ def demonstrate_sync_memory(local_config, sample_messages, sample_preferences, u
else:
print("No results found")
all_memories = memory.get_all(user_id=user_id)
all_memories = memory.get_all(filters={"user_id": user_id})
if all_memories and "results" in all_memories:
print(f"Total memories: {len(all_memories['results'])}")
+3 -3
View File
@@ -23,7 +23,7 @@ pip install agno mem0ai python-dotenv
```
2. Valid API keys:
- [Mem0 API Key](https://app.mem0.ai/dashboard/api-keys)
- <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 API Key</a>
- OpenAI API Key (for the agent model)
## Quick Integration (Using `Mem0Tools`)
@@ -37,7 +37,7 @@ from agno.tools.mem0 import Mem0Tools
agent = Agent(
name="Memory Agent",
model=OpenAIChat(id="gpt-4.1-nano-2025-04-14"),
model=OpenAIChat(id="gpt-5-mini"),
tools=[Mem0Tools()],
description="An assistant that remembers and personalizes using Mem0 memory."
)
@@ -126,7 +126,7 @@ def chat_user(
if user_input:
# Search for relevant memories
memories = client.search(user_input, user_id=user_id)
memories = client.search(user_input, filters={"user_id": user_id})
memory_context = "\n".join(f"- {m['memory']}" for m in memories['results'])
# Construct the prompt
+3 -3
View File
@@ -19,7 +19,7 @@ pip install autogen mem0ai openai python-dotenv
First, we'll import the necessary libraries and set up our configurations.
<Note>Remember to get the Mem0 API key from [Mem0 Platform](https://app.mem0.ai).</Note>
<Note>Remember to get the Mem0 API key from <a href="https://app.mem0.ai" rel="nofollow">Mem0 Platform</a>.</Note>
```python
import os
@@ -72,7 +72,7 @@ Create a function to get context-aware responses based on user's question and pr
```python
def get_context_aware_response(question):
relevant_memories = memory_client.search(question, user_id=USER_ID)
relevant_memories = memory_client.search(question, filters={"user_id": USER_ID})
context = "\n".join([m["memory"] for m in relevant_memories.get('results', [])])
prompt = f"""Answer the user question considering the previous interactions:
@@ -104,7 +104,7 @@ manager = ConversableAgent(
)
def escalate_to_manager(question):
relevant_memories = memory_client.search(question, user_id=USER_ID)
relevant_memories = memory_client.search(question, filters={"user_id": USER_ID})
context = "\n".join([m["memory"] for m in relevant_memories.get('results', [])])
prompt = f"""
+2 -5
View File
@@ -107,10 +107,10 @@ messages = [
m.add(messages, user_id="alice", metadata={"category": "movie_recommendations"})
# Search for memory
relevant = m.search("What kind of movies does Alice like?", user_id="alice")
relevant = m.search("What kind of movies does Alice like?", filters={"user_id": "alice"})
# Retrieve all user memories
all_memories = m.get_all(user_id="alice")
all_memories = m.get_all(filters={"user_id": "alice"})
```
## Key Features
@@ -125,8 +125,5 @@ all_memories = m.get_all(user_id="alice")
<Card title="AWS Bedrock Cookbook" icon="aws" href="/cookbooks/integrations/aws-bedrock">
Complete guide to using Bedrock with Mem0
</Card>
<Card title="Neptune Analytics Cookbook" icon="database" href="/cookbooks/integrations/neptune-analytics">
Build graph memory with AWS Neptune
</Card>
</CardGroup>
+243
View File
@@ -0,0 +1,243 @@
---
title: ChatDev
description: "Add persistent, cloud-managed memory to ChatDev multi-agent workflows with Mem0 — no code required, just YAML configuration."
---
Build multi-agent workflows in [ChatDev](https://github.com/OpenBMB/ChatDev) with persistent memory powered by Mem0. ChatDev is a zero-code multi-agent platform where agents, tools, and workflows are defined entirely in YAML. Mem0 integrates as a built-in memory store (`type: mem0`), giving your agents cloud-managed semantic search and cross-session persistence — all without writing any code.
## Overview
In this guide, you'll:
1. Set up ChatDev with the Mem0 memory store
2. Configure agents with persistent memory using YAML
3. Enable automatic memory retrieval and storage across conversations
4. Leverage cross-session persistence for personalized multi-agent interactions
## Prerequisites
- **Python 3.12+**
- **[uv](https://docs.astral.sh/uv/)** — Python package manager
- **Node.js 18+** and **npm** — only needed if using the web console
- A **Mem0 API key** from <a href="https://app.mem0.ai" rel="nofollow">app.mem0.ai</a>
- An **OpenAI API key** (or another LLM provider supported by ChatDev)
## Setup and Configuration
Install ChatDev and its dependencies (includes `mem0ai`):
```bash
git clone https://github.com/OpenBMB/ChatDev.git
cd ChatDev
uv sync
```
If you plan to use the web console, also install the frontend:
```bash
cd frontend && npm install && cd ..
```
Set up your environment variables in a `.env` file:
<Note>Get your Mem0 API key from <a href="https://app.mem0.ai" rel="nofollow">Mem0 Platform</a>.</Note>
```bash
MEM0_API_KEY=your-mem0-api-key
API_KEY=your-openai-api-key
BASE_URL=https://api.openai.com/v1
```
## Configure Mem0 Memory Store
In your ChatDev workflow YAML, add a Mem0 memory store in the `memory` section:
```yaml
memory:
- name: mem0_store
type: mem0
config:
api_key: ${MEM0_API_KEY}
user_id: my-user-123 # optional: scope memories to a user
agent_id: my-agent # optional: scope memories to an agent
```
Mem0 handles all storage, embeddings, and search server-side — no local vector databases or embedding models are needed.
## Attach Memory to an Agent
Reference the memory store in your agent node's `memories` list:
```yaml
nodes:
- id: writer
type: agent
config:
role: |
You are a knowledgeable writer. Use your memories to build
on past interactions.
memories:
- name: mem0_store
top_k: 5
similarity_threshold: 0.5 # minimum relevance score (0.0–1.0); set to -1.0 to disable
retrieve_stage:
- gen
read: true
write: true
```
- **`read: true`** — Agent retrieves relevant memories before generating a response
- **`write: true`** — Agent stores new memories from user input after each interaction
- **`top_k`** — Number of memories to retrieve per query
- **`similarity_threshold`** — Minimum relevance score for retrieved memories. Set to `-1.0` to return all results regardless of score
- **`retrieve_stage`** — When to retrieve memories. Options: `pre_gen_thinking` (before generation), `gen` (during generation), `post_gen_thinking` (after generation), `finished` (after completion)
## Full Example Workflow
Here's a complete workflow YAML that creates a memory-backed conversational agent:
```yaml
version: 0.4.0
graph:
description: Memory-backed conversation using Mem0
nodes:
- id: writer
type: agent
config:
base_url: ${BASE_URL}
api_key: ${API_KEY}
provider: openai
name: gpt-5.4
role: |
You are a knowledgeable writer. Use your memories to build
on past interactions. If memory sections are provided
(wrapped by ===== Related Memories =====), incorporate
relevant context from those memories into your response.
params:
temperature: 0.7
max_tokens: 2000
memories:
- name: mem0_store
top_k: 5
retrieve_stage:
- gen
read: true
write: true
memory:
- name: mem0_store
type: mem0
config:
api_key: ${MEM0_API_KEY}
user_id: project-user-123
agent_id: writer-agent
start:
- writer
end: []
```
Run the workflow:
```bash
# Option 1: CLI (recommended for quick testing)
uv run python run.py --path yaml_instance/demo_mem0_memory.yaml --name my_project
# Option 2: Web console
make dev
# Backend starts at http://localhost:6400, frontend at http://localhost:5173
```
To use the web console, open `http://localhost:5173`, create a new workflow, and paste your YAML configuration into the editor. The web console provides a visual chat interface for interacting with your memory-backed agents.
## How It Works
When an agent with Mem0 memory receives input, the following cycle runs automatically:
**1. Retrieve** — Before generating a response, ChatDev queries Mem0 with the user's input using semantic search. Relevant memories are injected into the agent's context in this format:
```
===== Related Memories =====
--- mem0_store ---
1. User's favorite language is Rust
2. User lives in San Francisco
===== End of Memory =====
```
This is why the role prompt in the example references `===== Related Memories =====` — the agent needs to know how to use this injected context.
**2. Generate** — The agent produces a response using the retrieved memories as additional context.
**3. Store** — After generation, the user's input is sent to Mem0 via `client.add()`. Mem0's extraction model automatically identifies and stores facts, preferences, and key information. Only user input is stored — agent output is excluded to keep memories clean.
Memories persist in Mem0's cloud across all sessions. The next time the same `user_id` or `agent_id` is used, previous memories are automatically retrieved.
## Dual-Scope Memory (User + Agent)
When both `user_id` and `agent_id` are configured, Mem0 uses an OR filter to search across both scopes in a single query:
```yaml
memory:
- name: shared_store
type: mem0
config:
api_key: ${MEM0_API_KEY}
user_id: alice # stores user preferences ("Alice prefers dark mode")
agent_id: support-bot # stores agent-learned context ("Resolved Alice's billing issue")
```
This means retrieval returns memories from **both** the user's scope and the agent's scope. Writes include both IDs, so each memory is accessible from either dimension. Use this when you want an agent to remember both what the user told it *and* what the agent learned across sessions.
## Configuration Reference
### Memory Store Config
| Field | Required | Description |
|-------|----------|-------------|
| `api_key` | Yes | Mem0 API key from <a href="https://app.mem0.ai" rel="nofollow">app.mem0.ai</a> |
| `user_id` | No | Scope memories to a specific user |
| `agent_id` | No | Scope memories to a specific agent |
### Memory Attachment Config
| Field | Default | Description |
|-------|---------|-------------|
| `top_k` | `3` | Number of memories to retrieve |
| `similarity_threshold` | `-1.0` (disabled) | Minimum relevance score. Set a value between `0.0` and `1.0` to filter low-relevance results. Default (`-1.0`) returns all matches without filtering |
| `retrieve_stage` | `["gen"]` | When to retrieve: `pre_gen_thinking`, `gen`, `post_gen_thinking`, or `finished` |
| `read` | `true` | Whether the agent retrieves memories |
| `write` | `true` | Whether the agent stores new memories |
## Tips and Common Pitfalls
<Info>
**Indexing delay** — Freshly stored memories may take a few seconds to become searchable. If a memory isn't retrieved immediately after being stored, wait a moment and try again.
</Info>
- **No memories returned on first run** — This is expected. Memories are stored *after* the agent responds, so the first interaction has no prior context. Memories appear starting from the second interaction onward.
- **`mem0ai` not installed** — If you see `ImportError: mem0ai is required for Mem0Memory`, run `uv add mem0ai` or `pip install mem0ai` to add the dependency.
- **Invalid API key** — A wrong or expired `MEM0_API_KEY` will log errors like `Mem0 search failed` or `Mem0 add failed` but won't crash the agent. Check your key at <a href="https://app.mem0.ai" rel="nofollow">app.mem0.ai</a>.
- **Pipeline headers in memories** — ChatDev automatically strips internal pipeline headers (e.g., `=== INPUT FROM TASK (user) ===`) before sending text to Mem0, so your memories stay clean.
- **Clearing test memories** — To delete memories created during testing, use the Mem0 dashboard at <a href="https://app.mem0.ai" rel="nofollow">app.mem0.ai</a> or the Python SDK: `MemoryClient().delete_all(user_id="your-test-user")`.
## Key Features
1. **Zero-Code Integration** — Configure Mem0 entirely through YAML, no Python code required
2. **Cloud-Managed Storage** — Mem0 handles embeddings, persistence, and search server-side
3. **Semantic Search** — Retrieve contextually relevant memories, not just keyword matches
4. **Cross-Session Persistence** — Memories survive across runs, sessions, and restarts
5. **Multi-Agent Memory Sharing** — Multiple agents can share memories through common `user_id` or `agent_id` scopes
6. **Intelligent Input Processing** — Only user input is stored; agent output is excluded to prevent noisy memories
## Conclusion
By adding Mem0 as a memory store in ChatDev, your multi-agent workflows gain persistent, intelligent memory with zero code changes. Agents automatically remember past interactions and use that context to provide personalized, coherent responses across sessions.
<CardGroup cols={2}>
<Card title="CrewAI Integration" icon="users" href="/integrations/crewai">
Build multi-agent systems with CrewAI and Mem0
</Card>
<Card title="AutoGen Integration" icon="robot" href="/integrations/autogen">
Build conversational agents with AutoGen and Mem0
</Card>
</CardGroup>
+2 -2
View File
@@ -17,8 +17,8 @@ Add persistent memory to [**Claude Code**](https://docs.anthropic.com/en/docs/cl
Before setting up Mem0 with Claude Code, ensure you have:
1. A Mem0 Platform account and API key:
- [Sign up at app.mem0.ai](https://app.mem0.ai)
- [Get your API key](https://app.mem0.ai/dashboard/api-keys) (starts with `m0-`)
- <a href="https://app.mem0.ai" rel="nofollow">Sign up at app.mem0.ai</a>
- <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Get your API key</a> (starts with `m0-`)
2. Claude Code CLI or Claude Cowork desktop app installed
+2 -2
View File
@@ -17,8 +17,8 @@ Add persistent memory to [**OpenAI Codex**](https://openai.com/index/codex/) wit
Before setting up Mem0 with Codex, ensure you have:
1. A Mem0 Platform account and API key:
- [Sign up at app.mem0.ai](https://app.mem0.ai)
- [Get your API key](https://app.mem0.ai/dashboard/api-keys) (starts with `m0-`)
- <a href="https://app.mem0.ai" rel="nofollow">Sign up at app.mem0.ai</a>
- <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Get your API key</a> (starts with `m0-`)
2. OpenAI Codex access
+1 -1
View File
@@ -22,7 +22,7 @@ pip install crewai crewai-tools mem0ai
Import required modules and set up configurations:
<Note>Remember to get your API keys from [Mem0 Platform](https://app.mem0.ai), [OpenAI](https://platform.openai.com) and [Serper Dev](https://serper.dev) for search capabilities.</Note>
<Note>Remember to get your API keys from <a href="https://app.mem0.ai" rel="nofollow">Mem0 Platform</a>, [OpenAI](https://platform.openai.com) and [Serper Dev](https://serper.dev) for search capabilities.</Note>
```python
import os
+2 -2
View File
@@ -17,8 +17,8 @@ Add persistent memory to [**Cursor**](https://cursor.com) with the Mem0 plugin.
Before setting up Mem0 with Cursor, ensure you have:
1. A Mem0 Platform account and API key:
- [Sign up at app.mem0.ai](https://app.mem0.ai)
- [Get your API key](https://app.mem0.ai/dashboard/api-keys) (starts with `m0-`)
- <a href="https://app.mem0.ai" rel="nofollow">Sign up at app.mem0.ai</a>
- <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Get your API key</a> (starts with `m0-`)
2. Cursor installed ([cursor.com](https://cursor.com))
+3 -3
View File
@@ -38,7 +38,7 @@ npx flowise start
### 2. Obtain Your Mem0 API Key
1. Navigate to the [Mem0 API Key dashboard](https://app.mem0.ai/dashboard/api-keys).
1. Navigate to the <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 API Key dashboard</a>.
2. Generate or copy your existing Mem0 API Key.
![Mem0 API Key](https://raw.githubusercontent.com/FlowiseAI/FlowiseDocs/main/en/.gitbook/assets/mem0/api-key.png)
@@ -70,7 +70,7 @@ Test your memory configuration:
1. Save your Flowise configuration
2. Run a test chat and store some information
3. Verify the stored memories in the [Mem0 Dashboard](https://app.mem0.ai/dashboard/requests)
3. Verify the stored memories in the <a href="https://app.mem0.ai/dashboard/requests" rel="nofollow">Mem0 Dashboard</a>
![Flowise Test Chat](https://raw.githubusercontent.com/FlowiseAI/FlowiseDocs/main/en/.gitbook/assets/mem0/flowise-chat-1.png)
@@ -103,7 +103,7 @@ Available settings include:
### Platform Configuration
Additional settings available in [Mem0 Project Settings](https://app.mem0.ai/dashboard/project-settings):
Additional settings available in <a href="https://app.mem0.ai/dashboard/project-settings" rel="nofollow">Mem0 Project Settings</a>:
1. **Custom Instructions**: Define memory extraction rules
2. **Expiration Date**: Set automatic memory cleanup periods
+2 -2
View File
@@ -22,7 +22,7 @@ pip install google-adk mem0ai python-dotenv
```
2. Valid API keys:
- [Mem0 API Key](https://app.mem0.ai/dashboard/api-keys)
- <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 API Key</a>
- Google AI Studio API Key
## Basic Integration Example
@@ -268,7 +268,7 @@ memories = mem0.search(
{"categories": {"contains": "travel"}}
]
},
limit=5
top_k=5
)
# Configure agent with custom model settings
+1 -1
View File
@@ -52,7 +52,7 @@ hermes memory setup
Select **mem0** as the provider and enter your Mem0 API key when prompted. The wizard writes your config to `~/.hermes/mem0.json`.
<Note>Get your API key from [app.mem0.ai](https://app.mem0.ai).</Note>
<Note>Get your API key from <a href="https://app.mem0.ai" rel="nofollow">app.mem0.ai</a>.</Note>
### Option 2: Manual Configuration
+2 -3
View File
@@ -16,7 +16,7 @@ Combining Mem0 with Keywords AI allows you to:
4. Optimize token usage and reduce costs
<Note>
You can get your Mem0 API key, user_id, and org_id from the [Mem0 dashboard](https://app.mem0.ai/). These are required for proper integration.
You can get your Mem0 API key from the <a href="https://app.mem0.ai/" rel="nofollow">Mem0 dashboard</a>.
</Note>
## Setup and Configuration
@@ -56,7 +56,7 @@ config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4.1-nano-2025-04-14",
"model": "gpt-5-mini",
"temperature": 0.0,
"api_key": keywordsai_api_key,
"openai_base_url": base_url,
@@ -107,7 +107,6 @@ response = client.chat.completions.create(
extra_body={
"mem0_params": {
"user_id": "test_user",
"org_id": "org_1",
"api_key": os.environ.get("MEM0_API_KEY"),
"add_memories": {
"messages": messages,
+1 -4
View File
@@ -29,10 +29,7 @@ import os
os.environ["MEM0_API_KEY"] = "your-api-key"
client = MemoryClient(
org_id=your_org_id,
project_id=your_project_id
)
client = MemoryClient()
```
## Available Tools
+3 -3
View File
@@ -22,7 +22,7 @@ pip install langchain langchain_openai mem0ai python-dotenv
Import required modules and set up configurations:
<Note>Remember to get the Mem0 API key from [Mem0 Platform](https://app.mem0.ai).</Note>
<Note>Remember to get the Mem0 API key from <a href="https://app.mem0.ai" rel="nofollow">Mem0 Platform</a>.</Note>
```python
import os
@@ -40,7 +40,7 @@ load_dotenv()
# os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
# Initialize LangChain and Mem0
llm = ChatOpenAI(model="gpt-4.1-nano-2025-04-14")
llm = ChatOpenAI(model="gpt-5-mini")
mem0 = MemoryClient()
```
@@ -66,7 +66,7 @@ Create functions to handle context retrieval, response generation, and addition
def retrieve_context(query: str, user_id: str) -> List[Dict]:
"""Retrieve relevant context from Mem0"""
try:
memories = mem0.search(query, user_id=user_id)
memories = mem0.search(query, filters={"user_id": user_id})
memory_list = memories['results']
serialized_memories = ' '.join([mem["memory"] for mem in memory_list])
+2 -2
View File
@@ -23,7 +23,7 @@ pip install langgraph langchain-openai mem0ai python-dotenv
Import required modules and set up configurations:
<Note>Remember to get the Mem0 API key from [Mem0 Platform](https://app.mem0.ai).</Note>
<Note>Remember to get the Mem0 API key from <a href="https://app.mem0.ai" rel="nofollow">Mem0 Platform</a>.</Note>
```python
from typing import Annotated, TypedDict, List
@@ -68,7 +68,7 @@ def chatbot(state: State):
try:
# Retrieve relevant memories
memories = mem0.search(messages[-1].content, user_id=user_id)
memories = mem0.search(messages[-1].content, filters={"user_id": user_id})
# Handle dict response format
memory_list = memories['results']
+1 -1
View File
@@ -148,7 +148,7 @@ async def entrypoint(ctx: JobContext):
session = AgentSession(
stt=deepgram.STT(),
llm=openai.LLM(model="gpt-4.1-nano-2025-04-14"),
llm=openai.LLM(model="gpt-5-mini"),
tts=openai.TTS(voice="ash",),
turn_detection=EnglishModel(),
vad=silero.VAD.load(),
+3 -3
View File
@@ -22,7 +22,7 @@ pip install llama-index-core llama-index-memory-mem0 python-dotenv
Set your Mem0 Platform API key as an environment variable. You can replace `<your-mem0-api-key>` with your actual API key:
<Note type="info">
You can obtain your Mem0 Platform API key from the [Mem0 Platform](https://app.mem0.ai/login).
You can obtain your Mem0 Platform API key from the <a href="https://app.mem0.ai/login" rel="nofollow">Mem0 Platform</a>.
</Note>
```python
@@ -83,7 +83,7 @@ config = {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4.1-nano-2025-04-14",
"model": "gpt-5-mini",
"temperature": 0.2,
"max_tokens": 2000,
},
@@ -116,7 +116,7 @@ from dotenv import load_dotenv
load_dotenv()
# os.environ["OPENAI_API_KEY"] = "<your-openai-api-key>"
llm = OpenAI(model="gpt-4.1-nano-2025-04-14")
llm = OpenAI(model="gpt-5-mini")
```
### SimpleChatEngine
+1 -1
View File
@@ -23,7 +23,7 @@ npm install @mastra/core @mastra/mem0 @ai-sdk/openai zod
Set up your environment variables:
<Note>Remember to get the Mem0 API key from [Mem0 Platform](https://app.mem0.ai).</Note>
<Note>Remember to get the Mem0 API key from <a href="https://app.mem0.ai" rel="nofollow">Mem0 Platform</a>.</Note>
```bash
MEM0_API_KEY=your-mem0-api-key
+7 -7
View File
@@ -22,7 +22,7 @@ pip install openai-agents mem0ai
```
2. Valid API keys:
- [Mem0 API Key](https://app.mem0.ai/dashboard/api-keys)
- <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 API Key</a>
- [OpenAI API Key](https://platform.openai.com/api-keys)
## Basic Integration Example
@@ -45,7 +45,7 @@ mem0 = MemoryClient()
@function_tool
def search_memory(query: str, user_id: str) -> str:
"""Search through past conversations and memories"""
memories = mem0.search(query, user_id=user_id, limit=3)
memories = mem0.search(query, filters={"user_id": user_id}, top_k=3)
if memories and memories.get('results'):
return "\n".join([f"- {mem['memory']}" for mem in memories['results']])
return "No relevant memories found."
@@ -64,7 +64,7 @@ agent = Agent(
Use the save_memory tool to store important information about the user.
Always personalize your responses based on available memory.""",
tools=[search_memory, save_memory],
model="gpt-4.1-nano-2025-04-14"
model="gpt-5-mini"
)
def chat_with_agent(user_input: str, user_id: str) -> str:
@@ -115,7 +115,7 @@ travel_agent = Agent(
understand the user's travel preferences and history before making recommendations.
After providing your response, use store_conversation to save important details.""",
tools=[search_memory, save_memory],
model="gpt-4.1-nano-2025-04-14"
model="gpt-5-mini"
)
health_agent = Agent(
@@ -124,7 +124,7 @@ health_agent = Agent(
understand the user's health goals and dietary preferences.
After providing advice, use store_conversation to save relevant information.""",
tools=[search_memory, save_memory],
model="gpt-4.1-nano-2025-04-14"
model="gpt-5-mini"
)
# Triage agent with handoffs
@@ -135,7 +135,7 @@ triage_agent = Agent(
For health-related questions (fitness, diet, wellness, exercise), hand off to the Health Advisor.
For general questions, handle them directly using available tools.""",
handoffs=[travel_agent, health_agent],
model="gpt-4.1-nano-2025-04-14"
model="gpt-5-mini"
)
def chat_with_handoffs(user_input: str, user_id: str) -> str:
@@ -215,7 +215,7 @@ Customize memory behavior:
memories = mem0.search(
query="travel preferences",
user_id="alex",
limit=5 # Number of memories to retrieve
top_k=5 # Number of memories to retrieve
)
# Add metadata to memories
+2 -3
View File
@@ -42,7 +42,7 @@ All memories are scoped to this `userId` — different values create separate me
### Platform Mode (Mem0 Cloud)
<Note>Get your API key from [app.mem0.ai](https://app.mem0.ai).</Note>
<Note>Get your API key from <a href="https://app.mem0.ai" rel="nofollow">app.mem0.ai</a>.</Note>
Add to your `openclaw.json`:
@@ -147,7 +147,6 @@ openclaw mem0 stats
| `apiKey` | `string` | — | **Required.** Mem0 API key (supports `${MEM0_API_KEY}`) |
| `orgId` | `string` | — | Organization ID |
| `projectId` | `string` | — | Project ID |
| `enableGraph` | `boolean` | `false` | Entity graph for relationships |
| `customInstructions` | `string` | *(built-in)* | Extraction rules — what to store, how to format |
| `customCategories` | `object` | *(12 defaults)* | Category name → description map for tagging |
@@ -155,7 +154,7 @@ openclaw mem0 stats
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `customPrompt` | `string` | *(built-in)* | Extraction prompt for memory processing |
| `customInstructions` | `string` | *(built-in)* | Extraction prompt for memory processing |
| `oss.embedder.provider` | `string` | `"openai"` | Embedding provider (`"openai"`, `"ollama"`, etc.) |
| `oss.embedder.config` | `object` | — | Provider config: `apiKey`, `model`, `baseURL` |
| `oss.vectorStore.provider` | `string` | `"memory"` | Vector store (`"memory"`, `"qdrant"`, `"chroma"`, etc.) |
+1 -1
View File
@@ -9,7 +9,7 @@ Mem0 is a self-improving memory layer for LLM applications, enabling personalize
**Get your API Key**: You'll need a Mem0 API key to use this extension:
a. Sign up at [app.mem0.ai](https://app.mem0.ai)
a. Sign up at <a href="https://app.mem0.ai" rel="nofollow">app.mem0.ai</a>
b. Navigate to your API Keys page
+3 -21
View File
@@ -29,7 +29,7 @@ npm install @mem0/vercel-ai-provider
### Setting Up Mem0
1. Get your **Mem0 API Key** from the [Mem0 Dashboard](https://app.mem0.ai/dashboard/api-keys).
1. Get your **Mem0 API Key** from the <a href="https://app.mem0.ai/dashboard/api-keys" rel="nofollow">Mem0 Dashboard</a>.
2. Initialize the Mem0 Client in your application:
@@ -52,7 +52,7 @@ npm install @mem0/vercel-ai-provider
> **Note**: The `openai` provider is set as default. Consider using `MEM0_API_KEY` and `OPENAI_API_KEY` as environment variables for security.
> **Note**: The `mem0Config` is optional. It is used to set the global config for the Mem0 Client (eg. `user_id`, `agent_id`, `app_id`, `run_id`, `org_id`, `project_id` etc).
> **Note**: The `mem0Config` is optional. It is used to set the global config for the Mem0 Client (eg. `user_id`, `agent_id`, `app_id`, `run_id` etc).
3. Add Memories to Enhance Context:
@@ -78,7 +78,7 @@ npm install @mem0/vercel-ai-provider
> `getMemories` will return raw memories in the form of an array of objects, while `retrieveMemories` will return a response in string format with a system prompt ingested with the retrieved memories.
> `getMemories` is an object with two keys: `results` and `relations` if `enable_graph` is enabled. Otherwise, it will return an array of objects.
> `getMemories` returns an array of memory objects.
### 1. Basic Text Generation with Memory Context
@@ -270,24 +270,6 @@ main();
> **Note**: File support is available with providers that support multimodal capabilities like Google's Gemini models. The example shows how to process PDF files, but you can also work with images, text files, and other supported formats.
## Graph Memory
Mem0 AI SDK now supports Graph Memory. You can enable it by setting `enable_graph` to `true` in the `mem0Config` object.
```typescript
const mem0 = createMem0({
mem0Config: { enable_graph: true },
});
```
You can also pass `enable_graph` in the standalone functions. This includes `getMemories`, `retrieveMemories`, and `addMemories`.
```typescript
const memories = await getMemories(prompt, { user_id: "borat", mem0ApiKey: "m0-xxx", enable_graph: true });
```
The `getMemories` function will return an object with two keys: `results` and `relations`, if `enable_graph` is set to `true`. Otherwise, it will return an array of objects.
## Supported LLM Providers
| Provider | Configuration Value |
+1 -5
View File
@@ -45,7 +45,6 @@ Key differentiators:
- [Custom Categories](https://docs.mem0.ai/platform/features/custom-categories): Define domain-specific categories to improve memory organization
### Advanced Features
- [Graph Memory](https://docs.mem0.ai/platform/features/graph-memory): Build and query relationships between entities for contextually relevant retrieval
- [Graph Threshold](https://docs.mem0.ai/platform/features/graph-threshold): Configure graph relationship sensitivity and strength
- [Advanced Retrieval](https://docs.mem0.ai/platform/features/advanced-retrieval): Enhanced search with keyword search, reranking, and filtering capabilities
- [Criteria-Based Retrieval](https://docs.mem0.ai/platform/features/criteria-retrieval): Targeted memory retrieval using custom criteria
@@ -81,12 +80,11 @@ Key differentiators:
### Open Source Features
- [Features Overview](https://docs.mem0.ai/open-source/features/overview): Overview of all open-source features
- [Graph Memory](https://docs.mem0.ai/open-source/features/graph-memory): Build and query entity relationships using graph stores like Neo4j
- [Metadata Filtering](https://docs.mem0.ai/open-source/features/metadata-filtering): Advanced filtering using custom metadata fields
- [Reranker Search](https://docs.mem0.ai/open-source/features/reranker-search): Enhanced search results with reranking models
- [Async Memory](https://docs.mem0.ai/open-source/features/async-memory): Asynchronous memory operations for better performance
- [Multimodal Support](https://docs.mem0.ai/open-source/features/multimodal-support): Handle text, images, and documents in self-hosted setup
- [Custom Fact Extraction](https://docs.mem0.ai/open-source/features/custom-fact-extraction-prompt): Tailor information extraction for specific use cases
- [Custom Instructions](https://docs.mem0.ai/open-source/features/custom-instructions): Tailor information extraction for specific use cases
- [Custom Memory Update Prompt](https://docs.mem0.ai/open-source/features/custom-update-memory-prompt): Customize how memories are updated and merged
- [REST API Server](https://docs.mem0.ai/open-source/features/rest-api): FastAPI-based server with core operations and OpenAPI documentation
- [OpenAI Compatibility](https://docs.mem0.ai/open-source/features/openai_compatibility): Seamless integration with OpenAI-compatible APIs
@@ -245,9 +243,7 @@ Key differentiators:
- [LlamaIndex Multiagent](https://docs.mem0.ai/cookbooks/frameworks/llamaindex-multiagent): Multi-agent systems with shared memory
- [Multimodal Retrieval](https://docs.mem0.ai/cookbooks/frameworks/multimodal-retrieval): Memory systems handling text, images, and documents
- [Eliza OS Character](https://docs.mem0.ai/cookbooks/frameworks/eliza-os-character): Character-based AI with persistent personality
- [Chrome Extension](https://docs.mem0.ai/cookbooks/frameworks/chrome-extension): Browser extensions that remember user interactions
- [Gemini with Mem0 MCP](https://docs.mem0.ai/cookbooks/frameworks/gemini-3-with-mem0-mcp): Google Gemini integration using MCP server
- [Mirofish Swarm Memory](https://docs.mem0.ai/cookbooks/frameworks/mirofish-swarm-memory): Swarm-based multi-agent memory patterns
## API Reference
+2 -2
View File
@@ -319,7 +319,7 @@ config = {
"graph_store": {...},
"version": "v1.0", # ❌ v1.0 no longer supported
"history_db_path": "...",
"custom_fact_extraction_prompt": "..."
"custom_instructions": "..."
}
```
@@ -336,7 +336,7 @@ config = {
},
"version": "v1.1", # ✅ v1.1+ only
"history_db_path": "...",
"custom_fact_extraction_prompt": "...",
"custom_instructions": "...",
"custom_update_memory_prompt": "..." # ✅ NEW: Custom update prompt
}
```
-383
View File
@@ -1,383 +0,0 @@
---
title: Breaking Changes in v1.0.0
description: 'Complete list of breaking changes when upgrading from v0.x to v1.0.0 '
icon: "triangle-exclamation"
iconType: "solid"
---
<Warning>
**Important:** This page lists all breaking changes. Please review carefully before upgrading.
</Warning>
## API Version Changes
### Removed v1.0 API Support
**Breaking Change:** The v1.0 API format is completely removed and no longer supported.
#### Before (v0.x)
```python
# This was supported in v0.x
config = {
"version": "v1.0" # ❌ No longer supported
}
result = m.add(
"memory content",
user_id="alice"
)
```
#### After (v1.0.0 )
```python
# v1.1 is the minimum supported version
config = {
"version": "v1.1" # ✅ Required minimum
}
result = m.add(
"memory content",
user_id="alice"
)
```
**Error Message:**
```
ValueError: The v1.0 API format is no longer supported in mem0ai 1.0.0+.
Please use v1.1 format which returns a dict with 'results' key.
```
## Parameter Removals
### 1. version Parameter in Method Calls
**Breaking Change:** Version parameter removed from method calls.
#### Before (v0.x)
```python
result = m.add("content", user_id="alice", version="v1.0")
```
#### After (v1.0.0 )
```python
result = m.add("content", user_id="alice")
```
### 2. async_mode Parameter (Platform Client)
**Change:** For `MemoryClient` (Platform API), `async_mode` now defaults to `True` but can still be configured.
#### Before (v0.x)
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-key")
result = client.add("content", user_id="alice", async_mode=True)
result = client.add("content", user_id="alice", async_mode=False)
```
#### After (v1.0.0 )
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-key")
# async_mode now defaults to True, but you can still override it
result = client.add("content", user_id="alice") # Uses async_mode=True by default
# You can still explicitly set it to False if needed
result = client.add("content", user_id="alice", async_mode=False)
```
## Response Format Changes
### Standardized Response Structure
**Breaking Change:** All responses now return a standardized dictionary format.
#### Before (v0.x)
```python
# Could return different formats based on version configuration
result = m.add("content", user_id="alice")
# With v1.0: Returns [{"id": "...", "memory": "...", "event": "ADD"}]
# With v1.1: Returns {"results": [{"id": "...", "memory": "...", "event": "ADD"}]}
```
#### After (v1.0.0 )
```python
# Always returns standardized format
result = m.add("content", user_id="alice")
# Always returns: {"results": [{"id": "...", "memory": "...", "event": "ADD"}]}
# Access results consistently
for memory in result["results"]:
print(memory["memory"])
```
## Configuration Changes
### Version Configuration
**Breaking Change:** Default API version changed.
#### Before (v0.x)
```python
# v1.0 was supported
config = {
"version": "v1.0" # ❌ No longer supported
}
```
#### After (v1.0.0 )
```python
# v1.1 is minimum, v1.1 is default
config = {
"version": "v1.1" # ✅ Minimum supported
}
# Or omit for default
config = {
# version defaults to v1.1
}
```
### Memory Configuration
**Breaking Change:** Some configuration options have changed defaults.
#### Before (v0.x)
```python
from mem0 import Memory
# Default configuration in v0.x
m = Memory() # Used default settings suitable for v0.x
```
#### After (v1.0.0 )
```python
from mem0 import Memory
# Default configuration optimized for v1.0.0
m = Memory() # Uses v1.1+ optimized defaults
# Explicit configuration recommended
config = {
"version": "v1.1",
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333
}
}
}
m = Memory.from_config(config)
```
## Method Signature Changes
### Search Method
**Enhanced but backward compatible:**
#### Before (v0.x)
```python
results = m.search(
"query",
user_id="alice",
filters={"key": "value"} # Simple key-value only
)
```
#### After (v1.0.0 )
```python
# Basic usage remains the same
results = m.search("query", user_id="alice")
# Enhanced filtering available (optional)
results = m.search(
"query",
user_id="alice",
filters={
"AND": [
{"key": "value"},
{"score": {"gte": 0.8}}
]
},
rerank=True # New parameter
)
```
## Error Handling Changes
### New Error Types
**Breaking Change:** More specific error types and messages.
#### Before (v0.x)
```python
try:
result = m.add("content", user_id="alice", version="v1.0")
except Exception as e:
print(f"Generic error: {e}")
```
#### After (v1.0.0 )
```python
try:
result = m.add("content", user_id="alice")
except ValueError as e:
if "v1.0 API format is no longer supported" in str(e):
# Handle version error specifically
print("Please upgrade your code to use v1.1+ format")
else:
print(f"Value error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
```
### Validation Changes
**Breaking Change:** Stricter parameter validation.
#### Before (v0.x)
```python
# Some invalid parameters might have been ignored
result = m.add(
"content",
user_id="alice",
invalid_param="ignored" # Might have been silently ignored
)
```
#### After (v1.0.0 )
```python
# Strict validation - unknown parameters cause errors
try:
result = m.add(
"content",
user_id="alice",
invalid_param="value" # ❌ Will raise TypeError
)
except TypeError as e:
print(f"Invalid parameter: {e}")
```
## Import Changes
### No Breaking Changes in Imports
**Good News:** Import statements remain the same.
```python
# These imports work in both v0.x and v1.0.0
from mem0 import Memory, AsyncMemory
from mem0 import MemoryConfig
```
## Dependency Changes
### Minimum Python Version
**Potential Breaking Change:** Check Python version requirements.
#### Before (v0.x)
- Python 3.8+ supported
#### After (v1.0.0 )
- Python 3.9+ required (check current requirements)
### Package Dependencies
**Breaking Change:** Some dependencies updated with potential breaking changes.
```bash
# Check for conflicts after upgrade
pip install --upgrade mem0ai
pip check # Verify no dependency conflicts
```
## Data Migration
### Database Schema
**Good News:** No database schema changes required.
- Existing memories remain compatible
- No data migration required
- Vector store data unchanged
### Memory Format
**Good News:** Memory storage format unchanged.
- Existing memories work with v1.0.0
- Search continues to work with old memories
- No re-indexing required
## Testing Changes
### Test Updates Required
**Breaking Change:** Update tests for new response format.
#### Before (v0.x)
```python
def test_add_memory():
result = m.add("content", user_id="alice")
assert isinstance(result, list) # ❌ No longer true
assert len(result) > 0
```
#### After (v1.0.0 )
```python
def test_add_memory():
result = m.add("content", user_id="alice")
assert isinstance(result, dict) # ✅ Always dict
assert "results" in result # ✅ Always has results key
assert len(result["results"]) > 0
```
## Rollback Considerations
### Safe Rollback Process
If you need to rollback:
```bash
# 1. Rollback package
pip install mem0ai==0.1.20 # Last stable v0.x
# 2. Revert code changes
git checkout previous_commit
# 3. Test functionality
python test_mem0_functionality.py
```
### Data Safety
- **Safe:** Memories stored in v0.x format work with v1.0.0
- **Safe:** Rollback doesn't lose data
- **Safe:** Vector store data remains intact
## Next Steps
1. **Review all breaking changes** in your codebase
2. **Update method calls** to remove deprecated parameters
3. **Update response handling** to use standardized format
4. **Test thoroughly** with your existing data
5. **Update error handling** for new error types
<CardGroup cols={2}>
<Card title="Migration Guide" icon="arrow-right" href="/migration/v0-to-v1">
Step-by-step migration instructions
</Card>
<Card title="API Changes" icon="code" href="/migration/api-changes">
Complete API reference changes
</Card>
</CardGroup>
<Warning>
**Need Help?** If you encounter issues during migration, check our [GitHub Discussions](https://github.com/mem0ai/mem0/discussions) or community support channels.
</Warning>
+12 -8
View File
@@ -28,7 +28,7 @@ Move your Mem0 implementation to managed infrastructure with enterprise features
## Plan
1. **Sign up**: Create an account on [Mem0 Platform](https://app.mem0.ai).
1. **Sign up**: Create an account on <a href="https://app.mem0.ai" rel="nofollow">Mem0 Platform</a>.
2. **Get API Key**: Navigate to **Settings > API Keys** and generate a new key.
3. **Review Usage**: Identify where you instantiate `Memory` and where you call `search` or `get_all`.
@@ -81,6 +81,10 @@ client = MemoryClient(api_key="m0-...")
**Critical Change**: Platform uses v2 endpoints that require filtering parameters to be nested inside a `filters` dictionary.
</Warning>
<Note>
The `limit` parameter has been removed in favor of `top_k` across all SDKs. Update any code using `limit=` to use `top_k=` instead.
</Note>
| Method | Open Source | Platform |
| ------ | ----------- | -------- |
| `search()` | `m.search(query, user_id="alex")` | `client.search(query, filters={"user_id": "alex"})` |
@@ -121,18 +125,18 @@ Note: `add()` and `delete()` methods remain unchanged. The `update()` method is
<CodeGroup>
```python Open Source (Old)
# Get all memories for a user
memories = m.get_all(user_id="alex", limit=10)
memories = m.get_all(user_id="alex", top_k=10)
# Get memories with pagination
memories = m.get_all(user_id="alex", limit=5, offset=10)
memories = m.get_all(user_id="alex", top_k=5, offset=10)
```
```python Platform (New)
# Get all memories for a user
memories = client.get_all(filters={"user_id": "alex"}, limit=10)
memories = client.get_all(filters={"user_id": "alex"}, top_k=10)
# Get memories with pagination
memories = client.get_all(filters={"user_id": "alex"}, limit=5, offset=10)
memories = client.get_all(filters={"user_id": "alex"}, top_k=5, offset=10)
```
</CodeGroup>
</Accordion>
@@ -283,7 +287,7 @@ The Platform introduces powerful capabilities not available in OSS:
"user preferences",
filters={"user_id": "alex"},
rerank=True, # Platform exclusive
limit=5
top_k=5
)
# Search with keyword expansion
@@ -335,7 +339,7 @@ The Platform introduces powerful capabilities not available in OSS:
{"timestamp": {"gte": "2024-01-01"}}
]
},
limit=100
top_k=100
)
# Monitor usage patterns
@@ -368,7 +372,7 @@ If you encounter issues, you can revert immediately by switching your import bac
## Next Steps
- [Platform Dashboard](https://app.mem0.ai) - Monitor usage and manage settings.
- <a href="https://app.mem0.ai" rel="nofollow">Platform Dashboard</a> - Monitor usage and manage settings.
- [Webhooks Setup](/platform/features/webhooks) - Configure real-time event notifications.
- [Organizations & Projects](/api-reference/organizations-projects) - Set up multi-tenancy for your team.
+538
View File
@@ -0,0 +1,538 @@
---
title: "Open Source: Migrating to the New Memory Algorithm"
description: "Guide for self-hosted Mem0 users to upgrade to the new memory algorithm with ADD-only extraction, hybrid search, and entity linking."
icon: "arrow-right"
iconType: "solid"
---
<Warning>
**Breaking changes ahead.** This release includes renamed parameters, removed parameters, changed defaults, and a fundamentally different extraction model. Read this guide before upgrading.
</Warning>
## Overview
The new Mem0 release redesigns both extraction and retrieval, and cleans up the SDK surface across Python and TypeScript:
- **Extraction**: Single-pass ADD-only (one LLM call, no UPDATE/DELETE)
- **Retrieval**: Multi-signal hybrid search (semantic + BM25 keyword + entity matching)
- **Entity linking**: Automatic entity extraction and cross-memory linking
- **SDK cleanup**: Deprecated parameters removed, naming conventions standardized
- **API surface aligned with Platform**: Entity IDs now follow the same convention across OSS and Platform — top-level kwargs for `add()` / `delete_all()`, inside `filters` for `search()` / `get_all()`
These changes produce a **+20 point improvement on LoCoMo** (71.4 → 91.6) and **+26 point improvement on LongMemEval** (67.8 → 93.4), while cutting extraction latency roughly in half.
## Breaking Changes
### Python Open Source
| Change | Old | New | Migration |
|---|---|---|---|
| `search()` / `get_all()` entity IDs | Top-level kwargs (`user_id="..."`) | Inside `filters` dict | `m.search("q", filters={"user_id": "..."})` — top-level kwargs now raise `ValueError` |
| `top_k` default | `100` | `20` | Pass `top_k=100` explicitly to restore |
| `threshold` default | `None` (no filtering) | `0.1` (filters low-relevance) | Pass `threshold=0.0` for old behavior |
| `threshold` validation | Any float | Must be in `[0, 1]` | Out-of-range values now raise `ValueError` |
| `rerank` default | `True` | `False` | Pass `rerank=True` to restore |
| Entity ID validation | Accepted any string | Trimmed; empty / whitespace-only rejected (`ValueError`) | Pass a non-empty identifier without internal spaces |
| `messages` in `add()` | Could be `None` | Must be `str` / `dict` / `list[dict]` — other types raise `Mem0ValidationError` (code `VALIDATION_003`) | Always pass a string, dict, or list of messages |
| `add()` events | Returns `ADD`, `UPDATE`, `DELETE` | Returns `ADD` only | Update code expecting UPDATE/DELETE |
| Custom extraction prompt | `custom_fact_extraction_prompt` | `custom_instructions` | Rename in config |
| Custom update prompt | `custom_update_memory_prompt` | Deprecated | Use `custom_instructions` instead |
| Graph memory | `enable_graph` + `graph_store` in config | Removed | Graph store support has been removed entirely |
| Qdrant client | `>=1.9.1` | `>=1.12.0` | Update dependency |
| Upstash client | `>=0.1.0` | `>=0.6.0` | Update dependency |
### TypeScript Open Source
| Change | Old | New | Migration |
|---|---|---|---|
| Search parameter | `search(query, { limit: 10 })` | `search(query, { topK: 10 })` | Rename `limit` → `topK` |
| `topK` default | `100` | `20` | Pass `topK: 100` explicitly to restore |
| `search()` / `getAll()` entity IDs | Top-level options (`userId: "..."`) | Inside `filters` object | `m.search("q", { filters: { userId: "..." } })` |
| `threshold` validation | Any number | Must be in `[0, 1]` | Out-of-range values now throw |
| Entity ID validation | Any string | Trimmed; empty / whitespace-only rejected | Pass non-empty identifiers without internal spaces |
| `messages` in `add()` | Could be `null` / `undefined` | Required — throws on null/undefined | Always pass a string or array |
| Payload key for lemmatized text | `text_lemmatized` (snake_case) | `textLemmatized` (camelCase) | TS-only internal field. If you share a vector store collection between Python and TS SDKs, lemma-based BM25 will not resolve across languages — keep collections language-scoped. |
| Custom prompt | `customPrompt` | `customInstructions` | Rename in config |
| Graph memory | `enableGraph` + `graphStore` in config | Removed | Graph store support has been removed entirely |
| Default graph config | Neo4j default config applied | No default graph config | Graph store config is no longer used |
### Python Client SDK
| Change | Old | New | Migration |
|---|---|---|---|
| Constructor | `MemoryClient(api_key, org_id, project_id)` | `MemoryClient(api_key)` | Remove `org_id`, `project_id` from constructor |
| Method options | `client.add(messages, **kwargs)` | `client.add(messages, options=AddMemoryOptions(...))` | Use typed option classes (or `**kwargs` still works) |
| Removed params | `api_version`, `output_format`, `async_mode`, `filter_memories`, `expiration_date`, `keyword_search`, `force_add_only`, `batch_size`, `immutable`, `includes`, `excludes`, `enable_graph`, `org_name`, `project_name` | — | Remove from all calls |
### TypeScript Client SDK
| Change | Old | New | Migration |
|---|---|---|---|
| Constructor | `new MemoryClient({ apiKey, organizationId, projectId })` | `new MemoryClient({ apiKey })` | Remove `organizationId`, `projectId`, `organizationName`, `projectName` |
| All params | snake_case: `user_id`, `agent_id`, `top_k` | camelCase: `userId`, `agentId`, `topK` | Rename all params to camelCase |
| Removed params | `api_version`, `output_format`, `async_mode`, `enable_graph`, `org_id`, `project_id`, `org_name`, `project_name`, `filter_memories`, `batch_size`, `force_add_only`, `immutable`, `expiration_date`, `includes`, `excludes`, `keyword_search` | — | Remove from all calls |
| Output format enum | `OutputFormat.V1`, `OutputFormat.V1_1` | Removed | v1.1 is now always used |
| API version enum | `API_VERSION.V1`, `API_VERSION.V2` | Removed | Handled internally |
## Step-by-Step Migration
### 1. Update Installation
<Tabs>
<Tab title="Python">
```bash
# Basic upgrade
pip install --upgrade mem0ai
# For hybrid search + entity extraction (recommended)
pip install --upgrade "mem0ai[nlp]"
python -m spacy download en_core_web_sm
# Qdrant users: also install fastembed to enable BM25 keyword search
pip install fastembed
```
<Info>
**Supported Python versions for `[nlp]` extras: 3.10 – 3.12.** spaCy and its `blis` / `thinc` dependencies do not yet ship prebuilt wheels for Python 3.13, so installs on 3.13 will fail at build time. Use Python 3.12 (or older) for the `[nlp]` extras until upstream support lands. The base `mem0ai` package works on all supported Python versions; only the NLP extras are constrained.
</Info>
</Tab>
<Tab title="TypeScript">
```bash
npm install mem0ai@latest
```
</Tab>
</Tabs>
<Info>
The Python `[nlp]` extra installs [spaCy](https://spacy.io/) for entity extraction and keyword lemmatization. Without it, Mem0 still works but falls back to semantic-only search (no entity linking, no BM25 lemmatization).
</Info>
<Warning>
**Qdrant users — install `fastembed` to enable BM25 keyword search.** The Qdrant backend uses [fastembed](https://github.com/qdrant/fastembed) to encode sparse (BM25) vectors alongside dense vectors in the same collection. Without it, BM25 is silently disabled and search falls back to semantic-only — you'll see a log warning `"fastembed not installed — BM25 keyword search disabled"` on the first search call. Other vector stores use their native full-text capabilities and don't need `fastembed`.
```bash
pip install fastembed
```
</Warning>
### 2. Update Configuration
<Tabs>
<Tab title="Python OSS">
```python
# Before
config = {
"custom_fact_extraction_prompt": "Focus on user preferences", # [REMOVED] Renamed
"custom_update_memory_prompt": "Be concise when updating", # [REMOVED] Deprecated
"graph_store": {
"provider": "neo4j",
"config": { "url": "...", "username": "...", "password": "..." }
},
"enable_graph": True, # [REMOVED] Removed
}
# After
config = {
"custom_instructions": "Focus on user preferences", # [OK] New name
# custom_update_memory_prompt removed — use custom_instructions
# enable_graph and graph_store removed — graph store support has been removed
}
```
</Tab>
<Tab title="TypeScript OSS">
```typescript
// Before
const config = {
customPrompt: "Focus on user preferences", // [REMOVED] Renamed
enableGraph: true, // [REMOVED] Removed
graphStore: {
provider: "neo4j",
config: { url: "...", username: "...", password: "..." }
}
};
// After
const config = {
customInstructions: "Focus on user preferences", // [OK] New name
// enableGraph and graphStore removed — graph store support has been removed
};
```
</Tab>
</Tabs>
### 3. Update Search Calls
<Tabs>
<Tab title="Python OSS">
```python
# Before — entity IDs as top-level kwargs
results = m.search(
"what meetings did I attend?",
user_id="alice",
top_k=20
)
for r in results:
print(r["score"]) # Was raw cosine similarity
# After — entity IDs go inside `filters` (matches Platform API)
results = m.search(
"what meetings did I attend?",
filters={"user_id": "alice"}, # [REMOVED top-level kwarg, use filters]
top_k=20, # New default is 20 (was 100)
threshold=0.1, # New default (pass 0.0 to disable)
rerank=False # New default (pass True to restore)
)
for r in results:
print(r["score"])
```
<Warning>
Passing `user_id`, `agent_id`, or `run_id` as a top-level kwarg to `search()` or `get_all()` now raises `ValueError`. They must be inside the `filters` dict. The change aligns the OSS SDK with the Platform API contract.
</Warning>
</Tab>
<Tab title="TypeScript OSS">
```typescript
// Before — entity IDs as top-level options
const results = await m.search("what meetings did I attend?", {
userId: "alice",
limit: 20 // [REMOVED] Renamed to 'topK' for consistency
});
// After — entity IDs go inside `filters` (matches Platform API)
const results = await m.search("what meetings did I attend?", {
filters: { userId: "alice" }, // [REMOVED top-level option, use filters]
topK: 20 // [OK] Renamed from 'limit'
});
```
</Tab>
<Tab title="Python Client SDK">
```python
from mem0 import MemoryClient
from mem0.client.types import SearchMemoryOptions
# Before
client = MemoryClient(api_key="...", org_id="org-1", project_id="proj-1")
results = client.search("query", user_id="alice", top_k=20, enable_graph=True)
# After
client = MemoryClient(api_key="...") # org_id, project_id removed
results = client.search(
"query",
options=SearchMemoryOptions(
filters={"user_id": "alice"},
top_k=20
)
)
```
</Tab>
<Tab title="TypeScript Client SDK">
```typescript
// Before
const client = new MemoryClient({
apiKey: "...",
organizationId: "org-1", // [REMOVED] Removed
projectId: "proj-1" // [REMOVED] Removed
});
const results = await client.search("query", {
user_id: "alice", // [REMOVED] snake_case
top_k: 20, // [REMOVED] snake_case
enable_graph: true // [REMOVED] Removed
});
// After
const client = new MemoryClient({ apiKey: "..." });
const results = await client.search("query", {
filters: { userId: "alice" },
topK: 20
});
```
</Tab>
</Tabs>
### 4. Update Add Calls
<Tabs>
<Tab title="Python OSS">
```python
# Before — could return ADD, UPDATE, DELETE events
result = m.add("I love hiking and my dog's name is Max", user_id="alice")
for item in result["results"]:
if item["event"] == "ADD":
print("New memory:", item["memory"])
elif item["event"] == "UPDATE":
print("Updated:", item["memory"]) # [REMOVED] No longer returned
elif item["event"] == "DELETE":
print("Deleted:", item["memory"]) # [REMOVED] No longer returned
# After — only ADD events
result = m.add("I love hiking and my dog's name is Max", user_id="alice")
for item in result["results"]:
print("New memory:", item["memory"]) # Only ADD events
```
</Tab>
<Tab title="Python Client SDK">
```python
from mem0.client.types import AddMemoryOptions
# Before
client.add(messages, user_id="alice", async_mode=True, output_format="v1.1")
# After — async_mode and output_format removed (async by default, v1.1 always)
client.add(
messages,
options=AddMemoryOptions(user_id="alice")
)
# Or using **kwargs
client.add(messages, user_id="alice")
```
</Tab>
<Tab title="TypeScript Client SDK">
```typescript
// Before
await client.add(messages, {
user_id: "alice", // [REMOVED] snake_case
async_mode: true, // [REMOVED] Removed
output_format: "v1.1", // [REMOVED] Removed
enable_graph: true // [REMOVED] Removed
});
// After
await client.add(messages, {
userId: "alice" // [OK] camelCase
});
```
</Tab>
</Tabs>
<Tip>
The ADD-only model means memories accumulate over time. When information changes, the new fact is stored alongside the old one. Retrieval handles ranking — the most relevant, current information surfaces first.
</Tip>
### 5. Update Vector Store Dependencies
If you're using Qdrant or Upstash, update your client libraries:
```bash
# Qdrant users
pip install "qdrant-client>=1.12.0"
# Upstash users
pip install "upstash-vector>=0.6.0"
```
### 6. Entity Store Setup
The new algorithm automatically creates a parallel entity store collection named `{your_collection}_entities`. No manual setup is required — it's created on first use.
<Warning>
Make sure your vector store user/credentials have permission to create new collections. If you're using a managed vector database with restricted permissions, pre-create the `{collection_name}_entities` collection with the same embedding dimensions as your main collection.
</Warning>
## Graph Memory → Entity Linking
Graph store support has been removed from the open-source SDK. It is replaced by **built-in entity linking**, which runs natively with no external dependencies.
**What was removed:**
- `enable_graph` / `enableGraph` config flag
- `graph_store` / `graphStore` configuration block (Neo4j, Memgraph, Kuzu, Apache AGE, Neptune)
- All graph memory code paths (~4000 lines)
**What replaces it:**
Entity linking extracts entities (proper nouns, quoted text, compound noun phrases) from every memory during the add pipeline and stores them in a parallel collection (`{collection}_entities`) inside your existing vector store. At search time, entities from the query are matched against this collection and used to boost relevant memories. The boost is folded into the combined `score` on each result.
**Migration:**
- Remove `enable_graph` / `enableGraph` from your config
- Remove the `graph_store` / `graphStore` block — it is no longer read
- Uninstall graph drivers (neo4j, memgraph, etc.) if you were using them only for Mem0
- No data migration is required. Entity linking activates automatically on the next `add()` call.
<Warning>
Graph relationships exposed via the old `relations` field on search results are no longer populated. Entity relationships are consumed indirectly through retrieval ranking, not exposed as a queryable graph structure. If your application depended on traversing graph relationships directly, you will need to redesign that part against the new API.
</Warning>
## How the New Algorithm Works
### Extraction: Single-Pass ADD-Only
```
Input conversation
→ Retrieve top-10 related existing memories (for deduplication context)
→ Single LLM call: extract all distinct new facts
→ Batch embed extracted memories
→ Hash-based deduplication (MD5, prevents exact duplicates)
→ Batch insert into vector store
→ Entity extraction + linking
```
The previous algorithm used two LLM calls — one to extract candidate facts, one to decide ADD/UPDATE/DELETE actions against existing memories. The new algorithm collapses this into a single call that only adds. The model spends its capacity on understanding the input rather than diffing against existing state.
### Retrieval: Multi-Signal Hybrid Search
```
Query
→ Preprocess (lemmatize keywords, extract entities)
→ Parallel scoring:
1. Semantic search (vector similarity)
2. BM25 keyword search (normalized term matching)
3. Entity matching (entity graph boost)
→ Score fusion → Top-K selection
```
**Scoring:** The three signals are normalized and fused into a single combined `score` per result. The fusion adapts based on which signals are available at runtime (semantic-only, semantic + BM25, or all three when spaCy + the entity store are active).
**BM25 is a boost signal, not a recall expander.** Only semantic search results are candidates — BM25 and entity scores boost ranking but don't add new candidates.
## Vector Store Compatibility
All 15 supported vector stores have been enhanced with two new capabilities:
| Capability | Purpose | Fallback if Unsupported |
|---|---|---|
| `keyword_search()` | BM25/full-text keyword matching | Falls back to semantic-only search |
| `search_batch()` | Batch search for entity matching | Falls back to sequential search |
**Qdrant-specific changes:**
- Now uses sparse vectors (BM25) alongside dense vectors in the same collection
- Requires `fastembed` library for BM25 encoding (lazy-loaded, gracefully degrades)
- Install: `pip install fastembed`
**All other vector stores:**
- Enhanced with `keyword_search()` methods using their native full-text capabilities
- No additional dependencies required
## Graceful Degradation
The new features degrade gracefully when optional dependencies are missing:
| Missing Dependency | Impact | Search Still Works? |
|---|---|---|
| spaCy (`mem0ai[nlp]`) | No entity extraction, no BM25 lemmatization | Yes (semantic-only) |
| `fastembed` (Qdrant) | No BM25 keyword search | Yes (semantic + entity) |
| Entity store unavailable | No entity boosting | Yes (semantic + BM25) |
You always get semantic search. Hybrid search features layer on top when available.
## Removed Parameters Reference
These parameters have been removed across all SDKs. Remove them from your code:
### Python Client SDK — Removed parameters
**Constructor:** `org_id`, `project_id`
**All methods:** `api_version`, `output_format`, `async_mode`, `org_name`, `project_name`, `org_id`, `project_id`
**add():** `enable_graph`, `immutable`, `expiration_date`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`
**search():** `enable_graph`
**get_all():** `enable_graph`
**project.update():** `enable_graph`
### TypeScript Client SDK — Removed parameters
**Constructor:** `organizationId`, `projectId`, `organizationName`, `projectName`
**All methods:** `OutputFormat` enum, `API_VERSION` enum
**add():** `enable_graph` / `enableGraph`, `async_mode` / `asyncMode`, `output_format` / `outputFormat`, `immutable`, `expiration_date` / `expirationDate`, `filter_memories` / `filterMemories`, `batch_size` / `batchSize`, `force_add_only` / `forceAddOnly`, `includes`, `excludes`, `keyword_search` / `keywordSearch`
**search():** `enable_graph` / `enableGraph`
**get_all():** `enable_graph` / `enableGraph`
### Python OSS — Removed/renamed parameters
**Config:** `custom_fact_extraction_prompt` → renamed to `custom_instructions`
**Config:** `custom_update_memory_prompt` → deprecated, use `custom_instructions`
**Config:** `enable_graph` + `graph_store` → removed (graph store support removed entirely)
### TypeScript OSS — Removed/renamed parameters
**Config:** `customPrompt` → renamed to `customInstructions`
**Config:** `enableGraph` + `graphStore` → removed (graph store support removed entirely)
**search():** `limit` → renamed to `topK`
## Common Issues
### TypeScript: `limit` is not a valid parameter
The `limit` parameter has been renamed to `topK` in the TypeScript OSS:
```typescript
// Before
const results = await m.search("query", { userId: "alice", limit: 20 });
// After
const results = await m.search("query", { filters: { userId: "alice" }, topK: 20 });
```
### TypeScript Client: snake_case params no longer work
All TypeScript Client SDK parameters now use camelCase. The SDK handles conversion to/from the API automatically:
```typescript
// Before
await client.search("query", { user_id: "alice", top_k: 20 });
// After
await client.search("query", { filters: { userId: "alice" }, topK: 20 });
```
### `ValueError: Top-level entity parameters not supported in search() / get_all()`
`search()` and `get_all()` now require entity IDs inside `filters`. Top-level kwargs raise `ValueError`. This aligns the OSS SDK with the Platform API.
```python
# Before
results = m.search("query", user_id="alice", top_k=20)
# After
results = m.search("query", filters={"user_id": "alice"}, top_k=20)
```
`add()` and `delete_all()` continue to accept entity IDs as top-level kwargs.
### Search returns fewer results than before
The default `threshold` changed from `None` to `0.1`. Low-relevance results that were previously included are now filtered out. To restore the old behavior:
```python
results = m.search("query", filters={"user_id": "alice"}, threshold=0.0)
```
### spaCy model not found
If you see errors about missing spaCy models, download the required model:
```bash
python -m spacy download en_core_web_sm
```
If spaCy is not installed at all, install the NLP extras:
```bash
pip install "mem0ai[nlp]"
```
### Entity store collection creation fails
The entity store tries to create a `{collection_name}_entities` collection automatically. If your vector database has restricted permissions, pre-create this collection with the same embedding dimensions as your main collection.
### Score values are different from before
The top-level `score` still ranges `[0, 1]`, but it is computed differently in v3. Relative ranking between results stays comparable, but absolute numbers shift — retune any hard thresholds in your app against representative queries.
If you need the raw cosine similarity for a specific use case, run an unboosted vector query directly against your vector store via `vector_store.search(...)`.
## Need Help?
- Join our [Discord community](https://mem0.ai/discord) for real-time support
- Open an issue on [GitHub](https://github.com/mem0ai/mem0/issues)
- Check the [evaluation docs](/core-concepts/memory-evaluation) to benchmark the new algorithm on your data
+328
View File
@@ -0,0 +1,328 @@
---
title: "Platform: Migrating to the New Memory Algorithm"
description: "Guide for Mem0 Platform users to adopt the new memory algorithm with single-pass extraction, entity linking, and multi-signal retrieval."
icon: "arrow-right"
iconType: "solid"
---
<Info>
**No action required for most users.** The new algorithm is rolling out automatically to all Mem0 Platform projects. This guide covers what changed, what to expect, and how to take full advantage of the new capabilities.
</Info>
## Overview
The new Mem0 memory algorithm is a ground-up redesign of how memories are extracted, stored, and retrieved. It scores **91.6 on LoCoMo** and **93.4 on LongMemEval** — a +20 and +26 point improvement over the previous algorithm — while cutting extraction latency roughly in half.
| What Changed | Before | After |
|---|---|---|
| **Extraction** | Two LLM passes (extract + merge) | Single-pass ADD-only (one LLM call) |
| **Memory mutations** | ADD, UPDATE, DELETE | ADD only — nothing is overwritten or deleted |
| **Agent-generated facts** | Often ignored | First-class, stored with equal weight |
| **Entity linking** | Not available | Entities extracted and linked across memories |
| **Graph memory** | Separate graph store + dashboard visualization | Replaced by built-in entity linking, no graph visuals on platform dashboard |
| **Retrieval** | Semantic (vector) only | Hybrid retrieval combining multiple signals |
## What This Means for Your Application
### Memories accumulate instead of being overwritten
The previous algorithm could UPDATE or DELETE existing memories during extraction. The new algorithm only adds new facts. When information changes (e.g., a user moves from New York to San Francisco), both facts are preserved with temporal context. This means:
- **More memories over time** — your memory count will grow rather than plateau
- **Better temporal reasoning** — the system can distinguish "used to live in New York" from "now lives in San Francisco"
- **No information loss** — facts that seemed contradictory but were actually complementary are preserved
<Tip>
If your application previously relied on UPDATE/DELETE behavior to keep memory counts low, the new algorithm handles this at retrieval time instead. Multi-signal retrieval ranks the most relevant, current information higher without destroying historical context.
</Tip>
### Agent-generated facts are now captured
Previously, when an agent said something like "I've booked your flight for March 3rd," the system would often ignore it and only store what the user explicitly stated. The new algorithm treats agent-generated facts as first-class memories. If your application involves agents that confirm actions, provide recommendations, or share information, you'll see significantly better recall on those interactions.
### Retrieval is hybrid now
Search now uses hybrid retrieval, which improves ranking quality — especially for queries involving exact keywords, proper nouns, or entities that appear across multiple memories. The response shape is unchanged:
```json
{
"results": [
{
"id": "mem-uuid",
"memory": "User moved to San Francisco in January 2026",
"score": 0.82,
"metadata": {},
"categories": ["location"]
}
]
}
```
The top-level `score` remains a `[0, 1]` value. Relative ranking between results stays comparable to v2, but absolute numbers shift since the scoring method changed — retune any hard thresholds in your app against representative queries.
## API Changes
### New V3 Endpoints
The new algorithm is available through the V3 API. The endpoints split into per-operation paths:
| Operation | SDK method | Endpoint |
|---|---|---|
| Add memories | `client.add()` | `POST /v3/memories/add/` |
| Search memories | `client.search()` | `POST /v3/memories/search/` |
| Get all memories (paginated) | `client.get_all()` | `POST /v3/memories/` |
<Info>
`get_all` / list now returns a paginated envelope: `{"count": int, "next": str | null, "previous": str | null, "results": [...]}`. Pass `page` and `page_size` as query params to paginate; defaults return the first page.
</Info>
<CodeGroup>
```python Python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-api-key")
# Add memories (same interface, improved extraction)
result = client.add(
messages=[
{"role": "user", "content": "I just moved to San Francisco from New York"},
{"role": "assistant", "content": "That's exciting! I'll update your location preferences."}
],
user_id="alice"
)
# Search with multi-signal retrieval
results = client.search(
query="where does the user live?",
filters={"user_id": "alice"}
)
# List memories (paginated)
page = client.get_all(filters={"user_id": "alice"}, page=1, page_size=50)
# page == {"count": 123, "next": "...", "previous": None, "results": [...]}
```
```bash cURL
# Add memories
curl -X POST https://api.mem0.ai/v3/memories/add/ \
-H "Authorization: Token your-api-key" \
-H "Content-Type: application/json" \
-d '{
"messages": [
{"role": "user", "content": "I just moved to San Francisco from New York"},
{"role": "assistant", "content": "That'\''s exciting! I'\''ll update your location preferences."}
],
"user_id": "alice"
}'
# Search memories
curl -X POST https://api.mem0.ai/v3/memories/search/ \
-H "Authorization: Token your-api-key" \
-H "Content-Type: application/json" \
-d '{
"query": "where does the user live?",
"filters": {"user_id": "alice"}
}'
# List memories (paginated)
curl -X POST 'https://api.mem0.ai/v3/memories/?page=1&page_size=50' \
-H "Authorization: Token your-api-key" \
-H "Content-Type: application/json" \
-d '{"filters": {"user_id": "alice"}}'
```
</CodeGroup>
### Search Parameter Changes
| Parameter | V1/V2 | V3 | Notes |
|---|---|---|---|
| `top_k` | Supported | Supported (1-1000, default 10) | No change |
| `threshold` | Default: none | Default: `0.1` | Pass `0.0` to disable |
| `rerank` | Default: `true` | Default: `false` | Pass `true` to enable (adds latency) |
| Entity IDs in `search` / `get_all` | Top-level | Inside `filters` dict | Top-level raises 400 |
### Response Format
**Add response** — asynchronous, returns an `event_id` for polling:
```json
{
"message": "Memory processing has been queued for background execution",
"status": "PENDING",
"event_id": "evt-uuid"
}
```
Poll status via `GET /v1/event/{event_id}/` — status will be `SUCCEEDED` or `FAILED`.
**Search response** — combined multi-signal score per result:
```json
{
"results": [
{
"id": "mem-uuid",
"memory": "User moved to San Francisco from New York in January 2026",
"score": 0.82,
"metadata": {},
"categories": ["location"],
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-01-15T10:30:00Z"
}
]
}
```
**List response** — paginated envelope (new in V3):
```json
{
"count": 123,
"next": "https://api.mem0.ai/v3/memories/?page=2&page_size=50",
"previous": null,
"results": [
{
"id": "mem-uuid",
"memory": "...",
"metadata": {},
"categories": [],
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-01-15T10:30:00Z"
}
]
}
```
## SDK Breaking Changes
Alongside the algorithm update, the Python and TypeScript client SDKs have been cleaned up. These changes affect how you initialize and call the client.
### Python Client SDK
```python
from mem0 import MemoryClient
# Before
client = MemoryClient(
api_key="...",
org_id="org-1", # [REMOVED] Removed
project_id="proj-1" # [REMOVED] Removed
)
client.add(messages, user_id="alice", async_mode=True, output_format="v1.1")
# After
client = MemoryClient(api_key="...")
client.add(messages, user_id="alice")
# async_mode and output_format removed (async by default, v1.1 always)
```
**Removed parameters:** `org_id`, `project_id`, `api_version`, `output_format`, `async_mode`, `enable_graph`, `immutable`, `expiration_date`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`, `org_name`, `project_name`
### TypeScript Client SDK
All parameters now use **camelCase** (the SDK handles conversion to/from the API automatically):
```typescript
// Before
const client = new MemoryClient({
apiKey: "...",
organizationId: "org-1", // [REMOVED] Removed
projectId: "proj-1" // [REMOVED] Removed
});
await client.search("query", {
user_id: "alice", // [REMOVED] snake_case
top_k: 20, // [REMOVED] snake_case
enable_graph: true // [REMOVED] Removed
});
// After
const client = new MemoryClient({ apiKey: "..." });
await client.search("query", {
filters: { userId: "alice" }, // [OK] inside filters
topK: 20 // [OK] camelCase
});
```
**Removed:** `OutputFormat` enum, `API_VERSION` enum, `organizationId`, `projectId`, `organizationName`, `projectName`, `enableGraph`, `asyncMode`, `outputFormat`, `immutable`, `expirationDate`, `filterMemories`, `batchSize`, `forceAddOnly`, `includes`, `excludes`, `keywordSearch`
<Info>
For the full list of parameter changes across all SDKs, see the [OSS migration guide](/migration/oss-v2-to-v3#removed-parameters-reference).
</Info>
## Graph Memory → Entity Linking
Graph memory has been replaced by **built-in entity linking**. The changes:
- **Graph visualizations removed from the platform dashboard.** The graph view in your project dashboard is no longer available.
- **`enable_graph` project setting removed.** The toggle is gone from the dashboard; the API parameter is ignored.
- **No external graph store to configure.** Previously graph memory required a separate Neo4j (or similar) deployment. Entity linking runs natively inside the platform — nothing to provision, no connection strings to manage.
- **Entity linking is the native replacement.** Entities (proper nouns, quoted text, compound noun phrases) are automatically extracted from every memory and linked across memories belonging to the same user. At search time, entities from the query are matched against this index and used to boost ranking. The boost is folded into the combined `score` returned on each result.
**No migration work is required.** Entity linking activates automatically for all projects on the new algorithm. Existing memories are not re-processed, but any new memories you add will be indexed for entity-based retrieval going forward.
<Note>
If your application previously read graph relations from the API response (`relations` field on search results), note that this field is no longer populated. Entity relationships are now consumed indirectly through retrieval ranking, not exposed as a separate graph structure.
</Note>
## Migration Checklist
<Steps>
<Step title="Review your search thresholds">
The default `threshold` is now `0.1` (previously no threshold). If your application was relying on unfiltered results, explicitly pass `threshold=0.0` in your search calls to preserve the old behavior. In most cases, the new default is better — it filters out low-relevance noise.
</Step>
<Step title="Review reranking usage">
Reranking is now `false` by default. If your application depended on reranked results, add `rerank=True` to your search calls. Note that reranking adds latency (~200-400ms) but can improve ordering quality for complex queries.
</Step>
<Step title="Update score handling (optional)">
The top-level `score` field continues to work as before. It is now a combined multi-signal score (semantic + keyword + entity) rather than pure cosine similarity, so the absolute numbers will differ. Relative ranking remains comparable — if you have threshold-based filtering in your app, retune on a representative query set.
</Step>
<Step title="Adjust memory count expectations">
With ADD-only extraction, memory counts will grow over time rather than being consolidated. This is by design — retrieval handles relevance ranking. If you have hard limits on memory count, consider using the memory expiration feature or periodic cleanup.
</Step>
<Step title="Test with representative queries">
The biggest improvements are in temporal reasoning (+29.6 on LoCoMo), multi-hop queries (+23.1), and assistant memory recall (+53.6 on LongMemEval). Test queries in these categories to see the improvement.
</Step>
</Steps>
## Backward Compatibility
- **V1 and V2 endpoints continue to work.** There is no requirement to migrate to V3 endpoints immediately.
- **Existing memories are preserved.** The new algorithm does not modify or re-process previously stored memories.
- **Search response shape is unchanged.** The top-level `score` and `results[]` array are the same; existing code that reads `score` continues to work. What changed is the scoring method behind the number (multi-signal fusion instead of pure cosine), so the absolute values shift even when ranking stays comparable.
- **List response shape changed.** `get_all` now returns a paginated envelope (`{count, next, previous, results}`) instead of a bare `{results: [...]}`. Update code that reads `response["results"]` to continue working, or switch to the client SDKs which handle both shapes.
## Performance Improvements
| Metric | Previous Algorithm | New Algorithm |
|---|---|---|
| **LoCoMo Overall** | 71.4 | **91.6** (+20.2) |
| **LongMemEval Overall** | 67.8 | **93.4** (+25.6) |
| **Extraction latency (p50)** | ~2.0s | **~1.0s** |
| **Mean tokens per query** | — | 6.8-7.0K (top200) |
All benchmarks were run on a production-representative stack — deliberately avoiding frontier models to keep numbers representative of real production workloads.
## FAQ
<AccordionGroup>
<Accordion title="Do I need to re-process my existing memories?">
No. Existing memories remain as-is. New memories added after the rollout will use the new extraction algorithm. Both old and new memories are searchable through the same retrieval pipeline.
</Accordion>
<Accordion title="Will my memory count increase faster now?">
Yes. The ADD-only approach means memories accumulate rather than being consolidated. This is intentional — the retrieval system handles ranking and relevance. If you need to manage memory volume, use the expiration date feature or the delete API.
</Accordion>
<Accordion title="Can I opt out of the new algorithm?">
The new algorithm is the default for all platform users. If you have a specific need to use the previous extraction behavior, contact support.
</Accordion>
<Accordion title="How does entity linking affect my existing integrations?">
Entity linking is automatic and transparent. It improves retrieval quality without requiring any changes to your integration. Entities are extracted from both new memories and search queries, and matched automatically.
</Accordion>
</AccordionGroup>
## Need Help?
If you run into issues during migration or have questions about the new algorithm:
- Join our [Discord community](https://mem0.ai/discord) for real-time support
- Email us at [support@mem0.ai](mailto:support@mem0.ai)
- Check the [API reference](/api-reference) for detailed endpoint documentation
-481
View File
@@ -1,481 +0,0 @@
---
title: Migrating from v0.x to v1.0.0
description: 'Complete guide to upgrade your Mem0 implementation to version 1.0.0 '
icon: "arrow-right"
iconType: "solid"
---
<Warning>
**Breaking Changes Ahead!** Mem0 1.0.0 introduces several breaking changes. Please read this guide carefully before upgrading.
</Warning>
## Overview
Mem0 1.0.0 is a major release that modernizes the API, improves performance, and adds powerful new features. This guide will help you migrate your existing v0.x implementation to the new version.
## Key Changes Summary
| Feature | v0.x | v1.0.0 | Migration Required |
|---------|------|-------------|-------------------|
| API Version | v1.0 supported | v1.0 **removed**, v1.1+ only | ✅ Yes |
| Async Mode (Platform Client) | Optional/manual | Defaults to `True`, configurable | ⚠️ Partial |
| Metadata Filtering | Basic | Enhanced with operators | ⚠️ Optional |
| Reranking | Not available | Full support | ⚠️ Optional |
## Step-by-Step Migration
### 1. Update Installation
```bash
# Update to the latest version
pip install --upgrade mem0ai
```
### 2. Remove Deprecated Parameters
#### Before (v0.x)
```python
from mem0 import Memory
# These parameters are no longer supported
m = Memory()
result = m.add(
"I love pizza",
user_id="alice",
version="v1.0" # ❌ REMOVED
)
```
#### After (v1.0.0 )
```python
from mem0 import Memory
# Clean, simplified API
m = Memory()
result = m.add(
"I love pizza",
user_id="alice"
# version parameter removed
)
```
### 3. Update Configuration
#### Before (v0.x)
```python
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333
}
},
"version": "v1.0" # ❌ No longer supported
}
m = Memory.from_config(config)
```
#### After (v1.0.0 )
```python
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333
}
},
"version": "v1.1" # ✅ v1.1 is the minimum supported version
}
m = Memory.from_config(config)
```
### 4. Handle Response Format Changes
#### Before (v0.x)
```python
# Response could be a list or dict depending on version
result = m.add("I love coffee", user_id="alice")
if isinstance(result, list):
# Handle list format
for item in result:
print(item["memory"])
else:
# Handle dict format
print(result["results"])
```
#### After (v1.0.0 )
```python
# Response is always a standardized dict with "results" key
result = m.add("I love coffee", user_id="alice")
# Always access via "results" key
for item in result["results"]:
print(item["memory"])
```
### 5. Update Search Operations
#### Before (v0.x)
```python
# Basic search
results = m.search("What do I like?", user_id="alice")
# With filters
results = m.search(
"What do I like?",
user_id="alice",
filters={"category": "food"}
)
```
#### After (v1.0.0 )
```python
# Same basic search API
results = m.search("What do I like?", user_id="alice")
# Enhanced filtering with operators (optional upgrade)
results = m.search(
"What do I like?",
user_id="alice",
filters={
"AND": [
{"category": "food"},
{"rating": {"gte": 8}}
]
}
)
# New: Reranking support (optional)
results = m.search(
"What do I like?",
user_id="alice",
rerank=True # Requires reranker configuration
)
```
### 6. Platform Client async_mode Default Changed
**Change:** For `MemoryClient`, the `async_mode` parameter now defaults to `True` for better performance.
#### Before (v0.x)
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-key")
# Had to explicitly set async_mode
result = client.add("I enjoy hiking", user_id="alice", async_mode=True)
```
#### After (v1.0.0 )
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-key")
# async_mode now defaults to True (best performance)
result = client.add("I enjoy hiking", user_id="alice")
# You can still override if needed for synchronous processing
result = client.add("I enjoy hiking", user_id="alice", async_mode=False)
```
## Configuration Migration
### Basic Configuration
#### Before (v0.x)
```python
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333
}
},
"llm": {
"provider": "openai",
"config": {
"model": "gpt-3.5-turbo",
"api_key": "your-key"
}
},
"version": "v1.0"
}
```
#### After (v1.0.0 )
```python
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333
}
},
"llm": {
"provider": "openai",
"config": {
"model": "gpt-3.5-turbo",
"api_key": "your-key"
}
},
"version": "v1.1", # Minimum supported version
# New optional features
"reranker": {
"provider": "cohere",
"config": {
"model": "rerank-english-v3.0",
"api_key": "your-cohere-key"
}
}
}
```
### Enhanced Features (Optional)
```python
# Take advantage of new features
config = {
"vector_store": {
"provider": "qdrant",
"config": {
"host": "localhost",
"port": 6333
}
},
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4",
"api_key": "your-key"
}
},
"embedder": {
"provider": "openai",
"config": {
"model": "text-embedding-3-small",
"api_key": "your-key"
}
},
"reranker": {
"provider": "sentence_transformer",
"config": {
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2"
}
},
"version": "v1.1"
}
```
## Error Handling Migration
### Before (v0.x)
```python
try:
result = m.add("memory", user_id="alice", version="v1.0")
except Exception as e:
print(f"Error: {e}")
```
### After (v1.0.0 )
```python
try:
result = m.add("memory", user_id="alice")
except ValueError as e:
if "v1.0 API format is no longer supported" in str(e):
print("Please upgrade your code to use v1.1+ format")
else:
print(f"Error: {e}")
except Exception as e:
print(f"Unexpected error: {e}")
```
## Testing Your Migration
### 1. Basic Functionality Test
```python
def test_basic_functionality():
m = Memory()
# Test add
result = m.add("I love testing", user_id="test_user")
assert "results" in result
assert len(result["results"]) > 0
# Test search
search_results = m.search("testing", user_id="test_user")
assert "results" in search_results
# Test get_all
all_memories = m.get_all(user_id="test_user")
assert "results" in all_memories
print("✅ Basic functionality test passed")
test_basic_functionality()
```
### 2. Enhanced Features Test
```python
def test_enhanced_features():
config = {
"reranker": {
"provider": "sentence_transformer",
"config": {
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2"
}
}
}
m = Memory.from_config(config)
# Test reranking
m.add("I love advanced features", user_id="test_user")
results = m.search("features", user_id="test_user", rerank=True)
assert "results" in results
# Test enhanced filtering
results = m.search(
"features",
user_id="test_user",
filters={"user_id": {"eq": "test_user"}}
)
assert "results" in results
print("✅ Enhanced features test passed")
test_enhanced_features()
```
## Common Migration Issues
### Issue 1: Version Error
**Error:**
```
ValueError: The v1.0 API format is no longer supported in mem0ai 1.0.0+
```
**Solution:**
```python
# Remove version parameters or set to v1.1+
config = {
# ... other config
"version": "v1.1" # or remove entirely for default
}
```
### Issue 2: Response Format Error
**Error:**
```
KeyError: 'results'
```
**Solution:**
```python
# Always access response via "results" key
result = m.add("memory", user_id="alice")
memories = result["results"] # Not result directly
```
### Issue 3: Parameter Error
**Error:**
```
TypeError: add() got an unexpected keyword argument 'output_format'
```
**Solution:**
```python
# Remove deprecated parameters
result = m.add(
"memory",
user_id="alice"
# Remove: version
)
```
## Rollback Plan
If you encounter issues during migration:
### 1. Immediate Rollback
```bash
# Downgrade to last v0.x version
pip install mem0ai==0.1.20 # Replace with your last working version
```
### 2. Gradual Migration
```python
# Test both versions side by side
import mem0_v0 # Your old version
import mem0 # New version
def compare_results(query, user_id):
old_results = mem0_v0.search(query, user_id=user_id)
new_results = mem0.search(query, user_id=user_id)
print("Old format:", old_results)
print("New format:", new_results["results"])
```
## Performance Improvements
### Before (v0.x)
```python
# Sequential operations
result1 = m.add("memory 1", user_id="alice")
result2 = m.add("memory 2", user_id="alice")
result3 = m.search("query", user_id="alice")
```
### After (v1.0.0 )
```python
# Better async performance
async def batch_operations():
async_memory = AsyncMemory()
# Concurrent operations
results = await asyncio.gather(
async_memory.add("memory 1", user_id="alice"),
async_memory.add("memory 2", user_id="alice"),
async_memory.search("query", user_id="alice")
)
return results
```
## Next Steps
1. **Complete the migration** using this guide
2. **Test thoroughly** with your existing data
3. **Explore new features** like enhanced filtering and reranking
4. **Update your documentation** to reflect the new API
5. **Monitor performance** and optimize as needed
<CardGroup cols={2}>
<Card title="Breaking Changes" icon="triangle-exclamation" href="/migration/breaking-changes">
Detailed list of all breaking changes
</Card>
<Card title="API Changes" icon="code" href="/migration/api-changes">
Complete API reference changes
</Card>
</CardGroup>
<Info>
Need help with migration? Check our [GitHub Discussions](https://github.com/mem0ai/mem0/discussions) or reach out to our community for support.
</Info>
+1 -1
View File
@@ -130,7 +130,7 @@ memory = Memory.from_config_file("config.yaml")
</Tabs>
<Info icon="check">
Run `memory.add(["Remember my favorite cafe in Tokyo."], user_id="alex")` and then `memory.search("favorite cafe", user_id="alex")`. You should see the Qdrant collection populate and the reranker mark the memory as a top hit.
Run `memory.add(["Remember my favorite cafe in Tokyo."], user_id="alex")` and then `memory.search("favorite cafe", filters={"user_id": "alex"})`. You should see the Qdrant collection populate and the reranker mark the memory as a top hit.
</Info>
## Tune component settings

Some files were not shown because too many files have changed in this diff Show More