fix(n8n): drop Add fields the v3 API does not accept, correct docs
The Add operation exposed app_id, includes, and excludes in Additional Fields and forwarded them to POST /v3/memories/add/. None of the three are declared on that endpoint's schema (they belong to MemoryInput, used by POST /v1/memories/), so they were silently dropped by the server. app_id was worse than a no-op: the entity-id guard accepted it as satisfying "at least one entity id", so filling only App ID passed local validation and then sent a v3 request carrying no scope v3 recognises. The guard now requires User ID, Agent ID, or Run ID. Docs corrections alongside it: - Add: document Custom Instructions and Custom Categories, which the node has always supported but the docs never mentioned - Get Many: document Return All, which the docs omitted entirely - README: Infer and Wait for Completion are independent controls; the README claimed infer=false returns synchronously, contradicting the node's own field description and its actual behaviour
This commit is contained in:
@@ -40,7 +40,16 @@ Create a **Mem0 API** credential in n8n:
|
||||
|
||||
### Add
|
||||
|
||||
Extracts and stores memories from one or more messages. Provide at least one entity id (**User ID**, **Agent ID**, **Run ID**, or **App ID** in Additional Fields); the node validates this before calling the API. Additional Fields also expose **Metadata (JSON)** and **Infer** (run LLM extraction, or store verbatim).
|
||||
Extracts and stores memories from one or more messages. Provide at least one entity id (**User ID**, or **Agent ID** / **Run ID** in Additional Fields); the node validates this before calling the API.
|
||||
|
||||
Additional Fields also expose:
|
||||
|
||||
| Field | Purpose |
|
||||
| --- | --- |
|
||||
| **Metadata (JSON)** | Arbitrary JSON attached to each extracted memory |
|
||||
| **Infer** | On by default. Turn off to store messages verbatim instead of running LLM extraction |
|
||||
| **Custom Instructions** | Free-text guidance steering what the extractor keeps or ignores, for this call |
|
||||
| **Custom Categories** | JSON array of `{category: description}` objects, replacing the project-level catalog for this call |
|
||||
|
||||
Extraction is asynchronous. **Wait for Completion** (on by default) polls the event until it finishes and returns the resulting memories; turn it off to return immediately with the event ID.
|
||||
|
||||
@@ -50,7 +59,7 @@ Semantic search over stored memories. Provide a **Query**, a **User ID** (requir
|
||||
|
||||
### Get Many
|
||||
|
||||
Lists memories for a **User ID** with **Page** and **Page Size** controls.
|
||||
Lists memories for a **User ID**. Turn on **Return All** to page through every memory automatically; leave it off to fetch a single **Page**. **Page Size** applies either way.
|
||||
|
||||
### Get / Update / Delete
|
||||
|
||||
|
||||
@@ -20,14 +20,21 @@ The **Memory** resource supports:
|
||||
| --- | --- | --- |
|
||||
| **Add** | Extract and store memories from messages | `POST /v3/memories/add/` |
|
||||
| **Search** | Semantic search over stored memories | `POST /v3/memories/search/` |
|
||||
| **Get Many** | List memories for a user (paginated) | `POST /v3/memories/` |
|
||||
| **Get Many** | List memories for a user (single page, or **Return All**) | `POST /v3/memories/` |
|
||||
| **Get** | Retrieve a single memory by ID | `GET /v1/memories/{id}/` |
|
||||
| **Update** | Update a memory's text or metadata | `PUT /v1/memories/{id}/` |
|
||||
| **Delete** | Delete a single memory by ID | `DELETE /v1/memories/{id}/` |
|
||||
|
||||
### Add & asynchronous extraction
|
||||
|
||||
By default, **Add** runs LLM-based extraction asynchronously — the API returns an event ID and the node polls until extraction finishes, then returns the resulting memories. Disable **Wait for Completion** to return immediately with the event ID, or set **Infer = false** (under Additional Fields) to store messages verbatim and return synchronously.
|
||||
By default, **Add** runs LLM-based extraction asynchronously: the API returns an event ID and the node polls until extraction finishes, then returns the resulting memories.
|
||||
|
||||
Two independent controls:
|
||||
|
||||
- **Wait for Completion** (on by default) decides whether the node polls. Turn it off to return immediately with the event ID.
|
||||
- **Infer** (on by default, under Additional Fields) decides whether the API runs LLM extraction at all. Turn it off to store the messages verbatim.
|
||||
|
||||
**Custom Instructions** and **Custom Categories** (also under Additional Fields) steer what extraction keeps for that call.
|
||||
|
||||
## Credentials
|
||||
|
||||
|
||||
@@ -163,12 +163,6 @@ export class Mem0 implements INodeType {
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'App ID',
|
||||
name: 'app_id',
|
||||
type: 'string',
|
||||
default: '',
|
||||
},
|
||||
{
|
||||
displayName: 'Custom Categories',
|
||||
name: 'custom_categories',
|
||||
@@ -186,20 +180,6 @@ export class Mem0 implements INodeType {
|
||||
description:
|
||||
'Optional instructions that steer what the extractor keeps or ignores',
|
||||
},
|
||||
{
|
||||
displayName: 'Excludes',
|
||||
name: 'excludes',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Optional: skip memories matching this description',
|
||||
},
|
||||
{
|
||||
displayName: 'Includes',
|
||||
name: 'includes',
|
||||
type: 'string',
|
||||
default: '',
|
||||
description: 'Optional: only extract memories matching this description',
|
||||
},
|
||||
{
|
||||
displayName: 'Infer',
|
||||
name: 'infer',
|
||||
@@ -366,7 +346,6 @@ export class Mem0 implements INodeType {
|
||||
const userId = this.getNodeParameter('userId', i, '') as string;
|
||||
if (userId) body.user_id = userId;
|
||||
if (addFields.agent_id) body.agent_id = addFields.agent_id;
|
||||
if (addFields.app_id) body.app_id = addFields.app_id;
|
||||
if (addFields.run_id) body.run_id = addFields.run_id;
|
||||
if (addFields.metadata) {
|
||||
try {
|
||||
@@ -400,14 +379,11 @@ export class Mem0 implements INodeType {
|
||||
}
|
||||
}
|
||||
|
||||
if (addFields.includes) body.includes = addFields.includes;
|
||||
if (addFields.excludes) body.excludes = addFields.excludes;
|
||||
|
||||
// API requires at least one entity id — fail clearly instead of a raw 4xx.
|
||||
if (!body.user_id && !body.agent_id && !body.run_id && !body.app_id) {
|
||||
if (!body.user_id && !body.agent_id && !body.run_id) {
|
||||
throw new NodeOperationError(
|
||||
this.getNode(),
|
||||
'Add requires at least one of User ID, Agent ID, Run ID, or App ID',
|
||||
'Add requires at least one of User ID, Agent ID, or Run ID',
|
||||
{ itemIndex: i },
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user