Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c1bd4e19fe | ||
|
|
8d172d6139 | ||
|
|
a5355f7488 | ||
|
|
f13f3b9283 | ||
|
|
56351d1f8d | ||
|
|
a9d1383909 | ||
|
|
80c9c6a577 | ||
|
|
e4e5511642 | ||
|
|
a4b085553a | ||
|
|
e12273c7cb | ||
|
|
ee2b5adfc0 | ||
|
|
205a03a5f2 | ||
|
|
7be029a26f | ||
|
|
0bd177b30c | ||
|
|
82359774b7 |
@@ -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}/
|
||||
---
|
||||
@@ -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` |
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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" />
|
||||
@@ -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
@@ -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
@@ -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",
|
||||
|
||||
@@ -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
@@ -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()
|
||||
|
||||
|
||||
@@ -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
@@ -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 = [
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user