Compare commits

..
15 Commits
27 changed files with 823 additions and 434 deletions
@@ -1,4 +0,0 @@
---
title: 'Get Custom Instructions and Categories'
openapi: get /api/v1/orgs/organizations/{org_id}/projects/{project_id}/custom-instructions-and-categories/
---
@@ -1,6 +0,0 @@
---
title: 'Update Custom Instructions and Categories'
openapi: post /api/v1/orgs/organizations/{org_id}/projects/{project_id}/custom-instructions-and-categories/
---
Please refer to the [how to use custom instructions/categories](/features/custom-instructions) for more information.
@@ -0,0 +1,4 @@
---
title: 'Update Project'
openapi: patch /api/v1/orgs/organizations/{org_id}/projects/{project_id}/
---
+1 -1
View File
@@ -30,7 +30,7 @@ Here's the parameters available for configuring pgvector:
| Parameter | Description | Default Value |
| --- | --- | --- |
| `dbname` | The name of the database | `postgres` |
| `dbname` | The name of the | `postgres` |
| `collection_name` | The name of the collection | `mem0` |
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
| `user` | User name to connect to the database | `None` |
-2
View File
@@ -44,8 +44,6 @@ Mem0's memory implementation for Large Language Models (LLMs) offers several adv
- **Entity Relationships**: Mem0 can understand and relate entities across different interactions, unlike RAG which retrieves information from static documents. This leads to a deeper understanding of context and relationships.
- **Recency, Relevancy, and Decay**: Mem0 uses custom search algorithms to prioritize recent interactions and gradually forgets outdated information, ensuring the memory remains relevant and up-to-date for more accurate responses.
- **Contextual Continuity**: Mem0 retains information across sessions, maintaining continuity in conversations and interactions, which is essential for long-term engagement applications like virtual companions or personalized learning assistants.
- **Adaptive Learning**: Mem0 improves its personalization based on user interactions and feedback, making the memory more accurate and tailored to individual users over time.
+125 -55
View File
@@ -5,60 +5,29 @@ description: 'Enhance your product experience by adding custom categories tailor
## How to set custom categories?
Users can now create custom categories tailored to their specific needs, in addition to the default categories such as travel, sports, music, and more. When custom categories are provided, they will override the default categories.
To setup the custom categories, user has to specify the category name and a description of what that category signifies.
Here’s how you can do it:
You can now create custom categories tailored to your specific needs, instead of using the default categories such as travel, sports, music, and more (see [default categories](#default-categories) below). **When custom categories are provided, they will override the default categories.**
```python
from mem0 import MemoryClient
There are two ways to set custom categories:
m = MemoryClient(api_key="xxx")
### 1. Project Level
custom_categories = [
{"cooking": "For users interested in cooking, including recipes, cooking tips, and culinary experiences."},
{"fitness": "Includes content related to fitness, such as workouts, exercises, and fitness tips."}
]
messages = [
{"role" : "user", "content" : "Hi, my name is Alice. I love to play badminton."},
{"role" : "assistant", "content" : "Hello Alice! It's nice to meet you. Badminton is such an amazing sport. How can I assist you today?"},
{"role" : "user", "content" : "I am a fitness freak, I go to gym daily."},
{"role" : "assistant", "content" : "That's great! Regular exercise is very beneficial for health."},
{"role" : "user", "content" : "Because of my gym plan, I mostly cook at home."},
{"role" : "assistant", "content" : "Cooking at home is a good way to ensure you have a balanced diet."}
]
```
<CodeGroup>
```python Code
client.add(messages, user_id="alice", custom_categories=custom_categories)
```
```markdown Memories with categories
User's name is Alice (personal_details)
Loves playing badminton (sports)
User is a fitness freak. (fitness)
Likes to go to gym daily. (fitness)
Mostly cook at home because of gym plan. (fitness, cooking)
```
</CodeGroup>
<Note> The more detailed the description of categories is, the better output the user will receive. When custom categories are provided in the `add` API call, they will completely replace the default categories and will be directly assigned to the memory, so make sure to include all categories you want to use. </Note>
## Setting Project-Level Custom Categories
You can also set custom categories at the project level, which will be applied to all memories added within that project. We will automatically assign relevant categories from your custom set to new memories based on their content.
You can set custom categories at the project level, which will be applied to all memories added within that project. Mem0 will automatically assign relevant categories from your custom set to new memories based on their content. Setting custom categories at the project level will override the default categories.
Here's how to set custom categories:
<CodeGroup>
```python Code
from mem0 import MemoryClient
client = MemoryClient(api_key="<your_mem0_api_key>")
# Update custom categories
new_categories = [
{"cooking": "For users interested in cooking and culinary experiences"},
{"fitness": "Content related to fitness and exercise"}
{"lifestyle_management_concerns": "Tracks daily routines, habits, hobbies and interests including cooking, time management and work-life balance"},
{"seeking_structure": "Documents goals around creating routines, schedules, and organized systems in various life areas"},
{"personal_information": "Basic information about the user including name, preferences, and personality traits"}
]
response = client.update_custom_instructions_and_categories({"custom_categories": new_categories})
print(response)
```
@@ -70,40 +39,99 @@ print(response)
```
</CodeGroup>
This is how you will use these custom categories during the `add` API call:
<CodeGroup>
```python Code
messages = [
{"role": "user", "content": "My name is Alice. I need help organizing my daily schedule better. I feel overwhelmed trying to balance work, exercise, and social life."},
{"role": "assistant", "content": "I understand how overwhelming that can feel. Let's break this down together. What specific areas of your schedule feel most challenging to manage?"},
{"role": "user", "content": "I want to be more productive at work, maintain a consistent workout routine, and still have energy for friends and hobbies."},
{"role": "assistant", "content": "Those are great goals for better time management. What's one small change you could make to start improving your daily routine?"},
]
# Add memories with custom categories
client.add(messages, user_id="alice"))
```
```python Memories with categories
# Following categories will be created for the memories added
Wants to have energy for friends and hobbies (lifestyle_management_concerns)
Wants to maintain a consistent workout routine (seeking_structure, lifestyle_management_concerns)
Wants to be more productive at work (lifestyle_management_concerns, seeking_structure)
Name is Alice (personal_information)
```
</CodeGroup>
You can also retrieve the current custom categories:
<CodeGroup>
```python Code
from mem0 import MemoryClient
client = MemoryClient(api_key="xxx")
# Get current custom categories
categories = client.get_custom_instructions_and_categories(["custom_categories"])
categories = client.get_project(fields=["custom_categories"])
print(categories)
```
```json Output
{
"custom_categories": [
{"cooking": "For users interested in cooking and culinary experiences"},
{"fitness": "Content related to fitness and exercise"}
]
"custom_categories": [
{"lifestyle_management_concerns": "Tracks daily routines, habits, hobbies and interests including cooking, time management and work-life balance"},
{"seeking_structure": "Documents goals around creating routines, schedules, and organized systems in various life areas"},
{"personal_information": "Basic information about the user including name, preferences, and personality traits"}
]
}
```
</CodeGroup>
These project-level categories will be automatically applied to all new memories added to the project.
## Default Categories
Here is the list of **default categories**. Ensure you review these before creating custom categories to prevent duplication.
### 2. During the `add` API call
You can also set custom categories during the `add` API call. This will override any project-level custom categories for that specific memory addition. For example, if you want to use different categories for food-related memories, you can provide custom categories like "food" and "user_preferences" in the `add` call. These custom categories will be used instead of the project-level categories when categorizing those specific memories.
<CodeGroup>
```python Code
from mem0 import MemoryClient
client = MemoryClient(api_key="<your_mem0_api_key>")
custom_categories = [
{"seeking_structure": "Documents goals around creating routines, schedules, and organized systems in various life areas"},
{"personal_information": "Basic information about the user including name, preferences, and personality traits"}
]
messages = [
{"role": "user", "content": "My name is Alice. I need help organizing my daily schedule better. I feel overwhelmed trying to balance work, exercise, and social life."},
{"role": "assistant", "content": "I understand how overwhelming that can feel. Let's break this down together. What specific areas of your schedule feel most challenging to manage?"},
{"role": "user", "content": "I want to be more productive at work, maintain a consistent workout routine, and still have energy for friends and hobbies."},
{"role": "assistant", "content": "Those are great goals for better time management. What's one small change you could make to start improving your daily routine?"},
]
client.add(messages, user_id="alice", custom_categories=custom_categories)
```
```python Memories with categories
# Following categories will be created for the memories added
Wants to have energy for friends and hobbies (seeking_structure)
Wants to maintain a consistent workout routine (seeking_structure)
Wants to be more productive at work (seeking_structure)
Name is Alice (personal_information)
```
</CodeGroup>
<Note>Providing more detailed and specific category descriptions will lead to more accurate and relevant memory categorization.</Note>
## Default Categories
Here is the list of **default categories**. If you don't specify any custom categories using the above methods, these will be used as default categories.
```
- personal_details
- family
- professional_details
- sports
- travel
- travel
- food
- music
- health
@@ -116,6 +144,48 @@ Here is the list of **default categories**. Ensure you review these before creat
- misc
```
<CodeGroup>
```python Code
from mem0 import MemoryClient
client = MemoryClient(api_key="<your_mem0_api_key>")
messages = [
{"role": "user", "content": "Hi, my name is Alice."},
{"role": "assistant", "content": "Hi Alice, what sports do you like to play?"},
{"role": "user", "content": "I love playing badminton, football, and basketball. I'm quite athletic!"},
{"role": "assistant", "content": "That's great! Alice seems to enjoy both individual sports like badminton and team sports like football and basketball."},
{"role": "user", "content": "Sometimes, I also draw and sketch in my free time."},
{"role": "assistant", "content": "That's cool! I'm sure you're good at it."}
]
# Add memories with default categories
client.add(messages, user_id='alice')
```
```python Memories with categories
# Following categories will be created for the memories added
Sometimes draws and sketches in free time (hobbies)
Is quite athletic (sports)
Loves playing badminton, football, and basketball (sports)
Name is Alice (personal_details)
```
</CodeGroup>
You can check whether default categories are being used by calling `get_custom_instructions_and_categories()`. If `custom_categories` returns `None`, it means the default categories are being used.
<CodeGroup>
```python Code
client.get_custom_instructions_and_categories(["custom_categories"])
```
```json Output
{
'custom_categories': None
}
```
</CodeGroup>
If you have any questions, please feel free to reach out to us using one of the following methods:
<Snippet file="get-help.mdx" />
+25 -10
View File
@@ -22,16 +22,31 @@ You can set custom instructions for your project using the following method:
<CodeGroup>
```python Code
# Update custom instructions
prompt = """
Your task is to extract ONLY health-related information from conversations, including:
prompt ="""
Your Task: Extract ONLY health-related information from conversations, focusing on the following areas:
- Medical conditions, symptoms, diagnoses
- Medications, treatments, procedures
- Diet, exercise, sleep habits
- Doctor visits and appointments
- Health metrics (weight, blood pressure, etc)
1. Medical Conditions, Symptoms, and Diagnoses:
- Illnesses, disorders, or symptoms (e.g., fever, diabetes).
- Confirmed or suspected diagnoses.
2. Medications, Treatments, and Procedures:
- Prescription or OTC medications (names, dosages).
- Treatments, therapies, or medical procedures.
3. Diet, Exercise, and Sleep:
- Dietary habits, fitness routines, and sleep patterns.
4. Doctor Visits and Appointments:
- Past, upcoming, or regular medical visits.
5. Health Metrics:
- Data like weight, BP, cholesterol, or sugar levels.
Guidelines:
- Focus solely on health-related content.
- Maintain clarity and context accuracy while recording.
"""
response = client.update_custom_instructions_and_categories({"custom_instructions": prompt})
response = client.update_project(custom_instructions=prompt)
print(response)
```
@@ -47,13 +62,13 @@ You can also retrieve the current custom instructions:
<CodeGroup>
```python Code
# Retrieve current custom instructions
response = client.get_custom_instructions_and_categories(["custom_instructions"])
response = client.get_project(fields=["custom_instructions"])
print(response)
```
```json Output
{
"custom_instructions": "Your task is to extract ONLY health-related information from conversations, including:\n\n- Medical conditions, symptoms, diagnoses\n- Medications, treatments, procedures\n- Diet, exercise, sleep habits\n- Doctor visits and appointments\n- Health metrics (weight, blood pressure, etc)"
"custom_instructions": "Your Task: Extract ONLY health-related information from conversations, focusing on the following areas:\n1. Medical Conditions, Symptoms, and Diagnoses - illnesses, disorders, or symptoms (e.g., fever, diabetes), confirmed or suspected diagnoses.\n2. Medications, Treatments, and Procedures - prescription or OTC medications (names, dosages), treatments, therapies, or medical procedures.\n3. Diet, Exercise, and Sleep - dietary habits, fitness routines, and sleep patterns.\n4. Doctor Visits and Appointments - past, upcoming, or regular medical visits.\n5. Health Metrics - data like weight, BP, cholesterol, or sugar levels.\n\nGuidelines: Focus solely on health-related content. Maintain clarity and context accuracy while recording."
}
```
</CodeGroup>
+1 -2
View File
@@ -196,10 +196,9 @@
"pages": [
"api-reference/project/get-projects",
"api-reference/project/get-project",
"api-reference/project/update-project",
"api-reference/project/create-project",
"api-reference/project/delete-project",
"api-reference/project/get-instructions-and-categories",
"api-reference/project/update-instructions-and-categories",
{
"group": "Members APIs",
"pages":[
+270 -232
View File
@@ -201,7 +201,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\nusers = client.users()\nprint(users)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\nusers = client.users()\nprint(users)"
},
{
"lang": "JavaScript",
@@ -496,7 +496,33 @@
}
}
}
}
},
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"project_id\")\n\nresponse = client.get_memory_export(user_id=\"your_user_id\")\nprint(response)"
},
{
"lang": "JavaScript",
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\n// Get memory export\nclient.getMemoryExport({ user_id: \"your_user_id\" })\n .then(result => console.log(result))\n .catch(error => console.error(error));"
},
{
"lang": "cURL",
"source": "curl --request GET \\\n --url 'https://api.mem0.ai/v1/exports/?user_id=your_user_id' \\\n --header 'Authorization: Token <api-key>'"
},
{
"lang": "Go",
"source": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\turl := \"https://api.mem0.ai/v1/exports/?user_id=your_user_id\"\n\n\treq, _ := http.NewRequest(\"GET\", url, nil)\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(string(body))\n}"
},
{
"lang": "PHP",
"source": "<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/v1/exports/?user_id=your_user_id\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"GET\",\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
},
{
"lang": "Java",
"source": "HttpResponse<String> response = Unirest.get(\"https://api.mem0.ai/v1/exports/?user_id=your_user_id\")\n .header(\"Authorization\", \"Token <api-key>\")\n .asString();"
}
]
},
"post": {
"tags": [
@@ -585,7 +611,33 @@
}
}
}
}
},
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\njson_schema = {pydantic_json_schema}\n\nresponse = client.create_memory_export(\n schema=json_schema,\n user_id=\"your_user_id\"\n)\nprint(response)"
},
{
"lang": "JavaScript",
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst jsonSchema = {pydantic_json_schema};\n\nclient.createMemoryExport({\n schema: jsonSchema,\n user_id: \"your_user_id\"\n})\n .then(result => console.log(result))\n .catch(error => console.error(error));"
},
{
"lang": "cURL",
"source": "curl --request POST \\\n --url 'https://api.mem0.ai/v1/exports/' \\\n --header 'Authorization: Token <api-key>' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"schema\": {pydantic_json_schema},\n \"user_id\": \"your_user_id\"\n }'"
},
{
"lang": "Go",
"source": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\turl := \"https://api.mem0.ai/v1/exports/\"\n\n\tdata := map[string]interface{}{\n\t\t\"schema\": map[string]interface{}{}, // Your schema here\n\t\t\"user_id\": \"user123\",\n\t}\n\n\tjsonData, _ := json.Marshal(data)\n\n\treq, _ := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\treq.Header.Add(\"Content-Type\", \"application/json\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(string(body))\n}"
},
{
"lang": "PHP",
"source": "<?php\n\n$curl = curl_init();\n\n$data = array(\n \"schema\" => array(), // Your schema here\n \"user_id\" => \"your_user_id\"\n);\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/v1/exports/\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"POST\",\n CURLOPT_POSTFIELDS => json_encode($data),\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\",\n \"Content-Type: application/json\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
},
{
"lang": "Java",
"source": "import com.mashape.unirest.http.HttpResponse;\nimport com.mashape.unirest.http.JsonNode;\nimport com.mashape.unirest.http.Unirest;\nimport org.json.JSONObject;\n\nJSONObject data = new JSONObject()\n .put(\"schema\", new JSONObject()) // Your schema here\n .put(\"user_id\", \"your_user_id\");\n\nHttpResponse<JsonNode> response = Unirest.post(\"https://api.mem0.ai/v1/exports/\")\n .header(\"Authorization\", \"Token <api-key>\")\n .header(\"Content-Type\", \"application/json\")\n .body(data.toString())\n .asJson();"
}
]
}
},
"/v1/memories/": {
@@ -811,7 +863,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\n# Retrieve memories for a specific user\nuser_memories = client.get_all(user_id=\"<user_id>\")\n\nprint(user_memories)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\n# Retrieve memories for a specific user\nuser_memories = client.get_all(user_id=\"<user_id>\")\n\nprint(user_memories)"
},
{
"lang": "JavaScript",
@@ -918,7 +970,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your-api-key\")\n\nmessages = [\n {\"role\": \"user\", \"content\": \"<user-message>\"},\n {\"role\": \"assistant\", \"content\": \"<assistant-response>\"}\n]\n\nclient.add(messages, user_id=\"<user-id>\")"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nmessages = [\n {\"role\": \"user\", \"content\": \"<user-message>\"},\n {\"role\": \"assistant\", \"content\": \"<assistant-response>\"}\n]\n\nclient.add(messages, user_id=\"<user-id>\")"
},
{
"lang": "JavaScript",
@@ -1046,7 +1098,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\n# Delete all memories for a specific user\nclient.delete_all(user_id=\"<user_id>\")"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\n# Delete all memories for a specific user\nclient.delete_all(user_id=\"<user_id>\")"
},
{
"lang": "JavaScript",
@@ -1084,9 +1136,32 @@
"name": "filters",
"in": "query",
"schema": {
"type": "object"
"type": "object",
"properties": {
"user_id": {"type": "string"},
"agent_id": {"type": "string"},
"app_id": {"type": "string"},
"run_id": {"type": "string"},
"created_at": {"type": "string", "format": "date-time"},
"updated_at": {"type": "string", "format": "date-time"},
"categories": {"type": "array", "items": {"type": "string"}},
"keywords": {"type": "string"}
},
"additionalProperties": {
"type": "object",
"properties": {
"in": {"type": "array"},
"gte": {"type": "string"},
"lte": {"type": "string"},
"gt": {"type": "string"},
"lt": {"type": "string"},
"ne": {"type": "string"},
"contains": {"type": "string"},
"icontains": {"type": "string"}
}
}
},
"description": "Filters to apply to the memories",
"description": "Filters to apply to the memories. Available fields are: user_id, agent_id, app_id, run_id, created_at, updated_at, categories, keywords. Supports logical operators (AND, OR) and comparison operators (in, gte, lte, gt, lt, ne, contains, icontains)",
"style": "deepObject",
"explode": true
},
@@ -1216,7 +1291,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\n# Retrieve memories with filters\nmemories = client.get_all(\n filters={\n \"AND\": [\n {\n \"user_id\": \"alex\"\n },\n {\n \"created_at\": {\n \"gte\": \"2024-07-01\",\n \"lte\": \"2024-07-31\"\n }\n }\n ]\n },\n version=\"v2\"\n)\n\nprint(memories)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\n# Retrieve memories with filters\nmemories = client.get_all(\n filters={\n \"AND\": [\n {\n \"user_id\": \"alex\"\n },\n {\n \"created_at\": {\n \"gte\": \"2024-07-01\",\n \"lte\": \"2024-07-31\"\n }\n }\n ]\n },\n version=\"v2\"\n)\n\nprint(memories)"
},
{
"lang": "JavaScript",
@@ -1376,7 +1451,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\nquery = \"Your search query here\"\n\nresults = client.search(query, user_id=\"<user_id>\", output_format=\"v1.0\")\nprint(results)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nquery = \"Your search query here\"\n\nresults = client.search(query, user_id=\"<user_id>\", output_format=\"v1.0\")\nprint(results)"
},
{
"lang": "JavaScript",
@@ -1505,7 +1580,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\nquery = \"What do you know about me?\"\nfilters = {\n \"AND\":[\n {\n \"user_id\":\"alex\"\n },\n {\n \"agent_id\":{\n \"in\":[\n \"travel-assistant\",\n \"customer-support\"\n ]\n }\n }\n ]\n}\nclient.search(query, version=\"v2\", filters=filters)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nquery = \"What do you know about me?\"\nfilters = {\n \"AND\":[\n {\n \"user_id\":\"alex\"\n },\n {\n \"agent_id\":{\n \"in\":[\n \"travel-assistant\",\n \"customer-support\"\n ]\n }\n }\n ]\n}\nclient.search(query, version=\"v2\", filters=filters)"
},
{
"lang": "JavaScript",
@@ -1663,7 +1738,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\nmemory = client.get(memory_id=\"<memory_id>\")"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nmemory = client.get(memory_id=\"<memory_id>\")"
},
{
"lang": "JavaScript",
@@ -1784,7 +1859,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\n# Update a memory\nmemory_id = \"<memory_id>\"\nmessage = \"Your updated memory message here\"\nclient.update(memory_id, message)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\n# Update a memory\nmemory_id = \"<memory_id>\"\nmessage = \"Your updated memory message here\"\nclient.update(memory_id, message)"
},
{
"lang": "JavaScript",
@@ -1848,7 +1923,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\nmemory_id = \"<memory_id>\"\nclient.delete(memory_id=memory_id)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nmemory_id = \"<memory_id>\"\nclient.delete(memory_id=memory_id)"
},
{
"lang": "JavaScript",
@@ -1994,7 +2069,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\n# Add some message to create history\nmessages = [{\"role\": \"user\", \"content\": \"<user-message>\"}]\nclient.add(messages, user_id=\"<user-id>\")\n\n# Add second message to update history\nmessages.append({\"role\": \"user\", \"content\": \"<user-message>\"})\nclient.add(messages, user_id=\"<user-id>\")\n\n# Get history of how memory changed over time\nmemory_id = \"<memory-id-here>\"\nhistory = client.history(memory_id)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\n# Add some message to create history\nmessages = [{\"role\": \"user\", \"content\": \"<user-message>\"}]\nclient.add(messages, user_id=\"<user-id>\")\n\n# Add second message to update history\nmessages.append({\"role\": \"user\", \"content\": \"<user-message>\"})\nclient.add(messages, user_id=\"<user-id>\")\n\n# Get history of how memory changed over time\nmemory_id = \"<memory-id-here>\"\nhistory = client.history(memory_id)"
},
{
"lang": "JavaScript",
@@ -3295,31 +3370,152 @@
},
"x-code-samples": [
{
"lang": "Python",
"source": "import requests\n\nurl = \"https://api.mem0.ai/api/v1/orgs/organizations/{org_id}/projects/{project_id}/\"\n\nheaders = {\"Authorization\": \"<api-key>\"}\n\nresponse = requests.request(\"GET\", url, headers=headers)\n\nprint(response.text)"
},
{
"lang": "JavaScript",
"source": "const options = {method: 'GET', headers: {Authorization: 'Token <api-key>'}};\n\nfetch('https://api.mem0.ai/api/v1/orgs/organizations/{org_id}/projects/{project_id}/', options)\n .then(response => response.json())\n .then(response => console.log(response))\n .catch(err => console.error(err));"
},
{
"lang": "cURL",
"source": "curl --request GET \\\n --url https://api.mem0.ai/api/v1/orgs/organizations/{org_id}/projects/{project_id}/ \\\n --header 'Authorization: Token <api-key>'"
},
{
"lang": "Go",
"source": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\turl := \"https://api.mem0.ai/api/v1/orgs/organizations/{org_id}/projects/{project_id}/\"\n\n\treq, _ := http.NewRequest(\"GET\", url, nil)\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(res)\n\tfmt.Println(string(body))\n\n}"
},
{
"lang": "PHP",
"source": "<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/api/v1/orgs/organizations/{org_id}/projects/{project_id}/\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"GET\",\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
},
{
"lang": "Java",
"source": "HttpResponse<String> response = Unirest.get(\"https://api.mem0.ai/api/v1/orgs/organizations/{org_id}/projects/{project_id}/\")\n .header(\"Authorization\", \"Token <api-key>\")\n .asString();"
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nresponse = client.get_project()\nprint(response)"
},
{
"lang": "JavaScript",
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nclient.getProject()\n .then(response => console.log(response))\n .catch(err => console.error(err));"
},
{
"lang": "cURL",
"source": "curl --request GET \\\n --url https://api.mem0.ai/api/v1/orgs/organizations/{org_id}/projects/{project_id}/ \\\n --header 'Authorization: Token <api-key>'"
},
{
"lang": "Go",
"source": "// To use the Go SDK, install the package:\n// go get github.com/mem0ai/mem0-go\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/mem0ai/mem0-go\"\n)\n\nfunc main() {\n\tclient := mem0.NewClient(\"your-api-key\")\n\n\tresponse, err := client.GetProject()\n\tif err != nil {\n\t\tfmt.Printf(\"Error: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"%+v\\n\", response)\n}"
},
{
"lang": "PHP",
"source": "<?php\n// To use the PHP SDK, install the package:\n// composer require mem0ai/mem0-php\n\nrequire_once('vendor/autoload.php');\n\nuse Mem0\\MemoryClient;\n\n$client = new MemoryClient('your-api-key');\n\ntry {\n $response = $client->getProject();\n print_r($response);\n} catch (Exception $e) {\n echo 'Error: ' . $e->getMessage();\n}"
},
{
"lang": "Java",
"source": "// To use the Java SDK, add this dependency to your pom.xml:\n// <dependency>\n// <groupId>ai.mem0</groupId>\n// <artifactId>mem0-java</artifactId>\n// <version>1.0.0</version>\n// </dependency>\n\nimport ai.mem0.MemoryClient;\n\npublic class Example {\n public static void main(String[] args) {\n MemoryClient client = new MemoryClient(\"your-api-key\");\n \n try {\n Object response = client.getProject();\n System.out.println(response);\n } catch (Exception e) {\n System.err.println(\"Error: \" + e.getMessage());\n }\n }\n}"
}
]
},
"patch": {
"tags": [
"projects"
],
"summary": "Update Project",
"description": "Update a specific project's settings.",
"operationId": "update_project",
"parameters": [
{
"name": "org_id",
"in": "path",
"required": true,
"description": "Unique identifier of the organization",
"schema": {
"type": "string"
}
},
{
"name": "project_id",
"in": "path",
"required": true,
"description": "Unique identifier of the project to be updated",
"schema": {
"type": "string"
}
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "Name of the project"
},
"description": {
"type": "string",
"description": "Description of the project"
},
"custom_instructions": {
"type": "array",
"items": {
"type": "string"
},
"description": "Custom instructions for memory processing in this project"
},
"custom_categories": {
"type": "array",
"items": {
"type": "object"
},
"description": "List of custom categories to be used for memory categorization"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Project updated successfully",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Project updated successfully"
}
}
}
}
}
},
"404": {
"description": "Organization or project not found",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Organization or project not found"
}
}
}
}
}
}
},
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\")\n\nnew_categories = [\n {\"cooking\": \"For users interested in cooking and culinary experiences\"},\n {\"fitness\": \"Includes content related to fitness and workouts\"}\n]\n\nresponse = client.update_project(custom_categories=new_categories)\nprint(response)"
},
{
"lang": "JavaScript",
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst newCategories = [\n {\"cooking\": \"For users interested in cooking and culinary experiences\"},\n {\"fitness\": \"Includes content related to fitness and workouts\"}\n];\n\nclient.updateProject({ custom_categories: newCategories })\n .then(response => console.log(response))\n .catch(err => console.error(err));"
},
{
"lang": "cURL",
"source": "curl --request PATCH \\\n --url https://api.mem0.ai/api/v1/orgs/organizations/{org_id}/projects/{project_id}/ \\\n --header 'Authorization: Token <api-key>' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"custom_categories\": [\n {\"cooking\": \"For users interested in cooking and culinary experiences\"},\n {\"fitness\": \"Includes content related to fitness and workouts\"}\n ]\n }'"
},
{
"lang": "Go",
"source": "// To use the Go SDK, install the package:\n// go get github.com/mem0ai/mem0-go\n\npackage main\n\nimport (\n\t\"fmt\"\n\t\"github.com/mem0ai/mem0-go\"\n)\n\nfunc main() {\n\tclient := mem0.NewClient(\"your-api-key\")\n\n\tnewCategories := []map[string]string{\n\t\t{\"cooking\": \"For users interested in cooking and culinary experiences\"},\n\t\t{\"fitness\": \"Includes content related to fitness and workouts\"},\n\t}\n\n\tresponse, err := client.UpdateProject(mem0.UpdateProjectParams{\n\t\tCustomCategories: newCategories,\n\t})\n\tif err != nil {\n\t\tfmt.Printf(\"Error: %v\\n\", err)\n\t\treturn\n\t}\n\tfmt.Printf(\"%+v\\n\", response)\n}"
},
{
"lang": "PHP",
"source": "<?php\n// To use the PHP SDK, install the package:\n// composer require mem0ai/mem0-php\n\nrequire_once('vendor/autoload.php');\n\nuse Mem0\\MemoryClient;\n\n$client = new MemoryClient('your-api-key');\n\n$newCategories = [\n ['cooking' => 'For users interested in cooking and culinary experiences'],\n ['fitness' => 'Includes content related to fitness and workouts']\n];\n\ntry {\n $response = $client->updateProject(['custom_categories' => $newCategories]);\n print_r($response);\n} catch (Exception $e) {\n echo 'Error: ' . $e->getMessage();\n}"
},
{
"lang": "Java",
"source": "// To use the Java SDK, add this dependency to your pom.xml:\n// <dependency>\n// <groupId>ai.mem0</groupId>\n// <artifactId>mem0-java</artifactId>\n// <version>1.0.0</version>\n// </dependency>\n\nimport ai.mem0.MemoryClient;\nimport java.util.*;\n\npublic class Example {\n public static void main(String[] args) {\n MemoryClient client = new MemoryClient(\"your-api-key\");\n \n List<Map<String, String>> newCategories = Arrays.asList(\n Collections.singletonMap(\"cooking\", \"For users interested in cooking and culinary experiences\"),\n Collections.singletonMap(\"fitness\", \"Includes content related to fitness and workouts\")\n );\n \n try {\n Map<String, Object> params = new HashMap<>();\n params.put(\"custom_categories\", newCategories);\n \n Object response = client.updateProject(params);\n System.out.println(response);\n } catch (Exception e) {\n System.err.println(\"Error: \" + e.getMessage());\n }\n }\n}"
}
]
},
"delete": {
"tags": [
"projects"
@@ -3967,7 +4163,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\nupdate_memories = [\n {\n \"memory_id\": \"285ed74b-6e05-4043-b16b-3abd5b533496\",\n \"text\": \"Watches football\"\n },\n {\n \"memory_id\": \"2c9bd859-d1b7-4d33-a6b8-94e0147c4f07\",\n \"text\": \"Likes to travel\"\n }\n]\n\nresponse = client.batch_update(update_memories)\nprint(response)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nupdate_memories = [\n {\n \"memory_id\": \"285ed74b-6e05-4043-b16b-3abd5b533496\",\n \"text\": \"Watches football\"\n },\n {\n \"memory_id\": \"2c9bd859-d1b7-4d33-a6b8-94e0147c4f07\",\n \"text\": \"Likes to travel\"\n }\n]\n\nresponse = client.batch_update(update_memories)\nprint(response)"
},
{
"lang": "JavaScript",
@@ -4044,7 +4240,7 @@
"x-code-samples": [
{
"lang": "Python",
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your-api-key\")\n\ndelete_memories = [\n {\"memory_id\": \"285ed74b-6e05-4043-b16b-3abd5b533496\"},\n {\"memory_id\": \"2c9bd859-d1b7-4d33-a6b8-94e0147c4f07\"}\n]\n\nresponse = client.batch_delete(delete_memories)\nprint(response)"
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\ndelete_memories = [\n {\"memory_id\": \"285ed74b-6e05-4043-b16b-3abd5b533496\"},\n {\"memory_id\": \"2c9bd859-d1b7-4d33-a6b8-94e0147c4f07\"}\n]\n\nresponse = client.batch_delete(delete_memories)\nprint(response)"
},
{
"lang": "JavaScript",
@@ -4056,197 +4252,6 @@
}
]
}
},
"/api/v1/orgs/organizations/{org_id}/projects/{project_id}/custom-instructions-and-categories/": {
"get": {
"tags": ["custom-instructions-and-categories"],
"summary": "Get custom instructions and categories",
"description": "Retrieve custom categories and instructions for a specific project",
"operationId": "get_custom_instructions_and_categories",
"parameters": [
{
"name": "org_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "Organization ID"
},
{
"name": "project_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "Project ID"
}
],
"responses": {
"200": {
"description": "Successfully retrieved custom instructions and categories",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"custom_categories": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of custom categories for the project"
},
"custom_instructions": {
"type": "string",
"description": "Custom instructions text for the project"
}
},
"required": ["custom_categories", "custom_instructions"]
}
}
}
},
"403": {
"description": "Unauthorized access",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "Unauthorized to modify custom instructions and categories."
}
}
}
}
}
}
},
"x-code-samples": [
{
"lang": "Python",
"source": "import requests\n\nurl = \"https://api.mem0.ai/api/organizations/{org_id}/projects/{project_id}/custom-instructions-and-categories/\"\nheaders = {\"Authorization\": \"Token <api-key>\"}\n\nresponse = requests.get(url, headers=headers)\nprint(response.json())"
},
{
"lang": "JavaScript",
"source": "fetch('https://api.mem0.ai/api/organizations/{org_id}/projects/{project_id}/custom-instructions-and-categories/', {\n headers: {\n 'Authorization': 'Token <api-key>'\n }\n})\n.then(response => response.json())\n.then(data => console.log(data))\n.catch(error => console.error(error));"
}
]
},
"post": {
"tags": ["custom-instructions-and-categories"],
"summary": "Update custom instructions and categories",
"description": "Update custom categories and instructions for a specific project",
"operationId": "update_custom_instructions_and_categories",
"parameters": [
{
"name": "org_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "Organization ID"
},
{
"name": "project_id",
"in": "path",
"required": true,
"schema": {
"type": "string"
},
"description": "Project ID"
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"custom_categories": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of new custom categories for the project"
},
"custom_instructions": {
"type": "string",
"description": "New custom instructions text for the project"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Successfully updated custom instructions and categories",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"message": {
"type": "string",
"example": "Updated custom categories / instructions"
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
},
"example": {
"field_name": ["error message"]
}
}
}
}
},
"403": {
"description": "Unauthorized access",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"error": {
"type": "string",
"example": "Unauthorized to modify custom instructions and categories."
}
}
}
}
}
}
},
"x-code-samples": [
{
"lang": "Python",
"source": "import requests\n\nurl = \"https://api.mem0.ai/api/organizations/{org_id}/projects/{project_id}/custom-instructions-and-categories/\"\nheaders = {\n \"Authorization\": \"Token <api-key>\",\n \"Content-Type\": \"application/json\"\n}\npayload = {\n \"custom_categories\": [\"new_category1\", \"new_category2\"],\n \"custom_instructions\": \"New custom instructions text\"\n}\n\nresponse = requests.post(url, headers=headers, json=payload)\nprint(response.json())"
},
{
"lang": "JavaScript",
"source": "fetch('https://api.mem0.ai/api/organizations/{org_id}/projects/{project_id}/custom-instructions-and-categories/', {\n method: 'POST',\n headers: {\n 'Authorization': 'Token <api-key>',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n custom_categories: ['new_category1', 'new_category2'],\n custom_instructions: 'New custom instructions text'\n })\n})\n.then(response => response.json())\n.then(data => console.log(data))\n.catch(error => console.error(error));"
}
]
}
}
},
"components": {
@@ -4541,9 +4546,30 @@
"filters": {
"title": "Filters",
"type": "object",
"description": "A dictionary of filters to apply to the search. Users can pass AND, OR, IN, gte, lte, gt, lt, ne, icontains operators for advanced filtering.",
"description": "A dictionary of filters to apply to the search. Available fields are: user_id, agent_id, app_id, run_id, created_at, updated_at, categories, keywords. Supports logical operators (AND, OR) and comparison operators (in, gte, lte, gt, lt, ne, contains, icontains).",
"properties": {
"user_id": {"type": "string"},
"agent_id": {"type": "string"},
"app_id": {"type": "string"},
"run_id": {"type": "string"},
"created_at": {"type": "string", "format": "date-time"},
"updated_at": {"type": "string", "format": "date-time"},
"text": {"type": "string"},
"categories": {"type": "array", "items": {"type": "string"}},
"metadata": {"type": "object"}
},
"additionalProperties": {
"type": "object"
"type": "object",
"properties": {
"in": {"type": "array"},
"gte": {"type": "string"},
"lte": {"type": "string"},
"gt": {"type": "string"},
"lt": {"type": "string"},
"ne": {"type": "string"},
"contains": {"type": "string"},
"icontains": {"type": "string"}
}
}
},
"top_k": {
@@ -4566,6 +4592,18 @@
"default": false,
"description": "Whether to rerank the memories."
},
"threshold": {
"title": "Threshold",
"type": "number",
"default": 0.3,
"description": "The minimum similarity threshold for returned results."
},
"smart_search": {
"title": "Smart Search",
"type": "boolean",
"default": false,
"description": "Whether to enable smart search functionality."
},
"org_name": {
"title": "Organization Name",
"type": "string",
+119 -2
View File
@@ -493,7 +493,7 @@ curl -X POST "https://api.mem0.ai/v1/memories/search/?version=v2" \
#### Search using custom filters
Our advanced search allows you to set custom search filters. You can filter by user_id, agent_id, app_id, date, and more.
Our advanced search allows you to set custom search filters. You can filter by user_id, agent_id, app_id, run_id, created_at, updated_at, categories, and text. The filters support logical operators (AND, OR) and comparison operators (in, gte, lte, gt, lt, ne, contains, icontains). For more details, see [V2 Search Memories](/api-reference/memory/v2-search-memories).
Here you need to define `version` as `v2` in the search method.
@@ -665,6 +665,91 @@ curl -X POST "https://api.mem0.ai/v1/memories/search/?version=v2" \
```
</CodeGroup>
Example 3: Search using metadata and categories Filters
<CodeGroup>
```python Python
query = "What do you know about me?"
filters = {
"AND": [
{"metadata": {"food": "vegan"}},
{
"categories":{
"contains": "food_preferences"
}
}
]
}
client.search(query, version="v2", filters=filters)
```
```javascript JavaScript
const query = "What do you know about me?";
const filters = {
"AND": [
{"metadata": {"food": "vegan"}},
{
"categories": {
"contains": "food_preferences"
}
}
]
};
client.search(query, { version: "v2", filters })
.then(results => console.log(results))
.catch(error => console.error(error));
```
```bash cURL
curl -X POST "https://api.mem0.ai/v1/memories/search/?version=v2" \
-H "Authorization: Token your-api-key" \
-H "Content-Type: application/json" \
-d '{
"query": "What do you know about me?",
"filters": {
"AND": [
{
"metadata": {
"food": "vegan"
}
},
{
"categories": {
"contains": "food_preferences"
}
}
]
}
}'
```
```json Output
[
{
"id": "654fee-b411-4afe-b7e5-35789b72c4a5",
"memory": "Name: Alex. Vegetarian. Allergic to nuts.",
"input": [
{
"role": "user",
"content": "Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts."
},
{
"role": "assistant",
"content": "Hello Alex! I've noted that you're a vegetarian and have a nut allergy. I'll keep this in mind for any food-related recommendations or discussions."
}
],
"user_id": "alex",
"hash": "9ee7e1455e84d1dab700eiy8749aed75a",
"metadata": {"food": "vegan"},
"categories": ["food_preferences"],
"created_at": "2024-07-20T01:30:36.275141-07:00",
"updated_at": "2024-07-20T01:30:36.275172-07:00"
}
]
```
</CodeGroup>
### 4.3 Get All Users
@@ -1124,7 +1209,7 @@ curl -X GET "https://api.mem0.ai/v1/memories/?user_id=alex123&keywords=to play&p
#### Get all memories using custom filters
Our advanced retrieval allows you to set custom filters when fetching memories. You can filter by user_id, agent_id, app_id, date, and more.
Our advanced retrieval allows you to set custom filters when fetching memories. You can filter by user_id, agent_id, app_id, run_id, created_at, updated_at, categories, and keywords. The filters support logical operators (AND, OR) and comparison operators (in, gte, lte, gt, lt, ne, contains, icontains). For more details, see [V2 Get Memories](/api-reference/memory/v2-get-memories).
Here you need to define `version` as `v2` in the get_all method.
@@ -1460,6 +1545,7 @@ curl -X DELETE "https://api.mem0.ai/v1/memories/?user_id=alex" \
```json Output
{'message': 'Memories deleted successfully!'}
```
</CodeGroup>
Delete all users.
@@ -1480,6 +1566,37 @@ client.delete_users()
{'message': 'All users, agents, and runs deleted.'}
```
Delete specific user or agent or app or run.
```python Python
# Delete specific user
client.delete_users(user_id="alex")
# Delete specific agent
#client.delete_users(agent_id="travel-assistant")
# Delete specific app
#client.delete_users(app_id="travel-app")
# Delete specific run
#client.delete_users(run_id="travel-run")
```
```javascript JavaScript
client.delete_users({ user_id: "alex" })
.then(result => console.log(result))
.catch(error => console.error(error));
```
```bash cURL
curl -X DELETE "https://api.mem0.ai/v1/entities/?user_id=alex" \
-H "Authorization: Token your-api-key"
```
```json Output
{'message': 'Entity deleted successfully.'}
```
</CodeGroup>
### 4.8 Reset Client
@@ -12,9 +12,9 @@
},
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"utils": "@/libs/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"lib": "@/libs",
"hooks": "@/hooks"
}
}
@@ -4,7 +4,7 @@ import { ScrollArea } from "@radix-ui/react-scroll-area";
import { Memory } from "../types";
import GlobalContext from "@/contexts/GlobalContext";
import { useContext, useEffect, useState } from "react";
import { AnimatePresence, motion } from "framer-motion";
import { motion } from "framer-motion";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -73,9 +73,8 @@ const Memories = (props: { isMemoriesExpanded: boolean }) => {
<ScrollArea className="flex-1 p-4">
<motion.div
className="space-y-4"
layout
>
<AnimatePresence mode="popLayout">
{/* <AnimatePresence mode="popLayout"> */}
{memories.map((memory: Memory, index: number) => (
<MemoryItem
key={memory.id}
@@ -83,7 +82,7 @@ const Memories = (props: { isMemoriesExpanded: boolean }) => {
index={index}
/>
))}
</AnimatePresence>
{/* </AnimatePresence> */}
</motion.div>
</ScrollArea>
</Card>
@@ -3,7 +3,7 @@
import * as React from "react"
import * as AvatarPrimitive from "@radix-ui/react-avatar"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
const Avatar = React.forwardRef<
React.ElementRef<typeof AvatarPrimitive.Root>,
@@ -1,7 +1,7 @@
import * as React from "react"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
const badgeVariants = cva(
"inline-flex items-center rounded-md border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2",
@@ -2,7 +2,7 @@ import * as React from "react"
import { Slot } from "@radix-ui/react-slot"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
@@ -1,6 +1,6 @@
import * as React from "react"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
const Card = React.forwardRef<
HTMLDivElement,
@@ -2,7 +2,7 @@ import * as React from "react"
import * as DialogPrimitive from "@radix-ui/react-dialog"
import { Cross2Icon } from "@radix-ui/react-icons"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
const Dialog = DialogPrimitive.Root
@@ -1,6 +1,6 @@
import * as React from "react"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
export interface InputProps
extends React.InputHTMLAttributes<HTMLInputElement> {}
@@ -2,7 +2,7 @@ import * as React from "react"
import * as LabelPrimitive from "@radix-ui/react-label"
import { cva, type VariantProps } from "class-variance-authority"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
const labelVariants = cva(
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
@@ -1,7 +1,7 @@
import * as React from "react"
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
const ScrollArea = React.forwardRef<
React.ElementRef<typeof ScrollAreaPrimitive.Root>,
@@ -9,7 +9,7 @@ import {
} from "@radix-ui/react-icons"
import * as SelectPrimitive from "@radix-ui/react-select"
import { cn } from "@/lib/utils"
import { cn } from "@/libs/utils"
const Select = SelectPrimitive.Root
@@ -119,7 +119,7 @@ const GlobalState = (props: any) => {
try {
const smemories = await searchMemories(messages, {
user_id: selectedUser || "",
mem0ApiKey: import.meta.env.VITE_MEM0_API_KEY,
mem0ApiKey: selectedMem0Key,
});
const newMemories = smemories.map((memory: any) => ({
@@ -0,0 +1,6 @@
import { clsx, type ClassValue } from "clsx"
import { twMerge } from "tailwind-merge"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
+160 -37
View File
@@ -111,6 +111,13 @@ class MemoryClient:
params = self._prepare_params()
response = self.client.get("/v1/ping/", params=params)
response.raise_for_status()
if response.status_code == 200:
data = response.json()
if data.get("org_id") and data.get("project_id"):
self.org_id = data.get("org_id")
self.project_id = data.get("project_id")
except httpx.HTTPStatusError:
raise ValueError("Invalid API Key. Please get a valid API Key from https://app.mem0.ai")
@@ -297,16 +304,61 @@ class MemoryClient:
return response.json()
@api_error_handler
def delete_users(self) -> Dict[str, str]:
"""Delete all users, agents, or sessions."""
def delete_users(
self,
user_id: Optional[str] = None,
agent_id: Optional[str] = None,
app_id: Optional[str] = None,
run_id: Optional[str] = None,
) -> Dict[str, str]:
"""Delete specific entities or all entities if no filters provided.
Args:
user_id: Optional user ID to delete specific user
agent_id: Optional agent ID to delete specific agent
app_id: Optional app ID to delete specific app
run_id: Optional run ID to delete specific run
Returns:
Dict with success message
Raises:
ValueError: If specified entity not found
APIError: If deletion fails
"""
params = self._prepare_params()
entities = self.users()
for entity in entities["results"]:
# Filter entities based on provided IDs using list comprehension
to_delete = [
entity
for entity in entities["results"]
if (user_id and entity["type"] == "user" and entity["name"] == user_id)
or (agent_id and entity["type"] == "agent" and entity["name"] == agent_id)
or (app_id and entity["type"] == "app" and entity["name"] == app_id)
or (run_id and entity["type"] == "run" and entity["name"] == run_id)
]
# If filters provided but no matches found, raise error
if not to_delete and (user_id or agent_id or app_id or run_id):
raise ValueError("No entity found with the provided ID.")
# If no filters provided, delete all entities
elif not to_delete:
to_delete = entities["results"]
# Delete entities and check response immediately
for entity in to_delete:
response = self.client.delete(f"/v1/entities/{entity['type']}/{entity['id']}/", params=params)
response.raise_for_status()
capture_client_event("client.delete_users", self)
return {"message": "All users, agents, and sessions deleted."}
capture_client_event(
"client.delete_users", self, {"user_id": user_id, "agent_id": agent_id, "app_id": app_id, "run_id": run_id}
)
return {
"message": "Entity deleted successfully."
if (user_id or agent_id or app_id or run_id)
else "All users, agents, apps and runs deleted."
}
@api_error_handler
def reset(self) -> Dict[str, str]:
@@ -400,14 +452,14 @@ class MemoryClient:
return response.json()
@api_error_handler
def get_custom_instructions_and_categories(self, fields: List[str]) -> Dict[str, Any]:
def get_project(self, fields: Optional[List[str]] = None) -> Dict[str, Any]:
"""Get instructions or categories for the current project.
Args:
fields: List of field names to retrieve (e.g. ['custom_instructions', 'custom_categories'])
fields: List of fields to retrieve
Returns:
Dictionary containing the requested instructions or categories.
Dictionary containing the requested fields.
Raises:
APIError: If the API request fails.
@@ -418,20 +470,22 @@ class MemoryClient:
params = self._prepare_params({"fields": fields})
response = self.client.get(
f"/api/v1/orgs/organizations/{self.org_id}/projects/{self.project_id}/custom-instructions-and-categories/",
f"/api/v1/orgs/organizations/{self.org_id}/projects/{self.project_id}/",
params=params,
)
response.raise_for_status()
capture_client_event("client.get_custom_instructions_and_categories", self, {"fields": fields})
capture_client_event("client.get_project_details", self, {"fields": fields})
return response.json()
@api_error_handler
def update_custom_instructions_and_categories(self, fields: Dict[str, Any]) -> Dict[str, Any]:
"""Update instructions or categories for the current project.
def update_project(
self, custom_instructions: Optional[str] = None, custom_categories: Optional[List[str]] = None
) -> Dict[str, Any]:
"""Update the project settings.
Args:
fields: Dictionary of fields to update
(e.g. {"custom_categories": "new instructions", "custom_categories": ["cat1"]})
custom_instructions: New instructions for the project
custom_categories: New categories for the project
Returns:
Dictionary containing the API response.
@@ -443,12 +497,24 @@ class MemoryClient:
if not (self.org_id and self.project_id):
raise ValueError("org_id and project_id must be set to update instructions or categories")
response = self.client.post(
f"/api/v1/orgs/organizations/{self.org_id}/projects/{self.project_id}/custom-instructions-and-categories/",
json=fields,
if custom_instructions is None and custom_categories is None:
raise ValueError(
"Currently we only support updating custom_instructions or custom_categories, so you must provide at least one of them"
)
payload = self._prepare_params(
{"custom_instructions": custom_instructions, "custom_categories": custom_categories}
)
response = self.client.patch(
f"/api/v1/orgs/organizations/{self.org_id}/projects/{self.project_id}/",
json=payload,
)
response.raise_for_status()
capture_client_event("client.update_custom_instructions_and_categories", self, {"fields": list(fields.keys())})
capture_client_event(
"client.update_project",
self,
{"custom_instructions": custom_instructions, "custom_categories": custom_categories},
)
return response.json()
def chat(self):
@@ -505,17 +571,19 @@ class MemoryClient:
"Note that org_name/project_name are deprecated."
)
# Add org_id and project_id if available
if self.org_id:
# Add org_id and project_id if both are available
if self.org_id and self.project_id:
kwargs["org_id"] = self.org_id
if self.project_id:
kwargs["project_id"] = self.project_id
elif self.org_id or self.project_id:
raise ValueError("Please provide both org_id and project_id")
# Add deprecated org_name and project_name for backward compatibility
if self.organization:
# Add deprecated org_name and project_name if both are available
if self.organization and self.project:
kwargs["org_name"] = self.organization
if self.project:
kwargs["project_name"] = self.project
elif self.organization or self.project:
raise ValueError("Please provide both org_name and project_name")
return {k: v for k, v in kwargs.items() if v is not None}
@@ -641,14 +709,59 @@ class AsyncMemoryClient:
return response.json()
@api_error_handler
async def delete_users(self) -> Dict[str, str]:
async def delete_users(
self,
user_id: Optional[str] = None,
agent_id: Optional[str] = None,
app_id: Optional[str] = None,
run_id: Optional[str] = None,
) -> Dict[str, str]:
"""Delete specific entities or all entities if no filters provided.
Args:
user_id: Optional user ID to delete specific user
agent_id: Optional agent ID to delete specific agent
app_id: Optional app ID to delete specific app
run_id: Optional run ID to delete specific run
Returns:
Dict with success message
Raises:
ValueError: If specified entity not found
APIError: If deletion fails
"""
params = self.sync_client._prepare_params()
entities = await self.users()
for entity in entities["results"]:
# Filter entities based on provided IDs using list comprehension
to_delete = [
entity
for entity in entities["results"]
if (user_id and entity["type"] == "user" and entity["name"] == user_id)
or (agent_id and entity["type"] == "agent" and entity["name"] == agent_id)
or (app_id and entity["type"] == "app" and entity["name"] == app_id)
or (run_id and entity["type"] == "run" and entity["name"] == run_id)
]
# If filters provided but no matches found, raise error
if not to_delete and (user_id or agent_id or app_id or run_id):
raise ValueError("No entity found with the provided ID.")
# If no filters provided, delete all entities
elif not to_delete:
to_delete = entities["results"]
# Delete entities and check response immediately
for entity in to_delete:
response = await self.async_client.delete(f"/v1/entities/{entity['type']}/{entity['id']}/", params=params)
response.raise_for_status()
capture_client_event("async_client.delete_users", self.sync_client)
return {"message": "All users, agents, and sessions deleted."}
return {
"message": "Entity deleted successfully."
if (user_id or agent_id or app_id or run_id)
else "All users, agents, apps and runs deleted."
}
@api_error_handler
async def reset(self) -> Dict[str, str]:
@@ -731,33 +844,43 @@ class AsyncMemoryClient:
return response.json()
@api_error_handler
async def get_custom_instructions_and_categories(self, fields: List[str]) -> Dict[str, Any]:
async def get_project(self, fields: Optional[List[str]] = None) -> Dict[str, Any]:
if not (self.sync_client.org_id and self.sync_client.project_id):
raise ValueError("org_id and project_id must be set to access instructions or categories")
params = self.sync_client._prepare_params({"fields": fields})
response = await self.async_client.get(
f"/api/v1/orgs/organizations/{self.sync_client.org_id}/projects/{self.sync_client.project_id}/custom-instructions-and-categories/",
f"/api/v1/orgs/organizations/{self.sync_client.org_id}/projects/{self.sync_client.project_id}/",
params=params,
)
response.raise_for_status()
capture_client_event(
"async_client.get_custom_instructions_and_categories", self.sync_client, {"fields": fields}
)
capture_client_event("async_client.get_project", self.sync_client, {"fields": fields})
return response.json()
@api_error_handler
async def update_custom_instructions_and_categories(self, fields: Dict[str, Any]) -> Dict[str, Any]:
async def update_project(
self, custom_instructions: Optional[str] = None, custom_categories: Optional[List[str]] = None
) -> Dict[str, Any]:
if not (self.sync_client.org_id and self.sync_client.project_id):
raise ValueError("org_id and project_id must be set to update instructions or categories")
response = await self.async_client.post(
f"/api/v1/orgs/organizations/{self.sync_client.org_id}/projects/{self.sync_client.project_id}/custom-instructions-and-categories/",
json=fields,
if custom_instructions is None and custom_categories is None:
raise ValueError(
"Currently we only support updating custom_instructions or custom_categories, so you must provide at least one of them"
)
payload = self.sync_client._prepare_params(
{"custom_instructions": custom_instructions, "custom_categories": custom_categories}
)
response = await self.async_client.patch(
f"/api/v1/orgs/organizations/{self.sync_client.org_id}/projects/{self.sync_client.project_id}/",
json=payload,
)
response.raise_for_status()
capture_client_event(
"async_client.update_custom_instructions_and_categories", self.sync_client, {"fields": list(fields.keys())}
"async_client.update_project",
self.sync_client,
{"custom_instructions": custom_instructions, "custom_categories": custom_categories},
)
return response.json()
+71 -32
View File
@@ -5,9 +5,7 @@ try:
from elasticsearch import Elasticsearch
from elasticsearch.helpers import bulk
except ImportError:
raise ImportError(
"Elasticsearch requires extra dependencies. Install with `pip install elasticsearch`"
) from None
raise ImportError("Elasticsearch requires extra dependencies. Install with `pip install elasticsearch`") from None
from pydantic import BaseModel
@@ -51,18 +49,28 @@ class ElasticsearchDB(VectorStoreBase):
def create_index(self) -> None:
"""Create Elasticsearch index with proper mappings if it doesn't exist"""
index_settings = {
"settings": {
"index": {
"number_of_replicas": 1,
"number_of_shards": 5,
"refresh_interval": "1s"
}
},
"mappings": {
"properties": {
"text": {"type": "text"},
"embedding": {
"vector": {
"type": "dense_vector",
"dims": self.vector_dim,
"index": True,
"similarity": "cosine",
"similarity": "cosine"
},
"metadata": {"type": "object"},
"user_id": {"type": "keyword"},
"hash": {"type": "keyword"},
"metadata": {
"type": "object",
"properties": {
"user_id": {"type": "keyword"}
}
}
}
}
}
@@ -101,44 +109,64 @@ class ElasticsearchDB(VectorStoreBase):
actions = []
for i, (vec, id_) in enumerate(zip(vectors, ids)):
action = {"_index": self.collection_name, "_id": id_, "vector": vec, "payload": payloads[i]}
action = {
"_index": self.collection_name,
"_id": id_,
"_source": {
"vector": vec,
"metadata": payloads[i] # Store all metadata in the metadata field
}
}
actions.append(action)
bulk(self.client, actions)
# Return OutputData objects for inserted documents
results = []
for i, id_ in enumerate(ids):
results.append(
OutputData(
id=id_,
score=1.0, # Default score for inserts
payload=payloads[i],
payload=payloads[i]
)
)
return results
def search(self, query: List[float], limit: int = 5, filters: Optional[Dict] = None) -> List[OutputData]:
"""Search for similar vectors using KNN search with pre-filtering."""
search_query = {
"query": {
"bool": {
"must": [
# Exact match filters for memory isolation
*({"term": {f"payload.{k}": v}} for k, v in (filters or {}).items()),
# KNN vector search
{
"knn": {
"vector": {
"vector": query,
"k": limit
}
}
if not filters:
# If no filters, just do KNN search
search_query = {
"knn": {
"field": "vector",
"query_vector": query,
"k": limit,
"num_candidates": limit * 2
}
}
else:
# If filters exist, apply them with KNN search
filter_conditions = []
for key, value in filters.items():
filter_conditions.append({
"term": {
f"metadata.{key}": value
}
})
search_query = {
"knn": {
"field": "vector",
"query_vector": query,
"k": limit,
"num_candidates": limit * 2,
"filter": {
"bool": {
"must": filter_conditions
}
]
}
}
}
}
response = self.client.search(index=self.collection_name, body=search_query)
@@ -148,7 +176,7 @@ class ElasticsearchDB(VectorStoreBase):
OutputData(
id=hit["_id"],
score=hit["_score"],
payload=hit["_source"].get("payload", {})
payload=hit.get("_source", {}).get("metadata", {})
)
)
@@ -164,7 +192,7 @@ class ElasticsearchDB(VectorStoreBase):
if vector is not None:
doc["vector"] = vector
if payload is not None:
doc["payload"] = payload
doc["metadata"] = payload
self.client.update(index=self.collection_name, id=vector_id, body={"doc": doc})
@@ -175,7 +203,7 @@ class ElasticsearchDB(VectorStoreBase):
return OutputData(
id=response["_id"],
score=1.0, # Default score for direct get
payload=response["_source"].get("payload", {}),
payload=response["_source"].get("metadata", {})
)
except KeyError as e:
logger.warning(f"Missing key in Elasticsearch response: {e}")
@@ -204,7 +232,18 @@ class ElasticsearchDB(VectorStoreBase):
query: Dict[str, Any] = {"query": {"match_all": {}}}
if filters:
query["query"] = {"bool": {"must": [{"match": {f"payload.{k}": v}} for k, v in filters.items()]}}
filter_conditions = []
for key, value in filters.items():
filter_conditions.append({
"term": {
f"metadata.{key}": value
}
})
query["query"] = {
"bool": {
"must": filter_conditions
}
}
if limit:
query["size"] = limit
@@ -217,7 +256,7 @@ class ElasticsearchDB(VectorStoreBase):
OutputData(
id=hit["_id"],
score=1.0, # Default score for list operation
payload=hit["_source"].get("payload", {}),
payload=hit.get("_source", {}).get("metadata", {})
)
)
+1 -1
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "mem0ai"
version = "0.1.43"
version = "0.1.47"
description = "Long-term memory for AI Agents"
authors = ["Mem0 <founders@mem0.ai>"]
exclude = [
+25 -34
View File
@@ -92,13 +92,11 @@ class TestElasticsearchDB(unittest.TestCase):
# Verify field mappings
mappings = create_args["body"]["mappings"]["properties"]
self.assertEqual(mappings["text"]["type"], "text")
self.assertEqual(mappings["embedding"]["type"], "dense_vector")
self.assertEqual(mappings["embedding"]["dims"], 1536)
self.assertEqual(mappings["embedding"]["index"], True)
self.assertEqual(mappings["embedding"]["similarity"], "cosine")
self.assertEqual(mappings["vector"]["type"], "dense_vector")
self.assertEqual(mappings["vector"]["dims"], 1536)
self.assertEqual(mappings["vector"]["index"], True)
self.assertEqual(mappings["vector"]["similarity"], "cosine")
self.assertEqual(mappings["metadata"]["type"], "object")
self.assertEqual(mappings["user_id"]["type"], "keyword")
self.assertEqual(mappings["hash"]["type"], "keyword")
# Reset mocks for next test
self.client_mock.reset_mock()
@@ -170,8 +168,8 @@ class TestElasticsearchDB(unittest.TestCase):
self.assertEqual(len(actions), 2)
self.assertEqual(actions[0]["_index"], "test_collection")
self.assertEqual(actions[0]["_id"], "id1")
self.assertEqual(actions[0]["vector"], vectors[0])
self.assertEqual(actions[0]["payload"], payloads[0])
self.assertEqual(actions[0]["_source"]["vector"], vectors[0])
self.assertEqual(actions[0]["_source"]["metadata"], payloads[0])
# Verify returned objects
self.assertEqual(len(results), 2)
@@ -189,34 +187,35 @@ class TestElasticsearchDB(unittest.TestCase):
"_score": 0.8,
"_source": {
"vector": [0.1] * 1536,
"payload": {"key1": "value1"}
"metadata": {"key1": "value1"}
}
}
]
}
}
self.client_mock.search.return_value = mock_response
# Perform search
query_vector = [0.1] * 1536
results = self.es_db.search(query=query_vector, limit=5)
# Verify search call
self.client_mock.search.assert_called_once()
search_args = self.client_mock.search.call_args[1]
# Verify search parameters
self.assertEqual(search_args["index"], "test_collection")
body = search_args["body"]
self.assertIn("script_score", body["query"])
self.assertEqual(
body["query"]["script_score"]["script"]["params"]["query_vector"],
query_vector
)
# Verify KNN query structure
self.assertIn("knn", body)
self.assertEqual(body["knn"]["field"], "vector")
self.assertEqual(body["knn"]["query_vector"], query_vector)
self.assertEqual(body["knn"]["k"], 5)
self.assertEqual(body["knn"]["num_candidates"], 10)
# Verify results
self.assertEqual(len(results), 1)
self.assertIsInstance(results[0], OutputData)
self.assertEqual(results[0].id, "id1")
self.assertEqual(results[0].score, 0.8)
self.assertEqual(results[0].payload, {"key1": "value1"})
@@ -227,10 +226,8 @@ class TestElasticsearchDB(unittest.TestCase):
"_id": "id1",
"_source": {
"vector": [0.1] * 1536,
"payload": {"key": "value"},
"text": "sample text",
"user_id": "test_user",
"hash": "sample_hash"
"metadata": {"key": "value"},
"text": "sample text"
}
}
self.client_mock.get.return_value = mock_response
@@ -244,17 +241,11 @@ class TestElasticsearchDB(unittest.TestCase):
id="id1"
)
# Basic assertions that should pass if OutputData is created correctly
# Verify result
self.assertIsNotNone(result)
self.assertTrue(hasattr(result, 'id'))
self.assertTrue(hasattr(result, 'score'))
self.assertTrue(hasattr(result, 'payload'))
# If the above assertions pass, we can safely check the values
if result is not None: # This satisfies the linter
self.assertEqual(result.id, "id1")
self.assertEqual(result.score, 1.0)
self.assertEqual(result.payload, {"key": "value"})
self.assertEqual(result.id, "id1")
self.assertEqual(result.score, 1.0)
self.assertEqual(result.payload, {"key": "value"})
def test_get_not_found(self):
# Mock get raising exception
@@ -273,7 +264,7 @@ class TestElasticsearchDB(unittest.TestCase):
"_id": "id1",
"_source": {
"vector": [0.1] * 1536,
"payload": {"key1": "value1"}
"metadata": {"key1": "value1"}
},
"_score": 1.0
},
@@ -281,7 +272,7 @@ class TestElasticsearchDB(unittest.TestCase):
"_id": "id2",
"_source": {
"vector": [0.2] * 1536,
"payload": {"key2": "value2"}
"metadata": {"key2": "value2"}
},
"_score": 0.8
}