Compare commits

..
Author SHA1 Message Date
kartik-mem0 1fa1c456b7 docs: add SECURITY.md and refresh contribution guidelines
- Add SECURITY.md with a private disclosure policy (GitHub Security
  Advisories + support@mem0.ai, 72h acknowledgement window).
- Expand CONTRIBUTING.md: issue-first workflow, mandatory CLA, separate
  Python (hatch) and TypeScript (pnpm) SDK setup, good-practices section,
  and a PR checklist.
- Update docs/contributing/development.mdx to match, adding the missing
  TypeScript SDK environment setup.
2026-06-25 14:41:42 +05:30
126 changed files with 1260 additions and 1982 deletions
@@ -50,7 +50,6 @@ Provide conversation messages for Mem0 to extract memories from. At least one en
| `app_id` | string | No* | Associates the memory with an app. | | `app_id` | string | No* | Associates the memory with an app. |
| `metadata` | object | Optional | Custom key/value metadata (e.g., `{"topic": "preferences"}`). | | `metadata` | object | Optional | Custom key/value metadata (e.g., `{"topic": "preferences"}`). |
| `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. | | `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. |
| `expiration_date` | string | Optional | Date in `YYYY-MM-DD` format. The memory is visible through this date and hidden by default after it passes. |
> \* At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required. > \* At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required.
@@ -84,11 +83,3 @@ The request is queued for background processing. The response contains an `event
<Info> <Info>
Poll the event status via `GET /v1/event/{event_id}/`. Status will be `SUCCEEDED` or `FAILED` once processing completes. Poll the event status via `GET /v1/event/{event_id}/`. Status will be `SUCCEEDED` or `FAILED` once processing completes.
</Info> </Info>
<Info>
Memories with `expiration_date` remain stored after they expire. Search and get-all hide them by default; pass `show_expired: true` to include them.
</Info>
<Info>
Python uses `expiration_date`; TypeScript uses `expirationDate`.
</Info>
@@ -4,4 +4,4 @@ description: "Submit an export job to create a structured memory export using a
openapi: post /v1/exports/ openapi: post /v1/exports/
--- ---
Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you're exporting a large number of memories. You can tailor the export by applying various filters (e.g., `user_id`, `agent_id`, `app_id`, or `run_id`) and by modifying the Pydantic schema to ensure the final data matches your exact needs. Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you're exporting a large number of memories. You can tailor the export by applying various filters (e.g., `user_id`, `agent_id`, `run_id`, or `session_id`) and by modifying the Pydantic schema to ensure the final data matches your exact needs.
@@ -6,10 +6,6 @@ openapi: post /v3/memories/
List memories scoped by filters with paginated results. Entity IDs (`user_id`, `agent_id`, `app_id`, `run_id`) **must** be passed inside the `filters` object — top-level entity IDs are rejected with 400. List memories scoped by filters with paginated results. Entity IDs (`user_id`, `agent_id`, `app_id`, `run_id`) **must** be passed inside the `filters` object — top-level entity IDs are rejected with 400.
Expired memories are hidden by default. Pass `show_expired: true` to include memories whose `expiration_date` has passed.
Python uses `show_expired`; TypeScript uses `showExpired`.
The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators: The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators:
- `in`: Matches any of the values specified - `in`: Matches any of the values specified
@@ -36,7 +32,6 @@ memories = client.get_all(
} }
] ]
}, },
show_expired=False,
page=1, page=1,
page_size=50 page_size=50
) )
@@ -51,14 +46,12 @@ memories = client.get_all(
{ {
"id": "f4cbdb08-7062-4f3e-8eb2-9f5c80dfe64c", "id": "f4cbdb08-7062-4f3e-8eb2-9f5c80dfe64c",
"memory": "Alex is planning a trip to San Francisco from July 1st to July 10th", "memory": "Alex is planning a trip to San Francisco from July 1st to July 10th",
"expiration_date": null,
"created_at": "2024-07-01T12:00:00Z", "created_at": "2024-07-01T12:00:00Z",
"updated_at": "2024-07-01T12:00:00Z" "updated_at": "2024-07-01T12:00:00Z"
}, },
{ {
"id": "a2b8c3d4-5e6f-7g8h-9i0j-1k2l3m4n5o6p", "id": "a2b8c3d4-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
"memory": "Alex prefers vegetarian restaurants", "memory": "Alex prefers vegetarian restaurants",
"expiration_date": null,
"created_at": "2024-07-05T15:30:00Z", "created_at": "2024-07-05T15:30:00Z",
"updated_at": "2024-07-05T15:30:00Z" "updated_at": "2024-07-05T15:30:00Z"
} }
@@ -4,4 +4,4 @@ description: "Retrieve the latest structured memory export after submitting an e
openapi: post /v1/exports/get openapi: post /v1/exports/get
--- ---
Retrieve the latest structured memory export after submitting an export job. You can filter the export by `user_id`, `agent_id`, `app_id`, `run_id`, `created_at`, or `updated_at` to get the most recent export matching your filters. Retrieve the latest structured memory export after submitting an export job. You can filter the export by `user_id`, `run_id`, `session_id`, or `app_id` to get the most recent export matching your filters.
+5 -11
View File
@@ -8,10 +8,6 @@ Relevance-ranked hybrid search across stored memories. V3 uses multi-signal retr
Entity IDs (`user_id`, `agent_id`, `app_id`, `run_id`) **must** be passed inside the `filters` object — top-level entity IDs are rejected with 400. At least one entity ID is required. Entity IDs (`user_id`, `agent_id`, `app_id`, `run_id`) **must** be passed inside the `filters` object — top-level entity IDs are rejected with 400. At least one entity ID is required.
Expired memories are hidden by default. Pass `show_expired: true` to include memories whose `expiration_date` has passed.
Python uses `show_expired`; TypeScript uses `showExpired`.
The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators: The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators:
- `in`: Matches any of the values specified - `in`: Matches any of the values specified
- `gte`: Greater than or equal to - `gte`: Greater than or equal to
@@ -24,17 +20,16 @@ The `filters` object supports complex logical operations (AND, OR, NOT) and comp
### Search parameter defaults ### Search parameter defaults
| Parameter | Default | | Parameter | V1/V2 | V3 |
| --- | --- | | --- | --- | --- |
| `top_k` | `10` (range 1–1000) | | `top_k` | Supported (default 10) | Supported (1-1000, default 10) |
| `threshold` | `0.1` (pass `0.0` to disable) | | `threshold` | No default | Default `0.1` (pass `0.0` to disable) |
| `rerank` | `false` (pass `true` to enable) | | `rerank` | Default `true` | Default `false` (pass `true` to enable) |
<CodeGroup> <CodeGroup>
```python Platform API Example ```python Platform API Example
related_memories = client.search( related_memories = client.search(
query="What are Alice's hobbies?", query="What are Alice's hobbies?",
show_expired=False,
filters={ filters={
"OR": [ "OR": [
{ {
@@ -59,7 +54,6 @@ related_memories = client.search(
"category": "hobbies" "category": "hobbies"
}, },
"score": 0.82, "score": 0.82,
"expiration_date": null,
"created_at": "2024-07-26T10:29:36.630547-07:00", "created_at": "2024-07-26T10:29:36.630547-07:00",
"updated_at": null, "updated_at": null,
"categories": ["hobbies"] "categories": ["hobbies"]
+2 -11
View File
@@ -1,14 +1,5 @@
--- ---
title: 'Update Memory' title: 'Update Memory'
description: "Update the content, metadata, timestamp, or expiration date of a single memory by its unique ID using the PUT endpoint." description: "Update the content or metadata of a single memory by its unique ID using the PUT endpoint."
openapi: put /v1/memories/{memory_id}/ openapi: put /v1/memories/{memory_id}/
--- ---
Use this endpoint to update mutable memory fields. To make a memory expire, set `expiration_date` to a `YYYY-MM-DD` date. To make it permanent again, send `expiration_date: null`.
```python
client.update("mem_123", expiration_date="2030-01-31")
client.update("mem_123", expiration_date=None)
```
TypeScript uses `expirationDate`.
@@ -1,5 +0,0 @@
---
title: "Remove Organization Member"
description: "Remove a member from an organization to revoke their access to its projects and resources."
openapi: "delete /api/v1/orgs/organizations/{org_id}/members/"
---
@@ -1,5 +0,0 @@
---
title: "Update Organization Member"
description: "Update an existing member's role within an organization to change their permissions and access level."
openapi: "put /api/v1/orgs/organizations/{org_id}/members/"
---
+2 -41
View File
@@ -14,7 +14,7 @@ Organizations and projects are **optional** features. You can use Mem0 without t
## Key Capabilities ## Key Capabilities
- **Multi-org/project Support**: Organization and project are resolved automatically from your API key via `/v1/ping/` — no org or project params are accepted by `MemoryClient.__init__`. Use a project-specific API key to target a particular project. - **Multi-org/project Support**: Specify organization and project when initializing the Mem0 client to attribute API usage appropriately
- **Member Management**: Control access to data through organization and project membership - **Member Management**: Control access to data through organization and project membership
- **Access Control**: Only members can access memories and data within their organization/project scope - **Access Control**: Only members can access memories and data within their organization/project scope
- **Team Isolation**: Maintain data separation between different teams and projects for secure collaboration - **Team Isolation**: Maintain data separation between different teams and projects for secure collaboration
@@ -79,7 +79,7 @@ new_project = client.project.create(
### Update Project Settings ### Update Project Settings
Modify project configuration including custom instructions, categories, language preferences, retrieval criteria, and memory decay: Modify project configuration including custom instructions, categories, and language preferences:
```python ```python
# Update project with custom categories # Update project with custom categories
@@ -98,17 +98,6 @@ client.project.update(
# Use the input language for memory storage and retrieval # Use the input language for memory storage and retrieval
client.project.update(multilingual=True) client.project.update(multilingual=True)
# Set retrieval criteria to control which memories are surfaced in search
client.project.update(
retrieval_criteria=[
{"name": "relevance", "description": "How directly relevant this memory is to the current topic or user query", "weight": 3},
{"name": "access_frequency", "description": "How often this memory has been accessed or surfaced recently", "weight": 1}
]
)
# Enable Memory Decay (boosts recently-accessed memories at search time)
client.project.update(decay=True)
# Update multiple settings at once # Update multiple settings at once
client.project.update( client.project.update(
custom_instructions="...", custom_instructions="...",
@@ -120,34 +109,6 @@ client.project.update(
) )
``` ```
#### Set Retrieval Criteria
`retrieval_criteria` is a per-project list of dictionaries (`List[Dict]`) that shapes how memories are ranked and filtered during search. Each dictionary has three fields: `name` (identifier), `description` (interpreted by the LLM to score each memory), and `weight` (relative influence on the final score). Use this to focus retrieval on intent-aligned or signal-specific memories:
```python
client.project.update(
retrieval_criteria=[
{
"name": "joy",
"description": "Measure the intensity of positive emotions such as happiness, excitement, or amusement expressed in the memory. A higher score reflects greater joy.",
"weight": 3
},
{
"name": "curiosity",
"description": "Assess the extent to which the memory reflects inquisitiveness or interest in exploring new information. A higher score reflects stronger curiosity.",
"weight": 2
},
{
"name": "access_frequency",
"description": "How often this memory has been accessed or surfaced recently.",
"weight": 1
}
]
)
```
Pass an empty list to clear all criteria and restore default retrieval behaviour.
#### Toggle Memory Decay #### Toggle Memory Decay
`decay` is a per-project boolean that turns on [Memory Decay](/platform/features/memory-decay) — a search-time ranking bias that reinforces recently-accessed memories and gently dampens stale ones. The flag is `false` by default; set it via the same project-update endpoint: `decay` is a per-project boolean that turns on [Memory Decay](/platform/features/memory-decay) — a search-time ranking bias that reinforces recently-accessed memories and gently dampens stale ones. The flag is `false` by default; set it via the same project-update endpoint:
@@ -1,5 +0,0 @@
---
title: "Remove Project Member"
description: "Remove a member from a project to revoke their access to its memories, configuration, and resources."
openapi: "delete /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/"
---
@@ -1,5 +0,0 @@
---
title: "Update Project Member"
description: "Update an existing member's role within a project to change their permissions and access level."
openapi: "put /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/"
---
@@ -1,5 +0,0 @@
---
title: "Update Project"
description: "Update a project's settings, including name, custom instructions, and other configuration options."
openapi: "patch /api/v1/orgs/organizations/{org_id}/projects/{project_id}/"
---
+1 -1
View File
@@ -113,7 +113,7 @@ Launched a unified Mem0 plugin across three major AI development environments
Major expansion of the provider ecosystem: Major expansion of the provider ecosystem:
- **Apache AGE** — New graph store support, bringing the total to 4 graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE). **Note:** All external graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE) were subsequently removed in v2.0.0 (2026-04-14). Graph memory is now built-in entity linking with no external graph store required; see the [v2.0.0 entry above](#mem0-sdk-v2-0-0-v3-0-0). - **Apache AGE** — New graph store support, bringing the total to 4 graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE)
- **Turbopuffer** — New vector database provider for Python SDK - **Turbopuffer** — New vector database provider for Python SDK
- **MiniMax** — New LLM provider with dedicated AWS Bedrock support - **MiniMax** — New LLM provider with dedicated AWS Bedrock support
- **pgvector for Node.js** — PostgreSQL vector support added to the TypeScript OSS SDK - **pgvector for Node.js** — PostgreSQL vector support added to the TypeScript OSS SDK
+2 -34
View File
@@ -7,21 +7,6 @@ mode: "wide"
<Tabs> <Tabs>
<Tab title="Python"> <Tab title="Python">
<Update label="2026-06-27" description="v2.0.10">
**New Features:**
- **Client:** Expose `expiration_date` on `MemoryClient.update()` and `AsyncMemoryClient.update()` — callers can now set or clear a memory's expiration date; `None` is preserved and forwarded to the API ([#5874](https://github.com/mem0ai/mem0/pull/5874))
**Bug Fixes:**
- **Memory (OSS):** Apply `remove_code_blocks()` to the LangChain path in async `_create_procedural_memory` so code fences are stripped consistently ([#5711](https://github.com/mem0ai/mem0/pull/5711))
- **Rerankers:** Score HuggingFace cross-encoder results with per-document sigmoid instead of set-relative min-max, preventing a single low-score document from collapsing all relevance scores to zero ([#5715](https://github.com/mem0ai/mem0/pull/5715))
- **Core:** Validate and trim entity IDs (`user_id`, `agent_id`, `run_id`) in `delete_all()` for both sync and async `Memory` ([#5735](https://github.com/mem0ai/mem0/pull/5735))
- **Vector Stores:** Use `.get()` for `hash` and `created_at` in the Redis `insert()` and `update()` paths so entity payloads that omit those fields no longer raise `KeyError` ([#5709](https://github.com/mem0ai/mem0/pull/5709))
- **Memory:** Fix scale-threshold notices not firing for Redis and search-engine backends by resolving `col_info()` signature differences and adding `num_docs` to the count-extraction lookup ([#5687](https://github.com/mem0ai/mem0/pull/5687))
- **Vector Stores:** Escape special characters in Valkey FT.SEARCH tag filter values to prevent wildcard and operator injection through tenant-isolation filters ([#5750](https://github.com/mem0ai/mem0/pull/5750))
</Update>
<Update label="2026-06-24" description="v2.0.9"> <Update label="2026-06-24" description="v2.0.9">
**Bug Fixes:** **Bug Fixes:**
@@ -136,7 +121,7 @@ mode: "wide"
**New Features:** **New Features:**
- **Memory:** Warn at init time when hybrid/BM25 search silently degrades to semantic-only because the configured vector store does not implement `keyword_search`. Affected stores: Chroma, FAISS, Cassandra, LangChain, Neptune Analytics, S3 Vectors, Supabase, TurboPuffer, Valkey ([#5444](https://github.com/mem0ai/mem0/pull/5444)) - **Memory:** Warn at init time when hybrid/BM25 search silently degrades to semantic-only because the configured vector store does not implement `keyword_search`. Affected stores: Chroma, FAISS, Cassandra, LangChain, Neptune Analytics, S3 Vectors, Supabase, TurboPuffer, Valkey ([#5444](https://github.com/mem0ai/mem0/pull/5444))
- **Memory:** Add opt-in `explain=True` parameter to `Memory.search()` and `AsyncMemory.search()`. When enabled, each result includes a `score_details` dict with `semantic_score`, `bm25_score`, `entity_boost`, `raw_score`, `max_possible_score`, `final_score`, and `threshold` so callers can understand and tune retrieval ranking ([#5102](https://github.com/mem0ai/mem0/pull/5102)) - **Memory:** Add opt-in `explain=True` parameter to `Memory.search()` and `AsyncMemory.search()`. When enabled, each result includes a `score_breakdown` dict with `semantic`, `keyword` (normalized BM25), `entity_boost`, and `temporal_boost` signals so callers can understand and tune retrieval ranking ([#5102](https://github.com/mem0ai/mem0/pull/5102))
**Bug Fixes:** **Bug Fixes:**
- **Vector Stores:** Normalize similarity scores to `[0, 1]` (higher = better) consistently across all backends. 11 adapters previously returned raw distance metrics (lower = better) — FAISS, Chroma, Milvus, Redis, Cassandra, PGVector, S3 Vectors, Supabase, Valkey, Azure MySQL, and Vertex AI Vector Search — causing incorrect ranking in multi-store setups ([#5391](https://github.com/mem0ai/mem0/pull/5391)) - **Vector Stores:** Normalize similarity scores to `[0, 1]` (higher = better) consistently across all backends. 11 adapters previously returned raw distance metrics (lower = better) — FAISS, Chroma, Milvus, Redis, Cassandra, PGVector, S3 Vectors, Supabase, Valkey, Azure MySQL, and Vertex AI Vector Search — causing incorrect ranking in multi-store setups ([#5391](https://github.com/mem0ai/mem0/pull/5391))
@@ -244,7 +229,7 @@ mode: "wide"
**Improvements:** **Improvements:**
- **Telemetry:** Sample OSS hot-path events at 10% via PostHog `before_send` hook to reduce event volume ([#4771](https://github.com/mem0ai/mem0/pull/4771)) - **Telemetry:** Sample OSS hot-path events at 10% via PostHog `before_send` hook to reduce event volume ([#4771](https://github.com/mem0ai/mem0/pull/4771))
See the [OSS v2 to v3 migration guide](https://docs.mem0.ai/migration/oss-v2-to-v3) and [Platform migration guide](https://docs.mem0.ai/migration/platform-v2-to-v3) for upgrade instructions. See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-v2) and [Platform migration guide](https://docs.mem0.ai/migration/platform-v2-to-v3) for upgrade instructions.
</Update> </Update>
@@ -1085,23 +1070,6 @@ See the [OSS v2 to v3 migration guide](https://docs.mem0.ai/migration/oss-v2-to-
<Tab title="TypeScript"> <Tab title="TypeScript">
<Update label="2026-06-27" description="v3.0.12">
**New Features:**
- **Client:** Add `expirationDate` to `AddMemoryOptions`, `update()`, and the `Memory` interface; add `showExpired` to `SearchMemoryOptions` and `GetAllMemoryOptions` ([#5874](https://github.com/mem0ai/mem0/pull/5874))
- **LLMs:** Add `MiniMaxLLM` provider backed by the OpenAI-compatible MiniMax API (`api.minimax.io/v1`, default model `MiniMax-M2.7`) ([#5858](https://github.com/mem0ai/mem0/pull/5858))
- **LLMs:** Add `LiteLLM` provider for routing requests through a local or hosted LiteLLM proxy ([#5830](https://github.com/mem0ai/mem0/pull/5830))
- **Vector Stores:** Add `connectionString` and `ssl` options to the PGVector config, allowing connection via URI instead of individual host/user/password/port fields ([#5789](https://github.com/mem0ai/mem0/pull/5789))
**Bug Fixes:**
- **Memory (OSS):** Validate and trim entity IDs (`userId`, `agentId`, `runId`) in `deleteAll()` via `validateAndTrimEntityId` ([#5735](https://github.com/mem0ai/mem0/pull/5735))
- **Vector Stores:** Use nullish coalescing for `hash` and timestamps in the Redis `insert()` and `update()` paths so entity payloads that omit those fields no longer crash ([#5860](https://github.com/mem0ai/mem0/pull/5860))
**Security:**
- **Dependencies:** Bump `undici` to `>=6.27.0` via pnpm override to remediate CVE-2026-12151 ([#5861](https://github.com/mem0ai/mem0/pull/5861))
</Update>
<Update label="2026-06-24" description="v3.0.11"> <Update label="2026-06-24" description="v3.0.11">
**Bug Fixes:** **Bug Fixes:**
@@ -59,9 +59,5 @@ Here are the parameters available for configuring AWS Bedrock embedder:
| Parameter | Description | Default Value | | Parameter | Description | Default Value |
| --- | --- | --- | | --- | --- | --- |
| `model` | The name of the embedding model to use | `amazon.titan-embed-text-v1` | | `model` | The name of the embedding model to use | `amazon.titan-embed-text-v1` |
| `aws_region` | AWS region for the Bedrock client | `us-west-2` |
| `aws_access_key_id` | AWS access key ID for authentication | `None` |
| `aws_secret_access_key` | AWS secret access key for authentication | `None` |
| `aws_session_token` | AWS session token for temporary credentials | `None` |
</Tab> </Tab>
</Tabs> </Tabs>
@@ -1,50 +0,0 @@
---
title: "FastEmbed"
description: "Configure FastEmbed as an embedding provider in Mem0 to generate embeddings locally using ONNX-based models without a GPU."
---
You can use FastEmbed to run embedding models locally in Mem0. FastEmbed is an ONNX-based embedding library that runs efficiently on CPU without requiring a GPU or an external API key.
### Installation
```bash
pip install fastembed
```
### Usage
<CodeGroup>
```python Python
import os
from mem0 import Memory
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
config = {
"embedder": {
"provider": "fastembed",
"config": {
"model": "thenlper/gte-large"
}
}
}
m = Memory.from_config(config)
messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about thriller movies? They can be quite engaging."},
{"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
]
m.add(messages, user_id="john")
```
</CodeGroup>
### Config
Here are the parameters available for configuring FastEmbed embedder:
| Parameter | Description | Default Value |
| --- | --- | --- |
| `model` | The name of the FastEmbed model to use | `thenlper/gte-large` |
| `embedding_dims` | Dimensions of the embedding model (auto-derived from the model if not set) | `None` |
@@ -67,15 +67,14 @@ Here are the parameters available for configuring Gemini embedder:
| Parameter | Description | Default Value | | Parameter | Description | Default Value |
| ---------------- | ------------------------------------ | ----------------------- | | ---------------- | ------------------------------------ | ----------------------- |
| `model` | The name of the embedding model to use| `models/gemini-embedding-001` | | `model` | The name of the embedding model to use| `models/gemini-embedding-001` |
| `embedding_dims` | Dimensions of the embedding model | `768` | | `embedding_dims` | Dimensions of the embedding model | `1536` |
| `api_key` | The Google API key | `None` | | `api_key` | The Google API key | `None` |
| `output_dimensionality` | Output dimensionality for the embedding model (Gemini-specific; used when `embedding_dims` is not set) | `None` |
</Tab> </Tab>
<Tab title="TypeScript"> <Tab title="TypeScript">
| Parameter | Description | Default Value | | Parameter | Description | Default Value |
| ----------------- | --------------------------------------------- | -------------------------- | | ----------------- | --------------------------------------------- | -------------------------- |
| `model` | The name of the embedding model to use | `gemini-embedding-001` | | `model` | The name of the embedding model to use | `gemini-embedding-001` |
| `embeddingDims` | Dimensions of the embedding model. When not set, uses the model's native output dimensionality (3072 for `gemini-embedding-001`; MRL truncation to 768, 1536, or 3072 is supported) | `None` | | `embeddingDims` | Dimensions of the embedding model | `1536` |
| `apiKey` | Google API key | `None` | | `apiKey` | Google API key | `None` |
</Tab> </Tab>
</Tabs> </Tabs>
@@ -16,7 +16,7 @@ config = {
"embedder": { "embedder": {
"provider": "lmstudio", "provider": "lmstudio",
"config": { "config": {
"model": "nomic-ai/nomic-embed-text-v1.5-GGUF" "model": "nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.f16.gguf"
} }
} }
} }
@@ -37,6 +37,6 @@ Here are the parameters available for configuring LM Studio embedder:
| Parameter | Description | Default Value | | Parameter | Description | Default Value |
| --- | --- | --- | | --- | --- | --- |
| `model` | The name of the LM Studio model to use | `nomic-ai/nomic-embed-text-v1.5-GGUF` | | `model` | The name of the LM Studio model to use | `nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.f16.gguf` |
| `embedding_dims` | Dimensions of the embedding model | `1536` | | `embedding_dims` | Dimensions of the embedding model | `1536` |
| `lmstudio_base_url` | Base URL for LM Studio connection | `http://localhost:1234/v1` | | `lmstudio_base_url` | Base URL for LM Studio connection | `http://localhost:1234/v1` |
+1 -2
View File
@@ -10,7 +10,7 @@ Mem0 offers support for various embedding models, allowing users to choose the o
See the list of supported embedders below. See the list of supported embedders below.
<Note> <Note>
All embedders listed below are supported in the Python implementation. The TypeScript implementation supports: **OpenAI**, **Azure OpenAI**, **Google AI**, **Langchain**, **LM Studio**, and **Ollama**. The following embedders are supported in the Python implementation. The TypeScript implementation currently only supports OpenAI.
</Note> </Note>
<CardGroup cols={4}> <CardGroup cols={4}>
@@ -24,7 +24,6 @@ See the list of supported embedders below.
<Card title="LM Studio" href="/components/embedders/models/lmstudio"></Card> <Card title="LM Studio" href="/components/embedders/models/lmstudio"></Card>
<Card title="Langchain" href="/components/embedders/models/langchain"></Card> <Card title="Langchain" href="/components/embedders/models/langchain"></Card>
<Card title="AWS Bedrock" href="/components/embedders/models/aws_bedrock"></Card> <Card title="AWS Bedrock" href="/components/embedders/models/aws_bedrock"></Card>
<Card title="FastEmbed" href="/components/embedders/models/fastembed"></Card>
</CardGroup> </CardGroup>
## Usage ## Usage
+2 -2
View File
@@ -98,7 +98,7 @@ Here's a comprehensive list of all parameters that can be used across different
| `max_tokens` | Tokens to generate | All | | `max_tokens` | Tokens to generate | All |
| `top_p` | Probability threshold for nucleus sampling | All | | `top_p` | Probability threshold for nucleus sampling | All |
| `top_k` | Number of highest probability tokens to keep | All | | `top_k` | Number of highest probability tokens to keep | All |
| `http_client_proxies`| Allow proxy server settings | All | | `http_client_proxies`| Allow proxy server settings | AzureOpenAI |
| `models` | List of models | Openrouter | | `models` | List of models | Openrouter |
| `route` | Routing strategy | Openrouter | | `route` | Routing strategy | Openrouter |
| `openrouter_base_url`| Base URL for Openrouter API | Openrouter | | `openrouter_base_url`| Base URL for Openrouter API | Openrouter |
@@ -110,7 +110,7 @@ Here's a comprehensive list of all parameters that can be used across different
| `deepseek_base_url` | Base URL for DeepSeek API | DeepSeek | | `deepseek_base_url` | Base URL for DeepSeek API | DeepSeek |
| `xai_base_url` | Base URL for XAI API | XAI | | `xai_base_url` | Base URL for XAI API | XAI |
| `sarvam_base_url` | Base URL for Sarvam API | Sarvam | | `sarvam_base_url` | Base URL for Sarvam API | Sarvam |
| `reasoning_effort` | Reasoning level (low, medium, high) | All | | `reasoning_effort` | Reasoning level (low, medium, high) | Sarvam |
| `frequency_penalty` | Penalize frequent tokens (-2.0 to 2.0) | Sarvam | | `frequency_penalty` | Penalize frequent tokens (-2.0 to 2.0) | Sarvam |
| `presence_penalty` | Penalize existing tokens (-2.0 to 2.0) | Sarvam | | `presence_penalty` | Penalize existing tokens (-2.0 to 2.0) | Sarvam |
| `seed` | Seed for deterministic sampling | Sarvam | | `seed` | Seed for deterministic sampling | Sarvam |
+2 -2
View File
@@ -20,7 +20,7 @@ config = {
"llm": { "llm": {
"provider": "anthropic", "provider": "anthropic",
"config": { "config": {
"model": "claude-sonnet-4-6", "model": "claude-sonnet-4-20250514",
"temperature": 0.1, "temperature": 0.1,
"max_tokens": 2000, "max_tokens": 2000,
} }
@@ -45,7 +45,7 @@ const config = {
provider: 'anthropic', provider: 'anthropic',
config: { config: {
apiKey: process.env.ANTHROPIC_API_KEY || '', apiKey: process.env.ANTHROPIC_API_KEY || '',
model: 'claude-sonnet-4-6', model: 'claude-sonnet-4-20250514',
temperature: 0.1, temperature: 0.1,
maxTokens: 2000, maxTokens: 2000,
}, },
+1 -1
View File
@@ -6,7 +6,7 @@ description: "Configure AWS Bedrock as an LLM provider in Mem0 with IAM authenti
### Setup ### Setup
- Before using the AWS Bedrock LLM, make sure you have the appropriate model access from [Bedrock Console](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess). - Before using the AWS Bedrock LLM, make sure you have the appropriate model access from [Bedrock Console](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess).
- You will also need to authenticate the `boto3` client by using a method in the [AWS documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials) - You will also need to authenticate the `boto3` client by using a method in the [AWS documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials)
- You will have to export `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY` to set environment variables. - You will have to export `AWS_REGION`, `AWS_ACCESS_KEY`, and `AWS_SECRET_ACCESS_KEY` to set environment variables.
### Usage ### Usage
+2 -2
View File
@@ -21,7 +21,7 @@ config = {
"llm": { "llm": {
"provider": "groq", "provider": "groq",
"config": { "config": {
"model": "llama-3.3-70b-versatile", "model": "mixtral-8x7b-32768",
"temperature": 0.1, "temperature": 0.1,
"max_tokens": 2000, "max_tokens": 2000,
} }
@@ -46,7 +46,7 @@ const config = {
provider: 'groq', provider: 'groq',
config: { config: {
apiKey: process.env.GROQ_API_KEY || '', apiKey: process.env.GROQ_API_KEY || '',
model: 'llama3-70b-8192', model: 'mixtral-8x7b-32768',
temperature: 0.1, temperature: 0.1,
maxTokens: 1000, maxTokens: 1000,
}, },
+1 -31
View File
@@ -4,12 +4,9 @@ description: "Use LiteLLM as an LLM provider in Mem0 to access over 100 language
--- ---
[Litellm](https://litellm.vercel.app/docs/) is compatible with over 100 large language models (LLMs), all using a standardized input/output format. You can explore the [available models](https://litellm.vercel.app/docs/providers) to use with Litellm. Ensure you set the `API_KEY` for the model you choose to use. [Litellm](https://litellm.vercel.app/docs/) is compatible with over 100 large language models (LLMs), all using a standardized input/output format. You can explore the [available models](https://litellm.vercel.app/docs/providers) to use with Litellm. Ensure you set the `API_KEY` for the model you choose to use.
In the TypeScript SDK, run LiteLLM as a [proxy server](https://docs.litellm.ai/docs/simple_proxy) (an OpenAI-compatible endpoint) and point Mem0 at it via `LITELLM_API_BASE` (defaults to `http://localhost:4000`).
## Usage ## Usage
<CodeGroup> ```python
```python Python
import os import os
from mem0 import Memory from mem0 import Memory
@@ -36,33 +33,6 @@ messages = [
m.add(messages, user_id="alice", metadata={"category": "movies"}) m.add(messages, user_id="alice", metadata={"category": "movies"})
``` ```
```typescript TypeScript
import { Memory } from 'mem0ai/oss';
// Point Mem0 at your LiteLLM proxy. apiKey defaults to "sk-anything"
// (the proxy handles real auth); baseURL defaults to http://localhost:4000.
const config = {
llm: {
provider: 'litellm',
config: {
apiKey: process.env.LITELLM_API_KEY || 'sk-anything',
baseURL: process.env.LITELLM_API_BASE || 'http://localhost:4000',
model: 'gpt-5-mini',
},
},
};
const memory = new Memory(config);
const messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about thriller movies? They can be quite engaging."},
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
];
await memory.add(messages, { userId: 'alice', metadata: { category: 'movies' } });
```
</CodeGroup>
## Config ## Config
All available parameters for the `litellm` config are present in [Master List of All Params in Config](../config). All available parameters for the `litellm` config are present in [Master List of All Params in Config](../config).
+2 -45
View File
@@ -7,8 +7,7 @@ To use MiniMax LLM models, you have to set the `MINIMAX_API_KEY` environment var
## Usage ## Usage
<CodeGroup> ```python
```python Python
import os import os
from mem0 import Memory from mem0 import Memory
@@ -37,37 +36,9 @@ messages = [
m.add(messages, user_id="alice", metadata={"category": "movies"}) m.add(messages, user_id="alice", metadata={"category": "movies"})
``` ```
```typescript TypeScript
import { Memory } from 'mem0ai/oss';
const config = {
llm: {
provider: 'minimax',
config: {
apiKey: process.env.MINIMAX_API_KEY || '',
model: 'MiniMax-M2.7',
temperature: 0.2,
maxTokens: 2000,
topP: 1.0,
},
},
};
const memory = new Memory(config);
const messages = [
{ role: "user", content: "I'm planning to watch a movie tonight. Any recommendations?" },
{ role: "assistant", content: "How about thriller movies? They can be quite engaging." },
{ role: "user", content: "I'm not a big fan of thriller movies but I love sci-fi movies." },
{ role: "assistant", content: "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future." },
];
await memory.add(messages, { userId: 'alice', metadata: { category: 'movies' } });
```
</CodeGroup>
You can also configure the API base URL in the config: You can also configure the API base URL in the config:
<CodeGroup> ```python
```python Python
config = { config = {
"llm": { "llm": {
"provider": "minimax", "provider": "minimax",
@@ -80,20 +51,6 @@ config = {
} }
``` ```
```typescript TypeScript
const config = {
llm: {
provider: 'minimax',
config: {
model: 'MiniMax-M2.7',
baseURL: 'https://your-custom-endpoint.com',
apiKey: 'your-api-key', // alternatively to using the environment variable
},
},
};
```
</CodeGroup>
## Config ## Config
All available parameters for the `minimax` config are present in [Master List of All Params in Config](../config). All available parameters for the `minimax` config are present in [Master List of All Params in Config](../config).
+1 -1
View File
@@ -20,7 +20,7 @@ config = {
"llm": { "llm": {
"provider": "xai", "provider": "xai",
"config": { "config": {
"model": "grok-4.3", "model": "grok-3-beta",
"temperature": 0.1, "temperature": 0.1,
"max_tokens": 2000, "max_tokens": 2000,
} }
+1 -1
View File
@@ -16,7 +16,7 @@ For a comprehensive list of available parameters for llm configuration, please r
See the list of supported LLMs below. See the list of supported LLMs below.
<Note> <Note>
All LLMs are supported in Python. The following LLMs are also supported in TypeScript: **OpenAI**, **Anthropic**, **Groq**, **Azure OpenAI**, **DeepSeek**, **Google AI**, **Langchain**, **LM Studio**, **Mistral AI**, and **Ollama**. All LLMs are supported in Python. The following LLMs are also supported in TypeScript: **OpenAI**, **Anthropic**, and **Groq**.
</Note> </Note>
<CardGroup cols={4}> <CardGroup cols={4}>
+226
View File
@@ -0,0 +1,226 @@
---
title: LLM as Reranker
description: "Use any LLM as a flexible reranker in Mem0 with custom prompts and domain-specific scoring logic."
---
<Warning>
**This page has been superseded.** Please see [LLM Reranker](/components/rerankers/models/llm_reranker) for the complete and up-to-date documentation on using LLMs for reranking.
</Warning>
LLM-based reranker provides maximum flexibility by using any Large Language Model to score document relevance. This approach allows for custom prompts and domain-specific scoring logic.
## Supported LLM Providers
Any LLM provider supported by Mem0 can be used for reranking:
- **OpenAI**: GPT-4, GPT-3.5-turbo, etc.
- **Anthropic**: Claude models
- **Together**: Open-source models
- **Groq**: Fast inference
- **Ollama**: Local models
- And more...
## Configuration
```python Python
from mem0 import Memory
config = {
"vector_store": {
"provider": "chroma",
"config": {
"collection_name": "my_memories",
"path": "./chroma_db"
}
},
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4o-mini"
}
},
"reranker": {
"provider": "llm",
"config": {
"model": "gpt-4o-mini",
"provider": "openai",
"api_key": "your-openai-api-key", # or set OPENAI_API_KEY
"top_k": 5,
"temperature": 0.0
}
}
}
memory = Memory.from_config(config)
```
## Custom Scoring Prompt
You can provide a custom prompt for relevance scoring:
```python Python
custom_prompt = """You are a relevance scoring assistant. Rate how well this document answers the query.
Query: "{query}"
Document: "{document}"
Score from 0.0 to 1.0 where:
- 1.0: Perfect match, directly answers the query
- 0.8-0.9: Highly relevant, good match
- 0.6-0.7: Moderately relevant, partial match
- 0.4-0.5: Slightly relevant, limited useful information
- 0.0-0.3: Not relevant or no useful information
Provide only a single numerical score between 0.0 and 1.0."""
config["reranker"]["config"]["scoring_prompt"] = custom_prompt
```
## Usage Example
```python Python
import os
from mem0 import Memory
# Set API key
os.environ["OPENAI_API_KEY"] = "your-api-key"
# Initialize memory with LLM reranker
config = {
"vector_store": {"provider": "chroma"},
"llm": {"provider": "openai", "config": {"model": "gpt-4o-mini"}},
"reranker": {
"provider": "llm",
"config": {
"model": "gpt-4o-mini",
"provider": "openai",
"temperature": 0.0
}
}
}
memory = Memory.from_config(config)
# Add memories
messages = [
{"role": "user", "content": "I'm learning Python programming"},
{"role": "user", "content": "I find object-oriented programming challenging"},
{"role": "user", "content": "I love hiking in national parks"}
]
memory.add(messages, user_id="david")
# Search with LLM reranking
results = memory.search("What programming topics is the user studying?", filters={"user_id": "david"})
for result in results['results']:
print(f"Memory: {result['memory']}")
print(f"Vector Score: {result['score']:.3f}")
print(f"Rerank Score: {result['rerank_score']:.3f}")
print()
```
```text Output
Memory: I'm learning Python programming
Vector Score: 0.856
Rerank Score: 0.920
Memory: I find object-oriented programming challenging
Vector Score: 0.782
Rerank Score: 0.850
```
## Domain-Specific Scoring
Create specialized scoring for your domain:
```python Python
medical_prompt = """You are a medical relevance expert. Score how relevant this medical record is to the clinical query.
Clinical Query: "{query}"
Medical Record: "{document}"
Consider:
- Clinical relevance and accuracy
- Patient safety implications
- Diagnostic value
- Treatment relevance
Score from 0.0 to 1.0. Provide only the numerical score."""
config = {
"reranker": {
"provider": "llm",
"config": {
"model": "gpt-4o-mini",
"provider": "openai",
"scoring_prompt": medical_prompt,
"temperature": 0.0
}
}
}
```
## Multiple LLM Providers
Use different LLM providers for reranking:
```python Python
# Using Anthropic Claude
anthropic_config = {
"reranker": {
"provider": "llm",
"config": {
"model": "claude-3-haiku-20240307",
"provider": "anthropic",
"temperature": 0.0
}
}
}
# Using local Ollama model
ollama_config = {
"reranker": {
"provider": "llm",
"config": {
"model": "llama2:7b",
"provider": "ollama",
"temperature": 0.0
}
}
}
```
## Configuration Parameters
| Parameter | Description | Type | Default |
|-----------|-------------|------|---------|
| `model` | LLM model to use for scoring | `str` | `"gpt-4o-mini"` |
| `provider` | LLM provider name | `str` | `"openai"` |
| `api_key` | API key for the LLM provider | `str` | `None` |
| `top_k` | Maximum documents to return | `int` | `None` |
| `temperature` | Temperature for LLM generation | `float` | `0.0` |
| `max_tokens` | Maximum tokens for LLM response | `int` | `100` |
| `scoring_prompt` | Custom prompt template | `str` | Default prompt |
## Advantages
- **Maximum Flexibility**: Custom prompts for any use case
- **Domain Expertise**: Leverage LLM knowledge for specialized domains
- **Interpretability**: Understand scoring through prompt engineering
- **Multi-criteria**: Score based on multiple relevance factors
## Considerations
- **Latency**: Higher latency than specialized rerankers
- **Cost**: LLM API costs per reranking operation
- **Consistency**: May have slight variations in scoring
- **Prompt Engineering**: Requires careful prompt design
## Best Practices
1. **Temperature**: Use 0.0 for consistent scoring
2. **Prompt Design**: Be specific about scoring criteria
3. **Token Efficiency**: Keep prompts concise to reduce costs
4. **Caching**: Cache results for repeated queries when possible
5. **Fallback**: Handle API errors gracefully
+1 -1
View File
@@ -46,7 +46,7 @@ Here are the parameters available for configuring Baidu VectorDB:
| `account` | Baidu VectorDB account name | `root` | | `account` | Baidu VectorDB account name | `root` |
| `api_key` | API key for accessing Baidu VectorDB | Required | | `api_key` | API key for accessing Baidu VectorDB | Required |
| `database_name` | Name of the database | `mem0` | | `database_name` | Name of the database | `mem0` |
| `table_name` | Name of the table | `mem0` | | `table_name` | Name of the table | `mem0_table` |
| `embedding_model_dims` | Dimensions of the embedding model | `1536` | | `embedding_model_dims` | Dimensions of the embedding model | `1536` |
| `metric_type` | Distance metric for similarity search | `L2` | | `metric_type` | Distance metric for similarity search | `L2` |
@@ -56,8 +56,6 @@ Here are the parameters available for configuring Elasticsearch:
| `api_key` | API key for authentication | `None` | | `api_key` | API key for authentication | `None` |
| `user` | Username for basic authentication | `None` | | `user` | Username for basic authentication | `None` |
| `password` | Password for basic authentication | `None` | | `password` | Password for basic authentication | `None` |
| `use_ssl` | Whether to use SSL for the connection | `True` |
| `ca_certs` | Path to CA bundle for SSL certificate verification | `None` |
| `verify_certs` | Whether to verify SSL certificates | `True` | | `verify_certs` | Whether to verify SSL certificates | `True` |
| `auto_create_index` | Whether to automatically create the index | `True` | | `auto_create_index` | Whether to automatically create the index | `True` |
| `custom_search_query` | Function returning a custom search query | `None` | | `custom_search_query` | Function returning a custom search query | `None` |
-1
View File
@@ -55,7 +55,6 @@ Here are the parameters available for configuring FAISS:
| `path` | Path to store FAISS index and metadata | `/tmp/faiss/<collection_name>` | | `path` | Path to store FAISS index and metadata | `/tmp/faiss/<collection_name>` |
| `distance_strategy` | Distance metric strategy to use (options: 'euclidean', 'inner_product', 'cosine') | `euclidean` | | `distance_strategy` | Distance metric strategy to use (options: 'euclidean', 'inner_product', 'cosine') | `euclidean` |
| `normalize_L2` | Whether to normalize L2 vectors (only applicable for euclidean distance) | `False` | | `normalize_L2` | Whether to normalize L2 vectors (only applicable for euclidean distance) | `False` |
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
### Performance Considerations ### Performance Considerations
+3 -3
View File
@@ -47,12 +47,12 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
``` ```
```typescript TypeScript ```typescript TypeScript
import { Memory } from "mem0ai/oss"; import { Memory } from "mem0ai";
import { OpenAIEmbeddings } from "@langchain/openai"; import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore } from "langchain/vectorstores/memory"; import { MemoryVectorStore as LangchainMemoryStore } from "langchain/vectorstores/memory";
const embeddings = new OpenAIEmbeddings(); const embeddings = new OpenAIEmbeddings();
const vectorStore = new MemoryVectorStore(embeddings); const vectorStore = new LangchainVectorStore(embeddings);
const config = { const config = {
"vector_store": { "vector_store": {
+3 -3
View File
@@ -42,8 +42,8 @@ Here are the parameters available for configuring MongoDB:
| Parameter | Description | Default Value | | Parameter | Description | Default Value |
| --- | --- | --- | | --- | --- | --- |
| db_name | Name of the MongoDB database | `"mem0_db"` | | db_name | Name of the MongoDB database | `"mem0_db"` |
| collection_name | Name of the MongoDB collection | `"mem0"` | | collection_name | Name of the MongoDB collection | `"mem0_collection"` |
| embedding_model_dims | Dimensions of the embedding vectors | `1536` | | embedding_model_dims | Dimensions of the embedding vectors | `1536` |
| mongo_uri | The MongoDB URI connection string | `mongodb://localhost:27017` | | mongo_uri | The MongoDB URI connection string | `mongodb://username:password@localhost:27017` |
> **Note**: If `mongo_uri` is not provided, it will default to `mongodb://localhost:27017`. > **Note**: If `mongo_uri` is not provided, it will default to `mongodb://username:password@localhost:27017`.
+18 -17
View File
@@ -21,33 +21,34 @@ from mem0 import Memory
load_dotenv() load_dotenv()
config = { config = {
"vector_store": { "vector_store": {
"provider": "pgvector", "provider": "pgvector",
"config": { "config": {
"connection_string": os.environ["DATABASE_URL"], "connection_string": os.environ["DATABASE_URL"],
"collection_name": "memories", "collection_name": "memories",
"embedding_model_dims": 1536, "embedding_model_dims": 1536,
"hnsw": True, "hnsw": True,
}, },
}, },
} }
m = Memory.from_config(config) m = Memory.from_config(config)
messages = [ messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"}, {"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about thriller movies? They can be quite engaging."}, {"role": "assistant", "content": "How about thriller movies? They can be quite engaging."},
{"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."}, {"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}, {"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."},
] ]
m.add(messages, user_id="alice", metadata={"category": "movies"}) m.add(messages, user_id="alice", metadata={"category": "movies"})
results = m.search( results = m.search(
"What movies should I recommend?", "What movies should I recommend?",
filters={"user_id": "alice"}, filters={"user_id": "alice"},
) )
print(results) print(results)
```
````
```typescript TypeScript ```typescript TypeScript
import "dotenv/config"; import "dotenv/config";
@@ -86,7 +87,7 @@ const results = await m.search("What movies should I recommend?", {
}); });
console.log(results); console.log(results);
``` ````
</CodeGroup> </CodeGroup>
@@ -10,7 +10,7 @@ description: "Use AWS Neptune Analytics as a vector store in Mem0, combining gra
## Installation ## Installation
```bash ```bash
pip install mem0ai[vector-stores] pip install mem0ai[vector_stores]
``` ```
## Usage ## Usage
+15 -15
View File
@@ -15,27 +15,27 @@ from mem0 import Memory
os.environ["OPENAI_API_KEY"] = "sk-xx" os.environ["OPENAI_API_KEY"] = "sk-xx"
config = { config = {
"vector_store": { "vector_store": {
"provider": "pgvector", "provider": "pgvector",
"config": { "config": {
"user": "test", "user": "test",
"password": "123", "password": "123",
"host": "127.0.0.1", "host": "127.0.0.1",
"port": "5432", "port": "5432",
}, },
} }
} }
m = Memory.from_config(config) m = Memory.from_config(config)
messages = [ messages = [
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"}, {"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
{"role": "assistant", "content": "How about thriller movies? They can be quite engaging."}, {"role": "assistant", "content": "How about thriller movies? They can be quite engaging."},
{"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."}, {"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}, {"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."},
] ]
m.add(messages, user_id="alice", metadata={"category": "movies"}) m.add(messages, user_id="alice", metadata={"category": "movies"})
``` ````
```typescript TypeScript ```typescript TypeScript
import { Memory } from "mem0ai/oss"; import { Memory } from "mem0ai/oss";
@@ -62,7 +62,7 @@ const messages = [
]; ];
await memory.add(messages, { userId: "alice", metadata: { category: "movies" } }); await memory.add(messages, { userId: "alice", metadata: { category: "movies" } });
``` ````
</CodeGroup> </CodeGroup>
@@ -18,9 +18,7 @@ os.environ["UPSTASH_VECTOR_REST_TOKEN"] = "..."
config = { config = {
"vector_store": { "vector_store": {
"provider": "upstash_vector", "provider": "upstash_vector",
"config": { "enable_embeddings": True,
"enable_embeddings": True,
}
} }
} }
+2 -2
View File
@@ -9,7 +9,7 @@ description: "Use Valkey as an open-source vector store in Mem0 for high-perform
## Installation ## Installation
```bash ```bash
pip install mem0ai[vector-stores] pip install mem0ai[vector_stores]
``` ```
## Usage ## Usage
@@ -51,7 +51,7 @@ Here are the parameters available for configuring Valkey:
| `hnsw_ef_construction` | Size of dynamic candidate list for HNSW | `200` | | `hnsw_ef_construction` | Size of dynamic candidate list for HNSW | `200` |
| `hnsw_ef_runtime` | Size of dynamic candidate list for search | `10` | | `hnsw_ef_runtime` | Size of dynamic candidate list for search | `10` |
| `cluster_mode` | Enable cluster mode for Valkey cluster (CME) deployments | `false` | | `cluster_mode` | Enable cluster mode for Valkey cluster (CME) deployments | `false` |
| `timezone` | Timezone for timestamp handling | `UTC` | | `distance_metric` | Distance metric for vector similarity | `cosine` |
## Cluster Mode ## Cluster Mode
+2 -3
View File
@@ -24,7 +24,7 @@ config = {
"deployment_index_id": "YOUR_DEPLOYMENT_INDEX_ID", # Required: Deployment-specific ID "deployment_index_id": "YOUR_DEPLOYMENT_INDEX_ID", # Required: Deployment-specific ID
"project_id": "YOUR_PROJECT_ID", # Required: Google Cloud project ID "project_id": "YOUR_PROJECT_ID", # Required: Google Cloud project ID
"project_number": "YOUR_PROJECT_NUMBER", # Required: Google Cloud project number "project_number": "YOUR_PROJECT_NUMBER", # Required: Google Cloud project number
"region": "YOUR_REGION", # Required: Google Cloud region "region": "YOUR_REGION", # Optional: Defaults to GOOGLE_CLOUD_REGION
"credentials_path": "path/to/credentials.json", # Optional: Defaults to GOOGLE_APPLICATION_CREDENTIALS "credentials_path": "path/to/credentials.json", # Optional: Defaults to GOOGLE_APPLICATION_CREDENTIALS
"vector_search_api_endpoint": "YOUR_API_ENDPOINT" # Required for get operations "vector_search_api_endpoint": "YOUR_API_ENDPOINT" # Required for get operations
} }
@@ -45,6 +45,5 @@ m.add("Your text here", user_id="user", metadata={"category": "example"})
| `project_id` | Google Cloud project ID | Yes | | `project_id` | Google Cloud project ID | Yes |
| `project_number` | Google Cloud project number | Yes | | `project_number` | Google Cloud project number | Yes |
| `vector_search_api_endpoint` | Vector search API endpoint | Yes (for get operations) | | `vector_search_api_endpoint` | Vector search API endpoint | Yes (for get operations) |
| `region` | Google Cloud region | Yes | | `region` | Google Cloud region | No (defaults to GOOGLE_CLOUD_REGION) |
| `credentials_path` | Path to service account credentials | No (defaults to GOOGLE_APPLICATION_CREDENTIALS) | | `credentials_path` | Path to service account credentials | No (defaults to GOOGLE_APPLICATION_CREDENTIALS) |
| `service_account_json` | Service account credentials as a dictionary (alternative to `credentials_path`) | `None` |
+2 -3
View File
@@ -7,7 +7,7 @@ description: "Use Weaviate as an open-source vector search engine in Mem0 for st
### Installation ### Installation
```bash ```bash
pip install weaviate-client pip install weaviate weaviate-client
``` ```
### Usage ### Usage
@@ -48,5 +48,4 @@ Here are the parameters available for configuring Weaviate:
| `collection_name` | The name of the collection to store the vectors | `mem0` | | `collection_name` | The name of the collection to store the vectors | `mem0` |
| `embedding_model_dims` | Dimensions of the embedding model | `1536` | | `embedding_model_dims` | Dimensions of the embedding model | `1536` |
| `cluster_url` | URL for the Weaviate server | `None` | | `cluster_url` | URL for the Weaviate server | `None` |
| `auth_client_secret` | API key for Weaviate authentication | `None` | | `auth_client_secret` | API key for Weaviate authentication | `None` |
| `additional_headers` | Additional headers to include in requests (`Dict[str, str]`) | `None` |
+1 -1
View File
@@ -10,7 +10,7 @@ Mem0 includes built-in support for various popular databases. Memory can utilize
See the list of supported vector databases below. See the list of supported vector databases below.
<Note> <Note>
The following vector databases are supported in the Python implementation. The TypeScript implementation currently supports Qdrant, Redis, PGVector, Supabase, LangChain, Azure AI Search, Vectorize, and an in-memory store. The following vector databases are supported in the Python implementation. The TypeScript implementation currently only supports Qdrant, Redis, Valkey, Vectorize and in-memory vector database.
</Note> </Note>
<CardGroup cols={3}> <CardGroup cols={3}>
@@ -31,7 +31,7 @@ const openaiClient = new OpenAI();
const memory = new Memory(); const memory = new Memory();
async function chatWithMemories(message, userId = "default_user") { async function chatWithMemories(message, userId = "default_user") {
const relevantMemories = await memory.search(message, { filters: { user_id: userId } }); const relevantMemories = await memory.search(message, { userId: userId });
const memoriesStr = relevantMemories.results const memoriesStr = relevantMemories.results
.map(entry => `- ${entry.memory}`) .map(entry => `- ${entry.memory}`)
@@ -289,7 +289,8 @@ print([m["memory"] for m in constraints["results"]])
```python ```python
constraints = memory.search( constraints = memory.search(
query="injury concerns", query="injury concerns",
filters={"user_id": "max", "memory_bucket": {"in": ["constraints"]}}, user_id="max",
filters={"memory_bucket": {"in": ["constraints"]}},
threshold=0.0 # optional: widen recall for short phrases threshold=0.0 # optional: widen recall for short phrases
) )
print([m["memory"] for m in constraints["results"]]) print([m["memory"] for m in constraints["results"]])
@@ -735,7 +736,8 @@ mem0_client.add(messages, user_id="max", run_id="nyc-2025")
# Retrieve only Boston memories # Retrieve only Boston memories
boston_memories = mem0_client.search( boston_memories = mem0_client.search(
"training plan", "training plan",
filters={"user_id": "max", "run_id": "boston-2025"} user_id="max",
run_id="boston-2025"
) )
``` ```
</Tab> </Tab>
@@ -747,7 +749,8 @@ memory.add(messages, user_id="max", run_id="nyc-2025")
# Retrieve only Boston memories # Retrieve only Boston memories
boston_memories = memory.search( boston_memories = memory.search(
"training plan", "training plan",
filters={"user_id": "max", "run_id": "boston-2025"}, user_id="max",
run_id="boston-2025",
) )
``` ```
</Tab> </Tab>
@@ -843,7 +846,8 @@ Prioritize recent training over old data:
```python ```python
recent = mem0_client.search( recent = mem0_client.search(
"training progress", "training progress",
filters={"user_id": "max", "created_at": {"gte": "2025-10-01"}} user_id="max",
filters={"created_at": {"gte": "2025-10-01"}}
) )
``` ```
</Tab> </Tab>
@@ -862,7 +866,8 @@ memory.add(
cutoff = int(datetime(2025, 10, 1).timestamp()) cutoff = int(datetime(2025, 10, 1).timestamp())
recent = memory.search( recent = memory.search(
"training progress", "training progress",
filters={"user_id": "max", "logged_epoch": {"gte": cutoff}}, user_id="max",
filters={"logged_epoch": {"gte": cutoff}},
) )
``` ```
</Tab> </Tab>
@@ -884,7 +889,8 @@ mem0_client.add(
# Later, find all speed workouts # Later, find all speed workouts
speed_sessions = mem0_client.search( speed_sessions = mem0_client.search(
"speed work", "speed work",
filters={"user_id": "max", "metadata": {"workout_type": "speed"}} user_id="max",
filters={"metadata": {"workout_type": "speed"}}
) )
``` ```
</Tab> </Tab>
@@ -899,7 +905,8 @@ memory.add(
# Later, find all speed workouts # Later, find all speed workouts
speed_sessions = memory.search( speed_sessions = memory.search(
"speed work", "speed work",
filters={"user_id": "max", "workout_type": "speed"}, user_id="max",
filters={"workout_type": "speed"},
) )
``` ```
</Tab> </Tab>
@@ -58,7 +58,6 @@ Use `get_all()` with filters to retrieve everything for a specific user:
```python ```python
dev_memories = client.get_all( dev_memories = client.get_all(
filters={"user_id": "dev"}, filters={"user_id": "dev"},
page=1,
page_size=50 page_size=50
) )
@@ -211,8 +211,8 @@ class MultiAgentLearningSystem:
try: try:
# Search memory for learning patterns # Search memory for learning patterns
memories = self.memory.search( memories = self.memory.search(
query="learning machine learning", user_id=self.student_id,
filters={"user_id": self.student_id} query="learning machine learning"
) )
if memories and memories.get('results'): if memories and memories.get('results'):
@@ -50,7 +50,7 @@ load_dotenv()
USER_ID = "Alex" USER_ID = "Alex"
# Initialize Mem0 client # Initialize Mem0 client
mem0_client = MemoryClient() mem0 = MemoryClient()
``` ```
## Define Memory Tools ## Define Memory Tools
@@ -76,7 +76,7 @@ def retrieve_patient_info(query: str) -> dict:
# Search Mem0 # Search Mem0
results = mem0_client.search( results = mem0_client.search(
query, query,
filters={"user_id": USER_ID}, user_id=USER_ID,
top_k=5, top_k=5,
threshold=0.7 # Higher threshold for more relevant results threshold=0.7 # Higher threshold for more relevant results
) )
@@ -53,12 +53,34 @@ async function addUserPreferences() {
await addUserPreferences(); await addUserPreferences();
``` ```
```json Output ```json Output (Memories)
{ [
"message": "Memory processing has been queued for background execution", {
"status": "PENDING", "id": "ff9f3367-9e83-415d-b9c5-dc8befd9a4b4",
"event_id": "9f8c2b1a-4e7d-4c3a-9b21-1a2b3c4d5e6f" "data": { "memory": "Loves BMW, Audi, and Porsche" },
} "event": "ADD"
},
{
"id": "04172ce6-3d7b-45a3-b4a1-ee9798593cb4",
"data": { "memory": "Hates Mercedes" },
"event": "ADD"
},
{
"id": "db363a5d-d258-4953-9e4c-777c120de34d",
"data": { "memory": "Loves red cars and maroon cars" },
"event": "ADD"
},
{
"id": "5519aaad-a2ac-4c0d-81d7-0d55c6ecdba8",
"data": { "memory": "Has a budget of 120K to 150K USD" },
"event": "ADD"
},
{
"id": "523b7693-7344-4563-922f-5db08edc8634",
"data": { "memory": "Likes Audi the most" },
"event": "ADD"
}
]
``` ```
</CodeGroup> </CodeGroup>
## Retrieving Memories ## Retrieving Memories
@@ -66,7 +88,7 @@ await addUserPreferences();
Search for relevant memories based on the current user input: Search for relevant memories based on the current user input:
```javascript ```javascript
const relevantMemories = await mem0Client.search(userInput, { filters: { user_id: USER_ID } }); const relevantMemories = await mem0Client.search(userInput, { userId: USER_ID });
``` ```
## Structured Responses with Zod ## Structured Responses with Zod
@@ -172,7 +194,7 @@ async function main(memory = false) {
// Search for relevant memories // Search for relevant memories
let relevantMemories = [] let relevantMemories = []
if (memory) { if (memory) {
relevantMemories = await mem0Client.search(input, { filters: { user_id: USER_ID } }); relevantMemories = await mem0Client.search(input, { userId: USER_ID });
} }
const response = await openAIClient.responses.create({ const response = await openAIClient.responses.create({
@@ -4,6 +4,8 @@ description: "Blend Tavily's realtime results with personal context stored in Me
--- ---
<Snippet file="security-compliance.mdx" />
Imagine asking a search assistant for "coffee shops nearby" and instead of generic results, it shows remote-work-friendly cafes with great WiFi in your city because it remembers you mentioned working remotely before. Or when you search for "lunchbox ideas for kids" it knows you have a 7-year-old daughter and recommends peanut-free options that align with her allergy. Imagine asking a search assistant for "coffee shops nearby" and instead of generic results, it shows remote-work-friendly cafes with great WiFi in your city because it remembers you mentioned working remotely before. Or when you search for "lunchbox ideas for kids" it knows you have a 7-year-old daughter and recommends peanut-free options that align with her allergy.
That's what we are going to build today, a Personalized Search Assistant powered by Mem0 for memory and [Tavily](https://tavily.com) for real-time search. That's what we are going to build today, a Personalized Search Assistant powered by Mem0 for memory and [Tavily](https://tavily.com) for real-time search.
@@ -217,7 +217,8 @@ def apply_writing_style(original_content):
results = memory.search( results = memory.search(
query="What are my writing style preferences?", query="What are my writing style preferences?",
filters={"user_id": USER_ID, "run_id": RUN_ID}, user_id=USER_ID,
run_id=RUN_ID,
) )
if not results: if not results:
@@ -314,16 +314,18 @@ class EmailProcessor:
user_id (str): User identifier user_id (str): User identifier
sender (str, optional): Filter by sender email address sender (str, optional): Filter by sender email address
""" """
# In OSS, user_id is an explicit parameter (not inside filters)
if not sender: if not sender:
results = self.memory.search( results = self.memory.search(
query=query, query=query,
filters={"user_id": user_id, "memory_category": "email"}, user_id=user_id,
filters={"memory_category": "email"},
) )
else: else:
results = self.memory.search( results = self.memory.search(
query=query, query=query,
user_id=user_id,
filters={ filters={
"user_id": user_id,
"AND": [ "AND": [
{"memory_category": "email"}, {"memory_category": "email"},
{"sender": sender}, {"sender": sender},
@@ -341,9 +343,10 @@ class EmailProcessor:
subject (str): Email subject to match subject (str): Email subject to match
user_id (str): User identifier user_id (str): User identifier
""" """
# In OSS, user_id is an explicit parameter
thread = self.memory.get_all( thread = self.memory.get_all(
user_id=user_id,
filters={ filters={
"user_id": user_id,
"AND": [ "AND": [
{"memory_category": "email"}, {"memory_category": "email"},
{"subject": {"icontains": subject}}, {"subject": {"icontains": subject}},
+1 -1
View File
@@ -57,7 +57,7 @@ class CustomerSupportAIAgent:
""" """
# Start a streaming chat completion request to the AI # Start a streaming chat completion request to the AI
stream = self.client.chat.completions.create( stream = self.client.chat.completions.create(
model="gpt-5-mini", model="gpt-4",
stream=True, stream=True,
messages=[ messages=[
{"role": "system", "content": "You are a customer support AI agent."}, {"role": "system", "content": "You are a customer support AI agent."},
@@ -238,11 +238,11 @@ client.search("preferences", filters={
- **Use natural language**: Mem0 understands intent, so describe what you're looking for naturally - **Use natural language**: Mem0 understands intent, so describe what you're looking for naturally
- **Scope with user ID**: Always provide `user_id` to scope search to relevant memories - **Scope with user ID**: Always provide `user_id` to scope search to relevant memories
- **Platform API**: Use `filters={"user_id": "alice"}` - **Platform API**: Use `filters={"user_id": "alice"}`
- **OSS**: Use `filters={"user_id": "alice"}` (passing `user_id` as a top-level kwarg raises `ValueError` in v3) - **OSS**: Use `user_id="alice"` as parameter
- **Combine filters**: Use AND/OR logic to create precise queries (Platform) - **Combine filters**: Use AND/OR logic to create precise queries (Platform)
- **Consider wildcard filters**: Use wildcard filters (e.g., `run_id: "*"`) for broader matches - **Consider wildcard filters**: Use wildcard filters (e.g., `run_id: "*"`) for broader matches
- **Tune parameters**: Adjust `top_k` for result count, `threshold` for relevance cutoff - **Tune parameters**: Adjust `top_k` for result count, `threshold` for relevance cutoff
- **Enable reranking**: Use `rerank=True` (default is `False`) when you have a reranker configured - **Enable reranking**: Use `rerank=True` (default) when you have a reranker configured
<Callout type="tip" icon="plug"> <Callout type="tip" icon="plug">
**MCP Alternative**: With <Link href="/platform/mem0-mcp">Mem0 MCP</Link>, AI agents can search their own memories proactively when needed. **MCP Alternative**: With <Link href="/platform/mem0-mcp">Mem0 MCP</Link>, AI agents can search their own memories proactively when needed.
+3 -2
View File
@@ -60,7 +60,7 @@ import os
from mem0 import Memory from mem0 import Memory
memory = Memory() memory = Memory(api_key=os.environ["MEM0_API_KEY"])
# Sticky note: conversation memory # Sticky note: conversation memory
memory.add( memory.add(
@@ -72,7 +72,8 @@ memory.add(
# Later in the session, pull long-term + session context # Later in the session, pull long-term + session context
results = memory.search( results = memory.search(
"Any hotel preferences?", "Any hotel preferences?",
filters={"user_id": "alex", "run_id": "trip-planning-2025"}, user_id="alex",
run_id="trip-planning-2025",
) )
``` ```
+3 -16
View File
@@ -123,7 +123,8 @@
"icon": "arrow-right", "icon": "arrow-right",
"pages": [ "pages": [
"migration/platform-v2-to-v3", "migration/platform-v2-to-v3",
"migration/oss-to-platform" "migration/oss-to-platform",
"migration/api-changes"
] ]
}, },
{ {
@@ -272,8 +273,7 @@
"components/embedders/models/lmstudio", "components/embedders/models/lmstudio",
"components/embedders/models/together", "components/embedders/models/together",
"components/embedders/models/langchain", "components/embedders/models/langchain",
"components/embedders/models/aws_bedrock", "components/embedders/models/aws_bedrock"
"components/embedders/models/fastembed"
] ]
} }
] ]
@@ -533,8 +533,6 @@
"api-reference/organization/get-org", "api-reference/organization/get-org",
"api-reference/organization/get-org-members", "api-reference/organization/get-org-members",
"api-reference/organization/add-org-member", "api-reference/organization/add-org-member",
"api-reference/organization/update-org-member",
"api-reference/organization/remove-org-member",
"api-reference/organization/delete-org" "api-reference/organization/delete-org"
] ]
}, },
@@ -547,9 +545,6 @@
"api-reference/project/get-project", "api-reference/project/get-project",
"api-reference/project/get-project-members", "api-reference/project/get-project-members",
"api-reference/project/add-project-member", "api-reference/project/add-project-member",
"api-reference/project/update-project",
"api-reference/project/update-project-member",
"api-reference/project/remove-project-member",
"api-reference/project/delete-project" "api-reference/project/delete-project"
] ]
}, },
@@ -629,10 +624,6 @@
] ]
}, },
"redirects": [ "redirects": [
{
"source": "/components/rerankers/models/llm",
"destination": "/components/rerankers/models/llm_reranker"
},
{ {
"source": "/migration/breaking-changes", "source": "/migration/breaking-changes",
"destination": "/" "destination": "/"
@@ -641,10 +632,6 @@
"source": "/migration/v0-to-v1", "source": "/migration/v0-to-v1",
"destination": "/" "destination": "/"
}, },
{
"source": "/migration/api-changes",
"destination": "/migration/oss-v2-to-v3"
},
{ {
"source": "/platform/features/expiration-date", "source": "/platform/features/expiration-date",
"destination": "/" "destination": "/"
+1 -1
View File
@@ -73,7 +73,7 @@ client = MemoryClient()
# Define the agent # Define the agent
agent = Agent( agent = Agent(
name="Personal Agent", name="Personal Agent",
model=OpenAIChat(id="gpt-5-mini"), model=OpenAIChat(id="gpt-4"),
description="You are a helpful personal agent that helps me with day to day activities." description="You are a helpful personal agent that helps me with day to day activities."
"You can process both text and images.", "You can process both text and images.",
markdown=True markdown=True
+2 -2
View File
@@ -43,7 +43,7 @@ OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')
memory_client = MemoryClient() memory_client = MemoryClient()
agent = ConversableAgent( agent = ConversableAgent(
"chatbot", "chatbot",
llm_config={"config_list": [{"model": "gpt-5-mini", "api_key": OPENAI_API_KEY}]}, llm_config={"config_list": [{"model": "gpt-4", "api_key": OPENAI_API_KEY}]},
code_execution_config=False, code_execution_config=False,
human_input_mode="NEVER", human_input_mode="NEVER",
) )
@@ -99,7 +99,7 @@ For more complex scenarios, you can create multiple agents:
manager = ConversableAgent( manager = ConversableAgent(
"manager", "manager",
system_message="You are a manager who helps in resolving complex customer issues.", system_message="You are a manager who helps in resolving complex customer issues.",
llm_config={"config_list": [{"model": "gpt-5-mini", "api_key": OPENAI_API_KEY}]}, llm_config={"config_list": [{"model": "gpt-4", "api_key": OPENAI_API_KEY}]},
human_input_mode="NEVER" human_input_mode="NEVER"
) )
+1 -2
View File
@@ -138,10 +138,9 @@ When installed via the plugin marketplace, Mem0 hooks into Claude Code's lifecyc
| Hook | Event | What it does | | Hook | Event | What it does |
|------|-------|-------------| |------|-------|-------------|
| **Setup** | `Setup` | Installs the mem0 SDK and dependencies (runs on init and maintenance) |
| **Session start** | `SessionStart` | Loads prior memories and displays status banner | | **Session start** | `SessionStart` | Loads prior memories and displays status banner |
| **User prompt** | `UserPromptSubmit` | Searches relevant memories before each message; skips short prompts | | **User prompt** | `UserPromptSubmit` | Searches relevant memories before each message; skips short prompts |
| **Pre-tool (3 handlers)** | `PreToolUse` | Blocks MEMORY.md writes; enforces `user_id`/`app_id` on mem0 tool calls; scans files being read for relevant memory context | | **Pre-tool** | `PreToolUse` | Blocks MEMORY.md writes, enforces `user_id`/`app_id` on mem0 tool calls |
| **Post-tool** | `PostToolUse` | Tracks stats, scans bash errors for related memories | | **Post-tool** | `PostToolUse` | Tracks stats, scans bash errors for related memories |
| **Stop** | `Stop` | Stores a session summary when the session ends | | **Stop** | `Stop` | Stores a session summary when the session ends |
| **Pre-compact** | `PreCompact` | Stores a summary before the context is compacted | | **Pre-compact** | `PreCompact` | Stores a summary before the context is compacted |
+1 -1
View File
@@ -123,7 +123,7 @@ When installed via the plugin marketplace, Mem0 hooks into Codex's lifecycle to
|------|-------|-------------| |------|-------|-------------|
| **Session start** | `SessionStart` | Loads prior memories and displays status banner | | **Session start** | `SessionStart` | Loads prior memories and displays status banner |
| **User prompt** | `UserPromptSubmit` | Searches relevant memories before each message | | **User prompt** | `UserPromptSubmit` | Searches relevant memories before each message |
| **Pre-tool (3 handlers)** | `PreToolUse` | Blocks MEMORY.md writes; enforces `user_id`/`app_id` on mem0 tool calls; scans files being read for relevant memory context | | **Pre-tool** | `PreToolUse` | Blocks MEMORY.md writes, enforces `user_id`/`app_id` on mem0 tool calls |
| **Post-tool** | `PostToolUse` | Tracks stats, scans bash errors for related memories | | **Post-tool** | `PostToolUse` | Tracks stats, scans bash errors for related memories |
| **Stop** | `Stop` | Stores a session summary when the session ends | | **Stop** | `Stop` | Stores a session summary when the session ends |
| **Pre-compact** | `PreCompact` | Stores a summary before the context is compacted | | **Pre-compact** | `PreCompact` | Stores a summary before the context is compacted |
+1 -1
View File
@@ -108,7 +108,7 @@ When installed via the Cursor Marketplace, Mem0 hooks into Cursor's lifecycle:
|------|-------|-------------| |------|-------|-------------|
| **Session start** | `sessionStart` | Loads prior memories and displays status banner | | **Session start** | `sessionStart` | Loads prior memories and displays status banner |
| **User prompt** | `beforeSubmitPrompt` | Searches relevant memories before each message; skips short prompts | | **User prompt** | `beforeSubmitPrompt` | Searches relevant memories before each message; skips short prompts |
| **Pre-tool (3 handlers)** | `preToolUse` | Blocks MEMORY.md writes; enforces `user_id`/`app_id` on mem0 tool calls; scans files being read for relevant memory context | | **Pre-tool (2 handlers)** | `preToolUse` | Blocks MEMORY.md writes, enforces `user_id`/`app_id` on mem0 tool calls |
| **Post-tool (2 handlers)** | `postToolUse` | Tracks stats, scans bash errors for related memories | | **Post-tool (2 handlers)** | `postToolUse` | Tracks stats, scans bash errors for related memories |
| **Stop** | `stop` | Stores a session summary when the session ends | | **Stop** | `stop` | Stores a session summary when the session ends |
| **Pre-compact** | `preCompact` | Stores a summary before the context is compacted | | **Pre-compact** | `preCompact` | Stores a summary before the context is compacted |
+31 -22
View File
@@ -98,9 +98,20 @@ add_result = add_tool.invoke(add_input)
```json Output ```json Output
{ {
"message": "Memory processing has been queued for background execution", "results": [
"status": "PENDING", {
"event_id": "3a1b2c3d-4e5f-6789-abcd-ef0123456789" "memory": "Name is Alex",
"event": "ADD"
},
{
"memory": "Is a vegetarian",
"event": "ADD"
},
{
"memory": "Is allergic to nuts",
"event": "ADD"
}
]
} }
``` ```
</CodeGroup> </CodeGroup>
@@ -162,25 +173,23 @@ result = search_tool.invoke(search_input)
``` ```
```json Output ```json Output
{ [
"results": [ {
{ "id": "1a75e827-7eca-45ea-8c5c-cfd43299f061",
"id": "1a75e827-7eca-45ea-8c5c-cfd43299f061", "memory": "Name is Alex",
"memory": "Name is Alex", "user_id": "alex",
"user_id": "alex", "hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca", "metadata": {
"metadata": { "food": "vegan"
"food": "vegan" },
}, "categories": [
"categories": [ "personal_details"
"personal_details" ],
], "created_at": "2024-11-27T16:53:43.276872-08:00",
"created_at": "2024-11-27T16:53:43.276872-08:00", "updated_at": "2024-11-27T16:53:43.276885-08:00",
"updated_at": "2024-11-27T16:53:43.276885-08:00", "score": 0.3810526501504994
"score": 0.3810526501504994 }
} ]
]
}
``` ```
</CodeGroup> </CodeGroup>
+1 -1
View File
@@ -41,7 +41,7 @@ load_dotenv()
# MEM0_API_KEY = 'your-mem0-key' # Replace with your actual Mem0 API key # MEM0_API_KEY = 'your-mem0-key' # Replace with your actual Mem0 API key
# Initialize LangChain and Mem0 # Initialize LangChain and Mem0
llm = ChatOpenAI(model="gpt-5-mini") llm = ChatOpenAI(model="gpt-4")
mem0 = MemoryClient() mem0 = MemoryClient()
``` ```
+1 -1
View File
@@ -121,7 +121,7 @@ async def websocket_endpoint(websocket: WebSocket):
# LLM for response generation # LLM for response generation
llm = OpenAILLMService( llm = OpenAILLMService(
api_key=os.getenv("OPENAI_API_KEY"), api_key=os.getenv("OPENAI_API_KEY"),
model="gpt-5-mini", model="gpt-3.5-turbo",
system_prompt="You are a helpful assistant that remembers past conversations." system_prompt="You are a helpful assistant that remembers past conversations."
) )
+5 -8
View File
@@ -26,12 +26,12 @@ Install the SDK provider and AI SDK:
npm install @mem0/vercel-ai-provider ai@^6 npm install @mem0/vercel-ai-provider ai@^6
``` ```
### Dependencies ### Peer Dependencies
`@mem0/vercel-ai-provider` bundles `ai`, all `@ai-sdk/*` provider packages, and `@ai-sdk/provider` as regular dependencies — you do **not** need to install them separately. The install command above (`npm install @mem0/vercel-ai-provider ai@^6`) is sufficient. `@mem0/vercel-ai-provider` v3.0.0 requires:
- `ai` v6+ (`^6.0.199`)
The only true peer dependency is `zod` (optional): - `@ai-sdk/provider` v3+ (`^3.0.10`)
- `zod` v3+ (`^3.0.0`) — required only if you use Zod schemas in tool definitions - Provider packages at v3+: `@ai-sdk/openai@^3`, `@ai-sdk/anthropic@^3`, `@ai-sdk/google@^3`, `@ai-sdk/groq@^3`, `@ai-sdk/cohere@^3`
## Getting Started ## Getting Started
@@ -305,8 +305,6 @@ These options can be passed per-request when creating a model instance:
| `rerank` | `boolean` | Enable reranking of results | | `rerank` | `boolean` | Enable reranking of results |
| `page` | `number` | Page number for pagination | | `page` | `number` | Page number for pagination |
| `page_size` | `number` | Results per page | | `page_size` | `number` | Results per page |
| `mem0ApiKey` | `string` | Mem0 API key; overrides the `MEM0_API_KEY` env var |
| `host` | `string` | Custom Mem0 API base URL for self-hosted deployments |
## Key Features ## Key Features
@@ -314,7 +312,6 @@ These options can be passed per-request when creating a model instance:
- `retrieveMemories()`: Retrieves memory context for prompts as a formatted system prompt string. - `retrieveMemories()`: Retrieves memory context for prompts as a formatted system prompt string.
- `getMemories()`: Get memories from your profile in array format. - `getMemories()`: Get memories from your profile in array format.
- `addMemories()`: Adds user memories to enhance contextual responses. - `addMemories()`: Adds user memories to enhance contextual responses.
- `searchMemories()`: Searches memories and returns the raw results array (semantic search rather than the full retrieval pipeline).
## Migrating from v2.x ## Migrating from v2.x
+4 -7
View File
@@ -228,6 +228,7 @@ If the user is on a pre-current major (Python < 2, TS < 3, or Platform `output_f
- [OSS to Platform Migration](https://docs.mem0.ai/migration/oss-to-platform) [Both]: Use when moving from self-hosted to managed. - [OSS to Platform Migration](https://docs.mem0.ai/migration/oss-to-platform) [Both]: Use when moving from self-hosted to managed.
- [OSS v2 to v3 Migration](https://docs.mem0.ai/migration/oss-v2-to-v3) [OSS]: Use when upgrading a self-hosted deployment across major versions. - [OSS v2 to v3 Migration](https://docs.mem0.ai/migration/oss-v2-to-v3) [OSS]: Use when upgrading a self-hosted deployment across major versions.
- [Platform v2 to v3 Migration](https://docs.mem0.ai/migration/platform-v2-to-v3) [Platform]: Use when upgrading a Platform integration across major versions. - [Platform v2 to v3 Migration](https://docs.mem0.ai/migration/platform-v2-to-v3) [Platform]: Use when upgrading a Platform integration across major versions.
- [API Changes](https://docs.mem0.ai/migration/api-changes) [Both]: Use when the upgrade involves API surface changes.
- [Server pgvector Image Upgrade](https://docs.mem0.ai/migration/server-pgvector-upgrade) [OSS]: Use when upgrading the self-hosted server Docker image from ankane/pgvector to pgvector/pgvector. - [Server pgvector Image Upgrade](https://docs.mem0.ai/migration/server-pgvector-upgrade) [OSS]: Use when upgrading the self-hosted server Docker image from ankane/pgvector to pgvector/pgvector.
- [Changelog](https://docs.mem0.ai/changelog/highlights) [Both]: Use when the user asks what shipped recently. - [Changelog](https://docs.mem0.ai/changelog/highlights) [Both]: Use when the user asks what shipped recently.
@@ -366,8 +367,6 @@ All API Reference docs describe Mem0 Platform REST endpoints (requires API key).
- [Get Organization](https://docs.mem0.ai/api-reference/organization/get-org) [Platform]: Use when fetching one org. - [Get Organization](https://docs.mem0.ai/api-reference/organization/get-org) [Platform]: Use when fetching one org.
- [Get Organization Members](https://docs.mem0.ai/api-reference/organization/get-org-members) [Platform]: Use when listing org members. - [Get Organization Members](https://docs.mem0.ai/api-reference/organization/get-org-members) [Platform]: Use when listing org members.
- [Add Organization Member](https://docs.mem0.ai/api-reference/organization/add-org-member) [Platform]: Use when inviting a member to an org. - [Add Organization Member](https://docs.mem0.ai/api-reference/organization/add-org-member) [Platform]: Use when inviting a member to an org.
- [Update Organization Member](https://docs.mem0.ai/api-reference/organization/update-org-member) [Platform]: Use when updating an org member's role.
- [Remove Organization Member](https://docs.mem0.ai/api-reference/organization/remove-org-member) [Platform]: Use when removing a member from an organization.
- [Delete Organization](https://docs.mem0.ai/api-reference/organization/delete-org) [Platform]: Use when removing an org. - [Delete Organization](https://docs.mem0.ai/api-reference/organization/delete-org) [Platform]: Use when removing an org.
### Projects ### Projects
@@ -376,9 +375,6 @@ All API Reference docs describe Mem0 Platform REST endpoints (requires API key).
- [Get Project](https://docs.mem0.ai/api-reference/project/get-project) [Platform]: Use when fetching one project. - [Get Project](https://docs.mem0.ai/api-reference/project/get-project) [Platform]: Use when fetching one project.
- [Get Project Members](https://docs.mem0.ai/api-reference/project/get-project-members) [Platform]: Use when listing project members. - [Get Project Members](https://docs.mem0.ai/api-reference/project/get-project-members) [Platform]: Use when listing project members.
- [Add Project Member](https://docs.mem0.ai/api-reference/project/add-project-member) [Platform]: Use when inviting a member to a project. - [Add Project Member](https://docs.mem0.ai/api-reference/project/add-project-member) [Platform]: Use when inviting a member to a project.
- [Update Project](https://docs.mem0.ai/api-reference/project/update-project) [Platform]: Use when updating project settings.
- [Update Project Member](https://docs.mem0.ai/api-reference/project/update-project-member) [Platform]: Use when updating a project member's role.
- [Remove Project Member](https://docs.mem0.ai/api-reference/project/remove-project-member) [Platform]: Use when removing a member from a project.
- [Delete Project](https://docs.mem0.ai/api-reference/project/delete-project) [Platform]: Use when removing a project. - [Delete Project](https://docs.mem0.ai/api-reference/project/delete-project) [Platform]: Use when removing a project.
### Webhooks ### Webhooks
@@ -464,7 +460,6 @@ Everything below is OSS-only provider configuration. Skip this entire section wh
- [LM Studio Embeddings](https://docs.mem0.ai/components/embedders/models/lmstudio) [OSS]: Use when embeddings run through LM Studio. - [LM Studio Embeddings](https://docs.mem0.ai/components/embedders/models/lmstudio) [OSS]: Use when embeddings run through LM Studio.
- [Together Embeddings](https://docs.mem0.ai/components/embedders/models/together) [OSS]: Use when embeddings run on Together. - [Together Embeddings](https://docs.mem0.ai/components/embedders/models/together) [OSS]: Use when embeddings run on Together.
- [LangChain Embeddings](https://docs.mem0.ai/components/embedders/models/langchain) [OSS]: Use when embeddings are wrapped behind a LangChain adapter. - [LangChain Embeddings](https://docs.mem0.ai/components/embedders/models/langchain) [OSS]: Use when embeddings are wrapped behind a LangChain adapter.
- [FastEmbed](https://docs.mem0.ai/components/embedders/models/fastembed) [OSS]: Use when embeddings run locally via FastEmbed (ONNX).
### Vector Databases [OSS] ### Vector Databases [OSS]
- [Vector Database Overview](https://docs.mem0.ai/components/vectordbs/overview) [OSS]: Use when choosing a vector store. - [Vector Database Overview](https://docs.mem0.ai/components/vectordbs/overview) [OSS]: Use when choosing a vector store.
@@ -503,5 +498,7 @@ Everything below is OSS-only provider configuration. Skip this entire section wh
- [Custom Reranker Prompts](https://docs.mem0.ai/components/rerankers/custom-prompts) [OSS]: Use when rewriting reranker prompts. - [Custom Reranker Prompts](https://docs.mem0.ai/components/rerankers/custom-prompts) [OSS]: Use when rewriting reranker prompts.
- [Cohere Reranker](https://docs.mem0.ai/components/rerankers/models/cohere) [OSS]: Use for Cohere Rerank. - [Cohere Reranker](https://docs.mem0.ai/components/rerankers/models/cohere) [OSS]: Use for Cohere Rerank.
- [Sentence Transformer Reranker](https://docs.mem0.ai/components/rerankers/models/sentence_transformer) [OSS]: Use for local cross-encoder rerankers. - [Sentence Transformer Reranker](https://docs.mem0.ai/components/rerankers/models/sentence_transformer) [OSS]: Use for local cross-encoder rerankers.
- [Hugging Face Reranker](https://docs.mem0.ai/components/rerankers/models/huggingface) [OSS]: Use for HF-hosted reranker models.- [LLM Reranker](https://docs.mem0.ai/components/rerankers/models/llm_reranker) [OSS]: Use when the reranker is a prompted LLM (implementation reference). - [Hugging Face Reranker](https://docs.mem0.ai/components/rerankers/models/huggingface) [OSS]: Use for HF-hosted reranker models.
- [LLM Reranker (prompt)](https://docs.mem0.ai/components/rerankers/models/llm) [OSS]: Use when the reranker is a prompted LLM (config guide).
- [LLM Reranker](https://docs.mem0.ai/components/rerankers/models/llm_reranker) [OSS]: Use when the reranker is a prompted LLM (implementation reference).
- [Zero Entropy Reranker](https://docs.mem0.ai/components/rerankers/models/zero_entropy) [OSS]: Use for the Zero Entropy reranker. - [Zero Entropy Reranker](https://docs.mem0.ai/components/rerankers/models/zero_entropy) [OSS]: Use for the Zero Entropy reranker.
+574
View File
@@ -0,0 +1,574 @@
---
title: API Reference Changes
description: "Comprehensive reference of all API changes between Mem0 v0.x and v1.0.0 Beta, organized by component and method."
icon: "code"
iconType: "solid"
---
## Overview
This page documents all API changes between Mem0 v0.x and v1.0.0 Beta, organized by component and method.
## Memory Class Changes
### Constructor
#### v0.x
```python
from mem0 import Memory
# Basic initialization
m = Memory()
# With configuration
config = {
"version": "v1.0", # Supported in v0.x
"vector_store": {...}
}
m = Memory.from_config(config)
```
#### v1.0.0
```python
from mem0 import Memory
# Basic initialization (same)
m = Memory()
# With configuration
config = {
"version": "v1.1", # v1.1+ only
"vector_store": {...},
# New optional features
"reranker": {
"provider": "cohere",
"config": {...}
}
}
m = Memory.from_config(config)
```
### add() Method
#### v0.x Signature
```python
def add(
self,
messages,
user_id: str = None,
agent_id: str = None,
run_id: str = None,
metadata: dict = None,
filters: dict = None,
output_format: str = None, # ❌ REMOVED
version: str = None # ❌ REMOVED
) -> Union[List[dict], dict]:
...
```
#### v1.0.0 Signature
```python
def add(
self,
messages,
user_id: str = None,
agent_id: str = None,
run_id: str = None,
metadata: dict = None,
filters: dict = None,
infer: bool = True # ✅ NEW: Control memory inference
) -> dict: # Always returns dict with "results" key
...
```
#### Changes Summary
| Parameter | v0.x | v1.0.0 | Change |
|-----------|------|-----------|---------|
| `messages` | ✅ | ✅ | Unchanged |
| `user_id` | ✅ | ✅ | Unchanged |
| `agent_id` | ✅ | ✅ | Unchanged |
| `run_id` | ✅ | ✅ | Unchanged |
| `metadata` | ✅ | ✅ | Unchanged |
| `filters` | ✅ | ✅ | Unchanged |
| `output_format` | ✅ | ❌ | **REMOVED** |
| `version` | ✅ | ❌ | **REMOVED** |
| `infer` | ❌ | ✅ | **NEW** |
#### Response Format Changes
**v0.x Response (variable format):**
```python
# With output_format="v1.0"
[
{
"id": "mem_123",
"memory": "User loves pizza",
"event": "ADD"
}
]
# With output_format="v1.1"
{
"results": [
{
"id": "mem_123",
"memory": "User loves pizza",
"event": "ADD"
}
]
}
```
**v1.0.0 Response (standardized):**
```python
# Always returns this format
{
"results": [
{
"id": "mem_123",
"memory": "User loves pizza",
"metadata": {...},
"event": "ADD"
}
]
}
```
### search() Method
#### v0.x Signature
```python
def search(
self,
query: str,
user_id: str = None,
agent_id: str = None,
run_id: str = None,
limit: int = 100,
filters: dict = None, # Basic key-value only
output_format: str = None, # ❌ REMOVED
version: str = None # ❌ REMOVED
) -> Union[List[dict], dict]:
...
```
#### v1.0.0 Signature
```python
def search(
self,
query: str,
user_id: str = None,
agent_id: str = None,
run_id: str = None,
limit: int = 100,
filters: dict = None, # ✅ ENHANCED: Advanced operators
rerank: bool = True # ✅ NEW: Reranking support
) -> dict: # Always returns dict with "results" key
...
```
#### Enhanced Filtering
**v0.x Filters (basic):**
```python
# Simple key-value filtering only
filters = {
"category": "food",
"user_id": "alice"
}
```
**v1.0.0 Filters (enhanced):**
```python
# Advanced filtering with operators
filters = {
"AND": [
{"category": "food"},
{"score": {"gte": 0.8}},
{
"OR": [
{"priority": "high"},
{"urgent": True}
]
}
]
}
# Comparison operators
filters = {
"score": {"gt": 0.5}, # Greater than
"priority": {"gte": 5}, # Greater than or equal
"rating": {"lt": 3}, # Less than
"confidence": {"lte": 0.9}, # Less than or equal
"status": {"eq": "active"}, # Equal
"archived": {"ne": True}, # Not equal
"tags": {"in": ["work", "personal"]}, # In list
"category": {"nin": ["spam", "deleted"]} # Not in list
}
```
### get_all() Method
#### v0.x Signature
```python
def get_all(
self,
user_id: str = None,
agent_id: str = None,
run_id: str = None,
filters: dict = None,
output_format: str = None, # ❌ REMOVED
version: str = None # ❌ REMOVED
) -> Union[List[dict], dict]:
...
```
#### v1.0.0 Signature
```python
def get_all(
self,
user_id: str = None,
agent_id: str = None,
run_id: str = None,
filters: dict = None # ✅ ENHANCED: Advanced operators
) -> dict: # Always returns dict with "results" key
...
```
### update() Method
#### No Breaking Changes
```python
# Same signature in both versions
def update(
self,
memory_id: str,
data: str
) -> dict:
...
```
### delete() Method
#### No Breaking Changes
```python
# Same signature in both versions
def delete(
self,
memory_id: str
) -> dict:
...
```
### delete_all() Method
#### Breaking Change — Empty filter no longer silently deletes everything
**Before:** calling `delete_all()` with no filters silently deleted **all memories in the project**.
**After:**
- No filters → raises a validation error (prevents accidental full-project wipe).
- Concrete ID (e.g. `user_id="alice"`) → deletes memories for that entity (unchanged).
- `"*"` for a filter → deletes all memories for that entity type across the project (new).
- All four filters set to `"*"` → explicit full project wipe (new, requires opt-in on every parameter).
This change replaces the silent full-project delete (triggered by an empty or missing filter) with a validation error, and introduces `"*"` wildcards as the intentional path for bulk deletion.
```python
# v0.x — no filter silently wiped all project memories
m.delete_all() # DANGER: deleted everything
m.delete_all(user_id="alice") # deleted alice's memories
# v1.x — no filter now raises an error; use "*" for intentional bulk deletes
m.delete_all() # ERROR: at least one filter required
m.delete_all(user_id="alice") # unchanged
m.delete_all(user_id="*") # NEW — delete all users' memories
m.delete_all(user_id="*", agent_id="*", app_id="*", run_id="*") # NEW — full project wipe
```
## Platform Client (MemoryClient) Changes
### async_mode Default Changed
#### v0.x
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-key")
# async_mode had to be explicitly set or had different default
result = client.add("content", user_id="alice", async_mode=True)
```
#### v1.0.0
```python
from mem0 import MemoryClient
client = MemoryClient(api_key="your-key")
# async_mode defaults to True now (better performance)
result = client.add("content", user_id="alice") # Uses async_mode=True by default
# Can still override if needed
result = client.add("content", user_id="alice", async_mode=False)
```
## Configuration Changes
### Memory Configuration
#### v0.x Config Options
```python
config = {
"vector_store": {...},
"llm": {...},
"embedder": {...},
"graph_store": {...},
"version": "v1.0", # ❌ v1.0 no longer supported
"history_db_path": "...",
"custom_instructions": "..."
}
```
#### v1.0.0 Config Options
```python
config = {
"vector_store": {...},
"llm": {...},
"embedder": {...},
"graph_store": {...},
"reranker": { # ✅ NEW: Reranker support
"provider": "cohere",
"config": {...}
},
"version": "v1.1", # ✅ v1.1+ only
"history_db_path": "...",
"custom_instructions": "...",
"custom_update_memory_prompt": "..." # ✅ NEW: Custom update prompt
}
```
### New Configuration Options
#### Reranker Configuration
```text
# Cohere reranker
"reranker": {
"provider": "cohere",
"config": {
"model": "rerank-english-v3.0",
"api_key": "your-api-key",
"top_k": 10
}
}
# Sentence Transformer reranker
"reranker": {
"provider": "sentence_transformer",
"config": {
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2",
"device": "cuda"
}
}
# Hugging Face reranker
"reranker": {
"provider": "huggingface",
"config": {
"model": "BAAI/bge-reranker-base",
"device": "cuda"
}
}
# LLM-based reranker
"reranker": {
"provider": "llm_reranker",
"config": {
"llm": {
"provider": "openai",
"config": {
"model": "gpt-4",
"api_key": "your-api-key"
}
}
}
}
```
## Error Handling Changes
### New Error Types
#### v0.x Errors
```python
# Generic exceptions
try:
result = m.add("content", user_id="alice", version="v1.0")
except Exception as e:
print(f"Error: {e}")
```
#### v1.0.0 Errors
```python
# More specific error handling
try:
result = m.add("content", user_id="alice")
except ValueError as e:
if "v1.0 API format is no longer supported" in str(e):
# Handle version compatibility error
pass
elif "Invalid filter operator" in str(e):
# Handle filter syntax error
pass
except TypeError as e:
# Handle parameter errors
pass
except Exception as e:
# Handle unexpected errors
pass
```
### Validation Changes
#### Stricter Parameter Validation
**v0.x (Lenient):**
```python
# Unknown parameters might be ignored
result = m.add("content", user_id="alice", unknown_param="value")
```
**v1.0.0 (Strict):**
```python
# Unknown parameters raise TypeError
try:
result = m.add("content", user_id="alice", unknown_param="value")
except TypeError as e:
print(f"Invalid parameter: {e}")
```
## Response Schema Changes
### Memory Object Schema
#### v0.x Schema
```python
{
"id": "mem_123",
"memory": "User loves pizza",
"user_id": "alice",
"metadata": {...},
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z",
"score": 0.95 # In search results
}
```
#### v1.0.0 Schema (Enhanced)
```python
{
"id": "mem_123",
"memory": "User loves pizza",
"user_id": "alice",
"agent_id": "assistant", # ✅ More context
"run_id": "session_001", # ✅ More context
"metadata": {...},
"categories": ["food"], # ✅ NEW: Auto-categorization
"immutable": false, # ✅ NEW: Immutability flag
"created_at": "2024-01-01T00:00:00Z",
"updated_at": "2024-01-01T00:00:00Z",
"score": 0.95, # In search results
"rerank_score": 0.98 # ✅ NEW: If reranking used
}
```
## Migration Code Examples
### Simple Migration
#### Before (v0.x)
```python
from mem0 import Memory
m = Memory()
# Add with deprecated parameters
result = m.add(
"I love pizza",
user_id="alice",
output_format="v1.1",
version="v1.0"
)
# Handle variable response format
if isinstance(result, list):
memories = result
else:
memories = result.get("results", [])
for memory in memories:
print(memory["memory"])
```
#### After (v1.0.0 )
```python
from mem0 import Memory
m = Memory()
# Add without deprecated parameters
result = m.add(
"I love pizza",
user_id="alice"
)
# Always dict format with "results" key
for memory in result["results"]:
print(memory["memory"])
```
### Advanced Migration
#### Before (v0.x)
```python
# Basic filtering
results = m.search(
"food preferences",
user_id="alice",
filters={"category": "food"},
output_format="v1.1"
)
```
#### After (v1.0.0 )
```python
# Enhanced filtering with reranking
results = m.search(
"food preferences",
user_id="alice",
filters={
"AND": [
{"category": "food"},
{"score": {"gte": 0.8}}
]
},
rerank=True
)
```
## Summary
| Component | v0.x | v1.0.0 | Status |
|-----------|------|-----------|---------|
| `add()` method | Variable response | Standardized response | ⚠️ Breaking |
| `search()` method | Basic filtering | Enhanced filtering + reranking | ⚠️ Breaking |
| `get_all()` method | Variable response | Standardized response | ⚠️ Breaking |
| Response format | Variable | Always `{"results": [...]}` | ⚠️ Breaking |
| Reranking | ❌ Not available | ✅ Full support | ✅ New feature |
| Advanced filtering | ❌ Basic only | ✅ Full operators | ✅ Enhancement |
| Error handling | Generic | Specific error types | ✅ Improvement |
<Info>
Use this reference to systematically update your codebase. Test each change thoroughly before deploying to production.
</Info>
+4 -4
View File
@@ -62,7 +62,7 @@ These changes produce a **+20 point improvement on LoCoMo** (71.4 → 91.6) and
|---|---|---|---| |---|---|---|---|
| Constructor | `MemoryClient(api_key, org_id, project_id)` | `MemoryClient(api_key)` | Remove `org_id`, `project_id` from constructor | | Constructor | `MemoryClient(api_key, org_id, project_id)` | `MemoryClient(api_key)` | Remove `org_id`, `project_id` from constructor |
| Method options | `client.add(messages, **kwargs)` | `client.add(messages, options=AddMemoryOptions(...))` | Use typed option classes (or `**kwargs` still works) | | Method options | `client.add(messages, **kwargs)` | `client.add(messages, options=AddMemoryOptions(...))` | Use typed option classes (or `**kwargs` still works) |
| Removed params | `api_version`, `output_format`, `async_mode`, `filter_memories`, `keyword_search`, `force_add_only`, `batch_size`, `immutable`, `includes`, `excludes`, `enable_graph`, `org_name`, `project_name` | — | Remove from all calls | | Removed params | `api_version`, `output_format`, `async_mode`, `filter_memories`, `expiration_date`, `keyword_search`, `force_add_only`, `batch_size`, `immutable`, `includes`, `excludes`, `enable_graph`, `org_name`, `project_name` | — | Remove from all calls |
### TypeScript Client SDK ### TypeScript Client SDK
@@ -70,7 +70,7 @@ These changes produce a **+20 point improvement on LoCoMo** (71.4 → 91.6) and
|---|---|---|---| |---|---|---|---|
| Constructor | `new MemoryClient({ apiKey, organizationId, projectId })` | `new MemoryClient({ apiKey })` | Remove `organizationId`, `projectId`, `organizationName`, `projectName` | | Constructor | `new MemoryClient({ apiKey, organizationId, projectId })` | `new MemoryClient({ apiKey })` | Remove `organizationId`, `projectId`, `organizationName`, `projectName` |
| All params | snake_case: `user_id`, `agent_id`, `top_k` | camelCase: `userId`, `agentId`, `topK` | Rename all params to camelCase | | All params | snake_case: `user_id`, `agent_id`, `top_k` | camelCase: `userId`, `agentId`, `topK` | Rename all params to camelCase |
| Removed params | `api_version`, `output_format`, `async_mode`, `enable_graph`, `org_id`, `project_id`, `org_name`, `project_name`, `filter_memories`, `batch_size`, `force_add_only`, `immutable`, `includes`, `excludes`, `keyword_search` | — | Remove from all calls | | Removed params | `api_version`, `output_format`, `async_mode`, `enable_graph`, `org_id`, `project_id`, `org_name`, `project_name`, `filter_memories`, `batch_size`, `force_add_only`, `immutable`, `expiration_date`, `includes`, `excludes`, `keyword_search` | — | Remove from all calls |
| Output format enum | `OutputFormat.V1`, `OutputFormat.V1_1` | Removed | v1.1 is now always used | | Output format enum | `OutputFormat.V1`, `OutputFormat.V1_1` | Removed | v1.1 is now always used |
| API version enum | `API_VERSION.V1`, `API_VERSION.V2` | Removed | Handled internally | | API version enum | `API_VERSION.V1`, `API_VERSION.V2` | Removed | Handled internally |
@@ -423,7 +423,7 @@ These parameters have been removed across all SDKs. Remove them from your code:
**All methods:** `api_version`, `output_format`, `async_mode`, `org_name`, `project_name`, `org_id`, `project_id` **All methods:** `api_version`, `output_format`, `async_mode`, `org_name`, `project_name`, `org_id`, `project_id`
**add():** `enable_graph`, `immutable`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search` **add():** `enable_graph`, `immutable`, `expiration_date`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`
**search():** `enable_graph` **search():** `enable_graph`
@@ -437,7 +437,7 @@ These parameters have been removed across all SDKs. Remove them from your code:
**All methods:** `OutputFormat` enum, `API_VERSION` enum **All methods:** `OutputFormat` enum, `API_VERSION` enum
**add():** `enable_graph` / `enableGraph`, `async_mode` / `asyncMode`, `output_format` / `outputFormat`, `immutable`, `filter_memories` / `filterMemories`, `batch_size` / `batchSize`, `force_add_only` / `forceAddOnly`, `includes`, `excludes`, `keyword_search` / `keywordSearch` **add():** `enable_graph` / `enableGraph`, `async_mode` / `asyncMode`, `output_format` / `outputFormat`, `immutable`, `expiration_date` / `expirationDate`, `filter_memories` / `filterMemories`, `batch_size` / `batchSize`, `force_add_only` / `forceAddOnly`, `includes`, `excludes`, `keyword_search` / `keywordSearch`
**search():** `enable_graph` / `enableGraph` **search():** `enable_graph` / `enableGraph`
+2 -2
View File
@@ -215,7 +215,7 @@ client.add(messages, user_id="alice")
# async_mode and output_format removed (async by default, v1.1 always) # async_mode and output_format removed (async by default, v1.1 always)
``` ```
**Removed parameters:** `org_id`, `project_id`, `api_version`, `output_format`, `async_mode`, `enable_graph`, `immutable`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`, `org_name`, `project_name` **Removed parameters:** `org_id`, `project_id`, `api_version`, `output_format`, `async_mode`, `enable_graph`, `immutable`, `expiration_date`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`, `org_name`, `project_name`
### TypeScript Client SDK ### TypeScript Client SDK
@@ -242,7 +242,7 @@ await client.search("query", {
}); });
``` ```
**Removed:** `OutputFormat` enum, `API_VERSION` enum, `organizationId`, `projectId`, `organizationName`, `projectName`, `enableGraph`, `asyncMode`, `outputFormat`, `immutable`, `filterMemories`, `batchSize`, `forceAddOnly`, `includes`, `excludes`, `keywordSearch` **Removed:** `OutputFormat` enum, `API_VERSION` enum, `organizationId`, `projectId`, `organizationName`, `projectName`, `enableGraph`, `asyncMode`, `outputFormat`, `immutable`, `expirationDate`, `filterMemories`, `batchSize`, `forceAddOnly`, `includes`, `excludes`, `keywordSearch`
<Info> <Info>
For the full list of parameter changes across all SDKs, see the [OSS migration guide](/migration/oss-v2-to-v3#removed-parameters-reference). For the full list of parameter changes across all SDKs, see the [OSS migration guide](/migration/oss-v2-to-v3#removed-parameters-reference).
+1 -1
View File
@@ -130,7 +130,7 @@ memory = Memory.from_config_file("config.yaml")
</Tabs> </Tabs>
<Info icon="check"> <Info icon="check">
Run `memory.add("Remember my favorite cafe in Tokyo.", user_id="alex")` and then `memory.search("favorite cafe", filters={"user_id": "alex"})`. You should see the Qdrant collection populate and the reranker mark the memory as a top hit. Run `memory.add(["Remember my favorite cafe in Tokyo."], user_id="alex")` and then `memory.search("favorite cafe", filters={"user_id": "alex"})`. You should see the Qdrant collection populate and the reranker mark the memory as a top hit.
</Info> </Info>
## Tune component settings ## Tune component settings
+1 -1
View File
@@ -18,7 +18,7 @@ icon: "bolt"
</Warning> </Warning>
<Note> <Note>
Working in TypeScript? The OSS `Memory` class in the Node SDK (`mem0ai/oss`) is also fully async — every method returns a `Promise` and must be `await`ed. Python’s `AsyncMemory` serves the same purpose within Python async frameworks like FastAPI. Both runtimes support awaited memory operations; choose the SDK that matches your language. Working in TypeScript? The Node SDK still uses synchronous calls—use `Memory` there and rely on Python’s `AsyncMemory` when you need awaited operations.
</Note> </Note>
## Feature anatomy ## Feature anatomy
@@ -165,7 +165,8 @@ await memory.add("Yesterday, I ordered a laptop, the order id is 12345", { userI
{"memory": "Ordered a laptop", "event": "ADD"}, {"memory": "Ordered a laptop", "event": "ADD"},
{"memory": "Order ID: 12345", "event": "ADD"}, {"memory": "Order ID: 12345", "event": "ADD"},
{"memory": "Order placed yesterday", "event": "ADD"} {"memory": "Order placed yesterday", "event": "ADD"}
] ],
"relations": []
} }
``` ```
</CodeGroup> </CodeGroup>
@@ -187,7 +188,8 @@ await memory.add("I like going to hikes", { userId: "user123" });
```json Output ```json Output
{ {
"results": [] "results": [],
"relations": []
} }
``` ```
</CodeGroup> </CodeGroup>
@@ -41,14 +41,6 @@ Multimodal support lets Mem0 extract facts from images alongside regular text. A
## Configure it ## Configure it
<Warning>
You must set `enable_vision: True` in your LLM config for image content to be processed. Without it, image turns are silently dropped and no vision memories are created. Example:
```python
config = {"llm": {"provider": "openai", "config": {"enable_vision": True, "vision_details": "auto"}}}
client = Memory.from_config(config)
```
</Warning>
### Add image messages from URLs ### Add image messages from URLs
<CodeGroup> <CodeGroup>
@@ -74,7 +66,7 @@ client.add(messages, user_id="alice")
``` ```
```ts TypeScript ```ts TypeScript
import { Memory } from "mem0ai/oss"; import { Memory } from "mem0ai";
const client = new Memory(); const client = new Memory();
@@ -131,7 +123,7 @@ client.add(messages, user_id="alice")
```ts TypeScript ```ts TypeScript
import fs from "fs"; import fs from "fs";
import { Memory } from "mem0ai/oss"; import { Memory } from "mem0ai";
function encodeImage(imagePath: string) { function encodeImage(imagePath: string) {
const buffer = fs.readFileSync(imagePath); const buffer = fs.readFileSync(imagePath);
@@ -234,7 +226,7 @@ client.add(messages, user_id="user123")
<CodeGroup> <CodeGroup>
```python Python ```python Python
from mem0 import Memory from mem0 import Memory
from mem0.exceptions import ValidationError from mem0.exceptions import InvalidImageError, FileSizeError
client = Memory() client = Memory()
@@ -250,14 +242,16 @@ try:
client.add(messages, user_id="user123") client.add(messages, user_id="user123")
print("Image processed successfully") print("Image processed successfully")
except ValidationError as exc: except InvalidImageError:
print(f"Image validation error: {exc}") print("Invalid image format or corrupted file")
except FileSizeError:
print("Image file too large")
except Exception as exc: except Exception as exc:
print(f"Unexpected error: {exc}") print(f"Unexpected error: {exc}")
``` ```
```ts TypeScript ```ts TypeScript
import { Memory } from "mem0ai/oss"; import { Memory } from "mem0ai";
const client = new Memory(); const client = new Memory();
@@ -124,7 +124,7 @@ config = {
"provider": "llm_reranker", "provider": "llm_reranker",
"config": { "config": {
"provider": "openai", "provider": "openai",
"model": "gpt-5-mini", "model": "gpt-4o-mini",
"api_key": "your-openai-api-key", "api_key": "your-openai-api-key",
"top_k": 5 "top_k": 5
} }
@@ -150,7 +150,7 @@ config = {
"llm": { "llm": {
"provider": "openai", "provider": "openai",
"config": { "config": {
"model": "gpt-5-mini", "model": "gpt-4",
"api_key": "your-openai-api-key" "api_key": "your-openai-api-key"
} }
}, },
+8 -43
View File
@@ -1779,11 +1779,6 @@
"type": "object", "type": "object",
"description": "Entity and metadata filters. Must include at least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`).", "description": "Entity and metadata filters. Must include at least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`).",
"additionalProperties": true "additionalProperties": true
},
"show_expired": {
"type": "boolean",
"default": false,
"description": "When true, include memories whose `expiration_date` has passed. Expired memories are hidden by default."
} }
} }
}, },
@@ -1982,12 +1977,6 @@
"additionalProperties": true, "additionalProperties": true,
"description": "User-supplied metadata to attach to each extracted memory." "description": "User-supplied metadata to attach to each extracted memory."
}, },
"expiration_date": {
"type": "string",
"format": "date",
"nullable": true,
"description": "Optional expiration date in YYYY-MM-DD format. After this date, memories are hidden from search and get-all unless `show_expired` is true."
},
"custom_instructions": { "custom_instructions": {
"type": "string", "type": "string",
"description": "Project-level instructions that guide extraction for this call." "description": "Project-level instructions that guide extraction for this call."
@@ -2105,11 +2094,6 @@
"description": "Entity and metadata filters. Must include at least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`). Supports `AND`, `OR`, `NOT`, and comparison operators (`in`, `gte`, `lte`, `gt`, `lt`, `contains`, `icontains`, `ne`).", "description": "Entity and metadata filters. Must include at least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`). Supports `AND`, `OR`, `NOT`, and comparison operators (`in`, `gte`, `lte`, `gt`, `lt`, `contains`, `icontains`, `ne`).",
"additionalProperties": true "additionalProperties": true
}, },
"show_expired": {
"type": "boolean",
"default": false,
"description": "When true, include memories whose `expiration_date` has passed. Expired memories are hidden by default."
},
"top_k": { "top_k": {
"type": "integer", "type": "integer",
"minimum": 1, "minimum": 1,
@@ -2448,12 +2432,6 @@
"metadata": { "metadata": {
"type": "object", "type": "object",
"description": "Additional metadata associated with the memory" "description": "Additional metadata associated with the memory"
},
"expiration_date": {
"type": "string",
"format": "date",
"nullable": true,
"description": "Expiration date in YYYY-MM-DD format, or null to clear the expiration date."
} }
} }
} }
@@ -4883,7 +4861,8 @@
"items": { "items": {
"type": "object", "type": "object",
"required": [ "required": [
"memory_id" "memory_id",
"text"
], ],
"properties": { "properties": {
"memory_id": { "memory_id": {
@@ -4894,11 +4873,6 @@
"text": { "text": {
"type": "string", "type": "string",
"description": "The new text content for the memory" "description": "The new text content for the memory"
},
"metadata": {
"type": "object",
"additionalProperties": true,
"description": "Updated metadata to associate with the memory."
} }
} }
}, },
@@ -4974,27 +4948,18 @@
"schema": { "schema": {
"type": "object", "type": "object",
"properties": { "properties": {
"memories": { "memory_ids": {
"type": "array", "type": "array",
"items": { "items": {
"type": "object", "type": "string",
"properties": { "format": "uuid"
"memory_id": {
"type": "string",
"format": "uuid",
"description": "The unique identifier of the memory to delete."
}
},
"required": [
"memory_id"
]
}, },
"maxItems": 1000, "maxItems": 1000,
"description": "Array of memory objects to delete." "description": "Array of memory IDs to delete."
} }
}, },
"required": [ "required": [
"memories" "memory_ids"
] ]
} }
} }
@@ -6291,4 +6256,4 @@
} }
}, },
"x-original-swagger-version": "2.0" "x-original-swagger-version": "2.0"
} }
+13 -8
View File
@@ -9,6 +9,7 @@ description: "Run richer add/search/update/delete flows on the managed platform
**Prerequisites** **Prerequisites**
- Platform workspace with API key - Platform workspace with API key
- Python 3.10+ and Node.js 18+ - Python 3.10+ and Node.js 18+
- Async memories enabled in your dashboard (Settings → Memory Options)
</Info> </Info>
<Tip> <Tip>
@@ -20,9 +21,9 @@ description: "Run richer add/search/update/delete flows on the managed platform
<Tabs> <Tabs>
<Tab title="Python"> <Tab title="Python">
<Steps> <Steps>
<Step title="Install the SDK"> <Step title="Install the SDK with async extras">
```bash ```bash
pip install mem0ai pip install "mem0ai[async]"
``` ```
</Step> </Step>
<Step title="Export your API key"> <Step title="Export your API key">
@@ -54,9 +55,9 @@ export MEM0_API_KEY="sk-platform-..."
</Step> </Step>
<Step title="Instantiate the client"> <Step title="Instantiate the client">
```typescript ```typescript
import MemoryClient from 'mem0ai'; import { Memory } from "mem0ai";
const memory = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! }); const memory = new Memory({ apiKey: process.env.MEM0_API_KEY!, async: true });
``` ```
</Step> </Step>
</Steps> </Steps>
@@ -120,8 +121,10 @@ const result = await memory.add(conversation, {
```python ```python
matches = await memory.search( matches = await memory.search(
"Any food alerts?", "Any food alerts?",
filters={"user_id": "traveler-42", "metadata.trip": "japan-2025"}, user_id="traveler-42",
filters={"metadata.trip": "japan-2025"},
rerank=True, rerank=True,
include_vectors=False,
) )
``` ```
</Step> </Step>
@@ -129,7 +132,7 @@ matches = await memory.search(
```python ```python
await memory.update( await memory.update(
memory_id=matches["results"][0]["id"], memory_id=matches["results"][0]["id"],
data="Morgan avoids shellfish and prefers boutique hotels in central Tokyo.", content="Morgan avoids shellfish and prefers boutique hotels in central Tokyo.",
) )
``` ```
</Step> </Step>
@@ -140,15 +143,17 @@ await memory.update(
<Step title="Search with metadata filters"> <Step title="Search with metadata filters">
```typescript ```typescript
const matches = await memory.search("Any food alerts?", { const matches = await memory.search("Any food alerts?", {
filters: { user_id: "traveler-42", "metadata.trip": "japan-2025" }, userId: "traveler-42",
filters: { "metadata.trip": "japan-2025" },
rerank: true, rerank: true,
includeVectors: false,
}); });
``` ```
</Step> </Step>
<Step title="Apply an update"> <Step title="Apply an update">
```typescript ```typescript
await memory.update(matches.results[0].id, { await memory.update(matches.results[0].id, {
text: "Morgan avoids shellfish and prefers boutique hotels in central Tokyo.", content: "Morgan avoids shellfish and prefers boutique hotels in central Tokyo.",
}); });
``` ```
</Step> </Step>
+14 -14
View File
@@ -26,7 +26,7 @@ Reorders results using deep semantic understanding to put the most relevant memo
results = client.search( results = client.search(
query="What are my upcoming travel plans?", query="What are my upcoming travel plans?",
rerank=True, rerank=True,
filters={"user_id": "user123"}, user_id="user123"
) )
# Before reranking: After reranking: # Before reranking: After reranking:
@@ -52,7 +52,7 @@ results = client.search(
results = client.search( results = client.search(
query="How do I like my bedroom temperature?", query="How do I like my bedroom temperature?",
rerank=True, # Get most recent preferences first rerank=True, # Get most recent preferences first
filters={"user_id": "user123"}, user_id="user123"
) )
# Finds: "Keep bedroom at 68°F", "Too cold last night at 65°F", etc. # Finds: "Keep bedroom at 68°F", "Too cold last night at 65°F", etc.
@@ -63,7 +63,7 @@ results = client.search(
# Find specific product issues with high precision # Find specific product issues with high precision
results = client.search( results = client.search(
query="Problems with premium subscription billing", query="Problems with premium subscription billing",
filters={"user_id": "customer456"}, user_id="customer456"
) )
# Returns only relevant billing problems, not general questions # Returns only relevant billing problems, not general questions
@@ -75,7 +75,7 @@ results = client.search(
results = client.search( results = client.search(
query="Patient allergies and contraindications", query="Patient allergies and contraindications",
rerank=True, # Most important info first rerank=True, # Most important info first
filters={"user_id": "patient789"}, user_id="patient789"
) )
# Ensures critical allergy info appears first # Ensures critical allergy info appears first
@@ -87,7 +87,7 @@ results = client.search(
results = client.search( results = client.search(
query="Python programming progress and difficulties", query="Python programming progress and difficulties",
rerank=True, # Recent progress first rerank=True, # Recent progress first
filters={"user_id": "student123"}, user_id="student123"
) )
# Gets comprehensive view of Python learning journey # Gets comprehensive view of Python learning journey
@@ -105,7 +105,7 @@ results = client.search(
def quick_search(query, user_id): def quick_search(query, user_id):
return client.search( return client.search(
query=query, query=query,
filters={"user_id": user_id}, user_id=user_id
) )
# Reranked search - good for most applications # Reranked search - good for most applications
@@ -113,7 +113,7 @@ def standard_search(query, user_id):
return client.search( return client.search(
query=query, query=query,
rerank=True, rerank=True,
filters={"user_id": user_id}, user_id=user_id
) )
# Reranked search - good for critical applications # Reranked search - good for critical applications
@@ -121,7 +121,7 @@ def precise_search(query, user_id):
return client.search( return client.search(
query=query, query=query,
rerank=True, rerank=True,
filters={"user_id": user_id}, user_id=user_id
) )
``` ```
@@ -129,23 +129,23 @@ def precise_search(query, user_id):
// Basic search - good for exploration // Basic search - good for exploration
function quickSearch(query, userId) { function quickSearch(query, userId) {
return client.search(query, { return client.search(query, {
filters: { user_id: userId }, user_id: userId
}); });
} }
// Reranked search - good for most applications // Reranked search - good for most applications
function standardSearch(query, userId) { function standardSearch(query, userId) {
return client.search(query, { return client.search(query, {
filters: { user_id: userId }, user_id: userId,
rerank: true, rerank: true
}); });
} }
// Reranked search - good for critical applications // Reranked search - good for critical applications
function preciseSearch(query, userId) { function preciseSearch(query, userId) {
return client.search(query, { return client.search(query, {
filters: { user_id: userId }, user_id: userId,
rerank: true, rerank: true
}); });
} }
``` ```
@@ -178,7 +178,7 @@ start_time = time.time()
results = client.search( results = client.search(
query="user preferences", query="user preferences",
rerank=True, # +150ms rerank=True, # +150ms
filters={"user_id": "user123"}, user_id="user123"
) )
latency = time.time() - start_time latency = time.time() - start_time
print(f"Search completed in {latency:.2f}s") print(f"Search completed in {latency:.2f}s")
+7 -7
View File
@@ -25,7 +25,7 @@ const messages = [
{"role": "assistant", "content": "Great! I'll remember your preference for Italian cuisine."} {"role": "assistant", "content": "Great! I'll remember your preference for Italian cuisine."}
]; ];
await client.add(messages, { userId: "user123" }); await client.add(messages, { userId: "user123", version: "v2" });
``` ```
</CodeGroup> </CodeGroup>
@@ -65,14 +65,14 @@ const messages1 = [
{"role": "user", "content": "Hi, I'm Sarah from New York"}, {"role": "user", "content": "Hi, I'm Sarah from New York"},
{"role": "assistant", "content": "Hello Sarah! Nice to meet you."} {"role": "assistant", "content": "Hello Sarah! Nice to meet you."}
]; ];
await client.add(messages1, { userId: "sarah" }); await client.add(messages1, { userId: "sarah", version: "v2" });
// Later interaction - just send new messages // Later interaction - just send new messages
const messages2 = [ const messages2 = [
{"role": "user", "content": "I'm planning a trip to Italy next month"}, {"role": "user", "content": "I'm planning a trip to Italy next month"},
{"role": "assistant", "content": "How exciting! Italy is beautiful this time of year."} {"role": "assistant", "content": "How exciting! Italy is beautiful this time of year."}
]; ];
await client.add(messages2, { userId: "sarah" }); await client.add(messages2, { userId: "sarah", version: "v2" });
// Mem0 automatically knows Sarah is from New York and can use this context // Mem0 automatically knows Sarah is from New York and can use this context
``` ```
</CodeGroup> </CodeGroup>
@@ -104,7 +104,7 @@ const messages = [
{"role": "assistant", "content": "I've noted your allergies for future reference."} {"role": "assistant", "content": "I've noted your allergies for future reference."}
]; ];
await client.add(messages, { userId: "user123" }); await client.add(messages, { userId: "user123", version: "v2" });
// This allergy info will be available in ALL future interactions // This allergy info will be available in ALL future interactions
``` ```
</CodeGroup> </CodeGroup>
@@ -143,21 +143,21 @@ const messages1 = [
{"role": "user", "content": "I want to plan a 5-day trip to Tokyo"}, {"role": "user", "content": "I want to plan a 5-day trip to Tokyo"},
{"role": "assistant", "content": "Perfect! Let's plan your Tokyo adventure."} {"role": "assistant", "content": "Perfect! Let's plan your Tokyo adventure."}
]; ];
await client.add(messages1, { userId: "user123", runId: "tokyo-trip-2024" }); await client.add(messages1, { userId: "user123", runId: "tokyo-trip-2024", version: "v2" });
// Later in the same trip planning session // Later in the same trip planning session
const messages2 = [ const messages2 = [
{"role": "user", "content": "I prefer staying near Shibuya"}, {"role": "user", "content": "I prefer staying near Shibuya"},
{"role": "assistant", "content": "Great choice! Shibuya is very convenient."} {"role": "assistant", "content": "Great choice! Shibuya is very convenient."}
]; ];
await client.add(messages2, { userId: "user123", runId: "tokyo-trip-2024" }); await client.add(messages2, { userId: "user123", runId: "tokyo-trip-2024", version: "v2" });
// Different session for work project (separate context) // Different session for work project (separate context)
const workMessages = [ const workMessages = [
{"role": "user", "content": "Let's discuss the Q4 marketing strategy"}, {"role": "user", "content": "Let's discuss the Q4 marketing strategy"},
{"role": "assistant", "content": "Sure! What are your main goals for Q4?"} {"role": "assistant", "content": "Sure! What are your main goals for Q4?"}
]; ];
await client.add(workMessages, { userId: "user123", runId: "q4-marketing" }); await client.add(workMessages, { userId: "user123", runId: "q4-marketing", version: "v2" });
``` ```
</CodeGroup> </CodeGroup>
@@ -182,7 +182,7 @@ If no criteria are defined for a project, search behaves normally based on seman
This lets you prioritize memories that align with your agent's goals and not just those that look similar to the query. This lets you prioritize memories that align with your agent's goals and not just those that look similar to the query.
<Note> <Note>
Criteria retrieval is automatically enabled when criteria are defined in your project. Use `use_criteria=False` in search to temporarily disable it for a specific query. `use_criteria` is a server-side parameter passed through to the Platform API — it is not a typed option in the SDK's `SearchMemoryOptions` interface, but the server accepts and processes it when included in the request body. Criteria retrieval is automatically enabled when criteria are defined in your project. Use `use_criteria=False` in search to temporarily disable it for a specific query.
</Note> </Note>
@@ -150,7 +150,7 @@ Handle potential errors when submitting feedback:
```python Python ```python Python
from mem0 import MemoryClient from mem0 import MemoryClient
from mem0.exceptions import MemoryNotFoundError, NetworkError from mem0.exceptions import MemoryNotFoundError, APIError
client = MemoryClient(api_key="your_api_key") client = MemoryClient(api_key="your_api_key")
@@ -163,8 +163,8 @@ try:
print("Feedback submitted successfully") print("Feedback submitted successfully")
except MemoryNotFoundError: except MemoryNotFoundError:
print("Memory not found") print("Memory not found")
except NetworkError as e: except APIError as e:
print(f"Network error: {e}") print(f"API error: {e}")
except Exception as e: except Exception as e:
print(f"Unexpected error: {e}") print(f"Unexpected error: {e}")
``` ```
+47 -58
View File
@@ -111,37 +111,32 @@ print(all_memories)
``` ```
```json Output ```json Output
{ [
"count": 3, {
"next": null, "id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
"previous": null, "memory": "suggests considering Angular because it has great enterprise support",
"results": [ "user_id": "charlie",
{ "run_id": "group_chat_1",
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4", "created_at": "2025-06-21T05:51:11.007223-07:00",
"memory": "suggests considering Angular because it has great enterprise support", "updated_at": "2025-06-21T05:51:11.626562-07:00"
"user_id": "charlie", },
"run_id": "group_chat_1", {
"created_at": "2025-06-21T05:51:11.007223-07:00", "id": "1d8b8f39-7b17-4d18-8632-ab1c64fa35b9",
"updated_at": "2025-06-21T05:51:11.626562-07:00" "memory": "prefers Vue.js for our use case",
}, "user_id": "bob",
{ "run_id": "group_chat_1",
"id": "1d8b8f39-7b17-4d18-8632-ab1c64fa35b9", "created_at": "2025-06-21T05:51:08.675301-07:00",
"memory": "prefers Vue.js for our use case", "updated_at": "2025-06-21T05:51:09.319269-07:00",
"user_id": "bob", },
"run_id": "group_chat_1", {
"created_at": "2025-06-21T05:51:08.675301-07:00", "id": "4d82478a-8d50-47e6-9324-1f65efff5829",
"updated_at": "2025-06-21T05:51:09.319269-07:00" "memory": "prefers using React for the frontend",
}, "user_id": "alice",
{ "run_id": "group_chat_1",
"id": "4d82478a-8d50-47e6-9324-1f65efff5829", "created_at": "2025-06-21T05:51:05.943223-07:00",
"memory": "prefers using React for the frontend", "updated_at": "2025-06-21T05:51:06.982539-07:00",
"user_id": "alice", }
"run_id": "group_chat_1", ]
"created_at": "2025-06-21T05:51:05.943223-07:00",
"updated_at": "2025-06-21T05:51:06.982539-07:00"
}
]
}
``` ```
</CodeGroup> </CodeGroup>
@@ -166,21 +161,17 @@ print(charlie_memories)
``` ```
```json Output ```json Output
{ [
"count": 1, {
"next": null, "id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
"previous": null, "memory": "suggests considering Angular because it has great enterprise support",
"results": [ "user_id": "charlie",
{ "run_id": "group_chat_1",
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4", "created_at": "2025-06-21T05:51:11.007223-07:00",
"memory": "suggests considering Angular because it has great enterprise support", "updated_at": "2025-06-21T05:51:11.626562-07:00",
"user_id": "charlie",
"run_id": "group_chat_1", }
"created_at": "2025-06-21T05:51:11.007223-07:00", ]
"updated_at": "2025-06-21T05:51:11.626562-07:00"
}
]
}
``` ```
</CodeGroup> </CodeGroup>
@@ -208,18 +199,16 @@ print(search_response)
``` ```
```json Output ```json Output
{ [
"results": [ {
{ "id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4", "memory": "suggests considering Angular because it has great enterprise support",
"memory": "suggests considering Angular because it has great enterprise support", "user_id": "charlie",
"user_id": "charlie", "run_id": "group_chat_1",
"run_id": "group_chat_1", "created_at": "2025-06-21T05:51:11.007223-07:00",
"created_at": "2025-06-21T05:51:11.007223-07:00", "updated_at": "2025-06-21T05:51:11.626562-07:00",
"updated_at": "2025-06-21T05:51:11.626562-07:00" }
} ]
]
}
``` ```
</CodeGroup> </CodeGroup>
+1
View File
@@ -251,6 +251,7 @@ You can apply various filters to customize which memories are included in the ex
- `user_id`: Filter memories by specific user - `user_id`: Filter memories by specific user
- `agent_id`: Filter memories by specific agent - `agent_id`: Filter memories by specific agent
- `run_id`: Filter memories by specific run - `run_id`: Filter memories by specific run
- `session_id`: Filter memories by specific session
- `created_at`: Filter memories by date - `created_at`: Filter memories by date
<Note> <Note>
+1 -1
View File
@@ -9,7 +9,7 @@ estimatedTime: "~2 minutes"
**Prerequisites** **Prerequisites**
- Mem0 Platform account (<a href="https://app.mem0.ai?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Sign up here</a>) - Mem0 Platform account (<a href="https://app.mem0.ai?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Sign up here</a>)
- API key (<a href="https://app.mem0.ai/settings/api-keys?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Get one from dashboard</a>) - API key (<a href="https://app.mem0.ai/settings/api-keys?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Get one from dashboard</a>)
- Node.js 18+ (for npx) - Node.js 14+ (for npx)
- An MCP-compatible client (Claude, Claude Code, Codex, Cursor, Windsurf, VS Code, OpenCode) - An MCP-compatible client (Claude, Claude Code, Codex, Cursor, Windsurf, VS Code, OpenCode)
</Info> </Info>
+1 -1
View File
@@ -15,7 +15,7 @@ Get started with Mem0 Platform's hosted API in under 5 minutes. This guide shows
- Mem0 Platform account (<a href="https://app.mem0.ai?utm_source=oss&utm_medium=platform-quickstart" rel="nofollow">Sign up here</a>) - Mem0 Platform account (<a href="https://app.mem0.ai?utm_source=oss&utm_medium=platform-quickstart" rel="nofollow">Sign up here</a>)
- API key (<a href="https://app.mem0.ai/dashboard/settings?tab=api-keys&subtab=configuration" rel="nofollow">Get one from dashboard</a>) - API key (<a href="https://app.mem0.ai/dashboard/settings?tab=api-keys&subtab=configuration" rel="nofollow">Get one from dashboard</a>)
- Python 3.10+, Node.js 18+, or cURL - Python 3.10+, Node.js 14+, or cURL
## Installation ## Installation
+1 -2
View File
@@ -71,8 +71,7 @@
"picomatch@<2.3.2": "^2.3.2", "picomatch@<2.3.2": "^2.3.2",
"@qdrant/js-client-rest": "^1.18.0", "@qdrant/js-client-rest": "^1.18.0",
"uuid@<11.1.1": ">=11.1.1", "uuid@<11.1.1": ">=11.1.1",
"esbuild": ">=0.28.1", "esbuild": ">=0.28.1"
"undici@<6.27.0": ">=6.27.0 <8.0.0"
} }
} }
} }
+5 -6
View File
@@ -13,7 +13,6 @@ overrides:
'@qdrant/js-client-rest': ^1.18.0 '@qdrant/js-client-rest': ^1.18.0
uuid@<11.1.1: '>=11.1.1' uuid@<11.1.1: '>=11.1.1'
esbuild: '>=0.28.1' esbuild: '>=0.28.1'
undici@<6.27.0: '>=6.27.0 <8.0.0'
importers: importers:
@@ -1997,9 +1996,9 @@ packages:
undici-types@6.21.0: undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
undici@7.28.0: undici@6.26.0:
resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} resolution: {integrity: sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==}
engines: {node: '>=20.18.1'} engines: {node: '>=18.17'}
util-deprecate@1.0.2: util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -2510,7 +2509,7 @@ snapshots:
dependencies: dependencies:
'@qdrant/openapi-typescript-fetch': 1.2.6 '@qdrant/openapi-typescript-fetch': 1.2.6
typescript: 5.9.3 typescript: 5.9.3
undici: 7.28.0 undici: 6.26.0
'@qdrant/openapi-typescript-fetch@1.2.6': {} '@qdrant/openapi-typescript-fetch@1.2.6': {}
@@ -4064,7 +4063,7 @@ snapshots:
undici-types@6.21.0: {} undici-types@6.21.0: {}
undici@7.28.0: {} undici@6.26.0: {}
util-deprecate@1.0.2: {} util-deprecate@1.0.2: {}
@@ -21,4 +21,3 @@ overrides:
"@qdrant/js-client-rest": "^1.18.0" "@qdrant/js-client-rest": "^1.18.0"
"uuid@<11.1.1": ">=11.1.1" "uuid@<11.1.1": ">=11.1.1"
"esbuild": ">=0.28.1" "esbuild": ">=0.28.1"
"undici@<6.27.0": ">=6.27.0 <8.0.0"
@@ -4,12 +4,10 @@
import { describe, it, expect } from "vitest"; import { describe, it, expect } from "vitest";
import { import {
safePath, safePath,
normalizeModuleUrlToPath,
loadSkill, loadSkill,
loadTriagePrompt, loadTriagePrompt,
loadCompactTriagePrompt, loadCompactTriagePrompt,
} from "./skill-loader.ts"; } from "./skill-loader.ts";
import { fileURLToPath, pathToFileURL } from "node:url";
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// safePath — path containment // safePath — path containment
@@ -76,31 +74,6 @@ describe("loadSkill path traversal", () => {
}); });
}); });
describe("normalizeModuleUrlToPath", () => {
it("normalizes raw Windows paths before fileURLToPath conversion", () => {
const rawWindowsMetaUrl = "C:\\Users\\example\\openclaw\\index.ts";
const result = normalizeModuleUrlToPath(rawWindowsMetaUrl);
// Assert the decoded property directly rather than reconstructing via the function body
expect(typeof result).toBe("string");
expect(result).not.toContain("%5C");
});
it("leaves already-correct file URLs unchanged", () => {
const fileMetaUrl = "file:///C:/Users/example/openclaw/index.ts";
const expected = fileURLToPath(fileMetaUrl);
expect(normalizeModuleUrlToPath(fileMetaUrl)).toBe(expected);
});
it.skipIf(process.platform === "win32")(
"passes POSIX absolute paths through unchanged",
() => {
const posixPath = "/home/user/openclaw/index.ts";
expect(normalizeModuleUrlToPath(posixPath)).toBe(posixPath);
},
);
});
describe("loadCompactTriagePrompt", () => { describe("loadCompactTriagePrompt", () => {
it("keeps the core triage instructions without inlining the full skill body", () => { it("keeps the core triage instructions without inlining the full skill body", () => {
const prompt = loadCompactTriagePrompt(); const prompt = loadCompactTriagePrompt();
+2 -10
View File
@@ -4,7 +4,7 @@
*/ */
import * as path from "node:path"; import * as path from "node:path";
import { fileURLToPath, pathToFileURL } from "node:url"; import { fileURLToPath } from "node:url";
import type { SkillsConfig, CategoryConfig } from "./types.ts"; import type { SkillsConfig, CategoryConfig } from "./types.ts";
import { readText, exists } from "./fs-safe.ts"; import { readText, exists } from "./fs-safe.ts";
@@ -84,14 +84,6 @@ function parseSkillFile(content: string): ParsedSkill {
}; };
} }
/** @internal — exported for testing only */
export function normalizeModuleUrlToPath(moduleUrl: string): string {
const normalizedUrl = moduleUrl.startsWith("file:")
? moduleUrl
: pathToFileURL(moduleUrl).toString();
return fileURLToPath(normalizedUrl);
}
// ============================================================================ // ============================================================================
// Skill Loader // Skill Loader
// ============================================================================ // ============================================================================
@@ -104,7 +96,7 @@ function resolveSkillsDir(): string {
// Strategy 1: import.meta.url (works in native ESM) // Strategy 1: import.meta.url (works in native ESM)
try { try {
const metaDir = path.dirname(normalizeModuleUrlToPath(import.meta.url)); const metaDir = path.dirname(fileURLToPath(import.meta.url));
candidates.push(path.join(metaDir, "skills")); candidates.push(path.join(metaDir, "skills"));
candidates.push(path.join(metaDir, "..", "skills")); candidates.push(path.join(metaDir, "..", "skills"));
} catch { } catch {
@@ -74,7 +74,6 @@
"form-data@<4.0.6": ">=4.0.6", "form-data@<4.0.6": ">=4.0.6",
"uuid@<11.1.1": ">=11.1.1", "uuid@<11.1.1": ">=11.1.1",
"esbuild": ">=0.28.1", "esbuild": ">=0.28.1",
"undici@<6.27.0": ">=6.27.0 <8.0.0",
"undici@>=8.0.0 <8.5.0": ">=8.5.0" "undici@>=8.0.0 <8.5.0": ">=8.5.0"
} }
} }
+5 -6
View File
@@ -8,7 +8,6 @@ overrides:
form-data@<4.0.6: '>=4.0.6' form-data@<4.0.6: '>=4.0.6'
uuid@<11.1.1: '>=11.1.1' uuid@<11.1.1: '>=11.1.1'
esbuild: '>=0.28.1' esbuild: '>=0.28.1'
undici@<6.27.0: '>=6.27.0 <8.0.0'
undici@>=8.0.0 <8.5.0: '>=8.5.0' undici@>=8.0.0 <8.5.0: '>=8.5.0'
importers: importers:
@@ -2352,9 +2351,9 @@ packages:
undici-types@7.24.6: undici-types@7.24.6:
resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==}
undici@7.28.0: undici@6.26.0:
resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} resolution: {integrity: sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==}
engines: {node: '>=20.18.1'} engines: {node: '>=18.17'}
undici@8.5.0: undici@8.5.0:
resolution: {integrity: sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==} resolution: {integrity: sha512-xamtWoB1EshgjpmlXd7GGm2VfdDtw1+rD8uhry8pSNW3If6S8E0m2T2+orSKeZXEn/aPJMviCpDBA65WJt8zhg==}
@@ -3203,7 +3202,7 @@ snapshots:
dependencies: dependencies:
'@qdrant/openapi-typescript-fetch': 1.2.6 '@qdrant/openapi-typescript-fetch': 1.2.6
typescript: 6.0.3 typescript: 6.0.3
undici: 7.28.0 undici: 6.26.0
'@qdrant/openapi-typescript-fetch@1.2.6': {} '@qdrant/openapi-typescript-fetch@1.2.6': {}
@@ -4895,7 +4894,7 @@ snapshots:
undici-types@7.24.6: {} undici-types@7.24.6: {}
undici@7.28.0: {} undici@6.26.0: {}
undici@8.5.0: {} undici@8.5.0: {}
@@ -5,5 +5,4 @@ overrides:
"form-data@<4.0.6": ">=4.0.6" "form-data@<4.0.6": ">=4.0.6"
"uuid@<11.1.1": ">=11.1.1" "uuid@<11.1.1": ">=11.1.1"
"esbuild": ">=0.28.1" "esbuild": ">=0.28.1"
"undici@<6.27.0": ">=6.27.0 <8.0.0"
"undici@>=8.0.0 <8.5.0": ">=8.5.0" "undici@>=8.0.0 <8.5.0": ">=8.5.0"
+2 -3
View File
@@ -1,6 +1,6 @@
{ {
"name": "mem0ai", "name": "mem0ai",
"version": "3.0.12", "version": "3.0.11",
"description": "The Memory Layer For Your AI Apps", "description": "The Memory Layer For Your AI Apps",
"main": "./dist/index.js", "main": "./dist/index.js",
"module": "./dist/index.mjs", "module": "./dist/index.mjs",
@@ -156,8 +156,7 @@
"tar-fs@>=2.0.0 <2.1.4": "^2.1.4", "tar-fs@>=2.0.0 <2.1.4": "^2.1.4",
"glob@>=10.2.0 <10.5.0": "^10.5.0", "glob@>=10.2.0 <10.5.0": "^10.5.0",
"@modelcontextprotocol/sdk": "^1.25.4", "@modelcontextprotocol/sdk": "^1.25.4",
"esbuild": ">=0.28.1", "esbuild": ">=0.28.1"
"undici@<6.27.0": ">=6.27.0 <8.0.0"
} }
} }
} }
+5 -6
View File
@@ -23,7 +23,6 @@ overrides:
glob@>=10.2.0 <10.5.0: ^10.5.0 glob@>=10.2.0 <10.5.0: ^10.5.0
'@modelcontextprotocol/sdk': ^1.25.4 '@modelcontextprotocol/sdk': ^1.25.4
esbuild: '>=0.28.1' esbuild: '>=0.28.1'
undici@<6.27.0: '>=6.27.0 <8.0.0'
importers: importers:
@@ -2926,9 +2925,9 @@ packages:
undici-types@6.21.0: undici-types@6.21.0:
resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==}
undici@7.28.0: undici@6.26.0:
resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} resolution: {integrity: sha512-4yqz8a3n5HmGTlsbADNtr/dJlhkh/55Rq798G6ibiULcXbDtaLpTl1pvdqcbFfeoj3iSi52lePFM7h9H21cw/A==}
engines: {node: '>=20.18.1'} engines: {node: '>=18.17'}
update-browserslist-db@1.2.3: update-browserslist-db@1.2.3:
resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==}
@@ -3748,7 +3747,7 @@ snapshots:
dependencies: dependencies:
'@qdrant/openapi-typescript-fetch': 1.2.6 '@qdrant/openapi-typescript-fetch': 1.2.6
typescript: 5.5.4 typescript: 5.5.4
undici: 7.28.0 undici: 6.26.0
'@qdrant/openapi-typescript-fetch@1.2.6': {} '@qdrant/openapi-typescript-fetch@1.2.6': {}
@@ -6114,7 +6113,7 @@ snapshots:
undici-types@6.21.0: {} undici-types@6.21.0: {}
undici@7.28.0: {} undici@6.26.0: {}
update-browserslist-db@1.2.3(browserslist@4.28.2): update-browserslist-db@1.2.3(browserslist@4.28.2):
dependencies: dependencies:
-1
View File
@@ -24,4 +24,3 @@ overrides:
"glob@>=10.2.0 <10.5.0": "^10.5.0" "glob@>=10.2.0 <10.5.0": "^10.5.0"
"@modelcontextprotocol/sdk": "^1.25.4" "@modelcontextprotocol/sdk": "^1.25.4"
"esbuild": ">=0.28.1" "esbuild": ">=0.28.1"
"undici@<6.27.0": ">=6.27.0 <8.0.0"
+2 -6
View File
@@ -281,22 +281,19 @@ export default class MemoryClient {
text, text,
metadata, metadata,
timestamp, timestamp,
expirationDate,
}: { }: {
text?: string; text?: string;
metadata?: Record<string, any>; metadata?: Record<string, any>;
timestamp?: number | string; timestamp?: number | string;
expirationDate?: string | null;
}, },
): Promise<Array<Memory>> { ): Promise<Array<Memory>> {
if ( if (
text === undefined && text === undefined &&
metadata === undefined && metadata === undefined &&
timestamp === undefined && timestamp === undefined
expirationDate === undefined
) { ) {
throw new Error( throw new Error(
"At least one of text, metadata, timestamp, or expirationDate must be provided for update.", "At least one of text, metadata, or timestamp must be provided for update.",
); );
} }
@@ -305,7 +302,6 @@ export default class MemoryClient {
if (text !== undefined) payload.text = text; if (text !== undefined) payload.text = text;
if (metadata !== undefined) payload.metadata = metadata; if (metadata !== undefined) payload.metadata = metadata;
if (timestamp !== undefined) payload.timestamp = timestamp; if (timestamp !== undefined) payload.timestamp = timestamp;
if (expirationDate !== undefined) payload.expiration_date = expirationDate;
const payloadKeys = Object.keys(payload); const payloadKeys = Object.keys(payload);
this._captureEvent("update", [payloadKeys]); this._captureEvent("update", [payloadKeys]);
-4
View File
@@ -13,7 +13,6 @@ export interface AddMemoryOptions extends EntityOptions {
customCategories?: custom_categories[]; customCategories?: custom_categories[];
customInstructions?: string; customInstructions?: string;
timestamp?: number; timestamp?: number;
expirationDate?: string;
structuredDataSchema?: Record<string, any>; structuredDataSchema?: Record<string, any>;
} }
@@ -26,7 +25,6 @@ export interface SearchMemoryOptions {
latestOnly?: boolean; latestOnly?: boolean;
fields?: string[]; fields?: string[];
categories?: string[]; categories?: string[];
showExpired?: boolean;
} }
export interface GetAllMemoryOptions { export interface GetAllMemoryOptions {
@@ -37,7 +35,6 @@ export interface GetAllMemoryOptions {
endDate?: string; endDate?: string;
latestOnly?: boolean; latestOnly?: boolean;
categories?: string[]; categories?: string[];
showExpired?: boolean;
} }
export interface DeleteAllMemoryOptions extends EntityOptions {} export interface DeleteAllMemoryOptions extends EntityOptions {}
@@ -122,7 +119,6 @@ export interface Memory {
memoryType?: string; memoryType?: string;
score?: number; score?: number;
metadata?: any | null; metadata?: any | null;
expirationDate?: string | null;
owner?: string | null; owner?: string | null;
agentId?: string | null; agentId?: string | null;
appId?: string | null; appId?: string | null;
@@ -59,21 +59,6 @@ describe("MemoryClient - add()", () => {
expect(getFetchBody(call!).user_id).toBe("user_1"); expect(getFetchBody(call!).user_id).toBe("user_1");
}); });
test("serializes expirationDate as expiration_date", async () => {
const extra = new Map<string, { status: number; body: unknown }>();
extra.set("/v3/memories/add/", { status: 200, body: [createMockMemory()] });
const mock = setupMockFetch(extra);
const client = new MemoryClient({ apiKey: TEST_API_KEY });
await client.add([{ role: "user", content: "test" }], {
userId: "u1",
expirationDate: "2030-01-31",
});
const call = findFetchCall(mock, "/v3/memories/add/", "POST");
expect(getFetchBody(call!).expiration_date).toBe("2030-01-31");
});
test("throws an error when given an empty messages array", async () => { test("throws an error when given an empty messages array", async () => {
setupMockFetch(); setupMockFetch();
@@ -191,26 +176,11 @@ describe("MemoryClient - update()", () => {
expect(body.timestamp).toBe(1710600000); expect(body.timestamp).toBe(1710600000);
}); });
test("sends expirationDate as expiration_date, including null", async () => {
const extra = new Map<string, { status: number; body: unknown }>();
extra.set("/v1/memories/mem_123/", {
status: 200,
body: createMockMemory(),
});
const mock = setupMockFetch(extra);
const client = new MemoryClient({ apiKey: TEST_API_KEY });
await client.update("mem_123", { expirationDate: null });
const call = findFetchCall(mock, "/v1/memories/mem_123/", "PUT");
expect(getFetchBody(call!).expiration_date).toBeNull();
});
test("throws when no fields provided", async () => { test("throws when no fields provided", async () => {
setupMockFetch(); setupMockFetch();
const client = new MemoryClient({ apiKey: TEST_API_KEY }); const client = new MemoryClient({ apiKey: TEST_API_KEY });
await expect(client.update("mem_123", {})).rejects.toThrow( await expect(client.update("mem_123", {})).rejects.toThrow(
"At least one of text, metadata, timestamp, or expirationDate must be provided", "At least one of text, metadata, or timestamp must be provided",
); );
}); });
}); });
@@ -81,24 +81,6 @@ describe("MemoryClient - search()", () => {
expect(getFetchBody(call!).latest_only).toBe(true); expect(getFetchBody(call!).latest_only).toBe(true);
}); });
test("serializes showExpired as show_expired", async () => {
const extra = new Map<string, { status: number; body: unknown }>();
extra.set("/v3/memories/search/", {
status: 200,
body: { results: [] },
});
const mock = setupMockFetch(extra);
const client = new MemoryClient({ apiKey: TEST_API_KEY });
await client.search("test", {
filters: { user_id: "u1" },
showExpired: true,
});
const call = findFetchCall(mock, "/v3/memories/search/", "POST");
expect(getFetchBody(call!).show_expired).toBe(true);
});
test("passes complex OR filters through to the API body", async () => { test("passes complex OR filters through to the API body", async () => {
const extra = new Map<string, { status: number; body: unknown }>(); const extra = new Map<string, { status: number; body: unknown }>();
extra.set("/v3/memories/search/", { extra.set("/v3/memories/search/", {
@@ -318,22 +300,4 @@ describe("MemoryClient - getAll() entity param rejection", () => {
const call = findFetchCall(mock, "/v3/memories/", "POST"); const call = findFetchCall(mock, "/v3/memories/", "POST");
expect(getFetchBody(call!).latest_only).toBe(true); expect(getFetchBody(call!).latest_only).toBe(true);
}); });
test("serializes showExpired as show_expired", async () => {
const extra = new Map<string, { status: number; body: unknown }>();
extra.set("/v3/memories/", {
status: 200,
body: { results: [] },
});
const mock = setupMockFetch(extra);
const client = new MemoryClient({ apiKey: TEST_API_KEY });
await client.getAll({
filters: { user_id: "u1" },
showExpired: true,
});
const call = findFetchCall(mock, "/v3/memories/", "POST");
expect(getFetchBody(call!).show_expired).toBe(true);
});
}); });
-1
View File
@@ -18,7 +18,6 @@ export * from "./llms/ollama";
export * from "./llms/lmstudio"; export * from "./llms/lmstudio";
export * from "./llms/mistral"; export * from "./llms/mistral";
export * from "./llms/langchain"; export * from "./llms/langchain";
export * from "./llms/litellm";
export * from "./vector_stores/base"; export * from "./vector_stores/base";
export * from "./vector_stores/memory"; export * from "./vector_stores/memory";
export * from "./vector_stores/qdrant"; export * from "./vector_stores/qdrant";
-39
View File
@@ -1,39 +0,0 @@
import { OpenAILLM } from "./openai";
import { LLMConfig, Message } from "../types";
import { LLMResponse } from "./base";
export class LiteLLM extends OpenAILLM {
constructor(config: LLMConfig) {
super({
...config,
apiKey: config.apiKey || process.env.LITELLM_API_KEY || "sk-anything",
baseURL:
config.baseURL ||
process.env.LITELLM_API_BASE ||
"http://localhost:4000",
model: config.model || "gpt-5-mini",
});
}
async generateResponse(
messages: Message[],
responseFormat?: { type: string },
tools?: any[],
): Promise<string | LLMResponse> {
try {
return await super.generateResponse(messages, responseFormat, tools);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`LiteLLM failed: ${message}`);
}
}
async generateChat(messages: Message[]): Promise<LLMResponse> {
try {
return await super.generateChat(messages);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`LiteLLM failed: ${message}`);
}
}
}
-43
View File
@@ -1,43 +0,0 @@
import { OpenAILLM } from "./openai";
import { LLMConfig, Message } from "../types";
import { LLMResponse } from "./base";
export class MiniMaxLLM extends OpenAILLM {
constructor(config: LLMConfig) {
const apiKey = config.apiKey || process.env.MINIMAX_API_KEY;
if (!apiKey) {
throw new Error("MiniMax API key is required");
}
super({
...config,
apiKey,
baseURL:
config.baseURL ||
process.env.MINIMAX_API_BASE ||
"https://api.minimax.io/v1",
model: config.model || "MiniMax-M2.7",
});
}
async generateResponse(
messages: Message[],
responseFormat?: { type: string },
tools?: any[],
): Promise<string | LLMResponse> {
try {
return await super.generateResponse(messages, responseFormat, tools);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`MiniMax LLM failed: ${message}`);
}
}
async generateChat(messages: Message[]): Promise<LLMResponse> {
try {
return await super.generateChat(messages);
} catch (err) {
const message = err instanceof Error ? err.message : String(err);
throw new Error(`MiniMax LLM failed: ${message}`);
}
}
}

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