From 553e2751126b240632967339723260fa30421615 Mon Sep 17 00:00:00 2001 From: Kartik Date: Fri, 24 Apr 2026 17:34:11 +0530 Subject: [PATCH 1/2] fix(docs): updating endpoints to v3 in the api reference (#4953) --- docs/api-reference/memory/add-memories.mdx | 43 ++++++++++--------- docs/api-reference/memory/get-memories.mdx | 24 ++++++++--- docs/api-reference/memory/search-memories.mdx | 27 ++++++++---- openmemory/README.md | 2 + 4 files changed, 62 insertions(+), 34 deletions(-) diff --git a/docs/api-reference/memory/add-memories.mdx b/docs/api-reference/memory/add-memories.mdx index 146f1ea07..338fa1b1a 100644 --- a/docs/api-reference/memory/add-memories.mdx +++ b/docs/api-reference/memory/add-memories.mdx @@ -1,18 +1,18 @@ --- -title: 'Add Memories' -description: "Add facts, messages, or metadata to a user memory store with support for async processing and event tracking." -openapi: post /v1/memories/ +title: Add Memories +description: "Add facts, messages, or metadata to a user memory store with async processing and event tracking via the V3 additive pipeline." +openapi: post /v3/memories/add/ --- -Add new facts, messages, or metadata to a user’s memory store. The Add Memories endpoint accepts either raw text or conversational turns and commits them asynchronously so the memory is ready for later search, retrieval, and graph queries. +Extract and store memories from a conversation using the V3 additive pipeline. The endpoint uses single-pass ADD-only extraction — one LLM call, no UPDATE/DELETE. Memories accumulate over time; nothing is overwritten. ## Endpoint - **Method**: `POST` -- **URL**: `/v1/memories/` +- **URL**: `/v3/memories/add/` - **Content-Type**: `application/json` -Memories are processed asynchronously by default. The response contains queued events you can track while the platform finalizes enrichment. +Processing is asynchronous. The response returns an `event_id` you can poll via `GET /v1/event/{event_id}/`. ## Required headers @@ -23,7 +23,7 @@ Memories are processed asynchronously by default. The response contains queued e ## Request body -Provide at least one message or direct memory string. Most callers supply `messages` so Mem0 can infer structured memories as part of ingestion. +Provide conversation messages for Mem0 to extract memories from. At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required so the memory is scoped to a session. Entity IDs are accepted at the top level. ```json Basic request @@ -43,12 +43,15 @@ Provide at least one message or direct memory string. Most callers supply `messa | Field | Type | Required | Description | | --- | --- | --- | --- | -| `user_id` | string | No* | Associates the memory with a user. Provide when you want the memory scoped to a specific identity. | -| `messages` | array | No* | Conversation turns for Mem0 to infer memories from. Each object should include `role` and `content`. | +| `messages` | array | Yes | Conversation turns for Mem0 to extract memories from. Each object should include `role` and `content`. | +| `user_id` | string | No* | Associates the memory with a user. | +| `agent_id` | string | No* | Associates the memory with an agent. | +| `run_id` | string | No* | Associates the memory with a run. | +| `app_id` | string | No* | Associates the memory with an app. | | `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. | -> \* Provide at least one `messages` entry to describe what you are storing. For scoped memories, include `user_id`. You can also attach `agent_id`, `app_id`, `run_id`, `project_id`, or `org_id` to refine ownership. +> \* At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required. Need more details? See [all request parameters](#body-messages) below for complete field descriptions, types, and constraints. @@ -56,19 +59,15 @@ Provide at least one message or direct memory string. Most callers supply `messa ## Response -Successful requests return an array of events queued for processing. Each event includes the generated memory text and an identifier you can persist for auditing. +The request is queued for background processing. The response contains an `event_id` for tracking status. ```json 200 response -[ - { - "id": "mem_01JF8ZS4Y0R0SPM13R5R6H32CJ", - "event": "ADD", - "data": { - "memory": "The user moved to Austin in 2025." - } - } -] +{ + "message": "Memory processing has been queued for background execution", + "status": "PENDING", + "event_id": "evt-uuid" +} ``` ```json 400 response @@ -81,3 +80,7 @@ Successful requests return an array of events queued for processing. Each event ``` + +Poll the event status via `GET /v1/event/{event_id}/`. Status will be `SUCCEEDED` or `FAILED` once processing completes. + + diff --git a/docs/api-reference/memory/get-memories.mdx b/docs/api-reference/memory/get-memories.mdx index 275b49cdb..08c61f16d 100644 --- a/docs/api-reference/memory/get-memories.mdx +++ b/docs/api-reference/memory/get-memories.mdx @@ -1,10 +1,12 @@ --- title: "Get Memories" -description: "Retrieve memories with advanced filtering using logical operators like AND, OR, NOT, and comparison queries." -openapi: post /v2/memories/ +description: "Retrieve memories with paginated results and advanced filtering using logical operators like AND, OR, NOT, and comparison queries." +openapi: post /v3/memories/ --- -The v2 get memories API is powerful and flexible, allowing for more precise memory listing without the need for a search query. It supports complex logical operations (AND, OR, NOT) and comparison operators for advanced filtering capabilities. The comparison operators include: +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. + +The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators: - `in`: Matches any of the values specified - `gte`: Greater than or equal to @@ -15,6 +17,8 @@ The v2 get memories API is powerful and flexible, allowing for more precise memo - `icontains`: Case-insensitive containment check - `*`: Wildcard character that matches everything +Pass `page` and `page_size` as query parameters to paginate through results. + ```python Code memories = client.get_all( @@ -27,12 +31,17 @@ memories = client.get_all( "created_at": {"gte": "2024-07-01", "lte": "2024-07-31"} } ] - } + }, + page=1, + page_size=50 ) ``` ```python Output { + "count": 2, + "next": null, + "previous": null, "results": [ { "id": "f4cbdb08-7062-4f3e-8eb2-9f5c80dfe64c", @@ -46,10 +55,13 @@ memories = client.get_all( "created_at": "2024-07-05T15:30:00Z", "updated_at": "2024-07-05T15:30:00Z" } - ], - "total": 2 + ] } ``` + +The response is a paginated envelope with `count`, `next`, `previous`, and `results`. Use `page` and `page_size` query params to step through results. + + diff --git a/docs/api-reference/memory/search-memories.mdx b/docs/api-reference/memory/search-memories.mdx index 6fbcb7856..b4d237cb1 100644 --- a/docs/api-reference/memory/search-memories.mdx +++ b/docs/api-reference/memory/search-memories.mdx @@ -1,10 +1,14 @@ --- title: 'Search Memories' -description: "Search memories with semantic queries and advanced filtering using logical and comparison operators." -openapi: post /v2/memories/search/ +description: "Search memories with hybrid retrieval (semantic + BM25 + entity matching) and advanced filtering using logical and comparison operators." +openapi: post /v3/memories/search/ --- -The v2 search API is powerful and flexible, allowing for more precise memory retrieval. It supports complex logical operations (AND, OR, NOT) and comparison operators for advanced filtering capabilities. The comparison operators include: +Relevance-ranked hybrid search across stored memories. V3 uses multi-signal retrieval — semantic, BM25 keyword, and entity matching scored in parallel and fused. The returned `score` is a combined `[0, 1]` value. + +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. + +The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators: - `in`: Matches any of the values specified - `gte`: Greater than or equal to - `lte`: Less than or equal to @@ -14,6 +18,14 @@ The v2 search API is powerful and flexible, allowing for more precise memory ret - `icontains`: Case-insensitive containment check - `*`: Wildcard character that matches everything +### Search parameter defaults + +| Parameter | V1/V2 | V3 | +| --- | --- | --- | +| `top_k` | Supported (default 10) | Supported (1-1000, default 10) | +| `threshold` | No default | Default `0.1` (pass `0.0` to disable) | +| `rerank` | Default `true` | Default `false` (pass `true` to enable) | + ```python Platform API Example related_memories = client.search( @@ -33,20 +45,19 @@ related_memories = client.search( ```json Output { - "memories": [ + "results": [ { "id": "ea925981-272f-40dd-b576-be64e4871429", "memory": "Likes to play cricket and plays cricket on weekends.", "metadata": { "category": "hobbies" }, - "score": 0.32116443111457704, + "score": 0.82, "created_at": "2024-07-26T10:29:36.630547-07:00", "updated_at": null, - "user_id": "alice", - "agent_id": "sports-agent" + "categories": ["hobbies"] } - ], + ] } ``` diff --git a/openmemory/README.md b/openmemory/README.md index b327df730..9c886bc20 100644 --- a/openmemory/README.md +++ b/openmemory/README.md @@ -1,5 +1,7 @@ # OpenMemory +> **⚠️ Sunsetting Notice:** OpenMemory is being sunset. For local self-hosted memory with a dashboard, please use the [Mem0 self-hosted server](https://docs.mem0.ai/open-source/overview) instead. Get started with `cd server && make bootstrap`. See the [self-hosted docs](https://docs.mem0.ai/open-source/setup) for configuration details. + OpenMemory is your personal memory layer for LLMs - private, portable, and open-source. Your memories live locally, giving you complete control over your data. Build AI applications with personalized memories while keeping your data secure. ![OpenMemory](https://github.com/user-attachments/assets/3c701757-ad82-4afa-bfbe-e049c2b4320b) From 693e709389526b45cfadfd06d89a0e13af7c7345 Mon Sep 17 00:00:00 2001 From: Pratik Rai <67469498+PratikRai0101@users.noreply.github.com> Date: Fri, 24 Apr 2026 23:52:14 +0530 Subject: [PATCH 2/2] fix(api): map entity params to filters in GET /memories (#4955) (#4960) --- server/main.py | 4 ++-- tests/test_server_params.py | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/server/main.py b/server/main.py index 9bafabf83..07d300d00 100644 --- a/server/main.py +++ b/server/main.py @@ -395,10 +395,10 @@ def get_all_memories( try: if not any([user_id, run_id, agent_id]): return _list_all_memories() - params = { + filters = { k: v for k, v in {"user_id": user_id, "run_id": run_id, "agent_id": agent_id}.items() if v is not None } - return get_memory_instance().get_all(**params) + return get_memory_instance().get_all(filters=filters) except Exception: raise upstream_error() diff --git a/tests/test_server_params.py b/tests/test_server_params.py index 5e2224974..54d6e1638 100644 --- a/tests/test_server_params.py +++ b/tests/test_server_params.py @@ -561,3 +561,30 @@ class TestUpdateOpenAPISchema: schema = client.get("/openapi.json").json() update_props = schema["components"]["schemas"]["MemoryUpdate"]["properties"] assert "metadata" in update_props + +# =========================================================================== +# GetMemories: Entity parameters to filters mapping (fix for #4955) +# =========================================================================== + +class TestGetMemories: + """Verify that GET /memories correctly maps entity parameters to the filters dict.""" + + def test_get_memories_entity_filters_routing(self, client, mock_memory): + """ + Issue #4955: Test that the GET /memories route correctly handles + top-level entity parameters by mapping them to the filters dictionary + instead of passing them as direct kwargs to get_all() + """ + # Send a request with a valid top-level entity parameter + response = client.get("/memories?user_id=test_routing_user") + + # 1. Verify the endpoint doesn't crash with a 500 error + assert response.status_code == 200 + + # 2. Verify the response is structured correctly + data = response.json() + assert isinstance(data, list) + + # 3. Verify the core logic: the param was mapped to the filters dict! + _, kwargs = mock_memory.get_all.call_args + assert kwargs["filters"] == {"user_id": "test_routing_user"}