diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json
index 82ce93578..8b0e16623 100644
--- a/.claude-plugin/marketplace.json
+++ b/.claude-plugin/marketplace.json
@@ -12,7 +12,7 @@
"name": "mem0",
"source": "./mem0-plugin",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search to Claude workflows.",
- "version": "0.1.0"
+ "version": "0.1.1"
}
]
}
diff --git a/.cursor-plugin/marketplace.json b/.cursor-plugin/marketplace.json
index c23fc2e22..e5e868c49 100644
--- a/.cursor-plugin/marketplace.json
+++ b/.cursor-plugin/marketplace.json
@@ -12,7 +12,7 @@
"name": "mem0",
"source": "./mem0-plugin",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search.",
- "version": "0.1.0"
+ "version": "0.1.1"
}
]
}
diff --git a/README.md b/README.md
index a0eef407e..9eef64f7c 100644
--- a/README.md
+++ b/README.md
@@ -39,7 +39,7 @@
- 📄 Building Production-Ready AI Agents with Scalable Long-Term Memory →
+ 📄 Benchmarking Mem0's token-efficient memory algorithm →
## New Memory Algorithm (April 2026)
diff --git a/docs/changelog/sdk.mdx b/docs/changelog/sdk.mdx
index 930d5157e..d20702f98 100644
--- a/docs/changelog/sdk.mdx
+++ b/docs/changelog/sdk.mdx
@@ -7,6 +7,23 @@ mode: "wide"
+
+
+**Bug Fixes:**
+- **Client:** Map `user_id`, `agent_id`, `run_id` entity params to filters in `GET /memories` ([#4960](https://github.com/mem0ai/mem0/pull/4960))
+- **Memory:** Honor `prompt` param in vector store extraction pipeline ([#4914](https://github.com/mem0ai/mem0/pull/4914))
+- **Memory:** Add missing `text_lemmatized` field in `AsyncMemory._create_memory` ([#4886](https://github.com/mem0ai/mem0/pull/4886))
+- **Memory:** Merge same-key operator dicts in AND metadata filters ([#4853](https://github.com/mem0ai/mem0/pull/4853))
+- **LLMs:** Narrow `_is_reasoning_model` check to not match `gpt-5.x` variants ([#4746](https://github.com/mem0ai/mem0/pull/4746))
+- **Vector Stores:** Add `ca_certs` config option for Elasticsearch vector store ([#3993](https://github.com/mem0ai/mem0/pull/3993))
+- **Vector Stores:** Add `agent_id` and `run_id` to Elasticsearch/OpenSearch default mappings ([#4906](https://github.com/mem0ai/mem0/pull/4906))
+- **Embeddings:** Set FastEmbed `embedding_dims` from model metadata at init ([#4711](https://github.com/mem0ai/mem0/pull/4711))
+
+**Security:**
+- Bump vulnerable dependencies to patched versions ([#4835](https://github.com/mem0ai/mem0/pull/4835))
+
+
+
**Major Release** — Python SDK with V3 memory pipeline, ADD-only extraction, and cleaned-up API surface.
@@ -893,6 +910,17 @@ See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-
+
+
+**Bug Fixes:**
+- **LLMs:** Forward `timeout` config to OpenAI client in JS OSS LLM providers ([#4770](https://github.com/mem0ai/mem0/pull/4770))
+
+**Improvements:**
+- **Telemetry:** Harden TS telemetry version injection and require changelog entry on version bump ([#4900](https://github.com/mem0ai/mem0/pull/4900))
+- **Docs:** Update memory tool list, CLI usage, and config file reading logic ([#4861](https://github.com/mem0ai/mem0/pull/4861))
+
+
+
**Bug Fixes:**
diff --git a/docs/images/banner-sm.png b/docs/images/banner-sm.png
index 3e5feeeda..ecc8f3f67 100644
Binary files a/docs/images/banner-sm.png and b/docs/images/banner-sm.png differ
diff --git a/mem0-plugin/.claude-plugin/plugin.json b/mem0-plugin/.claude-plugin/plugin.json
index e9571b96b..55820ea6f 100644
--- a/mem0-plugin/.claude-plugin/plugin.json
+++ b/mem0-plugin/.claude-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "mem0",
- "version": "0.1.0",
+ "version": "0.1.1",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search to Claude workflows using the Mem0 Platform MCP server.",
"author": {
"name": "Mem0",
diff --git a/mem0-plugin/.codex-plugin/plugin.json b/mem0-plugin/.codex-plugin/plugin.json
index d5727b46f..7cd1e89a3 100644
--- a/mem0-plugin/.codex-plugin/plugin.json
+++ b/mem0-plugin/.codex-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "mem0",
- "version": "0.1.0",
+ "version": "0.1.1",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search to Codex workflows using the Mem0 Platform MCP server.",
"author": {
"name": "Mem0",
diff --git a/mem0-plugin/.cursor-plugin/plugin.json b/mem0-plugin/.cursor-plugin/plugin.json
index 8ba1249cc..5c0cefd9e 100644
--- a/mem0-plugin/.cursor-plugin/plugin.json
+++ b/mem0-plugin/.cursor-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "mem0",
- "version": "0.1.0",
+ "version": "0.1.1",
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search using the Mem0 Platform MCP server.",
"author": {
"name": "Mem0",
diff --git a/mem0-plugin/README.md b/mem0-plugin/README.md
index 95415e7b8..12845318f 100644
--- a/mem0-plugin/README.md
+++ b/mem0-plugin/README.md
@@ -74,20 +74,30 @@ This points Codex at the repo's `.agents/plugins/marketplace.json`, which refere
> **Don't combine with Option A.** The plugin manifest auto-registers `mem0` as an MCP server via `mem0-plugin/.codex-mcp.json` — adding a manual `[mcp_servers.mem0]` block would duplicate the registration.
-**Optional — enable lifecycle hooks.** Codex doesn't auto-wire hooks from plugin manifests; it only reads `~/.codex/hooks.json` (or `/.codex/hooks.json`). Run the bundled installer once to merge Mem0's entries:
+**Optional — enable lifecycle hooks.** Codex doesn't auto-wire hooks from plugin manifests; it only reads `~/.codex/hooks.json` (or `/.codex/hooks.json`) ([docs](https://developers.openai.com/codex/hooks)). Run the bundled installer once to merge Mem0's entries:
```bash
python3 ~/codex-plugins/mem0-source/mem0-plugin/scripts/install_codex_hooks.py
```
-Then enable the feature flag in `~/.codex/config.toml`:
+This merges three entries into `~/.codex/hooks.json` with absolute paths pointing into your clone:
+
+| Event | What it does |
+|-------|--------------|
+| `SessionStart` | Loads prior memories as bootstrap context |
+| `UserPromptSubmit` | Injects relevant memories into the prompt |
+| `Stop` | Reminds the agent to persist learnings at turn end |
+
+Re-running the installer is idempotent (replaces the Mem0 entries rather than duplicating) and preserves any other hooks you have. To remove: `python3 .../install_codex_hooks.py --uninstall`. If you move or delete the clone directory, re-run the installer from the new location — the hooks file stores absolute paths.
+
+Codex hooks also require the `codex_hooks` feature flag in `~/.codex/config.toml`:
```toml
[features]
codex_hooks = true
```
-Restart Codex. This registers `SessionStart` (loads prior memories), `UserPromptSubmit` (injects relevant memories before each prompt), and `Stop` (reminds the agent to persist learnings at turn end). The installer is idempotent. To remove: `python3 .../install_codex_hooks.py --uninstall`. If you move or delete the clone directory, re-run the installer from the new location — the hooks file stores absolute paths into your clone.
+The installer prints a reminder if the flag isn't set. Restart Codex after editing the config.
**Managing the plugin:**
diff --git a/mem0-plugin/hooks/codex-hooks.json b/mem0-plugin/hooks/codex-hooks.json
new file mode 100644
index 000000000..0676308a9
--- /dev/null
+++ b/mem0-plugin/hooks/codex-hooks.json
@@ -0,0 +1,39 @@
+{
+ "hooks": {
+ "SessionStart": [
+ {
+ "matcher": "startup|resume",
+ "hooks": [
+ {
+ "type": "command",
+ "command": "${CODEX_PLUGIN_ROOT}/scripts/on_session_start.sh",
+ "statusMessage": "Loading mem0 context..."
+ }
+ ]
+ }
+ ],
+ "UserPromptSubmit": [
+ {
+ "hooks": [
+ {
+ "type": "command",
+ "command": "${CODEX_PLUGIN_ROOT}/scripts/on_user_prompt.sh",
+ "statusMessage": "Searching mem0 memories...",
+ "timeout": 5
+ }
+ ]
+ }
+ ],
+ "Stop": [
+ {
+ "hooks": [
+ {
+ "type": "command",
+ "command": "${CODEX_PLUGIN_ROOT}/scripts/on_stop_codex.sh",
+ "timeout": 10
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/mem0-plugin/scripts/install_codex_hooks.py b/mem0-plugin/scripts/install_codex_hooks.py
new file mode 100755
index 000000000..f3164287f
--- /dev/null
+++ b/mem0-plugin/scripts/install_codex_hooks.py
@@ -0,0 +1,149 @@
+#!/usr/bin/env python3
+"""Install Mem0 lifecycle hooks into ~/.codex/hooks.json.
+
+Codex discovers hooks only at ~/.codex/hooks.json or /.codex/hooks.json,
+and has no plugin-host mechanism for auto-wiring hooks from an installed
+plugin. This installer reads the template at hooks/codex-hooks.json, rewrites
+the ${CODEX_PLUGIN_ROOT} placeholder to the absolute install path of this
+plugin, then merges the entries into ~/.codex/hooks.json.
+
+Re-running is idempotent: existing Mem0 entries (identified by the plugin
+directory name in the command string) are removed before fresh entries are
+added, so upgrades don't leave duplicates.
+
+Usage:
+ python3 install_codex_hooks.py # install or update
+ python3 install_codex_hooks.py --uninstall # remove Mem0 entries
+
+After installing, Codex requires the hooks feature flag in ~/.codex/config.toml:
+
+ [features]
+ codex_hooks = true
+"""
+
+from __future__ import annotations
+
+import argparse
+import json
+import sys
+from pathlib import Path
+
+SCRIPT_DIR = Path(__file__).resolve().parent
+PLUGIN_ROOT = SCRIPT_DIR.parent
+
+CODEX_DIR = Path.home() / ".codex"
+HOOKS_FILE = CODEX_DIR / "hooks.json"
+CONFIG_FILE = CODEX_DIR / "config.toml"
+
+TEMPLATE_FILE = PLUGIN_ROOT / "hooks" / "codex-hooks.json"
+
+# Substring we look for when identifying entries this installer owns.
+# Matches the plugin directory name, which stays stable across install paths.
+OWNER_MARKER = "mem0-plugin"
+
+
+def load_template() -> dict:
+ raw = TEMPLATE_FILE.read_text()
+ raw = raw.replace("${CODEX_PLUGIN_ROOT}", str(PLUGIN_ROOT))
+ return json.loads(raw)
+
+
+def load_existing() -> dict:
+ if not HOOKS_FILE.exists():
+ return {"hooks": {}}
+ try:
+ return json.loads(HOOKS_FILE.read_text())
+ except (json.JSONDecodeError, OSError) as e:
+ print(f"error: failed to read {HOOKS_FILE}: {e}", file=sys.stderr)
+ sys.exit(1)
+
+
+def is_owned_entry(entry: dict) -> bool:
+ for hook in entry.get("hooks", []):
+ if OWNER_MARKER in hook.get("command", ""):
+ return True
+ return False
+
+
+def strip_owned_entries(config: dict) -> dict:
+ hooks = config.get("hooks", {}) or {}
+ for event in list(hooks.keys()):
+ hooks[event] = [e for e in hooks[event] if not is_owned_entry(e)]
+ if not hooks[event]:
+ del hooks[event]
+ config["hooks"] = hooks
+ return config
+
+
+def merge_template(config: dict, template: dict) -> dict:
+ hooks = config.setdefault("hooks", {})
+ for event, entries in template.get("hooks", {}).items():
+ hooks.setdefault(event, []).extend(entries)
+ return config
+
+
+def write_config(config: dict) -> None:
+ CODEX_DIR.mkdir(parents=True, exist_ok=True)
+ HOOKS_FILE.write_text(json.dumps(config, indent=2) + "\n")
+
+
+def feature_flag_enabled() -> bool:
+ if not CONFIG_FILE.exists():
+ return False
+ content = CONFIG_FILE.read_text()
+ for line in content.splitlines():
+ stripped = line.split("#", 1)[0].strip().replace(" ", "")
+ if stripped == "codex_hooks=true":
+ return True
+ return False
+
+
+def print_feature_flag_hint() -> None:
+ print()
+ print("Codex hooks feature flag is not enabled.")
+ print(f"Add this to {CONFIG_FILE}:")
+ print()
+ print(" [features]")
+ print(" codex_hooks = true")
+ print()
+ print("Then restart Codex.")
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser(description="Install or remove Mem0 Codex hooks.")
+ parser.add_argument(
+ "--uninstall",
+ action="store_true",
+ help="Remove Mem0 entries from ~/.codex/hooks.json and exit.",
+ )
+ args = parser.parse_args()
+
+ config = load_existing()
+
+ if args.uninstall:
+ config = strip_owned_entries(config)
+ write_config(config)
+ print(f"Removed Mem0 hooks from {HOOKS_FILE}")
+ return 0
+
+ if not TEMPLATE_FILE.exists():
+ print(f"error: template not found at {TEMPLATE_FILE}", file=sys.stderr)
+ return 1
+
+ template = load_template()
+ config = strip_owned_entries(config)
+ config = merge_template(config, template)
+ write_config(config)
+
+ print(f"Installed Mem0 hooks into {HOOKS_FILE}")
+ print(f"Plugin path: {PLUGIN_ROOT}")
+ print("Events: SessionStart, UserPromptSubmit, Stop")
+
+ if not feature_flag_enabled():
+ print_feature_flag_hint()
+
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/mem0-plugin/scripts/on_stop_codex.sh b/mem0-plugin/scripts/on_stop_codex.sh
new file mode 100755
index 000000000..80c16d311
--- /dev/null
+++ b/mem0-plugin/scripts/on_stop_codex.sh
@@ -0,0 +1,44 @@
+#!/usr/bin/env bash
+# Hook: Stop (Codex)
+#
+# Fires when Codex finishes a turn. Reminds the agent to persist any
+# important learnings via the mem0 MCP tools before the turn closes.
+#
+# Input: JSON on stdin with session_id, turn_id, stop_hook_active,
+# last_assistant_message, transcript_path, cwd,
+# hook_event_name, model
+# Output: JSON on stdout (Codex rejects plain text on Stop).
+# - stop_hook_active=true -> {"continue": true} (let the turn end)
+# - stop_hook_active=false -> {"decision":"block","reason":"..."}
+# (continue the turn with the reminder as context)
+#
+# We must respect stop_hook_active or we'd loop forever: every "block"
+# reopens the turn, which triggers Stop again when the agent settles.
+
+set -uo pipefail
+
+INPUT=$(cat)
+STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false' 2>/dev/null || echo "false")
+
+if [ "$STOP_HOOK_ACTIVE" = "true" ]; then
+ printf '{"continue":true}\n'
+ exit 0
+fi
+
+REASON=$(cat <<'EOF'
+Before finishing, check if there are important learnings from this interaction that should be persisted using the mem0 `add_memory` tool:
+
+1. Were any significant decisions made? -> Store with metadata `{"type": "decision"}`
+2. Were any new patterns or strategies discovered? -> Store with metadata `{"type": "task_learning"}`
+3. Did any approach fail? -> Store with metadata `{"type": "anti_pattern"}`
+4. Did you learn anything about the user's preferences? -> Store with metadata `{"type": "user_preference"}`
+5. Were there environment/setup discoveries? -> Store with metadata `{"type": "environmental"}`
+
+Memories can be as detailed as needed — include full context, reasoning, code snippets, file paths, and examples. Longer, searchable memories are more valuable than vague one-liners.
+
+If nothing notable happened in this interaction, it's fine to skip. Only store genuinely useful learnings.
+EOF
+)
+
+jq -cn --arg reason "$REASON" '{decision:"block", reason:$reason}'
+exit 0
diff --git a/mem0-plugin/skills/mem0/SKILL.md b/mem0-plugin/skills/mem0/SKILL.md
index c700e80a1..1ba8b43f9 100644
--- a/mem0-plugin/skills/mem0/SKILL.md
+++ b/mem0-plugin/skills/mem0/SKILL.md
@@ -1,25 +1,34 @@
---
name: mem0
description: >
- Integrate Mem0 Platform into AI applications for persistent memory, personalization, and semantic search.
- Use this skill when the user mentions "mem0", "memory layer", "remember user preferences",
- "persistent context", "personalization", or needs to add long-term memory to chatbots, agents,
- or AI apps. Covers Python and TypeScript SDKs, framework integrations (LangChain, CrewAI,
- Vercel AI SDK, OpenAI Agents SDK, Pipecat), and the full Platform API. Use even when the user
- doesn't explicitly say "mem0" but describes needing conversation memory, user context retention,
- or knowledge retrieval across sessions.
+ Mem0 Platform SDK for adding persistent memory to AI applications.
+ TRIGGER when: user mentions "mem0", "MemoryClient", "memory layer",
+ "remember user preferences", "persistent context", "personalization",
+ or needs to add long-term memory to chatbots, agents, or AI apps.
+ Covers Python SDK (mem0ai), TypeScript SDK (mem0ai), and framework integrations
+ (LangChain, CrewAI, OpenAI Agents SDK, Pipecat, LlamaIndex, AutoGen, LangGraph).
+ Also covers the open-source self-hosted Memory class.
+ This is the DEFAULT mem0 skill for ambiguous queries.
+ DO NOT TRIGGER when: user asks about CLI commands, terminal usage, or shell
+ scripts (use mem0-cli), or Vercel AI SDK / @mem0/vercel-ai-provider / createMem0
+ (use mem0-vercel-ai-sdk).
license: Apache-2.0
metadata:
author: mem0ai
- version: "0.1.0"
+ version: "0.1.1"
category: ai-memory
tags: "memory, personalization, ai, python, typescript, vector-search"
-compatibility: Requires Python 3.10+ or Node.js 18+, pip install mem0ai or npm install mem0ai, MEM0_API_KEY env var, and internet access to api.mem0.ai
+compatibility: Requires Python 3.10+ or Node.js 18+, pip install mem0ai or npm install mem0ai, MEM0_API_KEY env var (Platform), and internet access to api.mem0.ai. Uses Mem0 v3 API.
---
# Mem0 Platform Integration
-Mem0 is a managed memory layer for AI applications. It stores, retrieves, and manages user memories via API — no infrastructure to deploy.
+> **Skill Graph:** This skill is part of the Mem0 skill graph:
+> - **mem0** (this skill) -- Platform Client SDK + OSS (Python + TypeScript)
+> - **[mem0-cli](https://github.com/mem0ai/mem0/tree/main/skills/mem0-cli)** -- Command-line interface
+> - **[mem0-vercel-ai-sdk](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk)** -- Vercel AI SDK provider
+
+Mem0 is a managed memory layer for AI applications. It stores, retrieves, and manages user memories via API — no infrastructure to deploy. For self-hosted usage, see the OSS section in the client references below.
## Step 1: Install and authenticate
@@ -68,14 +77,14 @@ client.add(messages, user_id="alice")
### Search memories
```python
-results = client.search("dietary preferences", user_id="alice")
+results = client.search("dietary preferences", filters={"user_id": "alice"})
for mem in results.get("results", []):
print(mem["memory"])
```
### Get all memories
```python
-all_memories = client.get_all(user_id="alice")
+all_memories = client.get_all(filters={"user_id": "alice"})
```
### Update a memory
@@ -100,12 +109,12 @@ openai = OpenAI()
def chat(user_input: str, user_id: str) -> str:
# 1. Retrieve relevant memories
- memories = mem0.search(user_input, user_id=user_id)
+ memories = mem0.search(user_input, filters={"user_id": user_id})
context = "\n".join([m["memory"] for m in memories.get("results", [])])
# 2. Generate response with memory context
response = openai.chat.completions.create(
- model="gpt-4.1-nano-2025-04-14",
+ model="gpt-5-mini",
messages=[
{"role": "system", "content": f"User context:\n{context}"},
{"role": "user", "content": user_input},
@@ -123,11 +132,20 @@ def chat(user_input: str, user_id: str) -> str:
## Common edge cases
-- **Search returns empty:** Memories process asynchronously. Wait 2-3s after `add()` before searching. Also verify `user_id` matches exactly (case-sensitive).
+- **Search returns empty:** Memories process asynchronously. Wait 2-3s after `add()` before searching. Also verify `user_id` matches exactly (case-sensitive) and use `filters={"user_id": "..."}` syntax.
- **AND filter with user_id + agent_id returns empty:** Entities are stored separately. Use `OR` instead, or query separately.
- **Duplicate memories:** Don't mix `infer=True` (default) and `infer=False` for the same data. Stick to one mode.
- **Wrong import:** Always use `from mem0 import MemoryClient` (or `AsyncMemoryClient` for async). Do not use `from mem0 import Memory`.
-- **Immutable memories:** Cannot be updated or deleted once created. Use `client.history(memory_id)` to track changes over time.
+- **v3 defaults:** `top_k=20`, `threshold=0.1`, `rerank=False`. Adjust as needed for your use case.
+
+## v2 Compatibility
+
+If you're using SDK v2.x, note these differences:
+- **Entity IDs:** Pass `user_id` as top-level kwarg to `search()` instead of inside `filters`
+- **Defaults:** `top_k=100`, no threshold, `rerank=True`
+- **Graph memory:** Available via `enable_graph=True`
+
+See the [migration guide](https://docs.mem0.ai/migration/oss-v2-to-v3) for details.
## Live documentation search
@@ -141,7 +159,17 @@ python ${CLAUDE_SKILL_DIR}/scripts/mem0_doc_search.py --index
No API key needed — searches docs.mem0.ai directly.
-## References
+## Client SDK References
+
+Language-specific deep references (Platform + OSS):
+
+| Language | File |
+|----------|------|
+| Python (MemoryClient + AsyncMemoryClient + Memory OSS) | [client/python.md](client/python.md) |
+| TypeScript/Node.js (MemoryClient + Memory OSS) | [client/node.md](client/node.md) |
+| Python vs TypeScript differences | [client/differences.md](client/differences.md) |
+
+## Platform References
Load these on demand for deeper detail:
@@ -152,5 +180,12 @@ Load these on demand for deeper detail:
| API reference (endpoints, filters, object schema) | [references/api-reference.md](references/api-reference.md) |
| Architecture (pipeline, lifecycle, scoping, performance) | [references/architecture.md](references/architecture.md) |
| Platform features (retrieval, graph, categories, MCP, etc.) | [references/features.md](references/features.md) |
-| Framework integrations (LangChain, CrewAI, Vercel AI, etc.) | [references/integration-patterns.md](references/integration-patterns.md) |
+| Framework integrations (LangChain, CrewAI, OpenAI Agents, etc.) | [references/integration-patterns.md](references/integration-patterns.md) |
| Use cases & examples (real-world patterns with code) | [references/use-cases.md](references/use-cases.md) |
+
+## Related Mem0 Skills
+
+| Skill | When to use | Link |
+|-------|-------------|------|
+| mem0-cli | Terminal commands, scripting, CI/CD, agent tool loops | [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-cli) |
+| mem0-vercel-ai-sdk | Vercel AI SDK provider with automatic memory | [GitHub](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk) |
diff --git a/mem0-plugin/skills/mem0/client/differences.md b/mem0-plugin/skills/mem0/client/differences.md
new file mode 100644
index 000000000..e5e80e250
--- /dev/null
+++ b/mem0-plugin/skills/mem0/client/differences.md
@@ -0,0 +1,129 @@
+# Python vs TypeScript SDK Differences
+
+Quick-reference cheatsheet for developers working across both Mem0 SDKs.
+
+## Constructor
+
+| Aspect | Python | TypeScript |
+|--------|--------|------------|
+| Import (Platform) | `from mem0 import MemoryClient` | `import MemoryClient from 'mem0ai'` |
+| Import (OSS) | `from mem0 import Memory` | `import { Memory } from 'mem0ai/oss'` |
+| Constructor | `MemoryClient(api_key="m0-xxx")` | `new MemoryClient({ apiKey: 'm0-xxx' })` |
+| Required param | `api_key` (positional or kwarg) | `apiKey` (in options object) |
+
+Both read from `MEM0_API_KEY` env var if no key provided.
+
+## Method Naming
+
+| Operation | Python | TypeScript |
+|-----------|--------|------------|
+| Add | `add()` | `add()` |
+| Search | `search()` | `search()` |
+| Get | `get()` | `get()` |
+| Get all | `get_all()` | `getAll()` |
+| Update | `update()` | `update()` |
+| Delete | `delete()` | `delete()` |
+| Delete all | `delete_all()` | `deleteAll()` |
+| History | `history()` | `history()` |
+| Batch update | `batch_update()` | `batchUpdate()` |
+| Batch delete | `batch_delete()` | `batchDelete()` |
+| List users | `users()` | `users()` |
+| Delete users | `delete_users()` | `deleteUsers()` |
+| Get project | `project.get()` | `getProject()` |
+| Update project | `project.update()` | `updateProject()` |
+| Create webhook | `create_webhook()` | `createWebhook()` |
+| Get webhooks | `get_webhooks()` | `getWebhooks()` |
+| Update webhook | `update_webhook()` | `updateWebhook()` |
+| Delete webhook | `delete_webhook()` | `deleteWebhook()` |
+| Create export | `create_memory_export()` | `createMemoryExport()` |
+| Get export | `get_memory_export()` | `getMemoryExport()` |
+| Feedback | `feedback()` | `feedback()` |
+
+**Rule:** Python uses `snake_case`, TypeScript uses `camelCase` for method names.
+
+## Parameter Passing
+
+```python
+# Python: kwargs
+client.add(messages, user_id="alice", metadata={"source": "chat"})
+client.search("query", filters={"user_id": "alice"}, top_k=5, rerank=True)
+```
+
+```typescript
+// TypeScript: options object with camelCase for top-level params, snake_case for filter keys
+await client.add(messages, { userId: 'alice', metadata: { source: 'chat' } });
+await client.search('query', { filters: { user_id: 'alice' }, topK: 5, rerank: true });
+```
+
+**v3:** Python uses `snake_case` everywhere. TypeScript uses `camelCase` for top-level params (`userId`, `topK`) but `snake_case` for filter keys (`user_id`, `agent_id`).
+
+## Architectural Differences
+
+| Aspect | Python | TypeScript |
+|--------|--------|------------|
+| HTTP library | httpx | axios |
+| Default timeout | 300s | 60s |
+| Sync support | Yes (`MemoryClient`) | No (all async) |
+| Async support | Yes (`AsyncMemoryClient`) | All methods are async |
+| Project management | `client.project.*` (separate class) | `client.getProject()` / `client.updateProject()` |
+| Context manager | `async with AsyncMemoryClient()` | Not supported |
+
+## Platform Features: Python-only
+
+These methods exist in Python but not TypeScript:
+
+| Method | Description |
+|--------|-------------|
+| `get_summary(filters)` | Get summary of memories |
+| `reset()` | Delete ALL data (users + memories) |
+| `project.create(name)` | Create a new project |
+| `project.delete()` | Delete current project |
+| `project.get_members()` | List project members |
+| `project.add_member(email, role)` | Add member to project |
+| `project.update_member(email, role)` | Change member role |
+| `project.remove_member(email)` | Remove member |
+
+## Platform Features: TypeScript-only
+
+| Method | Description |
+|--------|-------------|
+| `deleteUser(data)` | Convenience method for single entity deletion |
+| `ping()` | Health check endpoint |
+
+## OSS Config Naming
+
+| Python config key | TypeScript config key |
+|-------------------|----------------------|
+| `vector_store` | `vectorStore` |
+| `history_db_path` | `historyDbPath` |
+| `custom_instructions` | `customInstructions` |
+
+## OSS Scope Parameter Naming
+
+| Python | TypeScript |
+|--------|------------|
+| `user_id="alice"` | `userId: 'alice'` |
+| `agent_id="bot"` | `agentId: 'bot'` |
+| `run_id="session"` | `runId: 'session'` |
+
+## Entity ID Passing (v3)
+
+| Method | Python | TypeScript |
+|--------|--------|------------|
+| add() | Top-level: `user_id="alice"` | Top-level: `{ userId: 'alice' }` |
+| search() | In filters: `filters={"user_id": "alice"}` | In filters: `{ filters: { user_id: 'alice' } }` |
+| get_all() | In filters: `filters={"user_id": "alice"}` | In filters: `{ filters: { user_id: 'alice' } }` |
+
+## Common Gotcha
+
+When searching/filtering, both Python and TypeScript use `snake_case` for filter keys. TypeScript only uses `camelCase` for top-level method parameters:
+
+```python
+# Python - snake_case in filters
+results = client.search("query", filters={"user_id": "alice"})
+```
+
+```typescript
+// TypeScript - snake_case in filters, camelCase for top-level params
+const results = await client.search('query', { filters: { user_id: 'alice' }, topK: 20 });
+```
diff --git a/mem0-plugin/skills/mem0/client/node.md b/mem0-plugin/skills/mem0/client/node.md
new file mode 100644
index 000000000..ca85ba7ba
--- /dev/null
+++ b/mem0-plugin/skills/mem0/client/node.md
@@ -0,0 +1,418 @@
+# Mem0 Node.js / TypeScript SDK Reference
+
+Complete reference for the `mem0ai` npm package. Covers both the Platform client (managed API) and the Open Source self-hosted variant.
+
+---
+
+## Platform Client
+
+### Installation
+
+```bash
+npm install mem0ai
+export MEM0_API_KEY="m0-your-api-key"
+```
+
+### MemoryClient
+
+```typescript
+import MemoryClient from 'mem0ai';
+
+const client = new MemoryClient({ apiKey: 'm0-xxx' });
+```
+
+**Constructor:** `new MemoryClient({ apiKey })`. If `apiKey` is not provided, reads from `MEM0_API_KEY` environment variable.
+
+- HTTP library: `axios`
+- Timeout: 60 seconds
+- Base URL: `https://api.mem0.ai`
+- All methods are async (return `Promise`)
+
+---
+
+### Memory Methods
+
+#### add(messages, options?)
+
+Store new memories from messages.
+
+```typescript
+const messages = [
+ { role: 'user', content: "I'm a vegetarian and allergic to nuts." },
+ { role: 'assistant', content: "Got it! I'll remember that." },
+];
+await client.add(messages, { userId: 'alice' });
+```
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `messages` | `Message[]` | Array of `{role, content}` objects |
+| `options.userId` | string | User identifier |
+| `options.agentId` | string | Agent identifier |
+| `options.appId` | string | Application identifier |
+| `options.runId` | string | Session identifier |
+| `options.metadata` | object | Custom key-value pairs |
+| `options.infer` | boolean | If false, store raw text (default: true) |
+
+**Returns:** `Promise` -- list of events
+
+#### search(query, options?)
+
+Search memories by semantic similarity.
+
+```typescript
+const results = await client.search('dietary preferences', { filters: { user_id: 'alice' }, topK: 20 });
+for (const mem of results.results) {
+ console.log(mem.memory, mem.score);
+}
+```
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `query` | string | Natural language search query |
+| `options.filters` | object | Filter object with entity IDs (`user_id`, `agent_id`, etc.) and/or `AND`/`OR`/`NOT` conditions |
+| `options.topK` | number | Number of results (default: 20) |
+| `options.rerank` | boolean | Enable semantic reranking (default: false) |
+| `options.threshold` | number | Minimum similarity (default: 0.1) |
+
+**Returns:** `Promise` -- `{results: [{id, memory, score, ...}]}`
+
+#### get(memoryId)
+
+```typescript
+const memory = await client.get('ea925981-...');
+```
+
+#### getAll(options?)
+
+Retrieve all memories. Requires at least one entity identifier in filters.
+
+```typescript
+const memories = await client.getAll({ filters: { user_id: 'alice' } });
+// With filters
+const filtered = await client.getAll({
+ filters: { AND: [{ user_id: 'alice' }, { categories: { contains: 'health' } }] },
+});
+```
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `options.filters` | object | Filter object with entity IDs (`user_id`, `agent_id`, etc.) and/or `AND`/`OR`/`NOT` conditions |
+| `options.page` | number | Page number |
+| `options.pageSize` | number | Results per page |
+
+#### update(memoryId, data)
+
+```typescript
+await client.update('ea925981-...', { text: 'Updated: vegan since 2024' });
+await client.update('ea925981-...', { text: 'Updated', metadata: { verified: true } });
+```
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `memoryId` | string | Memory ID |
+| `data.text` | string | New content |
+| `data.metadata` | object | New metadata |
+| `data.timestamp` | string | New timestamp |
+
+#### delete(memoryId)
+
+```typescript
+await client.delete('ea925981-...');
+```
+
+#### deleteAll(options?)
+
+```typescript
+await client.deleteAll({ userId: 'alice' });
+```
+
+#### history(memoryId)
+
+```typescript
+const history = await client.history('ea925981-...');
+// Returns: [{previousValue, newValue, action, timestamps}]
+```
+
+---
+
+### Batch Methods
+
+#### batchUpdate(memories)
+
+```typescript
+await client.batchUpdate([
+ { memoryId: 'uuid-1', text: 'Updated text' },
+ { memoryId: 'uuid-2', text: 'Another update' },
+]);
+```
+
+#### batchDelete(memories)
+
+```typescript
+await client.batchDelete(['uuid-1', 'uuid-2', 'uuid-3']);
+```
+
+---
+
+### User/Entity Management
+
+#### users()
+
+```typescript
+const users = await client.users();
+// Returns: {results: [{type: "user", name: "alice"}, ...]}
+```
+
+#### deleteUser(data) / deleteUsers(data)
+
+```typescript
+await client.deleteUser({ userId: 'alice' }); // Single entity
+await client.deleteUsers({ agentId: 'bot-1' }); // Flexible
+```
+
+---
+
+### Project Management
+
+```typescript
+// Get project config
+const config = await client.getProject({ fields: ['customCategories'] });
+
+// Update project settings
+await client.updateProject({
+ customInstructions: 'Extract dietary preferences and health info',
+ customCategories: [{ health: 'Medical and dietary info' }],
+});
+```
+
+---
+
+### Webhooks
+
+```typescript
+// List
+const webhooks = await client.getWebhooks({ projectId: 'proj_123' });
+
+// Create
+const webhook = await client.createWebhook({
+ url: 'https://your-app.com/webhook',
+ name: 'Memory Logger',
+ projectId: 'proj_123',
+ eventTypes: ['memory_add', 'memory_update'],
+});
+
+// Update
+await client.updateWebhook({
+ webhookId: 'wh_123',
+ name: 'Updated Logger',
+ url: 'https://new-url.com',
+});
+
+// Delete
+await client.deleteWebhook({ webhookId: 'wh_123' });
+```
+
+---
+
+### Feedback
+
+```typescript
+await client.feedback({
+ memoryId: 'mem-123',
+ feedback: 'POSITIVE',
+ feedbackReason: 'Accurately captured preference',
+});
+```
+
+---
+
+### Export
+
+```typescript
+const exportReq = await client.createMemoryExport({
+ schema: JSON.stringify({ type: 'object', properties: { name: { type: 'string' } } }),
+ filters: { user_id: 'alice' },
+});
+
+const result = await client.getMemoryExport({ memoryExportId: exportReq.id });
+```
+
+---
+
+### TypeScript Types
+
+Key interfaces from `mem0.types.ts`:
+
+```typescript
+interface Message { role: string; content: string; }
+interface Memory { id: string; memory: string; userId: string; categories: string[]; score?: number; /* ... */ }
+interface MemoryOptions { userId?: string; agentId?: string; appId?: string; runId?: string; metadata?: object; /* ... */ }
+interface SearchOptions { filters?: object; topK?: number; rerank?: boolean; threshold?: number; /* ... */ }
+interface MemoryHistory { id: string; memoryId: string; previousValue: string; newValue: string; action: string; /* ... */ }
+interface FeedbackPayload { memoryId: string; feedback: string; feedbackReason?: string; }
+interface WebhookCreatePayload { url: string; name: string; projectId: string; eventTypes: string[]; }
+```
+
+---
+
+## Open Source / Self-Hosted
+
+### Installation
+
+```bash
+npm install mem0ai
+```
+
+### Memory Class
+
+```typescript
+import { Memory } from 'mem0ai/oss';
+
+const m = new Memory(); // Uses default config
+```
+
+**Import:** `from 'mem0ai/oss'` (NOT the default export -- that is `MemoryClient` for Platform)
+
+### Configuration
+
+```typescript
+const config = {
+ llm: {
+ provider: 'openai', // openai, groq, anthropic, google, ollama, lmstudio, mistral, azure
+ config: {
+ model: 'gpt-5-mini',
+ apiKey: 'sk-xxx',
+ },
+ },
+ embedder: {
+ provider: 'openai', // openai, ollama, lmstudio, google, azure, langchain, anthropic
+ config: {
+ model: 'text-embedding-3-small',
+ apiKey: 'sk-xxx',
+ },
+ },
+ vectorStore: {
+ provider: 'qdrant', // memory, qdrant, redis, supabase, langchain, azure_ai_search, pgvector
+ config: {
+ collectionName: 'my_memories',
+ host: 'localhost',
+ port: 6333,
+ },
+ },
+ historyDbPath: 'history.db',
+ customInstructions: '...',
+ disableHistory: false,
+};
+
+const m = new Memory(config);
+// Or from dict with validation:
+const m2 = Memory.fromConfig(config);
+```
+
+### Methods
+
+All methods are async (return `Promise`):
+
+#### add(messages, config)
+
+```typescript
+await m.add('I prefer dark mode', { userId: 'alice' });
+await m.add([
+ { role: 'user', content: 'I like hiking' },
+ { role: 'assistant', content: 'Great outdoor activity!' },
+], { userId: 'alice' });
+```
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `messages` | `string \| Message[]` | Content to store |
+| `config.userId` | string | User identifier (at least one scope required) |
+| `config.agentId` | string | Agent identifier |
+| `config.runId` | string | Session identifier |
+| `config.metadata` | object | Custom key-value pairs |
+| `config.filters` | object | Additional filters |
+| `config.infer` | boolean | LLM inference (default: true) |
+
+**Returns:** `Promise<{results: [...], relations?: [...]}>`
+
+#### search(query, config)
+
+```typescript
+const results = await m.search('dietary preferences', { filters: { user_id: 'alice' }, topK: 5 });
+```
+
+| Parameter | Type | Description |
+|-----------|------|-------------|
+| `query` | string | Search query |
+| `config.filters` | object | Filter object with entity IDs (`user_id`, `agent_id`, `run_id`, etc.) |
+| `config.topK` | number | Max results (default: 20) |
+
+#### get(memoryId) / getAll(config) / update(memoryId, data) / delete(memoryId) / deleteAll(config) / history(memoryId)
+
+Same interface patterns. Note: OSS `update` takes a string for data, not an object.
+
+```typescript
+await m.update('mem-id', 'new content');
+```
+
+#### reset()
+
+Clear the entire vector store and history.
+
+```typescript
+await m.reset();
+```
+
+---
+
+## Key Differences: Platform vs OSS
+
+| Aspect | Platform (`MemoryClient`) | OSS (`Memory`) |
+|--------|--------------------------|----------------|
+| **Import** | `import MemoryClient from 'mem0ai'` | `import { Memory } from 'mem0ai/oss'` |
+| **Auth** | API key required (`MEM0_API_KEY`) | No API key -- config-based |
+| **Execution** | API calls to `api.mem0.ai` | Local execution |
+| **Infrastructure** | Fully managed | Self-managed vector DB, embedder, LLM |
+| **Param style** | Top-level: `camelCase` (`userId`, `topK`), filter keys: `snake_case` (`user_id`) | Top-level: `camelCase` (`userId`, `topK`), filter keys: `snake_case` (`user_id`) |
+| **Batch ops** | `batchUpdate`, `batchDelete` | Not available |
+| **Webhooks** | Full CRUD | Not available |
+| **Export** | `createMemoryExport` | Not available |
+| **Feedback** | `feedback()` | Not available |
+| **Project mgmt** | `getProject`, `updateProject` | Not available |
+| **User listing** | `users()`, `deleteUser()` | Not available |
+| **History** | Platform-managed | SQLite (configurable) |
+
+---
+
+## v2 Compatibility
+
+If you're using SDK v2.x:
+
+**Naming Changes:**
+- Top-level params now use camelCase: `topK`, `rerank` (not `top_k`)
+- Filter keys use snake_case: `user_id`, `agent_id`
+- OSS: `limit` renamed to `topK`
+
+**API Changes:**
+```typescript
+// v2 - top-level entity IDs, snake_case
+await client.search("query", { user_id: "alice", top_k: 20 });
+
+// v3 - filters object with snake_case keys, camelCase top-level params
+await client.search("query", { filters: { user_id: "alice" }, topK: 20 });
+```
+
+**Default Changes:**
+| Param | v2 | v3 |
+|-------|----|----|
+| `topK` | 100 | 20 |
+| `threshold` | none | 0.1 |
+| `rerank` | true | false |
+
+**Removed:**
+- `OutputFormat` and `API_VERSION` enums
+- `organizationId`, `projectId` from constructor
+- `enableGraph`, `asyncMode`, `outputFormat`, `immutable`, `expirationDate`, `filterMemories`, `batchSize`, `forceAddOnly`, `includes`, `excludes`, `keywordSearch`
+
+See the [v2 to v3 migration guide](https://docs.mem0.ai/migration/oss-v2-to-v3) for details.
diff --git a/mem0-plugin/skills/mem0/client/python.md b/mem0-plugin/skills/mem0/client/python.md
new file mode 100644
index 000000000..0cf35a550
--- /dev/null
+++ b/mem0-plugin/skills/mem0/client/python.md
@@ -0,0 +1,487 @@
+# Mem0 Python SDK Reference
+
+Complete reference for the `mem0ai` Python package. Covers both the Platform client (managed API) and the Open Source self-hosted variant.
+
+---
+
+## Platform Client
+
+### Installation
+
+```bash
+pip install mem0ai
+export MEM0_API_KEY="m0-your-api-key"
+```
+
+### MemoryClient (Synchronous)
+
+```python
+from mem0 import MemoryClient
+
+client = MemoryClient(api_key="m0-xxx")
+```
+
+**Constructor:** `MemoryClient(api_key=None)`. If `api_key` is not provided, reads from `MEM0_API_KEY` environment variable. Raises `ValueError` if no key found.
+
+- HTTP library: `httpx`
+- Timeout: 300 seconds
+- Base URL: `https://api.mem0.ai`
+
+### AsyncMemoryClient (Asynchronous)
+
+```python
+from mem0 import AsyncMemoryClient
+
+client = AsyncMemoryClient(api_key="m0-xxx")
+
+# Or use as context manager
+async with AsyncMemoryClient(api_key="m0-xxx") as client:
+ results = await client.search("query", filters={"user_id": "alice"})
+```
+
+Same methods as `MemoryClient`, all `async`/`await`. Supports async context manager.
+
+---
+
+### Memory Methods
+
+#### add(messages, **kwargs)
+
+Store new memories from messages.
+
+```python
+messages = [
+ {"role": "user", "content": "I'm a vegetarian and allergic to nuts."},
+ {"role": "assistant", "content": "Got it! I'll remember that."}
+]
+client.add(messages, user_id="alice")
+```
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `messages` | str \| dict \| list[dict] | required | Message content. Strings auto-convert to user messages |
+| `user_id` | str | None | User identifier |
+| `agent_id` | str | None | Agent identifier |
+| `app_id` | str | None | Application identifier |
+| `run_id` | str | None | Session/run identifier |
+| `metadata` | dict | None | Custom key-value pairs |
+| `infer` | bool | True | If False, store raw text without LLM inference |
+| `custom_categories` | list | None | Override project categories |
+| `custom_instructions` | str | None | Override extraction instructions |
+| `timestamp` | int \| float \| str | None | Custom timestamp (Unix epoch or ISO 8601) |
+
+**Returns:** `dict` -- list of events: `[{"id": "...", "event": "ADD", "data": {"memory": "..."}}]`
+
+#### search(query, **kwargs)
+
+Search memories by semantic similarity.
+
+```python
+results = client.search("dietary preferences", filters={"user_id": "alice"})
+for mem in results.get("results", []):
+ print(mem["memory"], mem["score"])
+```
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `query` | str | required | Natural language search query |
+| `filters` | dict | None | Filter object with entity IDs and/or `AND`/`OR`/`NOT` conditions (e.g., `{"user_id": "alice"}`) |
+| `top_k` | int | 10 | Number of results |
+| `rerank` | bool | False | Enable deep semantic reranking (+150-200ms) |
+| `threshold` | float | 0.1 | Minimum similarity score |
+| `fields` | list | None | Specific fields to return |
+| `categories` | list | None | Filter by category |
+
+**Returns:** `dict` -- `{"results": [{id, memory, user_id, categories, score, created_at, ...}]}`
+
+#### get(memory_id)
+
+Retrieve a single memory by ID.
+
+```python
+memory = client.get(memory_id="ea925981-...")
+```
+
+**Returns:** `dict` -- full memory object
+
+#### get_all(**kwargs)
+
+Retrieve all memories with optional filtering. Requires at least one entity identifier.
+
+```python
+memories = client.get_all(filters={"user_id": "alice"})
+# With compound filters
+memories = client.get_all(filters={"AND": [{"user_id": "alice"}, {"categories": {"contains": "health"}}]})
+```
+
+| Parameter | Type | Default | Description |
+|-----------|------|---------|-------------|
+| `filters` | dict | None | Filter object with entity IDs and/or `AND`/`OR`/`NOT` conditions |
+| `top_k` | int | None | Limit results |
+| `page` | int | None | Page number |
+| `page_size` | int | None | Results per page |
+
+**Returns:** `dict` -- `{"results": [...]}`
+
+#### update(memory_id, text=None, metadata=None, timestamp=None)
+
+Update a memory's content, metadata, or timestamp. At least one parameter required.
+
+```python
+client.update("ea925981-...", text="Updated: vegan since 2024")
+client.update("ea925981-...", metadata={"verified": True})
+```
+
+**Returns:** `dict` -- updated memory
+
+#### delete(memory_id)
+
+Permanently delete a single memory.
+
+```python
+client.delete("ea925981-...")
+```
+
+#### delete_all(**kwargs)
+
+Delete all memories matching filters. Irreversible.
+
+```python
+client.delete_all(user_id="alice")
+```
+
+#### history(memory_id)
+
+Get the change history of a memory.
+
+```python
+history = client.history("ea925981-...")
+# Returns: [{previous_value, new_value, action, timestamps}]
+```
+
+---
+
+### Batch Methods
+
+#### batch_update(memories)
+
+Update up to 1000 memories in a single request.
+
+```python
+client.batch_update([
+ {"memory_id": "uuid-1", "text": "Updated text"},
+ {"memory_id": "uuid-2", "text": "Another update", "metadata": {"verified": True}},
+])
+```
+
+#### batch_delete(memories)
+
+Delete up to 1000 memories in a single request.
+
+```python
+client.batch_delete([
+ {"memory_id": "uuid-1"},
+ {"memory_id": "uuid-2"},
+])
+```
+
+---
+
+### User/Entity Management
+
+#### users()
+
+List all users, agents, and sessions that have memories.
+
+```python
+users = client.users()
+# Returns: {"results": [{"type": "user", "name": "alice"}, ...]}
+```
+
+#### delete_users(user_id=None, agent_id=None, app_id=None, run_id=None)
+
+Delete a specific entity and all its memories.
+
+```python
+client.delete_users(user_id="alice")
+```
+
+#### reset()
+
+Delete ALL users, agents, sessions, and memories. Complete data reset.
+
+```python
+client.reset()
+```
+
+---
+
+### Export & Summary
+
+#### create_memory_export(schema, **kwargs)
+
+Create a structured export of memories.
+
+```python
+import json
+
+schema = json.dumps({
+ "type": "object",
+ "properties": {
+ "name": {"type": "string"},
+ "preferences": {"type": "array", "items": {"type": "string"}},
+ }
+})
+export = client.create_memory_export(schema=schema, user_id="alice")
+```
+
+#### get_memory_export(**kwargs)
+
+Retrieve a previously created export.
+
+```python
+result = client.get_memory_export(memory_export_id=export["id"])
+```
+
+#### get_summary(filters=None)
+
+Get a summary of memories.
+
+```python
+summary = client.get_summary(filters={"user_id": "alice"})
+```
+
+---
+
+### Feedback
+
+#### feedback(memory_id, feedback=None, feedback_reason=None)
+
+Provide quality feedback on a memory.
+
+```python
+client.feedback(
+ memory_id="mem-123",
+ feedback="POSITIVE", # POSITIVE | NEGATIVE | VERY_NEGATIVE | None (clear)
+ feedback_reason="Accurately captured preference"
+)
+```
+
+---
+
+### Webhooks
+
+```python
+# List
+webhooks = client.get_webhooks(project_id="proj_123")
+
+# Create
+webhook = client.create_webhook(
+ url="https://your-app.com/webhook",
+ name="Memory Logger",
+ project_id="proj_123",
+ event_types=["memory_add", "memory_update"]
+)
+
+# Update
+client.update_webhook(webhook_id=123, name="Updated", url="https://new-url.com")
+
+# Delete
+client.delete_webhook(webhook_id=123)
+```
+
+---
+
+### Project Management
+
+Access via `client.project.*`:
+
+```python
+# Get project config
+config = client.project.get(fields=["custom_categories", "custom_instructions"])
+
+# Update project settings
+client.project.update(
+ custom_instructions="Extract dietary preferences and health info",
+ custom_categories=[{"health": "Medical and dietary info"}],
+ multilingual=True,
+)
+
+# Create/delete project
+client.project.create(name="My Project", description="...")
+client.project.delete()
+
+# Member management
+members = client.project.get_members()
+client.project.add_member(email="user@example.com", role="READER") # READER or OWNER
+client.project.update_member(email="user@example.com", role="OWNER")
+client.project.remove_member(email="user@example.com")
+```
+
+---
+
+## Open Source / Self-Hosted
+
+### Installation
+
+```bash
+pip install mem0ai
+```
+
+### Memory Class
+
+```python
+from mem0 import Memory
+
+m = Memory() # Uses default config (OpenAI embedder + in-memory vector store)
+```
+
+**Import:** `from mem0 import Memory` (NOT `MemoryClient` -- that is the Platform client)
+
+### Configuration
+
+```python
+config = {
+ "llm": {
+ "provider": "openai", # openai, groq, azure, ollama, lmstudio, google, anthropic, mistral
+ "config": {
+ "model": "gpt-5-mini",
+ "api_key": "sk-xxx",
+ }
+ },
+ "embedder": {
+ "provider": "openai", # openai, ollama, azure, lmstudio, google, huggingface
+ "config": {
+ "model": "text-embedding-3-small",
+ "api_key": "sk-xxx",
+ }
+ },
+ "vector_store": {
+ "provider": "qdrant", # faiss, qdrant, pgvector, redis, supabase, azure_ai_search, memory
+ "config": {
+ "collection_name": "my_memories",
+ "host": "localhost",
+ "port": 6333,
+ }
+ },
+ "history_db_path": "history.db", # SQLite path for change history
+ "custom_instructions": "...", # Custom LLM prompt for extraction
+}
+
+m = Memory.from_config(config)
+```
+
+### Context Manager
+
+```python
+with Memory(config) as m:
+ m.add("I prefer dark mode", user_id="alice")
+ results = m.search("preferences", filters={"user_id": "alice"})
+# SQLite connections released automatically
+```
+
+### Methods
+
+All methods mirror the Platform client but run locally:
+
+#### add(messages, *, user_id, agent_id, run_id, metadata, infer=True)
+
+```python
+m.add("I'm a vegetarian", user_id="alice")
+m.add([
+ {"role": "user", "content": "I like hiking"},
+ {"role": "assistant", "content": "Great outdoor activity!"}
+], user_id="alice")
+```
+
+At least one of `user_id`, `agent_id`, `run_id` required.
+
+**Returns:** `{"results": [...], "relations": [...]}`
+
+#### search(query, *, filters=None, top_k=20, threshold=0.1, rerank=False)
+
+```python
+results = m.search("dietary preferences", filters={"user_id": "alice"}, top_k=5)
+```
+
+Entity IDs (`user_id`, `agent_id`, `run_id`) must be passed inside the `filters` dict.
+
+Supports filter operators: `eq`, `ne`, `in`, `nin`, `gt`, `gte`, `lt`, `lte`, `contains`, `not_contains`.
+
+#### get(memory_id) / get_all(**kwargs) / update(memory_id, data, metadata=None) / delete(memory_id) / delete_all(**kwargs) / history(memory_id)
+
+Same interface as Platform client.
+
+#### reset()
+
+Clear the entire vector store collection and history database. Recreates the vector store.
+
+```python
+m.reset()
+```
+
+#### close()
+
+Release SQLite connections. Called automatically when using context manager.
+
+### AsyncMemory
+
+```python
+from mem0 import AsyncMemory
+
+m = AsyncMemory(config)
+await m.add("text", user_id="alice")
+results = await m.search("query", filters={"user_id": "alice"})
+```
+
+---
+
+## Key Differences: Platform vs OSS
+
+| Aspect | Platform (`MemoryClient`) | OSS (`Memory`) |
+|--------|--------------------------|----------------|
+| **Import** | `from mem0 import MemoryClient` | `from mem0 import Memory` |
+| **Auth** | API key required (`MEM0_API_KEY`) | No API key -- config-based |
+| **Execution** | API calls to `api.mem0.ai` | Local execution |
+| **Infrastructure** | Fully managed | Self-managed vector DB, embedder, LLM |
+| **Entity filtering** | `filters={"user_id": "..."}` | `filters={"user_id": "..."}` |
+| **Batch ops** | `batch_update`, `batch_delete` | Not available |
+| **Webhooks** | Full CRUD | Not available |
+| **Export** | `create_memory_export`, `get_memory_export` | Not available |
+| **Feedback** | `feedback()` | Not available |
+| **Project mgmt** | `client.project.*` | Not available |
+| **User listing** | `users()`, `delete_users()` | Not available |
+| **Custom prompts** | Via project settings | Direct config (`custom_instructions`) |
+| **History** | Platform-managed | SQLite (configurable) |
+| **Async** | `AsyncMemoryClient` | `AsyncMemory` |
+
+---
+
+## v2 Compatibility
+
+If you're using SDK v2.x or the v2 API:
+
+**API Changes:**
+- **Entity IDs in search/get_all:** Pass `user_id`, `agent_id` as top-level kwargs instead of inside `filters`
+ ```python
+ # v2
+ results = client.search("query", user_id="alice")
+ # v3
+ results = client.search("query", filters={"user_id": "alice"})
+ ```
+- **add() returns:** v2 returns ADD, UPDATE, DELETE events; v3 returns ADD only
+
+**Default Changes:**
+| Param | v2 | v3 |
+|-------|----|----|
+| `top_k` | 100 | 20 |
+| `threshold` | None | 0.1 |
+| `rerank` | True | False |
+
+**Removed Parameters:**
+- Constructor: `org_id`, `project_id`
+- add(): `async_mode`, `output_format`, `enable_graph`, `immutable`, `expiration_date`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`
+- search()/get_all(): `enable_graph`
+- Config: `enable_graph`, `graph_store`, `custom_fact_extraction_prompt` (renamed to `custom_instructions`)
+
+See the [v2 to v3 migration guide](https://docs.mem0.ai/migration/oss-v2-to-v3) for full details.
diff --git a/mem0-plugin/skills/mem0/references/api-reference.md b/mem0-plugin/skills/mem0/references/api-reference.md
index e9fd20f24..62ec4bea7 100644
--- a/mem0-plugin/skills/mem0/references/api-reference.md
+++ b/mem0-plugin/skills/mem0/references/api-reference.md
@@ -8,13 +8,15 @@ All endpoints require: `Authorization: Token `
| Operation | Method | URL |
|-----------|--------|-----|
-| Add Memories | `POST` | `/v1/memories/` |
-| Search Memories | `POST` | `/v2/memories/search/` |
-| Get All Memories | `POST` | `/v2/memories/` |
+| Add Memories | `POST` | `/v3/memories/add/` |
+| Search Memories | `POST` | `/v3/memories/search/` |
+| Get All Memories | `POST` | `/v3/memories/` |
| Get Single Memory | `GET` | `/v1/memories/{memory_id}/` |
| Update Memory | `PUT` | `/v1/memories/{memory_id}/` |
| Delete Memory | `DELETE` | `/v1/memories/{memory_id}/` |
+Note: v1/v2 endpoints still work (backward compatible).
+
## Memory Object Structure
| Field | Type | Description |
@@ -27,8 +29,6 @@ All endpoints require: `Authorization: Token `
| `run_id` | string (nullable) | Run/session identifier |
| `metadata` | object | Custom key-value pairs |
| `categories` | array of strings | Auto-assigned category tags |
-| `immutable` | boolean | If true, prevents modification |
-| `expiration_date` | datetime (nullable) | Auto-expiry date |
| `hash` | string | Content hash |
| `created_at` | datetime | Creation timestamp |
| `updated_at` | datetime | Last modification timestamp |
@@ -50,10 +50,9 @@ Memories can be scoped to different levels:
## Processing Model
-- Memories are processed **asynchronously by default** (`async_mode=true`)
-- Add responses return queued events (`ADD`, `UPDATE`, `DELETE`) for tracking
-- Set `async_mode=false` for synchronous processing when needed
-- Graph metadata is processed asynchronously -- use `get_all()` for complete graph data
+- Memories are processed **asynchronously** (v3 default)
+- Add responses return queued `ADD` events only (v3 is ADD-only, no UPDATE/DELETE)
+- Poll status via `GET /v1/event/{event_id}/`
## Filter System
@@ -106,19 +105,17 @@ Root must be `AND`, `OR`, or `NOT`. Simple shorthand `{"user_id": "alice"}` also
## Response Formats
-### Add Response
+### Add Response (v3)
```json
-[
- {
- "id": "mem_01JF8ZS4Y0R0SPM13R5R6H32CJ",
- "event": "ADD",
- "data": { "memory": "The user moved to Austin in 2025." }
- }
-]
+{
+ "message": "Memory processing has been queued for background execution",
+ "status": "PENDING",
+ "event_id": "evt-uuid"
+}
```
-Event types: `ADD`, `UPDATE`, `DELETE`. A single add can trigger multiple events.
+v3 is ADD-only. No UPDATE or DELETE events.
### Search Response
@@ -137,4 +134,17 @@ Event types: `ADD`, `UPDATE`, `DELETE`. A single add can trigger multiple events
}
```
-With `enable_graph=true`, includes additional `relations` array with entity relationships.
+In v3, `score` is a combined multi-signal relevance score.
+
+### Get All Response (v3)
+
+```json
+{
+ "count": 123,
+ "next": "https://api.mem0.ai/v3/memories/?page=2&page_size=50",
+ "previous": null,
+ "results": [...]
+}
+```
+
+v3 returns paginated envelope. Use `page` and `page_size` query params.
diff --git a/mem0-plugin/skills/mem0/references/architecture.md b/mem0-plugin/skills/mem0/references/architecture.md
index f0c5c1bc8..4a04c820b 100644
--- a/mem0-plugin/skills/mem0/references/architecture.md
+++ b/mem0-plugin/skills/mem0/references/architecture.md
@@ -25,9 +25,9 @@ User Input → Retrieve relevant memories → Enrich LLM prompt → Generate res
Mem0 handles the complexity of extraction, deduplication, conflict resolution, and semantic retrieval so your application only needs to call `search()` and `add()`.
-**Dual storage architecture:**
+**Storage architecture:**
- **Vector store**: Embeddings for semantic similarity search
-- **Graph store** (optional): Entity nodes and relationship edges for structured knowledge
+- **Entity store**: Automatic entity linking for relationship-aware retrieval
---
@@ -40,41 +40,32 @@ Messages In
│
▼
┌─────────────────────┐
-│ 1. EXTRACTION │ LLM analyzes messages, extracts key facts
+│ 1. EXTRACTION │ Single LLM call extracts all distinct new facts
│ (infer=True) │ If infer=False, stores raw text as-is
└─────────┬───────────┘
│
▼
┌─────────────────────┐
-│ 2. CONFLICT │ Checks existing memories for duplicates
-│ RESOLUTION │ Latest truth wins (newer overrides older)
-│ │ Only runs when infer=True
+│ 2. DEDUPLICATION │ Hash-based dedup (MD5 prevents exact duplicates)
+│ │ No UPDATE/DELETE - v3 is ADD-only
└─────────┬───────────┘
│
▼
┌─────────────────────┐
-│ 3. STORAGE │ Generates embeddings → vector store
-│ │ Optional: entity extraction → graph store
-│ │ Indexes metadata, categories, timestamps
+│ 3. STORAGE │ Batch embed → vector store
+│ │ Entity extraction → entity store
└─────────┬───────────┘
│
▼
Memory Object
- (id, memory, categories, structured_attributes)
```
-### Processing modes
+### Processing (v3)
-**Async (default, `async_mode=True`):**
-- API returns immediately: `{"status": "PENDING", "event_id": "..."}`
-- Processing happens in background
+v3 processes memories asynchronously by default:
+- API returns immediately: `{"status": "PENDING", "event_id": "evt-..."}`
+- Poll status via `GET /v1/event/{event_id}/`
- Use webhooks for completion notifications
-- Best for: high-throughput, non-blocking workflows
-
-**Sync (`async_mode=False`):**
-- API waits for full processing
-- Returns complete memory object with `id`, `event`, `memory`
-- Best for: real-time access immediately after add
### Extraction modes
@@ -93,7 +84,7 @@ Messages In
---
-## Retrieval Pipeline
+## Retrieval Pipeline (v3)
### What happens when you call `client.search()`
@@ -102,45 +93,37 @@ Query In
│
▼
┌─────────────────────┐
-│ 1. QUERY EMBEDDING │ Convert query to vector representation
+│ 1. PREPROCESSING │ Lemmatize keywords, extract entities
└─────────┬───────────┘
│
▼
┌─────────────────────┐
-│ 2. VECTOR SEARCH │ Cosine similarity across stored embeddings
-│ │ Scoped by filters (user_id, agent_id, etc.)
-└─────────┬───────────┘
- │
- ▼ (optional enhancements)
-┌─────────────────────┐
-│ 3a. KEYWORD SEARCH │ Expands results with specific terms (+10ms)
-│ 3b. RERANKING │ Deep semantic reordering (+150-200ms)
-│ 3c. FILTER MEMORIES │ Precision filtering, removes low-relevance (+200-300ms)
-└─────────┬───────────┘
- │
- ▼ (if enable_graph=True)
-┌─────────────────────┐
-│ 4. GRAPH LOOKUP │ Finds entity relationships
-│ │ Appends relations WITHOUT reranking vector results
+│ 2. PARALLEL SCORING │ Semantic search (vector similarity)
+│ │ BM25 keyword search (term matching)
+│ │ Entity matching (entity graph boost)
└─────────┬───────────┘
│
▼
- Results + Relations
+┌─────────────────────┐
+│ 3. SCORE FUSION │ Combine signals into single score
+│ │ Optional: rerank=True for deep reordering
+└─────────┬───────────┘
+ │
+ ▼
+ Results (combined score per memory)
```
-### Retrieval enhancement combinations
+### v3 Search Defaults
-| Configuration | Latency | Best for |
-|--------------|---------|----------|
-| Base search only | ~100ms | Simple lookups |
-| `keyword_search=True` | ~110ms | Entity-heavy queries, broad coverage |
-| `rerank=True` | ~250-300ms | User-facing results, top-N precision |
-| `keyword_search=True` + `rerank=True` | ~310ms | Balanced (recommended for most apps) |
-| `rerank=True` + `filter_memories=True` | ~400-500ms | Safety-critical, production systems |
+| Parameter | Default | Notes |
+|-----------|---------|-------|
+| `top_k` | 20 | Was 100 in v2 |
+| `threshold` | 0.1 | Was None in v2 |
+| `rerank` | False | Was True in v2 |
### Implicit null scoping
-When you search with `user_id="alice"` only, Mem0 returns memories where `agent_id`, `app_id`, and `run_id` are all null. This prevents cross-scope leakage by default.
+When you search with `filters={"user_id": "alice"}` only, Mem0 returns memories where `agent_id`, `app_id`, and `run_id` are all null. This prevents cross-scope leakage by default.
To include memories with non-null fields, use explicit filters:
```python
@@ -150,53 +133,23 @@ filters={"OR": [{"user_id": "alice"}]}
---
-## Memory Lifecycle
+## Memory Lifecycle (v3)
-```
-CREATE ──→ ACTIVE ──→ UPDATE ──→ ACTIVE
- │ │ │
- │ ▼ ▼
- │ EXPIRED EXPIRED
- │ (still stored, (still stored,
- │ not retrieved) not retrieved)
- │ │ │
- ▼ ▼ ▼
-DELETE DELETE DELETE
-(permanent)
-```
+v3 uses ADD-only extraction. Memories accumulate over time rather than being consolidated.
### Creation
-- Triggered by `client.add(messages, user_id="...")`
-- Messages processed through extraction → conflict resolution → storage
-- Gets unique UUID, `created_at` timestamp
-- Optional: custom `timestamp`, `expiration_date`, `metadata`, `immutable`
+- `client.add(messages, user_id="...")`
+- Single-pass extraction → deduplication → storage
+- Returns `{"event_id": "...", "status": "PENDING"}`
### Updates
-- `client.update(memory_id, text="...")` replaces text and reindexes
-- `client.batch_update([...])` for up to 1000 memories at once
-- Immutable memories (`immutable=True`) cannot be updated — must delete and re-add
-
-### Deduplication
-- Automatic during `add()` with `infer=True`
-- Conflict resolution merges duplicate facts
-- Latest truth wins when contradictions detected
-- Prevents memory bloat from repeated information
-
-### Expiration
-- Optional `expiration_date` parameter (ISO 8601 or `YYYY-MM-DD`)
-- After expiration: memory NOT returned in searches but remains in storage
-- Useful for time-sensitive info (events, temporary preferences, session state)
+- `client.update(memory_id, text="...")` replaces text
+- Batch: `client.batch_update([...])`
### Deletion
-- Single: `client.delete(memory_id)` — permanent, no recovery
-- Batch: `client.batch_delete([memory_ids])` — up to 1000
-- Bulk: `client.delete_all(user_id="alice")` — all memories for entity
-- `delete_all()` without filters raises error to prevent accidental data loss
-
-### History tracking
-- `client.history(memory_id)` returns version timeline
-- Shows all changes: `{previous_value, new_value, action, timestamps}`
-- Useful for audit trails and debugging
+- Single: `client.delete(memory_id)`
+- Batch: `client.batch_delete([...])`
+- Bulk: `client.delete_all(filters={"user_id": "alice"})`
---
@@ -214,8 +167,6 @@ DELETE DELETE DELETE
"categories": ["health", "preferences"],
"created_at": "2025-03-12T12:34:56Z",
"updated_at": "2025-03-12T12:34:56Z",
- "expiration_date": null,
- "immutable": false,
"structured_attributes": {
"day": 12, "month": 3, "year": 2025,
"hour": 12, "minute": 34,
@@ -239,8 +190,6 @@ DELETE DELETE DELETE
| `categories` | array | Auto-assigned or custom category tags |
| `created_at` | datetime | Creation timestamp |
| `updated_at` | datetime | Last modification timestamp |
-| `expiration_date` | datetime | Auto-expiry date (stops retrieval, data persists) |
-| `immutable` | boolean | If true, prevents modification |
| `structured_attributes` | object | Temporal breakdown for time-based queries |
| `score` | float | Semantic similarity (search results only, 0-1) |
@@ -322,7 +271,7 @@ Mem0 supports three layers of memory, from shortest to longest lived:
```python
def chat(user_input: str, user_id: str, session_id: str) -> str:
# 1. Retrieve user memories (long-term preferences)
- user_mems = mem0.search(user_input, user_id=user_id)
+ user_mems = mem0.search(user_input, filters={"user_id": user_id})
# 2. Retrieve session memories (current task context)
session_mems = mem0.search(user_input, filters={
@@ -350,18 +299,13 @@ def chat(user_input: str, user_id: str, session_id: str) -> str:
| Operation | Typical Latency |
|-----------|----------------|
-| Base vector search | ~100ms |
-| + keyword_search | +10ms |
+| Hybrid search (v3 default) | ~100-150ms |
| + reranking | +150-200ms |
-| + filter_memories | +200-300ms |
-| Add (async, default) | < 50ms response, background processing |
-| Add (sync) | 500ms-2s depending on extraction complexity |
-| Graph operations | Slight overhead for large stores |
+| Add (async) | < 50ms response |
### Processing
-- **Async mode (default):** Returns immediately, processes in background
-- **Sync mode:** Waits for full extraction + storage pipeline
+- **Async (default):** Returns immediately, processes in background
- **Batch operations:** Up to 1000 memories per batch_update/batch_delete
- **Webhooks:** Real-time notifications when async processing completes
diff --git a/mem0-plugin/skills/mem0/references/features.md b/mem0-plugin/skills/mem0/references/features.md
index fa2130f47..b5d5e73ea 100644
--- a/mem0-plugin/skills/mem0/references/features.md
+++ b/mem0-plugin/skills/mem0/references/features.md
@@ -5,7 +5,7 @@ Additional platform capabilities beyond core CRUD operations.
## Table of Contents
- [Advanced Retrieval](#advanced-retrieval)
-- [Graph Memory](#graph-memory)
+- [Entity Linking](#entity-linking)
- [Custom Categories](#custom-categories)
- [Custom Instructions](#custom-instructions)
- [Criteria Retrieval](#criteria-retrieval)
@@ -18,124 +18,58 @@ Additional platform capabilities beyond core CRUD operations.
## Advanced Retrieval
-Three enhancement options for tuning search precision, recall, and latency.
+### Hybrid Search (v3 Default)
-### Keyword Search (`keyword_search=True`)
+v3 uses multi-signal hybrid search combining:
+- **Semantic search** (vector similarity)
+- **BM25 keyword search** (normalized term matching)
+- **Entity matching** (entity graph boost)
-Expands results to include memories with specific terms, names, and technical keywords.
-
-- Latency: +10ms
-- Recall: Significantly increased
-- Best for: entity-heavy queries, comprehensive coverage
+This is automatic — no configuration needed.
### Reranking (`rerank=True`)
Deep semantic reordering of results — most relevant first.
- Latency: +150-200ms
-- Accuracy: Significantly improved
+- Default: `False` (was `True` in v2)
- Best for: user-facing results, top-N precision
-### Filter Memories (`filter_memories=True`)
-
-Precision filtering — removes low-relevance results entirely.
-
-- Latency: +200-300ms
-- Precision: Maximized
-- Best for: safety-critical applications, production systems
-
-### Recommended Combinations
-
**Python:**
```python
-# Fast & broad
-results = client.search(query, keyword_search=True, user_id="user123")
-
-# Balanced (recommended for most apps)
-results = client.search(query, keyword_search=True, rerank=True, user_id="user123")
-
-# High precision (critical apps)
-results = client.search(query, rerank=True, filter_memories=True, user_id="user123")
+results = client.search(query, filters={"user_id": "user123"}, rerank=True)
```
**TypeScript:**
```typescript
const results = await client.search(query, {
- user_id: 'user123',
- keyword_search: true,
+ filters: { user_id: 'user123' },
rerank: true,
});
```
---
-## Graph Memory
+## Entity Linking
-Entity-level knowledge graph that creates relationships between memories.
+v3 replaces graph memory with built-in entity linking. Entities (proper nouns, quoted text, compound noun phrases) are automatically extracted and linked across memories.
### How It Works
-1. **Extraction**: LLM analyzes conversation and identifies entities and relationships
-2. **Storage**: Embeddings go to vector store; entity nodes and edges go to graph store
-3. **Retrieval**: Vector search returns semantic matches; graph relations are appended to results
+1. **Extraction**: During `add()`, entities are automatically extracted from memory text
+2. **Storage**: Entities are stored in a parallel collection (`{collection}_entities`)
+3. **Retrieval**: During `search()`, query entities are matched and used to boost relevant memories
-Graph relations **augment** vector results without reordering them. Vector similarity always determines hit sequence.
+Entity linking is automatic — no configuration required. The boost is folded into the combined `score` on each result.
-### Enabling Graph Memory
+### v2 Migration Note
-**Per request:**
-```python
-client.add(messages, user_id="alice", enable_graph=True)
-client.search("query", user_id="alice", enable_graph=True)
-client.get_all(filters={"AND": [{"user_id": "alice"}]}, enable_graph=True)
-```
+If you were using `enable_graph=True` in v2:
+- Remove `enable_graph` from all API calls
+- Remove `graph_store` from OSS configuration
+- Entity relationships are now consumed through retrieval ranking, not exposed as a separate `relations` array
-**Project-level (default for all operations):**
-```python
-client.project.update(enable_graph=True)
-```
-
-```javascript
-await client.updateProject({ enable_graph: true });
-```
-
-### Relation Structure
-
-Each relation in the response contains:
-
-| Field | Type | Description |
-|-------|------|-------------|
-| `source` | string | Source entity name |
-| `source_type` | string | Source entity type (e.g., "Person") |
-| `relationship` | string | Relationship label (e.g., "lives_in") |
-| `target` | string | Target entity name |
-| `target_type` | string | Target entity type (e.g., "City") |
-| `score` | number | Confidence score |
-
-**Example:**
-```json
-{
- "relations": [
- {
- "source": "Joseph",
- "source_type": "Person",
- "relationship": "lives_in",
- "target": "Seattle",
- "target_type": "City",
- "score": 0.92
- }
- ]
-}
-```
-
-### Technical Notes
-
-- Graph Memory adds processing time; see docs for current plan availability
-- Works optimally with rich conversation histories containing entity relationships
-- Best suited for long-running assistants tracking evolving information
-- Graph writes and reads toggle independently per request
-- Multi-agent context supported via `user_id`, `agent_id`, `run_id` scoping
-- Add operations are asynchronous; graph metadata may not be immediately available
+See the [v2 to v3 migration guide](https://docs.mem0.ai/migration/oss-v2-to-v3) for details.
---
@@ -160,7 +94,7 @@ client.project.update(custom_categories=new_categories)
```
```javascript
-await client.updateProject({ custom_categories: new_categories });
+await client.updateProject({ customCategories: newCategories });
```
**Retrieve active categories:**
@@ -185,7 +119,7 @@ client.project.update(custom_instructions="Your guidelines here...")
```
```javascript
-await client.updateProject({ custom_instructions: "Your guidelines here..." });
+await client.updateProject({ customInstructions: "Your guidelines here..." });
```
### Template Structure
@@ -229,7 +163,7 @@ client.project.update(retrieval_criteria=retrieval_criteria)
```typescript
await client.updateProject({
- retrieval_criteria: [
+ retrievalCriteria: [
{ name: 'joy', description: 'Positive emotions', weight: 3 },
{ name: 'urgency', description: 'Time-sensitive items', weight: 4 },
],
@@ -281,7 +215,7 @@ for item in feedback_data:
```typescript
await client.feedback('mem-123', {
feedback: 'POSITIVE',
- feedback_reason: 'Accurately captured dietary preference',
+ feedbackReason: 'Accurately captured dietary preference',
});
```
@@ -349,23 +283,18 @@ Use the `name` field in messages to identify speakers. Mem0 maps names to entity
## MCP Integration
-Model Context Protocol integration enables AI clients (Claude Desktop, Cursor, custom agents) to manage Mem0 memory autonomously.
+Model Context Protocol integration enables AI clients (Claude, Claude Code, Cursor, Windsurf, VS Code, OpenCode) to manage Mem0 memory autonomously.
-### Configuration
+### Setup
-```json
-{
- "mcpServers": {
- "mem0": {
- "command": "uvx",
- "args": ["mem0-mcp-server"],
- "env": {
- "MEM0_API_KEY": "m0-your-api-key",
- "MEM0_DEFAULT_USER_ID": "your-user-id"
- }
- }
- }
-}
+Add Mem0 MCP to your clients with a single command:
+
+```bash
+npx mcp-add \
+ --name mem0-mcp \
+ --type http \
+ --url "https://mcp.mem0.ai/mcp" \
+ --clients "claude,claude code,cursor,windsurf,vscode,opencode"
```
### Available MCP Tools
@@ -377,7 +306,7 @@ The MCP server exposes 9 memory tools that AI agents can use autonomously:
### How It Works
-1. Configure the MCP server in your AI client
+1. Add Mem0 MCP to your AI client using the setup command above
2. The agent autonomously decides when to store/retrieve memories
3. No manual API calls needed — the agent manages memory as part of its reasoning
diff --git a/mem0-plugin/skills/mem0/references/integration-patterns.md b/mem0-plugin/skills/mem0/references/integration-patterns.md
index e00d07ba7..71cfa981c 100644
--- a/mem0-plugin/skills/mem0/references/integration-patterns.md
+++ b/mem0-plugin/skills/mem0/references/integration-patterns.md
@@ -27,7 +27,7 @@ from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from mem0 import MemoryClient
-llm = ChatOpenAI(model="gpt-4.1-nano-2025-04-14")
+llm = ChatOpenAI(model="gpt-5-mini")
mem0 = MemoryClient()
prompt = ChatPromptTemplate.from_messages([
@@ -38,7 +38,7 @@ prompt = ChatPromptTemplate.from_messages([
def retrieve_context(query: str, user_id: str):
"""Retrieve relevant memories from Mem0"""
- memories = mem0.search(query, user_id=user_id)
+ memories = mem0.search(query, filters={"user_id": user_id})
memory_list = memories['results']
serialized = ' '.join([m["memory"] for m in memory_list])
return [
@@ -116,73 +116,24 @@ result = crew.kickoff()
## Vercel AI SDK
-Source: [docs.mem0.ai/integrations/vercel-ai-sdk](https://docs.mem0.ai/integrations/vercel-ai-sdk)
+> **Dedicated skill available.** For comprehensive Vercel AI SDK documentation, see the [mem0-vercel-ai-sdk skill](https://github.com/mem0ai/mem0/tree/main/skills/mem0-vercel-ai-sdk).
Install: `npm install @mem0/vercel-ai-provider`
-### Basic Text Generation with Memory
+Quick example (wrapped model with automatic memory):
```typescript
import { generateText } from "ai";
import { createMem0 } from "@mem0/vercel-ai-provider";
-const mem0 = createMem0({
- provider: "openai",
- mem0ApiKey: "m0-xxx",
- apiKey: "openai-api-key",
-});
-
-const { text } = await generateText({
- model: mem0("gpt-4-turbo", { user_id: "borat" }),
- prompt: "Suggest me a good car to buy!",
-});
-```
-
-### Streaming with Memory
-
-```typescript
-import { streamText } from "ai";
-import { createMem0 } from "@mem0/vercel-ai-provider";
-
const mem0 = createMem0();
-
-const { textStream } = streamText({
- model: mem0("gpt-4-turbo", { user_id: "borat" }),
+const { text } = await generateText({
+ model: mem0("gpt-5-mini", { user_id: "borat" }),
prompt: "Suggest me a good car to buy!",
});
-
-for await (const textPart of textStream) {
- process.stdout.write(textPart);
-}
```
-### Using Memory Utilities Standalone
-
-```typescript
-import { openai } from "@ai-sdk/openai";
-import { generateText } from "ai";
-import { retrieveMemories, addMemories } from "@mem0/vercel-ai-provider";
-
-// Retrieve memories and inject into any provider
-const prompt = "Suggest me a good car to buy.";
-const memories = await retrieveMemories(prompt, { user_id: "borat", mem0ApiKey: "m0-xxx" });
-
-const { text } = await generateText({
- model: openai("gpt-4-turbo"),
- prompt: prompt,
- system: memories,
-});
-
-// Store new memories
-await addMemories(
- [{ role: "user", content: [{ type: "text", text: "I love red cars." }] }],
- { user_id: "borat", mem0ApiKey: "m0-xxx" }
-);
-```
-
-### Supported Providers
-
-`openai`, `anthropic`, `google`, `groq`
+Supported providers: `openai`, `anthropic`, `google`, `groq`, `cohere`
---
@@ -199,7 +150,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, top_k=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."
@@ -216,7 +167,7 @@ agent = Agent(
Use search_memory to recall past conversations.
Use save_memory to store important information.""",
tools=[search_memory, save_memory],
- model="gpt-4.1-nano-2025-04-14"
+ model="gpt-5-mini"
)
result = Runner.run_sync(agent, "I love Italian food and I'm planning a trip to Rome next month")
@@ -232,21 +183,21 @@ travel_agent = Agent(
name="Travel Planner",
instructions="You are a travel planning specialist. Use search_memory and save_memory tools.",
tools=[search_memory, save_memory],
- model="gpt-4.1-nano-2025-04-14"
+ model="gpt-5-mini"
)
health_agent = Agent(
name="Health Advisor",
instructions="You are a health and wellness advisor. Use search_memory and save_memory tools.",
tools=[search_memory, save_memory],
- model="gpt-4.1-nano-2025-04-14"
+ model="gpt-5-mini"
)
triage_agent = Agent(
name="Personal Assistant",
instructions="""Route travel questions to Travel Planner, health questions to Health Advisor.""",
handoffs=[travel_agent, health_agent],
- model="gpt-4.1-nano-2025-04-14"
+ model="gpt-5-mini"
)
result = Runner.run_sync(triage_agent, "Plan a healthy meal for my Italy trip")
@@ -303,7 +254,7 @@ from langchain_openai import ChatOpenAI
from mem0 import MemoryClient
from langchain_core.messages import SystemMessage, HumanMessage, AIMessage
-llm = ChatOpenAI(model="gpt-4")
+llm = ChatOpenAI(model="gpt-5-mini")
mem0 = MemoryClient()
class State(TypedDict):
@@ -315,7 +266,7 @@ def chatbot(state: State):
user_id = state["mem0_user_id"]
# Retrieve relevant memories
- memories = mem0.search(messages[-1].content, user_id=user_id)
+ memories = mem0.search(messages[-1].content, filters={"user_id": user_id})
context = "Relevant context:\n"
for memory in memories["results"]:
context += f"- {memory['memory']}\n"
@@ -368,7 +319,7 @@ memory = Mem0Memory.from_client(
from llama_index.core.agent import FunctionCallingAgent
from llama_index.llms.openai import OpenAI
-llm = OpenAI(model="gpt-4")
+llm = OpenAI(model="gpt-5-mini")
agent = FunctionCallingAgent.from_tools(
tools=[],
llm=llm,
@@ -401,14 +352,14 @@ USER_ID = "alice"
agent = ConversableAgent(
"chatbot",
- llm_config={"config_list": [{"model": "gpt-4", "api_key": os.environ["OPENAI_API_KEY"]}]},
+ llm_config={"config_list": [{"model": "gpt-5-mini", "api_key": os.environ["OPENAI_API_KEY"]}]},
code_execution_config=False,
human_input_mode="NEVER",
)
def get_context_aware_response(question: str) -> str:
# Retrieve memories for context
- 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 considering previous interactions:
diff --git a/mem0-plugin/skills/mem0/references/quickstart.md b/mem0-plugin/skills/mem0/references/quickstart.md
index cfd34b86e..0a47a2fd4 100644
--- a/mem0-plugin/skills/mem0/references/quickstart.md
+++ b/mem0-plugin/skills/mem0/references/quickstart.md
@@ -27,7 +27,7 @@ messages = [
client.add(messages, user_id="user123")
# Search memories
-results = client.search("What are my dietary restrictions?", user_id="user123")
+results = client.search("What are my dietary restrictions?", filters={"user_id": "user123"})
print(results)
```
@@ -39,7 +39,7 @@ from mem0 import AsyncMemoryClient
client = AsyncMemoryClient(api_key="your-api-key")
await client.add(messages, user_id="user123")
-results = await client.search("query", user_id="user123")
+results = await client.search("query", filters={"user_id": "user123"})
```
## TypeScript / JavaScript Setup
@@ -59,11 +59,11 @@ const messages = [
{"role": "user", "content": "I'm a vegetarian and allergic to nuts."},
{"role": "assistant", "content": "Got it! I'll remember your dietary preferences."}
];
-await client.add(messages, { user_id: "user123" });
+await client.add(messages, { userId: "user123" });
// Search memories
const results = await client.search("What are my dietary restrictions?", {
- user_id: "user123"
+ filters: { user_id: "user123" }
});
console.log(results);
```
@@ -86,7 +86,7 @@ curl -X POST https://api.mem0.ai/v1/memories/ \
}'
# Search memories
-curl -X POST https://api.mem0.ai/v2/memories/search/ \
+curl -X POST https://api.mem0.ai/v3/memories/search/ \
-H "Authorization: Token $MEM0_API_KEY" \
-H "Content-Type: application/json" \
-d '{
diff --git a/mem0-plugin/skills/mem0/references/sdk-guide.md b/mem0-plugin/skills/mem0/references/sdk-guide.md
index dc744d625..512c0d19c 100644
--- a/mem0-plugin/skills/mem0/references/sdk-guide.md
+++ b/mem0-plugin/skills/mem0/references/sdk-guide.md
@@ -2,6 +2,8 @@
Complete SDK reference for Python and TypeScript. All methods use `MemoryClient` (Platform API).
+> **For language-specific deep references (including OSS):** See [client/python.md](../client/python.md) and [client/node.md](../client/node.md). For Python vs TypeScript differences: [client/differences.md](../client/differences.md).
+
## Initialization
**Python:**
@@ -38,16 +40,12 @@ client.add(messages, user_id="alice")
# With metadata
client.add(messages, user_id="alice", metadata={"source": "onboarding"})
-
-# With graph memory
-client.add(messages, user_id="alice", enable_graph=True)
```
**TypeScript:**
```typescript
-await client.add(messages, { user_id: "alice" });
-await client.add(messages, { user_id: "alice", metadata: { source: "onboarding" } });
-await client.add(messages, { user_id: "alice", enable_graph: true });
+await client.add(messages, { userId: "alice" });
+await client.add(messages, { userId: "alice", metadata: { source: "onboarding" } });
```
### Parameters
@@ -59,32 +57,14 @@ await client.add(messages, { user_id: "alice", enable_graph: true });
| `agent_id` | string | Agent identifier |
| `run_id` | string | Session identifier |
| `metadata` | object | Custom key-value pairs |
-| `enable_graph` | boolean | Activate knowledge graph |
| `infer` | boolean | If `false`, store raw text without inference (default: `true`) |
-| `immutable` | boolean | Prevents modification after creation |
-| `expiration_date` | string | Auto-expiry date (`YYYY-MM-DD`) |
-| `includes` | string | Preference filters for inclusion |
-| `excludes` | string | Preference filters for exclusion |
-| `async_mode` | boolean | Async processing (default: `true`). Set `false` to wait |
### Advanced Add Options
```python
-# Immutable -- cannot be modified or overwritten
-client.add(messages, user_id="alice", immutable=True)
-
-# Expiring memory
-client.add(messages, user_id="alice", expiration_date="2025-12-31")
-
-# Selective extraction
-client.add(messages, user_id="alice", includes="dietary preferences", excludes="payment info")
-
# Agent + session scoping
client.add(messages, user_id="alice", agent_id="nutrition-agent", run_id="session-456")
-# Synchronous processing (wait for completion)
-client.add(messages, user_id="alice", async_mode=False)
-
# Raw text -- skip LLM inference
client.add(
[{"role": "user", "content": "User prefers dark mode."}],
@@ -99,7 +79,7 @@ client.add(
**Python:**
```python
-results = client.search("dietary preferences?", user_id="alice")
+results = client.search("dietary preferences?", filters={"user_id": "alice"})
# With filters and reranking
results = client.search(
@@ -109,20 +89,14 @@ results = client.search(
rerank=True,
threshold=0.5
)
-
-# With graph relations
-results = client.search("colleagues", user_id="alice", enable_graph=True)
-
-# Keyword search
-results = client.search("vegetarian", user_id="alice", keyword_search=True)
```
**TypeScript:**
```typescript
-const results = await client.search("dietary preferences", { user_id: "alice" });
+const results = await client.search("dietary preferences", { filters: { user_id: "alice" } });
const results = await client.search("work experience", {
filters: { AND: [{ user_id: "alice" }, { categories: { contains: "professional_details" } }] },
- top_k: 5,
+ topK: 5,
rerank: true,
});
```
@@ -132,19 +106,17 @@ const results = await client.search("work experience", {
| Name | Type | Description |
|------|------|-------------|
| `query` | string | Natural language search query |
-| `user_id` | string | Filter by user |
-| `filters` | object | V2 filter object (AND/OR operators) |
-| `top_k` | number | Number of results (default: 10) |
-| `rerank` | boolean | Enable reranking for better relevance |
-| `threshold` | number | Minimum similarity score (default: 0.3) |
-| `keyword_search` | boolean | Use keyword-based search |
-| `enable_graph` | boolean | Include graph relations |
+| `filters` | object | Filter object (AND/OR operators). Use `{"user_id": "..."}` to filter by user |
+| `top_k` | number | Number of results (default: 10 for Platform) |
+| `rerank` | boolean | Enable reranking for better relevance (default: `false`) |
+| `threshold` | number | Minimum similarity score (default: 0.1) |
### Common Filter Patterns
+**Python:**
```python
-# Single user (shorthand)
-client.search("query", user_id="alice")
+# Single user filter
+filters={"user_id": "alice"}
# OR across agents
filters={"OR": [{"user_id": "alice"}, {"agent_id": {"in": ["travel-agent", "sports-agent"]}}]}
@@ -177,6 +149,21 @@ filters={"AND": [
]}
```
+**TypeScript:**
+```typescript
+// Single user filter
+filters: { user_id: "alice" }
+
+// OR across agents
+filters: { OR: [{ user_id: "alice" }, { agent_id: { in: ["travel-agent", "sports-agent"] } }] }
+
+// Category filtering (partial match)
+filters: { AND: [{ user_id: "alice" }, { categories: { contains: "finance" } }] }
+
+// Category filtering (exact match)
+filters: { AND: [{ user_id: "alice" }, { categories: { in: ["personal_information"] } }] }
+```
+
---
## get() / getAll() -- Retrieve Memories
@@ -187,7 +174,7 @@ filters={"AND": [
memory = client.get(memory_id="ea925981-...")
# All memories for a user
-memories = client.get_all(filters={"AND": [{"user_id": "alice"}]})
+memories = client.get_all(filters={"user_id": "alice"})
# With date range
memories = client.get_all(
@@ -196,15 +183,12 @@ memories = client.get_all(
{"created_at": {"gte": "2024-07-01", "lte": "2024-07-31"}}
]}
)
-
-# With graph data
-memories = client.get_all(filters={"AND": [{"user_id": "alice"}]}, enable_graph=True)
```
**TypeScript:**
```typescript
const memory = await client.get("ea925981-...");
-const memories = await client.getAll({ filters: { AND: [{ user_id: "alice" }] } });
+const memories = await client.getAll({ filters: { user_id: "alice" } });
```
**Note:** `get_all` requires at least one of `user_id`, `agent_id`, `app_id`, or `run_id` in filters.
@@ -224,8 +208,6 @@ client.update(memory_id="ea925981-...", text="Updated", metadata={"verified": Tr
await client.update("ea925981-...", { text: "Updated: vegan since 2024" });
```
-Cannot update immutable memories.
-
---
## delete() / deleteAll() -- Remove Memories
@@ -239,7 +221,7 @@ client.delete_all(user_id="alice") # Irreversible bulk delete
**TypeScript:**
```typescript
await client.delete("ea925981-...");
-await client.deleteAll({ user_id: "alice" });
+await client.deleteAll({ userId: "alice" });
```
---
@@ -299,10 +281,73 @@ data = client.get_memory_export(memory_export_id=export["id"])
2. **SQL operators rejected** -- use `gte`, `lt`, etc. Not `>=`, `<`.
3. **Metadata filtering is limited** -- only top-level keys with `eq`, `contains`, `ne`.
4. **Wildcard `*` excludes null** -- only matches non-null values.
-5. **Default threshold is 0.3** -- increase for stricter matching.
+5. **Default threshold is 0.1** -- increase for stricter matching.
6. **Async processing** -- memories process asynchronously. Wait 2-3s after `add()` before searching.
-7. **Immutable memories** -- cannot be updated or deleted once created.
## Naming Conventions
-Python uses `snake_case` (`user_id`, `memory_id`, `get_all`). TypeScript uses `camelCase` for methods (`getAll`, `deleteAll`, `batchUpdate`) but `snake_case` for API parameters (`user_id`, `agent_id`).
+Python uses `snake_case` everywhere (`user_id`, `memory_id`, `get_all`). TypeScript uses `camelCase` for methods (`getAll`, `deleteAll`, `batchUpdate`) and top-level parameters (`userId`, `topK`, `pageSize`), but filter keys use `snake_case` (`user_id`, `agent_id`).
+
+---
+
+## v2 to v3 Migration
+
+### Breaking Changes in v3
+
+**1. Entity IDs in search() and getAll()**
+
+v3 requires entity IDs (`user_id`, `agent_id`, `run_id`) inside `filters` instead of as top-level parameters:
+
+```python
+# v2 (deprecated)
+client.search("query", user_id="alice")
+client.get_all(user_id="alice")
+
+# v3
+client.search("query", filters={"user_id": "alice"})
+client.get_all(filters={"user_id": "alice"})
+```
+
+```typescript
+// v2 (deprecated)
+await client.search("query", { user_id: "alice" });
+await client.getAll({ user_id: "alice" });
+
+// v3
+await client.search("query", { filters: { user_id: "alice" } });
+await client.getAll({ filters: { user_id: "alice" } });
+```
+
+**2. TypeScript Parameter Naming**
+
+v3 TypeScript uses camelCase for all parameters:
+
+| v2 | v3 |
+|----|-----|
+| `user_id` | `userId` |
+| `agent_id` | `agentId` |
+| `run_id` | `runId` |
+| `top_k` | `topK` |
+| `page_size` | `pageSize` |
+
+**3. Default Values Changed**
+
+| Parameter | v2 Default | v3 Default |
+|-----------|------------|------------|
+| `threshold` | 0.3 | 0.1 |
+| `rerank` | (not specified) | `false` |
+
+**4. Removed Parameters**
+
+The following parameters are no longer supported:
+
+| Parameter | Status |
+|-----------|--------|
+| `enable_graph` | Removed from add/search/getAll |
+| `keyword_search` | Removed from search |
+| `filter_memories` | Removed |
+| `immutable` | Removed from add |
+| `expiration_date` | Removed from add |
+| `includes` | Removed from add |
+| `excludes` | Removed from add |
+| `async_mode` | Removed from add |
diff --git a/mem0-plugin/skills/mem0/references/use-cases.md b/mem0-plugin/skills/mem0/references/use-cases.md
index eaca88896..5f3ba655d 100644
--- a/mem0-plugin/skills/mem0/references/use-cases.md
+++ b/mem0-plugin/skills/mem0/references/use-cases.md
@@ -39,7 +39,7 @@ Use these known facts about the user to personalize your response:
{context if context else 'No prior context yet.'}"""
response = openai_client.chat.completions.create(
- model="gpt-4.1-nano-2025-04-14",
+ model="gpt-5-mini",
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_input},
@@ -72,14 +72,14 @@ const openai = new OpenAI();
async function chat(userInput: string, userId: string): Promise {
// 1. Retrieve relevant memories
- const memories = await mem0.search(userInput, { user_id: userId });
+ const memories = await mem0.search(userInput, { filters: { user_id: userId } });
const context = memories.results
?.map((m: any) => `- ${m.memory}`)
.join('\n') || 'No prior context yet.';
// 2. Generate response with memory context
const response = await openai.chat.completions.create({
- model: 'gpt-4.1-nano-2025-04-14',
+ model: 'gpt-5-mini',
messages: [
{ role: 'system', content: `You are Ray, a personal fitness coach.\nUser context:\n${context}` },
{ role: 'user', content: userInput },
@@ -90,7 +90,7 @@ async function chat(userInput: string, userId: string): Promise {
// 3. Store interaction
await mem0.add(
[{ role: 'user', content: userInput }, { role: 'assistant', content: reply }],
- { user_id: userId }
+ { userId: userId }
);
return reply;
}
@@ -182,7 +182,7 @@ await client.updateProject({
async function logInteraction(userId: string, message: string, priority = 'normal') {
await client.add(
[{ role: 'user', content: message }],
- { user_id: userId, metadata: { priority, source: 'support_chat' } }
+ { userId: userId, metadata: { priority, source: 'support_chat' } }
);
}
@@ -230,7 +230,7 @@ def consult(user_id: str, question: str) -> str:
context = "\n".join([f"- {m['memory']}" for m in memories.get("results", [])])
response = openai_client.chat.completions.create(
- model="gpt-4.1-nano-2025-04-14",
+ model="gpt-5-mini",
messages=[
{"role": "system", "content": f"You are a health coach. Patient context:\n{context}"},
{"role": "user", "content": question},
@@ -264,20 +264,20 @@ const openai = new OpenAI();
async function savePatientInfo(userId: string, info: string) {
await mem0.add(
[{ role: 'user', content: info }],
- { user_id: userId, run_id: 'healthcare_session', metadata: { type: 'patient_information' } }
+ { userId: userId, runId: 'healthcare_session', metadata: { type: 'patient_information' } }
);
}
async function consult(userId: string, question: string): Promise {
const memories = await mem0.search(question, {
- user_id: userId,
- top_k: 5,
+ filters: { user_id: userId },
+ topK: 5,
threshold: 0.7,
});
const context = memories.results?.map((m: any) => `- ${m.memory}`).join('\n') || '';
const response = await openai.chat.completions.create({
- model: 'gpt-4.1-nano-2025-04-14',
+ model: 'gpt-5-mini',
messages: [
{ role: 'system', content: `You are a health coach. Patient context:\n${context}` },
{ role: 'user', content: question },
@@ -287,7 +287,7 @@ async function consult(userId: string, question: string): Promise {
await mem0.add(
[{ role: 'user', content: question }, { role: 'assistant', content: reply }],
- { user_id: userId, run_id: 'healthcare_session' }
+ { userId: userId, runId: 'healthcare_session' }
);
return reply;
}
@@ -333,7 +333,7 @@ def draft_content(user_id: str, topic: str) -> str:
style_context = "\n".join([f"- {m['memory']}" for m in prefs.get("results", [])])
response = openai_client.chat.completions.create(
- model="gpt-4.1-nano-2025-04-14",
+ model="gpt-5-mini",
messages=[
{"role": "system", "content": f"Write content matching these style preferences:\n{style_context}"},
{"role": "user", "content": f"Write a blog post about: {topic}"},
@@ -359,7 +359,7 @@ const openai = new OpenAI();
async function storePreferences(userId: string, preferences: string) {
await mem0.add(
[{ role: 'user', content: preferences }],
- { user_id: userId, run_id: 'editing_session', metadata: { type: 'preferences' } }
+ { userId: userId, runId: 'editing_session', metadata: { type: 'preferences' } }
);
}
@@ -370,7 +370,7 @@ async function draftContent(userId: string, topic: string): Promise {
const styleContext = prefs.results?.map((m: any) => `- ${m.memory}`).join('\n') || '';
const response = await openai.chat.completions.create({
- model: 'gpt-4.1-nano-2025-04-14',
+ model: 'gpt-5-mini',
messages: [
{ role: 'system', content: `Write content matching these preferences:\n${styleContext}` },
{ role: 'user', content: `Write a blog post about: ${topic}` },
@@ -465,10 +465,10 @@ async function storeScopedMemory(
userId: string, agentId: string, runId: string, appId: string
) {
await client.add(messages, {
- user_id: userId,
- agent_id: agentId,
- run_id: runId,
- app_id: appId,
+ userId: userId,
+ agentId: agentId,
+ runId: runId,
+ appId: appId,
});
}
@@ -520,7 +520,7 @@ def personalized_search(user_id: str, query: str, search_results: list) -> str:
user_context = "\n".join([f"- {m['memory']}" for m in memories.get("results", [])])
response = openai_client.chat.completions.create(
- model="gpt-4.1-nano-2025-04-14",
+ model="gpt-5-mini",
messages=[
{"role": "system", "content": f"Personalize search results using user context:\n{user_context}"},
{"role": "user", "content": f"Query: {query}\n\nSearch results:\n{search_results}"},
@@ -551,11 +551,11 @@ const mem0 = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! });
const openai = new OpenAI();
async function personalizedSearch(userId: string, query: string, searchResults: string[]): Promise {
- const memories = await mem0.search(query, { user_id: userId, top_k: 5 });
+ const memories = await mem0.search(query, { filters: { user_id: userId }, topK: 5 });
const context = memories.results?.map((m: any) => `- ${m.memory}`).join('\n') || '';
const response = await openai.chat.completions.create({
- model: 'gpt-4.1-nano-2025-04-14',
+ model: 'gpt-5-mini',
messages: [
{ role: 'system', content: `Personalize results using user context:\n${context}` },
{ role: 'user', content: `Query: ${query}\nResults: ${searchResults.join(', ')}` },
@@ -563,7 +563,7 @@ async function personalizedSearch(userId: string, query: string, searchResults:
});
const reply = response.choices[0].message.content!;
- await mem0.add([{ role: 'user', content: query }], { user_id: userId });
+ await mem0.add([{ role: 'user', content: query }], { userId: userId });
return reply;
}
```
@@ -631,14 +631,14 @@ const client = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! });
async function storeEmail(userId: string, sender: string, subject: string, body: string, date: string) {
await client.add(
[{ role: 'user', content: `Email from ${sender}: ${subject}\n\n${body}` }],
- { user_id: userId, metadata: { email_type: 'incoming', sender, subject, date } }
+ { userId: userId, metadata: { email_type: 'incoming', sender, subject, date } }
);
}
async function searchEmails(userId: string, query: string) {
return client.search(query, {
filters: { AND: [{ user_id: userId }, { categories: { contains: 'email' } }] },
- top_k: 10,
+ topK: 10,
});
}
```
diff --git a/mem0-ts/package.json b/mem0-ts/package.json
index f0cd2994a..ec7235bac 100644
--- a/mem0-ts/package.json
+++ b/mem0-ts/package.json
@@ -1,6 +1,6 @@
{
"name": "mem0ai",
- "version": "3.0.1",
+ "version": "3.0.2",
"description": "The Memory Layer For Your AI Apps",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
diff --git a/pyproject.toml b/pyproject.toml
index fa3a553e1..94bdf4e1a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "mem0ai"
-version = "2.0.0"
+version = "2.0.1"
description = "Long-term memory for AI Agents"
authors = [
{ name = "Mem0", email = "support@mem0.ai" }