docs: correct filter grammar, categories operators, and memory-type validation claims
Addresses review feedback on #6908 and fixes the same claims at their source. - Flat multi-key v2 filters are implicitly ANDed. Verified against the production API: an AND/OR/NOT wrapper is needed for OR/NOT semantics and nested grouping, not merely to combine conditions. - categories rejects eq and ne. Only in and contains are accepted. - Platform restricts top-level filter keys to an allowlist and restricts operators per field, while OSS accepts the full operator set on any metadata key. - AsyncMemory.add() raises ValueError, not Mem0ValidationError. - Any explicit memory_type other than procedural_memory is rejected rather than stored as an ordinary memory. - Refresh the stale Memory Types llms.txt description.
This commit is contained in:
@@ -18,7 +18,7 @@ Mem0's Python SDK exposes a `memory_type` parameter on `add()`. The underlying `
|
||||
| Episodic memory | `episodic_memory` | **Not implemented** | Same as above: defined, never wired into the extraction pipeline, rejected by validation, no documented roadmap. |
|
||||
|
||||
<Warning>
|
||||
Only `procedural_memory` is a real, working value. Calling `memory.add(messages, memory_type="semantic_memory")` (or `episodic_memory`) raises `Mem0ValidationError`, telling you to pass `procedural_memory` instead.
|
||||
Only `procedural_memory` is a real, working value. Calling `memory.add(messages, memory_type="semantic_memory")` (or `episodic_memory`) is rejected and tells you to pass `procedural_memory` instead. Sync `Memory.add()` raises `Mem0ValidationError`; `AsyncMemory.add()` raises a plain `ValueError`.
|
||||
</Warning>
|
||||
|
||||
## Procedural memory
|
||||
@@ -40,7 +40,7 @@ memory.add(
|
||||
)
|
||||
```
|
||||
|
||||
If everything else about your call is unchanged but you omit `memory_type`, or set it to anything other than `procedural_memory`, Mem0 stores the messages as an ordinary memory instead: there is no semantic/episodic pathway for it to fall into.
|
||||
Omit `memory_type` entirely and Mem0 stores the messages as an ordinary memory: there is no semantic/episodic pathway for it to fall into. Any other explicit value is rejected by validation rather than quietly falling back to an ordinary memory.
|
||||
|
||||
## How every other memory is scoped
|
||||
|
||||
|
||||
+1
-1
@@ -185,7 +185,7 @@ If the user is on a pre-current major (Python < 2, TS < 3, or Platform `output_f
|
||||
## Core Concepts
|
||||
|
||||
- [How Mem0 Works](https://docs.mem0.ai/core-concepts/how-it-works) [Both]: Use when explaining the end-to-end pipeline: extraction (ADD-only distillation), storage across vector/entity/history stores, and multi-signal retrieval.
|
||||
- [Memory Types](https://docs.mem0.ai/core-concepts/memory-types) [Both]: Use when explaining working, factual, episodic, and semantic memory distinctions.
|
||||
- [Memory Types](https://docs.mem0.ai/core-concepts/memory-types) [Both]: Use when checking which `memory_type` values actually work: `procedural_memory` is implemented, `semantic_memory` and `episodic_memory` are defined in the enum but rejected by validation.
|
||||
- [Memory Operations - Add](https://docs.mem0.ai/core-concepts/memory-operations/add) [Both]: Use when explaining how `add()` extracts facts, resolves conflicts, and writes to both stores.
|
||||
- [Memory Operations - Search](https://docs.mem0.ai/core-concepts/memory-operations/search) [Both]: Use when explaining how queries are processed and ranked.
|
||||
- [Memory Operations - Update](https://docs.mem0.ai/core-concepts/memory-operations/update) [Both]: Use when memories need to be edited in place or reconciled against new info.
|
||||
|
||||
@@ -49,7 +49,7 @@ Filters use a nested JSON structure with logical operators at the root:
|
||||
### Content fields
|
||||
| Field | Operators | Example |
|
||||
|-------|-----------|---------|
|
||||
| `categories` | `eq`, `ne`, `in` (matches any category in the list), `contains` (case-insensitive) | `{"categories": {"in": ["finance"]}}` |
|
||||
| `categories` | `in` (takes a list, matches any category in it), `contains` (case-insensitive). `eq` and `ne` are rejected | `{"categories": {"in": ["finance"]}}` |
|
||||
| `metadata` | `eq`, `ne`, `contains` | `{"metadata": {"key": "value"}}` |
|
||||
| `keywords` | `contains` (case-sensitive), `icontains` (case-insensitive) | `{"keywords": {"icontains": "invoice"}}` |
|
||||
|
||||
@@ -328,7 +328,7 @@ Level up foundational patterns with compound filters that coordinate entity scop
|
||||
## Best practices
|
||||
|
||||
<Callout type="tip" icon="lightbulb" color="#26A17B">
|
||||
The root does not have to be `AND`, `OR`, or `NOT`. A bare filter like `{"user_id": "alice"}` works on its own; wrap conditions in a logical operator only when you need to combine more than one.
|
||||
The root does not have to be `AND`, `OR`, or `NOT`. A bare filter like `{"user_id": "alice"}` works on its own, and several top-level keys in one flat filter are implicitly ANDed. Wrap conditions in a logical operator when you need OR/NOT semantics or nested grouping.
|
||||
</Callout>
|
||||
|
||||
<Callout type="tip" icon="lightbulb" color="#26A17B">
|
||||
@@ -392,7 +392,7 @@ A filter object with both an `AND` key and a sibling `OR` key at the same level
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Do I need AND/OR/NOT?">
|
||||
No. A bare filter like `{"user_id": "u1"}` works on its own. Add `AND`, `OR`, or `NOT` only when you need to combine more than one condition.
|
||||
No. A bare filter like `{"user_id": "u1"}` works on its own, and several top-level keys in one flat filter like `{"user_id": "u1", "agent_id": "a1"}` are implicitly ANDed. Reach for `AND`, `OR`, or `NOT` when you need OR/NOT semantics or nested grouping, not merely to combine conditions.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="What does * match?">
|
||||
|
||||
@@ -37,7 +37,7 @@ Mem0 offers two ways to add memory to your AI applications. Both run the same co
|
||||
The core memory loop is identical on both: `add`, `search`, `get`, `get_all`, `update`, `delete`, `delete_all`, and per-memory `history` all exist on the self-hosted `Memory`/`AsyncMemory` classes and on the hosted `MemoryClient`/`AsyncMemoryClient`. Both support:
|
||||
|
||||
- **Entity scoping** by `user_id`, `agent_id`, and `run_id`
|
||||
- **Metadata filtering**: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `contains`, `icontains`, and wildcards match on both, and both understand `AND`/`OR`/`NOT` grouping. The grammar around that grouping differs (see below)
|
||||
- **Filter grouping**: both accept `AND`/`OR`/`NOT` wrappers, both implicitly AND a flat multi-key filter like `{"user_id": "alice", "agent_id": "a1"}`, and both accept `*` as a wildcard value. Which fields you may filter on, and which operators each field accepts, differ (see below)
|
||||
- **Entity-aware ranking**: both extract entities from memory text and use shared entities to boost related results at search time
|
||||
- **Multimodal input**, **memory expiration** (`expiration_date`), **reranking**, **procedural memory** (Python), and **custom extraction instructions** (`custom_instructions`)
|
||||
- Python and JavaScript SDKs, plus a REST API (self-hosted via `server/`, or hosted)
|
||||
@@ -79,8 +79,8 @@ The core memory loop is identical on both: `add`, `search`, `get`, `get_all`, `u
|
||||
| **Custom categories** | Set per project or per `add` call ([details](/platform/features/custom-categories)) | Not supported. `Memory.add()` has no `custom_categories` parameter, and OSS project updates are rejected outright |
|
||||
| **Webhooks** | Project-scoped HTTP callbacks on memory and ingest events ([details](/platform/features/webhooks)) | Not available |
|
||||
| **Memory Export** | Schema-driven structured export jobs over filtered memories ([details](/platform/features/memory-export)) | Not available |
|
||||
| **Filter grouping grammar** | A bare single-condition filter works on its own, but combining more than one condition requires an explicit `AND`/`OR`/`NOT` wrapper ([details](/platform/features/v2-memory-filters)) | Top-level filter keys are implicitly ANDed, so a flat multi-key filter like `{"user_id": "alice", "category": "work"}` works without a wrapper |
|
||||
| **`nin` (not-in) operator** | Not supported | Supported, alongside `in` |
|
||||
| **Filterable fields** | Top-level filter keys come from a fixed allowlist: `user_id`, `agent_id`, `app_id`, `run_id`, `created_at`, `updated_at`, `timestamp`, `expiration_date`, `text`, `categories`, `metadata`, `keywords_search`, `memory_ids`, `keywords`, plus the `AND`/`OR`/`NOT` operators. Any other key is rejected with a `400` ([details](/platform/features/v2-memory-filters)) | Any metadata key is filterable directly, with no allowlist |
|
||||
| **Comparison operators** | Depends on the field: `metadata` accepts `eq`, `ne`, `contains`; `categories` accepts `contains`, `in`; the date fields accept the range operators | The full set on any key: `eq`, `ne`, `gt`, `gte`, `lt`, `lte`, `in`, `nin`, `contains`, `icontains` |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Support" icon="life-ring">
|
||||
|
||||
Reference in New Issue
Block a user