Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3db028c719 | ||
|
|
c86b1e4d4c | ||
|
|
5f5b738745 | ||
|
|
acaf47ed54 | ||
|
|
9734b2db7e | ||
|
|
3fe31e1c31 | ||
|
|
f4c0f98fde | ||
|
|
6e781f616c | ||
|
|
dcba83186a | ||
|
|
a6d305f8d0 | ||
|
|
db512950b9 | ||
|
|
d4df9f6dfe | ||
|
|
0e6b20982a | ||
|
|
92e1a9b433 | ||
|
|
3be356a0e9 | ||
|
|
760cd54ddf | ||
|
|
1436da18b1 | ||
|
|
cc9acb7493 | ||
|
|
cbee71a63e | ||
|
|
b052a86424 | ||
|
|
95f5fb3ab4 |
@@ -13,7 +13,7 @@ install:
|
||||
install_all:
|
||||
poetry install
|
||||
poetry run pip install groq together boto3 litellm ollama chromadb sentence_transformers vertexai \
|
||||
google-generativeai elasticsearch
|
||||
google-generativeai elasticsearch opensearch-py
|
||||
|
||||
# Format code with ruff
|
||||
format:
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
# Mem0 API Overview
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 provides a powerful set of APIs that allow you to integrate advanced memory management capabilities into your applications. Our APIs are designed to be intuitive, efficient, and scalable, enabling you to create, retrieve, update, and delete memories across various entities such as users, agents, apps, and runs.
|
||||
|
||||
@@ -43,8 +47,6 @@ client = MemoryClient(
|
||||
project_id='YOUR_PROJECT_ID',
|
||||
)
|
||||
```
|
||||
> **Note**: The use of `organization` and `project` parameters is deprecated and will be removed in version `0.1.40`. Please use `org_id` and `project_id` instead.
|
||||
|
||||
|
||||
Example with the mem0 Node.js package:
|
||||
|
||||
|
||||
@@ -1,15 +1,19 @@
|
||||
## What is Config?
|
||||
---
|
||||
title: Configurations
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Config in mem0 is a dictionary that specifies the settings for your embedding models. It allows you to customize the behavior and connection details of your chosen embedder.
|
||||
|
||||
## How to Define Config
|
||||
## How to define configurations?
|
||||
|
||||
The config is defined as a Python dictionary with two main keys:
|
||||
- `embedder`: Specifies the embedder provider and its configuration
|
||||
- `provider`: The name of the embedder (e.g., "openai", "ollama")
|
||||
- `config`: A nested dictionary containing provider-specific settings
|
||||
|
||||
## How to Use Config
|
||||
## How to use configurations?
|
||||
|
||||
Here's a general example of how to use the config with mem0:
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 offers support for various embedding models, allowing users to choose the one that best suits their needs.
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
## What is Config?
|
||||
---
|
||||
title: Configurations
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Config in mem0 is a dictionary that specifies the settings for your llms. It allows you to customize the behavior and connection details of your chosen llm.
|
||||
## How to define configurations?
|
||||
|
||||
## How to Define Config
|
||||
|
||||
The config is defined as a Python dictionary with two main keys:
|
||||
The `config` is defined as a Python dictionary with two main keys:
|
||||
- `llm`: Specifies the llm provider and its configuration
|
||||
- `provider`: The name of the llm (e.g., "openai", "groq")
|
||||
- `config`: A nested dictionary containing provider-specific settings
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 includes built-in support for various popular large language models. Memory can utilize the LLM provided by the user, ensuring efficient use for specific needs.
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
## What is Config?
|
||||
---
|
||||
title: Configurations
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Config in mem0 is a dictionary that specifies the settings for your vector database. It allows you to customize the behavior and connection details of your chosen vector store.
|
||||
## How to define configurations?
|
||||
|
||||
## How to Define Config
|
||||
|
||||
The config is defined as a Python dictionary with two main keys:
|
||||
The `config` is defined as a Python dictionary with two main keys:
|
||||
- `vector_store`: Specifies the vector database provider and its configuration
|
||||
- `provider`: The name of the vector database (e.g., "chroma", "pgvector", "qdrant", "milvus","azure_ai_search")
|
||||
- `config`: A nested dictionary containing provider-specific settings
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
[OpenSearch](https://opensearch.org/) is an open-source, enterprise-grade search and observability suite that brings order to unstructured data at scale. OpenSearch supports k-NN (k-Nearest Neighbors) and allows you to store and retrieve high-dimensional vector embeddings efficiently.
|
||||
|
||||
### Installation
|
||||
|
||||
OpenSearch support requires additional dependencies. Install them with:
|
||||
|
||||
```bash
|
||||
pip install opensearch>=2.8.0
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "opensearch",
|
||||
"config": {
|
||||
"collection_name": "mem0",
|
||||
"host": "localhost",
|
||||
"port": 9200,
|
||||
"embedding_model_dims": 1536
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Let's see the available parameters for the `opensearch` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| ---------------------- | -------------------------------------------------- | ------------- |
|
||||
| `collection_name` | The name of the index to store the vectors | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `host` | The host where the OpenSearch server is running | `localhost` |
|
||||
| `port` | The port where the OpenSearch server is running | `9200` |
|
||||
| `api_key` | API key for authentication | `None` |
|
||||
| `user` | Username for basic authentication | `None` |
|
||||
| `password` | Password for basic authentication | `None` |
|
||||
| `verify_certs` | Whether to verify SSL certificates | `False` |
|
||||
| `auto_create_index` | Whether to automatically create the index | `True` |
|
||||
| `use_ssl` | Whether to use SSL for connection | `False` |
|
||||
|
||||
### Features
|
||||
|
||||
- Fast and Efficient Vector Search
|
||||
- Can be deployed on-premises, in containers, or on cloud platforms like AWS OpenSearch Service.
|
||||
- Multiple Authentication and Security Methods (Basic Authentication, API Keys, LDAP, SAML, and OpenID Connect)
|
||||
- Automatic index creation with optimized mappings for vector search
|
||||
- Memory Optimization through Disk-Based Vector Search and Quantization
|
||||
- Real-Time Analytics and Observability
|
||||
@@ -26,7 +26,8 @@ config = {
|
||||
"embedding_model_dims": 1536,
|
||||
"redis_url": "redis://localhost:6379"
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": "v1.1"
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 includes built-in support for various popular databases. Memory can utilize the database provided by the user, ensuring efficient use for specific needs.
|
||||
@@ -16,6 +18,7 @@ See the list of supported vector databases below.
|
||||
<Card title="Azure AI Search" href="/components/vectordbs/dbs/azure_ai_search"></Card>
|
||||
<Card title="Redis" href="/components/vectordbs/dbs/redis"></Card>
|
||||
<Card title="Elasticsearch" href="/components/vectordbs/dbs/elasticsearch"></Card>
|
||||
<Card title="OpenSearch" href="/components/vectordbs/dbs/opensearch"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: Memory Operations
|
||||
description: Understanding the core operations for managing memories in AI applications
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 provides two core operations for managing memories in AI applications: adding new memories and searching existing ones. This guide covers how these operations work and how to use them effectively in your application.
|
||||
|
||||
|
||||
## Core Operations
|
||||
|
||||
Mem0 exposes two main endpoints for interacting with memories:
|
||||
- The `add` endpoint for ingesting conversations and storing them as memories
|
||||
- The `search` endpoint for retrieving relevant memories based on queries
|
||||
|
||||
### Adding Memories
|
||||
|
||||
<Frame caption="Architecture diagram illustrating the process of adding memories.">
|
||||
<img src="../images/add_architecture.png" />
|
||||
</Frame>
|
||||
|
||||
The add operation processes conversations through several steps:
|
||||
|
||||
1. **Information Extraction**
|
||||
* An LLM extracts relevant memories from the conversation
|
||||
* It identifies important entities and their relationships
|
||||
|
||||
2. **Conflict Resolution**
|
||||
* The system compares new information with existing data
|
||||
* It identifies and resolves any contradictions
|
||||
|
||||
3. **Memory Storage**
|
||||
* Vector database stores the actual memories
|
||||
* Graph database maintains relationship information
|
||||
* Information is continuously updated with each interaction
|
||||
|
||||
### Searching Memories
|
||||
|
||||
<Frame caption="Architecture diagram illustrating the memory search process.">
|
||||
<img src="../images/search_architecture.png" />
|
||||
</Frame>
|
||||
|
||||
The search operation retrieves memories through a multi-step process:
|
||||
|
||||
1. **Query Processing**
|
||||
* LLM processes and optimizes the search query
|
||||
* System prepares filters for targeted search
|
||||
|
||||
2. **Vector Search**
|
||||
* Performs semantic search using the optimized query
|
||||
* Ranks results by relevance to the query
|
||||
* Applies specified filters (user, agent, metadata, etc.)
|
||||
|
||||
3. **Result Processing**
|
||||
* Combines and ranks the search results
|
||||
* Returns memories with relevance scores
|
||||
* Includes associated metadata and timestamps
|
||||
|
||||
This semantic search approach ensures accurate memory retrieval, whether you're looking for specific information or exploring related concepts.
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Memory Types
|
||||
description: Understanding different types of memory in AI Applications
|
||||
icon: "memory"
|
||||
iconType: "solid"
|
||||
---
|
||||
To build useful AI applications, we need to understand how different memory systems work together. This guide explores the fundamental types of memory in AI systems and shows how Mem0 implements these concepts.
|
||||
|
||||
## Why Memory Matters
|
||||
|
||||
AI systems need memory for three key purposes:
|
||||
1. Maintaining context during conversations
|
||||
2. Learning from past interactions
|
||||
3. Building personalized experiences over time
|
||||
|
||||
Without proper memory systems, AI applications would treat each interaction as completely new, losing valuable context and personalization opportunities.
|
||||
|
||||
## Short-Term Memory
|
||||
|
||||
The most basic form of memory in AI systems holds immediate context - like a person remembering what was just said in a conversation. This includes:
|
||||
|
||||
- **Conversation History**: Recent messages and their order
|
||||
- **Working Memory**: Temporary variables and state
|
||||
- **Attention Context**: Current focus of the conversation
|
||||
|
||||
## Long-Term Memory
|
||||
|
||||
More sophisticated AI applications implement long-term memory to retain information across conversations. This includes:
|
||||
|
||||
- **Factual Memory**: Stored knowledge about users, preferences, and domain-specific information
|
||||
- **Episodic Memory**: Past interactions and experiences
|
||||
- **Semantic Memory**: Understanding of concepts and their relationships
|
||||
|
||||
## Memory Characteristics
|
||||
|
||||
Each memory type has distinct characteristics:
|
||||
|
||||
| Type | Persistence | Access Speed | Use Case |
|
||||
|------|-------------|--------------|-----------|
|
||||
| Short-Term | Temporary | Instant | Active conversations |
|
||||
| Long-Term | Persistent | Fast | User preferences and history |
|
||||
|
||||
## How Mem0 Implements Long-Term Memory
|
||||
Mem0's long-term memory system builds on these foundations by:
|
||||
|
||||
1. Using vector embeddings to store and retrieve semantic information
|
||||
2. Maintaining user-specific context across sessions
|
||||
3. Implementing efficient retrieval mechanisms for relevant past interactions
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
{
|
||||
"$schema": "https://mintlify.com/docs.json",
|
||||
"theme": "maple",
|
||||
"name": "Mem0",
|
||||
"description": "Mem0 is a self-improving memory layer for LLM applications, enabling personalized AI experiences that save costs and delight users.",
|
||||
"colors": {
|
||||
"primary": "#6c60f0",
|
||||
"light": "#E6FFA2",
|
||||
"dark": "#a3df02"
|
||||
},
|
||||
"favicon": "/logo/favicon.png",
|
||||
"navigation": {
|
||||
"anchors": [
|
||||
{
|
||||
"anchor": "Documentation",
|
||||
"icon": "book-open",
|
||||
"tabs": [
|
||||
{
|
||||
"tab": "Documentation",
|
||||
"groups": [
|
||||
{
|
||||
"group": "Get Started",
|
||||
"icon": "rocket",
|
||||
"pages": [
|
||||
"overview",
|
||||
"quickstart",
|
||||
"faqs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Core Concepts",
|
||||
"icon": "brain",
|
||||
"pages": [
|
||||
"core-concepts/memory-types",
|
||||
"core-concepts/memory-operations"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Platform",
|
||||
"icon": "cogs",
|
||||
"pages": [
|
||||
"platform/overview",
|
||||
"platform/quickstart",
|
||||
{
|
||||
"group": "Features",
|
||||
"icon": "star",
|
||||
"pages": [
|
||||
"features/platform-overview",
|
||||
"features/advanced-retrieval",
|
||||
"features/multimodal-support",
|
||||
"features/selective-memory",
|
||||
"features/custom-categories",
|
||||
"features/custom-instructions",
|
||||
"features/direct-import",
|
||||
"features/async-client",
|
||||
"features/memory-export",
|
||||
"features/webhook"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Open Source",
|
||||
"icon": "code-branch",
|
||||
"pages": [
|
||||
"open-source/quickstart",
|
||||
{
|
||||
"group": "Features",
|
||||
"icon": "wrench",
|
||||
"pages": [
|
||||
"features/openai_compatibility",
|
||||
"features/custom-prompts",
|
||||
"open-source/multimodal-support"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Graph Memory",
|
||||
"icon": "spider-web",
|
||||
"pages": [
|
||||
"open-source/graph_memory/overview",
|
||||
"open-source/graph_memory/features"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "LLMs",
|
||||
"icon": "brain",
|
||||
"pages": [
|
||||
"components/llms/overview",
|
||||
"components/llms/config",
|
||||
{
|
||||
"group": "Supported LLMs",
|
||||
"icon": "list",
|
||||
"pages": [
|
||||
"components/llms/models/openai",
|
||||
"components/llms/models/anthropic",
|
||||
"components/llms/models/azure_openai",
|
||||
"components/llms/models/ollama",
|
||||
"components/llms/models/together",
|
||||
"components/llms/models/groq",
|
||||
"components/llms/models/litellm",
|
||||
"components/llms/models/mistral_AI",
|
||||
"components/llms/models/google_AI",
|
||||
"components/llms/models/aws_bedrock",
|
||||
"components/llms/models/gemini"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Vector Databases",
|
||||
"icon": "database",
|
||||
"pages": [
|
||||
"components/vectordbs/overview",
|
||||
"components/vectordbs/config",
|
||||
{
|
||||
"group": "Supported Vector Databases",
|
||||
"icon": "server",
|
||||
"pages": [
|
||||
"components/vectordbs/dbs/qdrant",
|
||||
"components/vectordbs/dbs/chroma",
|
||||
"components/vectordbs/dbs/pgvector",
|
||||
"components/vectordbs/dbs/milvus",
|
||||
"components/vectordbs/dbs/azure_ai_search",
|
||||
"components/vectordbs/dbs/redis",
|
||||
"components/vectordbs/dbs/elasticsearch",
|
||||
"components/vectordbs/dbs/opensearch"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Embedding Models",
|
||||
"icon": "layer-group",
|
||||
"pages": [
|
||||
"components/embedders/overview",
|
||||
"components/embedders/config",
|
||||
{
|
||||
"group": "Supported Embedding Models",
|
||||
"icon": "list",
|
||||
"pages": [
|
||||
"components/embedders/models/openai",
|
||||
"components/embedders/models/azure_openai",
|
||||
"components/embedders/models/ollama",
|
||||
"components/embedders/models/huggingface",
|
||||
"components/embedders/models/vertexai",
|
||||
"components/embedders/models/gemini"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "Examples",
|
||||
"groups": [
|
||||
{
|
||||
"group": "💡 Examples",
|
||||
"icon": "lightbulb",
|
||||
"pages": [
|
||||
"examples/overview",
|
||||
"examples/mem0-with-ollama",
|
||||
"examples/personal-ai-tutor",
|
||||
"examples/customer-support-agent",
|
||||
"examples/personal-travel-assistant",
|
||||
"examples/llama-index-mem0"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "Integrations",
|
||||
"groups": [
|
||||
{
|
||||
"group": "Integrations",
|
||||
"icon": "plug",
|
||||
"pages": [
|
||||
"integrations/overview",
|
||||
"integrations/vercel-ai-sdk",
|
||||
"integrations/crewai",
|
||||
"integrations/autogen",
|
||||
"integrations/langchain",
|
||||
"integrations/langgraph",
|
||||
"integrations/llama-index",
|
||||
"integrations/langchain-tools"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "API Reference",
|
||||
"icon": "square-terminal",
|
||||
"groups": [
|
||||
{
|
||||
"group": "API Reference",
|
||||
"icon": "terminal",
|
||||
"pages": [
|
||||
"api-reference/overview",
|
||||
{
|
||||
"group": "Memory APIs",
|
||||
"icon": "microchip",
|
||||
"pages": [
|
||||
"api-reference/memory/v1-get-memories",
|
||||
"api-reference/memory/v2-get-memories",
|
||||
"api-reference/memory/add-memories",
|
||||
"api-reference/memory/delete-memories",
|
||||
"api-reference/memory/get-memory",
|
||||
"api-reference/memory/update-memory",
|
||||
"api-reference/memory/delete-memory",
|
||||
"api-reference/memory/v1-search-memories",
|
||||
"api-reference/memory/v2-search-memories",
|
||||
"api-reference/memory/history-memory",
|
||||
"api-reference/memory/batch-update",
|
||||
"api-reference/memory/batch-delete",
|
||||
"api-reference/memory/create-memory-export",
|
||||
"api-reference/memory/get-memory-export"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Entities APIs",
|
||||
"icon": "users",
|
||||
"pages": [
|
||||
"api-reference/entities/get-users",
|
||||
"api-reference/entities/delete-user"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Organizations APIs",
|
||||
"icon": "building",
|
||||
"pages": [
|
||||
"api-reference/organization/get-orgs",
|
||||
"api-reference/organization/get-org",
|
||||
"api-reference/organization/create-org",
|
||||
"api-reference/organization/update-org",
|
||||
"api-reference/organization/delete-org",
|
||||
"api-reference/organization/get-org-members",
|
||||
"api-reference/organization/add-org-member",
|
||||
"api-reference/organization/remove-org-member",
|
||||
"api-reference/organization/get-org-projects",
|
||||
"api-reference/organization/add-org-project",
|
||||
"api-reference/organization/remove-org-project"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"anchor": "Your Dashboard",
|
||||
"href": "https://app.mem0.ai",
|
||||
"icon": "chart-simple"
|
||||
},
|
||||
{
|
||||
"anchor": "Discord",
|
||||
"href": "https://mem0.dev/DiD",
|
||||
"icon": "discord"
|
||||
},
|
||||
{
|
||||
"anchor": "GitHub",
|
||||
"href": "https://github.com/mem0ai/mem0",
|
||||
"icon": "github"
|
||||
},
|
||||
{
|
||||
"anchor": "Support",
|
||||
"href": "mailto:founders@mem0.ai",
|
||||
"icon": "envelope"
|
||||
}
|
||||
]
|
||||
},
|
||||
"logo": {
|
||||
"light": "/logo/light.svg",
|
||||
"dark": "/logo/dark.svg",
|
||||
"href": "https://github.com/mem0ai/mem0"
|
||||
},
|
||||
"background": {
|
||||
"color": {
|
||||
"light": "#fff",
|
||||
"dark": "#0f1117"
|
||||
}
|
||||
},
|
||||
"navbar": {
|
||||
"primary": {
|
||||
"type": "button",
|
||||
"label": "Your Dashboard",
|
||||
"href": "https://app.mem0.ai"
|
||||
}
|
||||
},
|
||||
"footer": {
|
||||
"socials": {
|
||||
"discord": "https://mem0.dev/DiD",
|
||||
"x": "https://x.com/mem0ai",
|
||||
"github": "https://github.com/mem0ai",
|
||||
"linkedin": "https://www.linkedin.com/company/mem0/"
|
||||
}
|
||||
},
|
||||
"integrations": {
|
||||
"posthog": {
|
||||
"apiKey": "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX",
|
||||
"apiHost": "https://mango.mem0.ai"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: FAQs
|
||||
icon: "question"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Features
|
||||
icon: "wrench"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Core features
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Advanced Retrieval
|
||||
icon: "magnifying-glass"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0's **Advanced Retrieval** feature delivers superior search results by leveraging state-of-the-art search algorithms. Beyond the default search functionality, Mem0 offers the following advanced retrieval modes:
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Async Client
|
||||
description: 'Asynchronous client for Mem0'
|
||||
icon: "bolt"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
The `AsyncMemoryClient` is an asynchronous client for interacting with the Mem0 API. It provides similar functionality to the synchronous `MemoryClient` but allows for non-blocking operations, which can be beneficial in applications that require high concurrency.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Custom Categories
|
||||
description: 'Enhance your product experience by adding custom categories tailored to your needs'
|
||||
icon: "tags"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## How to set custom categories?
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Custom Instructions
|
||||
description: 'Enhance your product experience by adding custom instructions tailored to your needs'
|
||||
icon: "pencil"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Introduction to Custom Instructions
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Custom Prompts
|
||||
description: 'Enhance your product experience by adding custom prompts tailored to your needs'
|
||||
icon: "pencil"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Introduction to Custom Prompts
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Direct Import
|
||||
description: 'Bypass the memory deduction phase and directly store pre-defined memories for efficient retrieval'
|
||||
icon: "arrow-right"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## How to use Direct Import?
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Memory Export
|
||||
description: 'Export memories in a structured format using customizable Pydantic schemas'
|
||||
icon: "file-export"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
---
|
||||
title: Multimodal Support
|
||||
icon: "image"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 extends its capabilities beyond text by supporting multimodal data, including images. Users can seamlessly integrate images into their interactions, allowing Mem0 to extract pertinent information from visual content and enrich the memory system.
|
||||
|
||||
## How It Works
|
||||
|
||||
When a user provides an image, Mem0 processes the image to extract textual information and relevant details, which are then added to the user's memory. This feature enhances the system's ability to understand and remember details based on visual inputs.
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
from mem0 import MemoryClient
|
||||
|
||||
# Initialize the MemoryClient with your API key
|
||||
client = MemoryClient(api_key="your_api_key_here")
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Hi, my name is Alice."
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "Nice to meet you, Alice! What do you like to eat?"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
# Calling the add method to ingest messages into the memory system
|
||||
client.add(messages, user_id="alice")
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"memory": "Name is Alice",
|
||||
"event": "ADD",
|
||||
"id": "7ae113a3-3cb5-46e9-b6f7-486c36391847"
|
||||
},
|
||||
{
|
||||
"memory": "Likes large pizza with toppings including cherry tomatoes, black olives, green spinach, yellow bell peppers, diced ham, and sliced mushrooms",
|
||||
"event": "ADD",
|
||||
"id": "56545065-7dee-4acf-8bf2-a5b2535aabb3"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Image Integration Methods
|
||||
|
||||
Mem0 allows you to add images to user interactions through two primary methods: by providing an image URL or by using a Base64-encoded image. Below are examples demonstrating each approach.
|
||||
|
||||
## 1. Using an Image URL (Recommended)
|
||||
|
||||
You can include an image by passing its direct URL. This method is simple and efficient for online images.
|
||||
|
||||
```python
|
||||
# Define the image URL
|
||||
image_url = "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
|
||||
|
||||
# Create the message dictionary with the image URL
|
||||
image_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": image_url
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Using Base64 Image Encoding for Local Files
|
||||
|
||||
For local images or scenarios where embedding the image directly is preferable, you can use a Base64-encoded string.
|
||||
|
||||
```python
|
||||
import base64
|
||||
|
||||
# Path to the image file
|
||||
image_path = "path/to/your/image.jpg"
|
||||
|
||||
# Encode the image in Base64
|
||||
with open(image_path, "rb") as image_file:
|
||||
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
|
||||
|
||||
# Create the message dictionary with the Base64-encoded image
|
||||
image_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": f"data:image/jpeg;base64,{base64_image}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By utilizing these methods, you can effectively incorporate images into user interactions, enhancing the multimodal capabilities of your Mem0 instance.
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: OpenAI Compatibility
|
||||
icon: "code"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 can be easily integrated into chat applications to enhance conversational agents with structured memory. Mem0's APIs are designed to be compatible with OpenAI's, with the goal of making it easy to leverage Mem0 in applications you may have already built.
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Learn about the key features and capabilities that make Mem0 a powerful platform for memory management and retrieval.
|
||||
|
||||
## Core Features
|
||||
|
||||
<CardGroup>
|
||||
<Card title="Advanced Retrieval" icon="magnifying-glass" href="/features/advanced-retrieval">
|
||||
Superior search results using state-of-the-art algorithms, including keyword search, reranking, and filtering capabilities.
|
||||
</Card>
|
||||
<Card title="Multimodal Support" icon="photo-film" href="/features/multimodal-support">
|
||||
Process and analyze various types of content including images.
|
||||
</Card>
|
||||
<Card title="Memory Customization" icon="filter" href="/features/selective-memory">
|
||||
Customize and curate stored memories to focus on relevant information while excluding unnecessary data, enabling improved accuracy, privacy control, and resource efficiency.
|
||||
</Card>
|
||||
<Card title="Custom Categories" icon="tags" href="/features/custom-categories">
|
||||
Create and manage custom categories to organize memories based on your specific needs and requirements.
|
||||
</Card>
|
||||
<Card title="Custom Instructions" icon="list-check" href="/features/custom-instructions">
|
||||
Define specific guidelines for your project to ensure consistent handling of information and requirements.
|
||||
</Card>
|
||||
<Card title="Direct Import" icon="message-bot" href="/features/direct-import">
|
||||
Tailor the behavior of your Mem0 instance with custom prompts for specific use cases or domains.
|
||||
</Card>
|
||||
<Card title="Async Client" icon="bolt" href="/features/async-client">
|
||||
Asynchronous client for non-blocking operations and high concurrency applications.
|
||||
</Card>
|
||||
<Card title="Memory Export" icon="file-export" href="/features/memory-export">
|
||||
Export memories in structured formats using customizable Pydantic schemas.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Getting Help
|
||||
|
||||
If you have any questions about these features or need assistance, our team is here to help:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Memory Customization
|
||||
description: 'Mem0 supports customizing the memories you store, allowing you to focus on pertinent information while omitting irrelevant data.'
|
||||
icon: "filter"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Benefits of Memory Customization
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
---
|
||||
title: Webhooks
|
||||
description: 'Configure and manage webhooks to receive real-time notifications about memory events'
|
||||
icon: "webhook"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Webhooks allow you to receive real-time notifications when memory events occur in your Mem0 project. Webhooks are configured at the project level, meaning each webhook is associated with a specific project and will only receive events from that project. You can configure webhooks to send HTTP POST requests to your specified URLs whenever memories are created, updated, or deleted.
|
||||
|
||||
## Managing Webhooks
|
||||
|
||||
### Create Webhook
|
||||
|
||||
Create a new webhook for your project. The webhook will only receive events from the specified project:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="your-api-key")
|
||||
|
||||
# Create webhook in a specific project
|
||||
webhook = client.create_webhook(
|
||||
url="https://your-app.com/webhook",
|
||||
name="Memory Logger",
|
||||
project_id="proj_123",
|
||||
event_types=["memory:add"]
|
||||
)
|
||||
print(webhook)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
const { MemoryClient } = require('mem0ai');
|
||||
const client = new MemoryClient('your-api-key');
|
||||
|
||||
// Create webhook in a specific project
|
||||
const webhook = await client.createWebhook({
|
||||
url: "https://your-app.com/webhook",
|
||||
name: "Memory Logger",
|
||||
projectId: "proj_123",
|
||||
eventTypes: ["memory:add"]
|
||||
});
|
||||
console.log(webhook);
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"webhook_id": "wh_123",
|
||||
"name": "Memory Logger",
|
||||
"url": "https://your-app.com/webhook",
|
||||
"event_types": ["memory_add"],
|
||||
"project": "default-project",
|
||||
"is_active": true,
|
||||
"created_at": "2025-02-18T22:59:56.804993-08:00",
|
||||
"updated_at": "2025-02-18T23:06:41.479361-08:00"
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Get Webhooks
|
||||
|
||||
Retrieve all webhooks configured for your project:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# Get webhooks for a specific project
|
||||
webhooks = client.get_webhooks(project_id="proj_123")
|
||||
print(webhooks)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// Get webhooks for a specific project
|
||||
const webhooks = await client.getWebhooks({projectId: "proj_123"});
|
||||
console.log(webhooks);
|
||||
```
|
||||
|
||||
```json Output
|
||||
[
|
||||
{
|
||||
"webhook_id": "wh_123",
|
||||
"url": "https://mem0.ai",
|
||||
"name": "mem0",
|
||||
"owner": "john",
|
||||
"event_types": ["memory_add"],
|
||||
"project": "default-project",
|
||||
"is_active": true,
|
||||
"created_at": "2025-02-18T22:59:56.804993-08:00",
|
||||
"updated_at": "2025-02-18T23:06:41.479361-08:00"
|
||||
}
|
||||
]
|
||||
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Update Webhook
|
||||
|
||||
Modify an existing webhook's configuration. Remember that webhooks can only be updated within their associated project:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# Update webhook for a specific project
|
||||
updated_webhook = client.update_webhook(
|
||||
name="Updated Logger",
|
||||
url="https://your-app.com/new-webhook",
|
||||
event_types=["memory:update", "memory:add"],
|
||||
project_id="proj_123",
|
||||
webhook_id="wh_123"
|
||||
)
|
||||
print(updated_webhook)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// Update webhook for a specific project
|
||||
const updatedWebhook = await client.updateWebhook({
|
||||
name: "Updated Logger",
|
||||
url: "https://your-app.com/new-webhook",
|
||||
eventTypes: ["memory:update", "memory:add"],
|
||||
projectId: "proj_123",
|
||||
webhookId: "wh_123"
|
||||
});
|
||||
console.log(updatedWebhook);
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"message": "Webhook updated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Delete Webhook
|
||||
|
||||
Remove a webhook configuration from a project:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# Delete webhook from a specific project
|
||||
response = client.delete_webhook(webhook_id="wh_123", project_id="proj_123")
|
||||
print(response)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// Delete webhook from a specific project
|
||||
const response = await client.deleteWebhook("wh_123", "proj_123");
|
||||
console.log(response);
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"message": "Webhook deleted successfully"
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Event Types
|
||||
|
||||
Mem0 supports the following event types for webhooks:
|
||||
|
||||
- `memory:add`: Triggered when a new memory is added.
|
||||
- `memory:update`: Triggered when an existing memory is updated.
|
||||
- `memory:delete`: Triggered when a memory is deleted.
|
||||
|
||||
## Webhook Payload
|
||||
|
||||
When a memory event occurs in your project, Mem0 sends a POST request to your webhook URL with the following example payload structure:
|
||||
|
||||
```json
|
||||
{
|
||||
"event_details": {
|
||||
"id": "a1b2c3d4-e5f6-4g7h-8i9j-k0l1m2n3o4p5",
|
||||
"data": {
|
||||
"memory": "Name is Alex"
|
||||
},
|
||||
"event": "ADD"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Implement Retry Logic**: Your webhook endpoint should be able to handle temporary failures and implement appropriate retry mechanisms.
|
||||
|
||||
2. **Verify Webhook Source**: Implement security measures to verify that webhook requests are coming from Mem0.
|
||||
|
||||
3. **Process Events Asynchronously**: Handle webhook events asynchronously to prevent timeouts and ensure reliable processing.
|
||||
|
||||
4. **Monitor Webhook Health**: Regularly check your webhook logs to ensure proper functionality and handle any delivery failures.
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -5,7 +5,7 @@ title: Vercel AI SDK
|
||||
The [**Mem0 AI SDK Provider**](https://www.npmjs.com/package/@mem0/vercel-ai-provider) is a library developed by **Mem0** to integrate with the Vercel AI SDK. This library brings enhanced AI interaction capabilities to your applications by introducing persistent memory functionality.
|
||||
|
||||
<Note type="info">
|
||||
🎉 Exciting news! Mem0 AI SDK now supports **OpenAI**, **Anthropic**, **Cohere**, and **Groq** providers.
|
||||
🎉 Exciting news! Mem0 AI SDK now supports <strong>Tools Call</strong>.
|
||||
</Note>
|
||||
|
||||
## Overview
|
||||
@@ -43,11 +43,19 @@ npm install @mem0/vercel-ai-provider
|
||||
config: {
|
||||
compatibility: "strict",
|
||||
},
|
||||
// Optional Mem0 Global Config
|
||||
mem0Config: {
|
||||
user_id: "mem0-user-id",
|
||||
org_id: "mem0-org-id",
|
||||
project_id: "mem0-project-id",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
> **Note**: The `openai` provider is set as default. Consider using `MEM0_API_KEY` and `OPENAI_API_KEY` as environment variables for security.
|
||||
|
||||
> **Note**: The `mem0Config` is optional. It is used to set the global config for the Mem0 Client (eg. `user_id`, `agent_id`, `app_id`, `run_id`, `org_id`, `project_id` etc).
|
||||
|
||||
3. Add Memories to Enhance Context:
|
||||
|
||||
```typescript
|
||||
@@ -145,6 +153,44 @@ npm install @mem0/vercel-ai-provider
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Generate Responses with Tools Call
|
||||
|
||||
```typescript
|
||||
import { generateText } from "ai";
|
||||
import { createMem0 } from "@mem0/vercel-ai-provider";
|
||||
import { z } from "zod";
|
||||
|
||||
const mem0 = createMem0({
|
||||
provider: "anthropic",
|
||||
apiKey: "anthropic-api-key",
|
||||
mem0Config: {
|
||||
// Global User ID
|
||||
user_id: "borat"
|
||||
}
|
||||
});
|
||||
|
||||
const prompt = "What the temperature in the city that I live in?"
|
||||
|
||||
const result = await generateText({
|
||||
model: mem0('claude-3-5-sonnet-20240620'),
|
||||
tools: {
|
||||
weather: tool({
|
||||
description: 'Get the weather in a location',
|
||||
parameters: z.object({
|
||||
location: z.string().describe('The location to get the weather for'),
|
||||
}),
|
||||
execute: async ({ location }) => ({
|
||||
location,
|
||||
temperature: 72 + Math.floor(Math.random() * 21) - 10,
|
||||
}),
|
||||
}),
|
||||
},
|
||||
prompt: prompt,
|
||||
});
|
||||
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
- `createMem0()`: Initializes a new Mem0 provider instance.
|
||||
|
||||
-262
@@ -1,262 +0,0 @@
|
||||
{
|
||||
"$schema": "https://mintlify.com/schema.json",
|
||||
"name": "Mem0.ai",
|
||||
"favicon": "/logo/favicon.png",
|
||||
"colors": {
|
||||
"primary": "#6c60f0",
|
||||
"light": "#E6FFA2",
|
||||
"dark": "#a3df02",
|
||||
"background": {
|
||||
"dark": "#0f1117",
|
||||
"light": "#fff"
|
||||
}
|
||||
},
|
||||
"logo": {
|
||||
"dark": "/logo/dark.svg",
|
||||
"light": "/logo/light.svg",
|
||||
"href": "https://github.com/mem0ai/mem0"
|
||||
},
|
||||
"topbarCtaButton": {
|
||||
"name": "Your Dashboard",
|
||||
"url": "https://app.mem0.ai"
|
||||
},
|
||||
"anchors": [
|
||||
{
|
||||
"name": "Your Dashboard",
|
||||
"icon": "chart-simple",
|
||||
"url": "https://app.mem0.ai"
|
||||
},
|
||||
{
|
||||
"name": "API Reference",
|
||||
"url": "api-reference",
|
||||
"icon": "square-terminal"
|
||||
},
|
||||
{
|
||||
"name": "Discord",
|
||||
"icon": "discord",
|
||||
"url": "https://mem0.dev/DiD"
|
||||
},
|
||||
{
|
||||
"name": "GitHub",
|
||||
"icon": "github",
|
||||
"url": "https://github.com/mem0ai/mem0"
|
||||
},
|
||||
{
|
||||
"name": "Support",
|
||||
"icon": "envelope",
|
||||
"url": "mailto:taranjeet@mem0.ai"
|
||||
}
|
||||
],
|
||||
"tabs": [{
|
||||
"name": "Documentation",
|
||||
"url": "content"
|
||||
},
|
||||
{
|
||||
"name": "Examples",
|
||||
"url": "examples"
|
||||
},
|
||||
{
|
||||
"name": "Integrations",
|
||||
"url": "integrations"
|
||||
}],
|
||||
"navigation": [
|
||||
{
|
||||
"group": "Get Started",
|
||||
"pages": [
|
||||
"overview",
|
||||
"quickstart",
|
||||
"faqs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Platform",
|
||||
"pages": [
|
||||
"platform/overview",
|
||||
"platform/quickstart",
|
||||
{
|
||||
"group": "Features",
|
||||
"pages": ["features/advanced-retrieval", "features/selective-memory", "features/custom-categories", "features/custom-instructions", "features/direct-import", "features/async-client", "features/memory-export"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Open Source",
|
||||
"pages": [
|
||||
"open-source/quickstart",
|
||||
{
|
||||
"group": "Graph Memory",
|
||||
"pages": ["open-source/graph_memory/overview", "open-source/graph_memory/features"]
|
||||
},
|
||||
{
|
||||
"group": "LLMs",
|
||||
"pages": [
|
||||
"components/llms/overview",
|
||||
"components/llms/config",
|
||||
{
|
||||
"group": "Supported LLMs",
|
||||
"pages": [
|
||||
"components/llms/models/openai",
|
||||
"components/llms/models/anthropic",
|
||||
"components/llms/models/azure_openai",
|
||||
"components/llms/models/ollama",
|
||||
"components/llms/models/together",
|
||||
"components/llms/models/groq",
|
||||
"components/llms/models/litellm",
|
||||
"components/llms/models/mistral_AI",
|
||||
"components/llms/models/google_AI",
|
||||
"components/llms/models/aws_bedrock",
|
||||
"components/llms/models/gemini"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Vector Databases",
|
||||
"pages": [
|
||||
"components/vectordbs/overview",
|
||||
"components/vectordbs/config",
|
||||
{
|
||||
"group": "Supported Vector Databases",
|
||||
"pages": [
|
||||
"components/vectordbs/dbs/qdrant",
|
||||
"components/vectordbs/dbs/chroma",
|
||||
"components/vectordbs/dbs/pgvector",
|
||||
"components/vectordbs/dbs/milvus",
|
||||
"components/vectordbs/dbs/azure_ai_search",
|
||||
"components/vectordbs/dbs/redis",
|
||||
"components/vectordbs/dbs/elasticsearch"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Embedding Models",
|
||||
"pages": [
|
||||
"components/embedders/overview",
|
||||
"components/embedders/config",
|
||||
{
|
||||
"group": "Supported Embedding Models",
|
||||
"pages": [
|
||||
"components/embedders/models/openai",
|
||||
"components/embedders/models/azure_openai",
|
||||
"components/embedders/models/ollama",
|
||||
"components/embedders/models/huggingface",
|
||||
"components/embedders/models/vertexai",
|
||||
"components/embedders/models/gemini"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Features",
|
||||
"pages": ["features/openai_compatibility", "features/custom-prompts"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "API Reference",
|
||||
"pages": [
|
||||
"api-reference/overview",
|
||||
{
|
||||
"group": "Memory APIs",
|
||||
"pages": [
|
||||
"api-reference/memory/v1-get-memories",
|
||||
"api-reference/memory/v2-get-memories",
|
||||
"api-reference/memory/add-memories",
|
||||
"api-reference/memory/delete-memories",
|
||||
"api-reference/memory/get-memory",
|
||||
"api-reference/memory/update-memory",
|
||||
"api-reference/memory/delete-memory",
|
||||
"api-reference/memory/v1-search-memories",
|
||||
"api-reference/memory/v2-search-memories",
|
||||
"api-reference/memory/history-memory",
|
||||
"api-reference/memory/batch-update",
|
||||
"api-reference/memory/batch-delete",
|
||||
"api-reference/memory/create-memory-export",
|
||||
"api-reference/memory/get-memory-export"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Entities APIs",
|
||||
"pages": [
|
||||
"api-reference/entities/get-users",
|
||||
"api-reference/entities/delete-user"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Organizations APIs",
|
||||
"pages": [
|
||||
"api-reference/organization/get-orgs",
|
||||
"api-reference/organization/get-org",
|
||||
"api-reference/organization/create-org",
|
||||
"api-reference/organization/delete-org",
|
||||
{
|
||||
"group": "Members APIs",
|
||||
"pages": [
|
||||
"api-reference/organization/get-org-members",
|
||||
"api-reference/organization/add-org-member",
|
||||
"api-reference/organization/update-org-member",
|
||||
"api-reference/organization/delete-org-member"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Projects APIs",
|
||||
"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",
|
||||
{
|
||||
"group": "Members APIs",
|
||||
"pages":[
|
||||
"api-reference/project/get-project-members",
|
||||
"api-reference/project/add-project-member",
|
||||
"api-reference/project/update-project-member",
|
||||
"api-reference/project/delete-project-member"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Integrations",
|
||||
"pages": [
|
||||
"integrations/overview",
|
||||
"integrations/vercel-ai-sdk",
|
||||
"integrations/crewai",
|
||||
"integrations/autogen",
|
||||
"integrations/langchain",
|
||||
"integrations/langgraph",
|
||||
"integrations/llama-index",
|
||||
"integrations/langchain-tools"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "💡 Examples",
|
||||
"pages": [
|
||||
"examples/overview",
|
||||
"examples/mem0-with-ollama",
|
||||
"examples/personal-ai-tutor",
|
||||
"examples/customer-support-agent",
|
||||
"examples/personal-travel-assistant",
|
||||
"examples/llama-index-mem0"
|
||||
]
|
||||
}
|
||||
],
|
||||
"footerSocials": {
|
||||
"discord": "https://mem0.dev/DiD",
|
||||
"x": "https://x.com/mem0ai",
|
||||
"github": "https://github.com/mem0ai",
|
||||
"linkedin": "https://www.linkedin.com/company/mem0/"
|
||||
},
|
||||
"analytics": {
|
||||
"posthog": {
|
||||
"apiKey": "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX",
|
||||
"apiHost": "https://mango.mem0.ai"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Features
|
||||
description: 'Graph Memory features'
|
||||
icon: "list-check"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Graph Memory is a powerful feature that allows users to create and utilize complex relationships between pieces of information.
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Overview
|
||||
description: 'Enhance your memory system with graph-based knowledge representation and retrieval'
|
||||
icon: "database"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 now supports **Graph Memory**.
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: Multimodal Support
|
||||
icon: "image"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 extends its capabilities beyond text by supporting multimodal data, including images. Users can seamlessly integrate images into their interactions, allowing Mem0 to extract pertinent information from visual content and enrich the memory system.
|
||||
|
||||
## How It Works
|
||||
|
||||
When a user provides an image, Mem0 processes the image to extract textual information and relevant details, which are then added to the user's memory. This feature enhances the system's ability to understand and remember details based on visual inputs.
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
from mem0 import Memory
|
||||
|
||||
client = Memory()
|
||||
|
||||
messages = [
|
||||
{
|
||||
"role": "user",
|
||||
"content": "Hi, my name is Alice."
|
||||
},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": "Nice to meet you, Alice! What do you like to eat?"
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
# Calling the add method to ingest messages into the memory system
|
||||
client.add(messages, user_id="alice")
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"memory": "Name is Alice",
|
||||
"event": "ADD",
|
||||
"id": "7ae113a3-3cb5-46e9-b6f7-486c36391847"
|
||||
},
|
||||
{
|
||||
"memory": "Likes large pizza with toppings including cherry tomatoes, black olives, green spinach, yellow bell peppers, diced ham, and sliced mushrooms",
|
||||
"event": "ADD",
|
||||
"id": "56545065-7dee-4acf-8bf2-a5b2535aabb3"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Image Integration Methods
|
||||
|
||||
Mem0 allows you to add images to user interactions through two primary methods: by providing an image URL or by using a Base64-encoded image. Below are examples demonstrating each approach.
|
||||
|
||||
## 1. Using an Image URL (Recommended)
|
||||
|
||||
You can include an image by passing its direct URL. This method is simple and efficient for online images.
|
||||
|
||||
```python
|
||||
# Define the image URL
|
||||
image_url = "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
|
||||
|
||||
# Create the message dictionary with the image URL
|
||||
image_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": image_url
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 2. Using Base64 Image Encoding for Local Files
|
||||
|
||||
For local images or scenarios where embedding the image directly is preferable, you can use a Base64-encoded string.
|
||||
|
||||
```python
|
||||
import base64
|
||||
|
||||
# Path to the image file
|
||||
image_path = "path/to/your/image.jpg"
|
||||
|
||||
# Encode the image in Base64
|
||||
with open(image_path, "rb") as image_file:
|
||||
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
|
||||
|
||||
# Create the message dictionary with the Base64-encoded image
|
||||
image_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": f"data:image/jpeg;base64,{base64_image}"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
By utilizing these methods, you can effectively incorporate images into user interactions, enhancing the multimodal capabilities of your Mem0 instance.
|
||||
|
||||
<Note>
|
||||
Currently, we support only OpenAI models for image description.
|
||||
</Note>
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Guide
|
||||
description: 'Get started with Mem0 quickly!'
|
||||
icon: "book"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
> Welcome to the Mem0 quickstart guide. This guide will help you get up and running with Mem0 in no time.
|
||||
|
||||
+18
-12
@@ -4276,18 +4276,24 @@
|
||||
},
|
||||
"nullable": true
|
||||
},
|
||||
"org_id": {
|
||||
"description": "The unique identifier of the organization associated with this memory.",
|
||||
"title": "Organization id",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"project_id": {
|
||||
"description": "The unique identifier of the project associated with this memory.",
|
||||
"title": "Project id",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
"custom_instructions": {
|
||||
"description": "Defines project-specific guidelines for handling and organizing memories. When set at the project level, they apply to all new memories in that project.",
|
||||
"title": "Custom instructions",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"org_id": {
|
||||
"description": "The unique identifier of the organization associated with this memory.",
|
||||
"title": "Organization id",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"project_id": {
|
||||
"description": "The unique identifier of the project associated with this memory.",
|
||||
"title": "Project id",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"MemorySearchInput": {
|
||||
|
||||
+18
-45
@@ -1,60 +1,34 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
<Note type="info">
|
||||
🎉 Exciting news! We have added support for [DeepSeek](/components/llms/models/deepseek).
|
||||
🔔 New Feature: [Webhooks](/features/webhook) are now available! Configure real-time notifications for memory events in your Mem0 project.
|
||||
</Note>
|
||||
|
||||
[Mem0](https://mem0.dev/wd) (pronounced "mem-zero") enhances AI assistants and agents with an intelligent memory layer, enabling personalized AI interactions. Mem0 remembers user preferences and traits and continuously updates over time, making it ideal for applications like customer support chatbots and AI assistants.
|
||||
# Introduction
|
||||
|
||||
## Understanding Mem0
|
||||
[Mem0](https://mem0.dev/wd) (pronounced "mem-zero") enhances AI assistants by giving them persistent, contextual memory. AI systems using Mem0 actively learn from and adapt to user interactions over time.
|
||||
|
||||
Mem0, described as "_The Memory Layer for your AI Agents_," leverages advanced LLMs and algorithms to detect, store, and retrieve memories from conversations and interactions. It identifies key information such as facts, user preferences, and other contextual information, smartly updates memories over time by resolving contradictions, and supports the development of an AI Agent that evolves with the user interactions. When needed, Mem0 employs a smart search system to find memories, ranking them based on relevance, importance, and recency to ensure only the most useful information is presented.
|
||||
Mem0's memory layer combines LLMs with vector based storage. LLMs extract and process key information from conversations, while the vector storage enables efficient semantic search and retrieval of memories. This architecture helps AI agents connect past interactions with current context for more relevant responses.
|
||||
|
||||
Mem0 provides multiple endpoints through which users can interact with their memories. The two main endpoints are `add` and `search`. The `add` endpoint lets users ingest their conversations into Mem0, storing them as memories. The `search` endpoint handles retrieval, allowing users to query their set of stored memories.
|
||||
## Key Features
|
||||
|
||||
### ADD Memories
|
||||
- **Memory Processing**: Uses LLMs to automatically extract and store important information from conversations while maintaining full context
|
||||
- **Memory Management**: Continuously updates and resolves contradictions in stored information to maintain accuracy
|
||||
- **Dual Storage Architecture**: Combines vector database for memory storage and graph database for relationship tracking
|
||||
- **Smart Retrieval System**: Employs semantic search and graph queries to find relevant memories based on importance and recency
|
||||
- **Simple API Integration**: Provides easy-to-use endpoints for adding (`add`) and retrieving (`search`) memories
|
||||
|
||||
<Frame caption="Architecture diagram illustrating the process of adding memories.">
|
||||
<img src="images/add_architecture.png" />
|
||||
</Frame>
|
||||
## Use Cases
|
||||
|
||||
When a user has a conversation, Mem0 uses an LLM to understand and extract important information. This model is designed to capture detailed information while maintaining the full context of the conversation.
|
||||
Here's how the process works:
|
||||
|
||||
1. First, the LLM extracts two key elements:
|
||||
* Relevant memories
|
||||
* Important entities and their relationships
|
||||
2. The system then compares this new information with existing data to identify contradictions, if present.
|
||||
3. A second LLM evaluates the new information and decides whether to:
|
||||
* Add it as new data
|
||||
* Update existing information
|
||||
* Delete outdated information
|
||||
4. These changes are automatically made to two databases:
|
||||
* A vector database (for storing memories)
|
||||
* A graph database (for storing relationships)
|
||||
|
||||
This entire process happens continuously with each user interaction, ensuring that the system always maintains an up-to-date understanding of the user's information.
|
||||
|
||||
### SEARCH Memories
|
||||
|
||||
<Frame caption="Architecture diagram illustrating the memory search process.">
|
||||
<img src="images/search_architecture.png" />
|
||||
</Frame>
|
||||
|
||||
When a user asks Mem0 a question, the system uses smart memory lookup to find relevant information. Here's how it works:
|
||||
|
||||
1. The user submits a question to Mem0
|
||||
2. The LLM processes this question in two ways:
|
||||
* It rewrites the question to search the vector database better
|
||||
* It identifies important entities and their relationships from the question
|
||||
3. The system then performs two parallel searches:
|
||||
* It searches the vector database using the rewritten question and semantic search
|
||||
* It searches the graph database using the identified entities and relationships using graph queries
|
||||
4. Finally, Mem0 combines the results from both databases to provide a complete answer to the user's question
|
||||
|
||||
This approach ensures that Mem0 can find and return all relevant information, whether it's stored as memories in the vector database or as relationships in the graph database.
|
||||
- **Customer Support Chatbots**: Create support agents that remember customer history, preferences, and past interactions to provide personalized assistance
|
||||
- **Personal AI Tutors**: Build educational assistants that track student progress, adapt to learning patterns, and provide contextual help
|
||||
- **Healthcare Applications**: Develop healthcare assistants that maintain patient history and provide personalized care recommendations
|
||||
- **Enterprise Knowledge Management**: Power systems that learn from organizational interactions and maintain institutional knowledge
|
||||
- **Personalized AI Assistants**: Create assistants that learn user preferences and adapt their responses over time
|
||||
|
||||
## Getting Started
|
||||
Mem0 offers two powerful ways to leverage our technology: our [managed platform](/platform/overview) and our [open source solution](/open-source/quickstart).
|
||||
@@ -72,7 +46,6 @@ Mem0 offers two powerful ways to leverage our technology: our [managed platform]
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
|
||||
## Need help?
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Introduction
|
||||
description: 'Empower your AI applications with long-term memory and personalization'
|
||||
icon: "eye"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Welcome to Mem0 Platform
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Guide
|
||||
description: 'Get started with Mem0 Platform in minutes'
|
||||
icon: "book"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
<Note type="info">
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
---
|
||||
title: Quickstart
|
||||
icon: "bolt"
|
||||
iconType: "solid"
|
||||
---
|
||||
Mem0 offers two powerful ways to leverage our technology: [our managed platform](#mem0-platform-managed-solution) and [our open source solution](#mem0-open-source).
|
||||
|
||||
|
||||
@@ -3,12 +3,12 @@ import { Card } from "@/components/ui/card";
|
||||
import { ScrollArea } from "@radix-ui/react-scroll-area";
|
||||
import { Memory } from "../types";
|
||||
import GlobalContext from "@/contexts/GlobalContext";
|
||||
import { useContext, useEffect, useState } from "react";
|
||||
import { useContext } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const MemoryItem = ({ memory, index }: { memory: Memory; index: number }) => {
|
||||
const MemoryItem = ({ memory }: { memory: Memory; index: number }) => {
|
||||
return (
|
||||
<motion.div
|
||||
layout
|
||||
@@ -39,14 +39,6 @@ const MemoryItem = ({ memory, index }: { memory: Memory; index: number }) => {
|
||||
const Memories = (props: { isMemoriesExpanded: boolean }) => {
|
||||
const { isMemoriesExpanded } = props;
|
||||
const { memories } = useContext(GlobalContext);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const [prevMemories, setPrevMemories] = useState<Memory[]>([]);
|
||||
|
||||
// Track memory positions for animation
|
||||
useEffect(() => {
|
||||
setPrevMemories(memories);
|
||||
}, [memories]);
|
||||
|
||||
return (
|
||||
<Card
|
||||
|
||||
+143
-7
@@ -96,16 +96,21 @@ class MemoryClient:
|
||||
try:
|
||||
params = self._prepare_params()
|
||||
response = self.client.get("/v1/ping/", params=params)
|
||||
data = response.json()
|
||||
|
||||
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")
|
||||
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")
|
||||
except httpx.HTTPStatusError as e:
|
||||
try:
|
||||
error_data = e.response.json()
|
||||
error_message = error_data.get("detail", str(e))
|
||||
except:
|
||||
error_message = str(e)
|
||||
raise ValueError(f"Error: {error_message}")
|
||||
|
||||
@api_error_handler
|
||||
def add(self, messages: Union[str, List[Dict[str, str]]], **kwargs) -> Dict[str, Any]:
|
||||
@@ -519,6 +524,97 @@ class MemoryClient:
|
||||
"""
|
||||
raise NotImplementedError("Chat is not implemented yet")
|
||||
|
||||
@api_error_handler
|
||||
def get_webhooks(self, project_id: str) -> Dict[str, Any]:
|
||||
"""Get webhooks configuration for the project.
|
||||
|
||||
Args:
|
||||
project_id: The ID of the project to get webhooks for.
|
||||
|
||||
Returns:
|
||||
Dictionary containing webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValueError: If project_id is not set.
|
||||
"""
|
||||
|
||||
response = self.client.get(f"api/v1/webhooks/{project_id}/webhook/")
|
||||
response.raise_for_status()
|
||||
capture_client_event("client.get_webhook", self)
|
||||
return response.json()
|
||||
|
||||
@api_error_handler
|
||||
def create_webhook(self, url: str, name: str, project_id: str, event_types: List[str]) -> Dict[str, Any]:
|
||||
"""Create a webhook for the current project.
|
||||
|
||||
Args:
|
||||
url: The URL to send the webhook to.
|
||||
name: The name of the webhook.
|
||||
event_types: List of event types to trigger the webhook for.
|
||||
|
||||
Returns:
|
||||
Dictionary containing the created webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValueError: If project_id is not set.
|
||||
"""
|
||||
|
||||
payload = {"url": url, "name": name, "event_types": event_types}
|
||||
response = self.client.post(f"api/v1/webhooks/{project_id}/webhook/", json=payload)
|
||||
response.raise_for_status()
|
||||
capture_client_event("client.create_webhook", self)
|
||||
return response.json()
|
||||
|
||||
@api_error_handler
|
||||
def update_webhook(
|
||||
self, webhook_id: int, project_id: str, name: Optional[str] = None, url: Optional[str] = None, event_types: Optional[List[str]] = None
|
||||
) -> Dict[str, Any]:
|
||||
"""Update a webhook configuration.
|
||||
|
||||
Args:
|
||||
webhook_id: ID of the webhook to update
|
||||
project_id: The ID of the project to update the webhook for.
|
||||
name: Optional new name for the webhook
|
||||
url: Optional new URL for the webhook
|
||||
event_types: Optional list of event types to trigger the webhook for.
|
||||
|
||||
Returns:
|
||||
Dictionary containing the updated webhook details.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValueError: If project_id is not set.
|
||||
"""
|
||||
|
||||
payload = {k: v for k, v in {"name": name, "url": url, "event_types": event_types}.items() if v is not None}
|
||||
response = self.client.put(f"api/v1/webhooks/{project_id}/webhook/{webhook_id}/", json=payload)
|
||||
response.raise_for_status()
|
||||
capture_client_event("client.update_webhook", self, {"webhook_id": webhook_id})
|
||||
return response.json()
|
||||
|
||||
@api_error_handler
|
||||
def delete_webhook(self, webhook_id: int, project_id: str) -> Dict[str, str]:
|
||||
"""Delete a webhook configuration.
|
||||
|
||||
Args:
|
||||
webhook_id: ID of the webhook to delete
|
||||
project_id: The ID of the project to delete the webhook for.
|
||||
|
||||
Returns:
|
||||
Dictionary containing success message.
|
||||
|
||||
Raises:
|
||||
APIError: If the API request fails.
|
||||
ValueError: If project_id is not set.
|
||||
"""
|
||||
|
||||
response = self.client.delete(f"api/v1/webhooks/{project_id}/webhook/{webhook_id}/")
|
||||
response.raise_for_status()
|
||||
capture_client_event("client.delete_webhook", self, {"webhook_id": webhook_id})
|
||||
return response.json()
|
||||
|
||||
def _prepare_payload(
|
||||
self, messages: Union[str, List[Dict[str, str]], None], kwargs: Dict[str, Any]
|
||||
) -> Dict[str, Any]:
|
||||
@@ -862,3 +958,43 @@ class AsyncMemoryClient:
|
||||
|
||||
async def chat(self):
|
||||
raise NotImplementedError("Chat is not implemented yet")
|
||||
|
||||
@api_error_handler
|
||||
async def get_webhooks(self, project_id: str) -> Dict[str, Any]:
|
||||
|
||||
response = await self.async_client.get(
|
||||
f"api/v1/webhooks/{project_id}/webhook/",
|
||||
)
|
||||
response.raise_for_status()
|
||||
capture_client_event("async_client.get_webhook", self.sync_client)
|
||||
return response.json()
|
||||
|
||||
@api_error_handler
|
||||
async def create_webhook(self, url: str, name: str, project_id: str, event_types: List[str]) -> Dict[str, Any]:
|
||||
|
||||
payload = {"url": url, "name": name, "event_types": event_types}
|
||||
response = await self.async_client.post(
|
||||
f"api/v1/webhooks/{project_id}/webhook/", json=payload
|
||||
)
|
||||
response.raise_for_status()
|
||||
capture_client_event("async_client.create_webhook", self.sync_client)
|
||||
return response.json()
|
||||
|
||||
@api_error_handler
|
||||
async def update_webhook(
|
||||
self, webhook_id: int,project_id: str, name: Optional[str] = None, url: Optional[str] = None, event_types: Optional[List[str]] = None
|
||||
) -> Dict[str, Any]:
|
||||
|
||||
payload = {k: v for k, v in {"name": name, "url": url, "event_types": event_types}.items() if v is not None}
|
||||
response = await self.async_client.put(f"api/v1/webhooks/{project_id}/webhook/{webhook_id}/", json=payload)
|
||||
response.raise_for_status()
|
||||
capture_client_event("async_client.update_webhook", self.sync_client, {"webhook_id": webhook_id})
|
||||
return response.json()
|
||||
|
||||
@api_error_handler
|
||||
async def delete_webhook(self, webhook_id: int, project_id: str) -> Dict[str, str]:
|
||||
|
||||
response = await self.async_client.delete(f"api/v1/webhooks/{project_id}/webhook/{webhook_id}/")
|
||||
response.raise_for_status()
|
||||
capture_client_event("async_client.delete_webhook", self.sync_client, {"webhook_id": webhook_id})
|
||||
return response.json()
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
|
||||
class OpenSearchConfig(BaseModel):
|
||||
collection_name: str = Field("mem0", description="Name of the index")
|
||||
host: str = Field("localhost", description="OpenSearch host")
|
||||
port: int = Field(9200, description="OpenSearch port")
|
||||
user: Optional[str] = Field(None, description="Username for authentication")
|
||||
password: Optional[str] = Field(None, description="Password for authentication")
|
||||
api_key: Optional[str] = Field(None, description="API key for authentication (if applicable)")
|
||||
embedding_model_dims: int = Field(1536, description="Dimension of the embedding vector")
|
||||
verify_certs: bool = Field(False, description="Verify SSL certificates (default False for OpenSearch)")
|
||||
use_ssl: bool = Field(False, description="Use SSL for connection (default False for OpenSearch)")
|
||||
auto_create_index: bool = Field(True, description="Automatically create index during initialization")
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def validate_auth(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
||||
# Check if host is provided
|
||||
if not values.get("host"):
|
||||
raise ValueError("Host must be provided for OpenSearch")
|
||||
|
||||
# Authentication: Either API key or user/password must be provided
|
||||
if not any([values.get("api_key"), (values.get("user") and values.get("password"))]):
|
||||
raise ValueError("Either api_key or user/password must be provided for OpenSearch authentication")
|
||||
|
||||
return values
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def validate_extra_fields(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
||||
allowed_fields = set(cls.model_fields.keys())
|
||||
input_fields = set(values.keys())
|
||||
extra_fields = input_fields - allowed_fields
|
||||
if extra_fields:
|
||||
raise ValueError(
|
||||
f"Extra fields not allowed: {', '.join(extra_fields)}. "
|
||||
f"Allowed fields: {', '.join(allowed_fields)}"
|
||||
)
|
||||
return values
|
||||
+2
-1
@@ -63,6 +63,7 @@ class OpenAILLM(LLMBase):
|
||||
response_format=None,
|
||||
tools: Optional[List[Dict]] = None,
|
||||
tool_choice: str = "auto",
|
||||
max_tokens: int = 100,
|
||||
):
|
||||
"""
|
||||
Generate a response based on the given messages using OpenAI.
|
||||
@@ -80,7 +81,7 @@ class OpenAILLM(LLMBase):
|
||||
"model": self.config.model,
|
||||
"messages": messages,
|
||||
"temperature": self.config.temperature,
|
||||
"max_tokens": self.config.max_tokens,
|
||||
"max_tokens": max_tokens,
|
||||
"top_p": self.config.top_p,
|
||||
}
|
||||
|
||||
|
||||
+8
-3
@@ -9,7 +9,7 @@ from typing import Any, Dict
|
||||
|
||||
import pytz
|
||||
from pydantic import ValidationError
|
||||
|
||||
from mem0.memory.utils import parse_vision_messages
|
||||
from mem0.configs.base import MemoryConfig, MemoryItem
|
||||
from mem0.configs.prompts import get_update_memory_messages
|
||||
from mem0.memory.base import MemoryBase
|
||||
@@ -114,6 +114,8 @@ class Memory(MemoryBase):
|
||||
if isinstance(messages, str):
|
||||
messages = [{"role": "user", "content": messages}]
|
||||
|
||||
messages = parse_vision_messages(messages)
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
future1 = executor.submit(self._add_to_vector_store, messages, metadata, filters)
|
||||
future2 = executor.submit(self._add_to_graph, messages, filters)
|
||||
@@ -143,7 +145,7 @@ class Memory(MemoryBase):
|
||||
|
||||
if self.custom_prompt:
|
||||
system_prompt = self.custom_prompt
|
||||
user_prompt = f"Input: {parsed_messages}"
|
||||
user_prompt = f"Input:\n{parsed_messages}"
|
||||
else:
|
||||
system_prompt, user_prompt = get_fact_retrieval_messages(parsed_messages)
|
||||
|
||||
@@ -174,7 +176,10 @@ class Memory(MemoryBase):
|
||||
)
|
||||
for mem in existing_memories:
|
||||
retrieved_old_memory.append({"id": mem.id, "text": mem.payload["data"]})
|
||||
|
||||
unique_data = {}
|
||||
for item in retrieved_old_memory:
|
||||
unique_data[item['id']] = item
|
||||
retrieved_old_memory = list(unique_data.values())
|
||||
logging.info(f"Total existing memories: {len(retrieved_old_memory)}")
|
||||
|
||||
# mapping UUIDs with integers for handling UUID hallucinations
|
||||
|
||||
+44
-2
@@ -1,10 +1,10 @@
|
||||
import re
|
||||
|
||||
from mem0.configs.prompts import FACT_RETRIEVAL_PROMPT
|
||||
from mem0.llms.openai import OpenAILLM
|
||||
|
||||
|
||||
def get_fact_retrieval_messages(message):
|
||||
return FACT_RETRIEVAL_PROMPT, f"Input: {message}"
|
||||
return FACT_RETRIEVAL_PROMPT, f"Input:\n{message}"
|
||||
|
||||
|
||||
def parse_messages(messages):
|
||||
@@ -43,3 +43,45 @@ def remove_code_blocks(content: str) -> str:
|
||||
pattern = r"^```[a-zA-Z0-9]*\n([\s\S]*?)\n```$"
|
||||
match = re.match(pattern, content.strip())
|
||||
return match.group(1).strip() if match else content.strip()
|
||||
|
||||
|
||||
def get_image_description(image_url):
|
||||
"""
|
||||
Get the description of the image
|
||||
"""
|
||||
llm = OpenAILLM()
|
||||
response = llm.generate_response(
|
||||
messages=[
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{"type": "text", "text": "Provide a description of the image and do not include any additional text."},
|
||||
{"type": "image_url", "image_url": {"url": image_url}}
|
||||
],
|
||||
},
|
||||
],
|
||||
max_tokens=100,
|
||||
)
|
||||
return response
|
||||
|
||||
|
||||
def parse_vision_messages(messages):
|
||||
"""
|
||||
Parse the vision messages from the messages
|
||||
"""
|
||||
returned_messages = []
|
||||
for msg in messages:
|
||||
if msg["role"] != "system":
|
||||
if not isinstance(msg["content"], str) and msg["content"]["type"] == "image_url":
|
||||
image_url = msg["content"]["image_url"]["url"]
|
||||
try:
|
||||
description = get_image_description(image_url)
|
||||
msg["content"]["text"] = description
|
||||
returned_messages.append({"role": msg["role"], "content": description})
|
||||
except Exception:
|
||||
raise Exception(f"Error while downloading {image_url}.")
|
||||
else:
|
||||
returned_messages.append(msg)
|
||||
else:
|
||||
returned_messages.append(msg)
|
||||
return returned_messages
|
||||
|
||||
@@ -68,6 +68,7 @@ class VectorStoreFactory:
|
||||
"azure_ai_search": "mem0.vector_stores.azure_ai_search.AzureAISearch",
|
||||
"redis": "mem0.vector_stores.redis.RedisDB",
|
||||
"elasticsearch": "mem0.vector_stores.elasticsearch.ElasticsearchDB",
|
||||
"opensearch": "mem0.vector_stores.opensearch.OpenSearchDB"
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -18,6 +18,7 @@ class VectorStoreConfig(BaseModel):
|
||||
"azure_ai_search": "AzureAISearchConfig",
|
||||
"redis": "RedisDBConfig",
|
||||
"elasticsearch": "ElasticsearchConfig",
|
||||
"opensearch": "OpenSearchConfig",
|
||||
}
|
||||
|
||||
@model_validator(mode="after")
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
import logging
|
||||
from typing import Any, Dict, List, Optional
|
||||
|
||||
try:
|
||||
from opensearchpy import OpenSearch
|
||||
from opensearchpy.helpers import bulk
|
||||
except ImportError:
|
||||
raise ImportError("OpenSearch requires extra dependencies. Install with `pip install opensearch-py`") from None
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from mem0.configs.vector_stores.opensearch import OpenSearchConfig
|
||||
from mem0.vector_stores.base import VectorStoreBase
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OutputData(BaseModel):
|
||||
id: str
|
||||
score: float
|
||||
payload: Dict
|
||||
|
||||
|
||||
class OpenSearchDB(VectorStoreBase):
|
||||
def __init__(self, **kwargs):
|
||||
config = OpenSearchConfig(**kwargs)
|
||||
|
||||
# Initialize OpenSearch client
|
||||
self.client = OpenSearch(
|
||||
hosts=[{"host": config.host, "port": config.port or 9200}],
|
||||
http_auth=(config.user, config.password) if (config.user and config.password) else None,
|
||||
use_ssl=config.use_ssl,
|
||||
verify_certs=config.verify_certs,
|
||||
)
|
||||
|
||||
self.collection_name = config.collection_name
|
||||
self.vector_dim = config.embedding_model_dims
|
||||
|
||||
# Create index only if auto_create_index is True
|
||||
if config.auto_create_index:
|
||||
self.create_index()
|
||||
|
||||
def create_index(self) -> None:
|
||||
"""Create OpenSearch index with proper mappings if it doesn't exist."""
|
||||
index_settings = {
|
||||
# ToDo change replicas to 1
|
||||
"settings": {
|
||||
"index": {"number_of_replicas": 1, "number_of_shards": 5, "refresh_interval": "1s", "knn": True}
|
||||
},
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"text": {"type": "text"},
|
||||
"vector": {
|
||||
"type": "knn_vector",
|
||||
"dimension": self.vector_dim
|
||||
},
|
||||
"metadata": {"type": "object", "properties": {"user_id": {"type": "keyword"}}},
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if not self.client.indices.exists(index=self.collection_name):
|
||||
self.client.indices.create(index=self.collection_name, body=index_settings)
|
||||
logger.info(f"Created index {self.collection_name}")
|
||||
else:
|
||||
logger.info(f"Index {self.collection_name} already exists")
|
||||
|
||||
def create_col(self, name: str, vector_size: int) -> None:
|
||||
"""Create a new collection (index in OpenSearch)."""
|
||||
index_settings = {
|
||||
"mappings": {
|
||||
"properties": {
|
||||
"vector": {
|
||||
"type": "knn_vector",
|
||||
"dimension": vector_size,
|
||||
"method": { "engine": "lucene", "name": "hnsw", "space_type": "cosinesimil"},
|
||||
},
|
||||
"payload": {"type": "object"},
|
||||
"id": {"type": "keyword"},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if not self.client.indices.exists(index=name):
|
||||
self.client.indices.create(index=name, body=index_settings)
|
||||
logger.info(f"Created index {name}")
|
||||
|
||||
def insert(
|
||||
self, vectors: List[List[float]], payloads: Optional[List[Dict]] = None, ids: Optional[List[str]] = None
|
||||
) -> List[OutputData]:
|
||||
"""Insert vectors into the index."""
|
||||
if not ids:
|
||||
ids = [str(i) for i in range(len(vectors))]
|
||||
|
||||
if payloads is None:
|
||||
payloads = [{} for _ in range(len(vectors))]
|
||||
|
||||
actions = []
|
||||
for i, (vec, id_) in enumerate(zip(vectors, ids)):
|
||||
action = {
|
||||
"_index": self.collection_name,
|
||||
"_id": id_,
|
||||
"_source": {
|
||||
"vector": vec,
|
||||
"metadata": payloads[i], # Store metadata in the metadata field
|
||||
},
|
||||
}
|
||||
actions.append(action)
|
||||
|
||||
bulk(self.client, actions)
|
||||
|
||||
results = []
|
||||
for i, id_ in enumerate(ids):
|
||||
results.append(OutputData(id=id_, score=1.0, 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 OpenSearch k-NN search with pre-filtering."""
|
||||
search_query = {
|
||||
"size": limit,
|
||||
"query": {
|
||||
"knn": {
|
||||
"vector": {
|
||||
"vector": query,
|
||||
"k": limit,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if filters:
|
||||
filter_conditions = [{"term": {f"metadata.{key}": value}} for key, value in filters.items()]
|
||||
search_query["query"]["knn"]["vector"]["filter"] = { "bool": {"filter": filter_conditions} }
|
||||
|
||||
response = self.client.search(index=self.collection_name, body=search_query)
|
||||
|
||||
results = [
|
||||
OutputData(id=hit["_id"], score=hit["_score"], payload=hit["_source"].get("metadata", {}))
|
||||
for hit in response["hits"]["hits"]
|
||||
]
|
||||
return results
|
||||
|
||||
def delete(self, vector_id: str) -> None:
|
||||
"""Delete a vector by ID."""
|
||||
self.client.delete(index=self.collection_name, id=vector_id)
|
||||
|
||||
def update(self, vector_id: str, vector: Optional[List[float]] = None, payload: Optional[Dict] = None) -> None:
|
||||
"""Update a vector and its payload."""
|
||||
doc = {}
|
||||
if vector is not None:
|
||||
doc["vector"] = vector
|
||||
if payload is not None:
|
||||
doc["metadata"] = payload
|
||||
|
||||
self.client.update(index=self.collection_name, id=vector_id, body={"doc": doc})
|
||||
|
||||
def get(self, vector_id: str) -> Optional[OutputData]:
|
||||
"""Retrieve a vector by ID."""
|
||||
try:
|
||||
response = self.client.get(index=self.collection_name, id=vector_id)
|
||||
return OutputData(id=response["_id"], score=1.0, payload=response["_source"].get("metadata", {}))
|
||||
except Exception as e:
|
||||
logger.error(f"Error retrieving vector {vector_id}: {e}")
|
||||
return None
|
||||
|
||||
def list_cols(self) -> List[str]:
|
||||
"""List all collections (indices)."""
|
||||
return list(self.client.indices.get_alias().keys())
|
||||
|
||||
def delete_col(self) -> None:
|
||||
"""Delete a collection (index)."""
|
||||
self.client.indices.delete(index=self.collection_name)
|
||||
|
||||
def col_info(self, name: str) -> Any:
|
||||
"""Get information about a collection (index)."""
|
||||
return self.client.indices.get(index=name)
|
||||
|
||||
def list(self, filters: Optional[Dict] = None, limit: Optional[int] = None) -> List[List[OutputData]]:
|
||||
"""List all memories."""
|
||||
query = {"query": {"match_all": {}}}
|
||||
|
||||
if filters:
|
||||
query["query"] = {"bool": {"must": [{"term": {f"metadata.{key}": value}} for key, value in filters.items()]}}
|
||||
|
||||
if limit:
|
||||
query["size"] = limit
|
||||
|
||||
response = self.client.search(index=self.collection_name, body=query)
|
||||
return [[OutputData(id=hit["_id"], score=1.0, payload=hit["_source"].get("metadata", {})) for hit in response["hits"]["hits"]]]
|
||||
Generated
+649
-419
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "mem0ai"
|
||||
version = "0.1.50"
|
||||
version = "0.1.53"
|
||||
description = "Long-term memory for AI Agents"
|
||||
authors = ["Mem0 <founders@mem0.ai>"]
|
||||
exclude = [
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
import os
|
||||
import unittest
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import dotenv
|
||||
|
||||
try:
|
||||
from opensearchpy import OpenSearch
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
"OpenSearch requires extra dependencies. Install with `pip install opensearch-py`"
|
||||
) from None
|
||||
|
||||
from mem0.vector_stores.opensearch import OpenSearchDB
|
||||
|
||||
|
||||
class TestOpenSearchDB(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
dotenv.load_dotenv()
|
||||
cls.original_env = {
|
||||
'OS_URL': os.getenv('OS_URL', 'http://localhost:9200'),
|
||||
'OS_USERNAME': os.getenv('OS_USERNAME', 'test_user'),
|
||||
'OS_PASSWORD': os.getenv('OS_PASSWORD', 'test_password')
|
||||
}
|
||||
os.environ['OS_URL'] = 'http://localhost'
|
||||
os.environ['OS_USERNAME'] = 'test_user'
|
||||
os.environ['OS_PASSWORD'] = 'test_password'
|
||||
|
||||
def setUp(self):
|
||||
self.client_mock = MagicMock(spec=OpenSearch)
|
||||
self.client_mock.indices = MagicMock()
|
||||
self.client_mock.indices.exists = MagicMock(return_value=False)
|
||||
self.client_mock.indices.create = MagicMock()
|
||||
self.client_mock.indices.delete = MagicMock()
|
||||
self.client_mock.indices.get_alias = MagicMock()
|
||||
self.client_mock.get = MagicMock()
|
||||
self.client_mock.update = MagicMock()
|
||||
self.client_mock.delete = MagicMock()
|
||||
self.client_mock.search = MagicMock()
|
||||
|
||||
patcher = patch('mem0.vector_stores.opensearch.OpenSearch', return_value=self.client_mock)
|
||||
self.mock_os = patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
|
||||
self.os_db = OpenSearchDB(
|
||||
host=os.getenv('OS_URL'),
|
||||
port=9200,
|
||||
collection_name="test_collection",
|
||||
embedding_model_dims=1536,
|
||||
user=os.getenv('OS_USERNAME'),
|
||||
password=os.getenv('OS_PASSWORD'),
|
||||
verify_certs=False,
|
||||
use_ssl=False,
|
||||
auto_create_index=False
|
||||
)
|
||||
self.client_mock.reset_mock()
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
for key, value in cls.original_env.items():
|
||||
if value is not None:
|
||||
os.environ[key] = value
|
||||
else:
|
||||
os.environ.pop(key, None)
|
||||
|
||||
def tearDown(self):
|
||||
self.client_mock.reset_mock()
|
||||
|
||||
def test_create_index(self):
|
||||
self.client_mock.indices.exists.return_value = False
|
||||
self.os_db.create_index()
|
||||
self.client_mock.indices.create.assert_called_once()
|
||||
create_args = self.client_mock.indices.create.call_args[1]
|
||||
self.assertEqual(create_args["index"], "test_collection")
|
||||
mappings = create_args["body"]["mappings"]["properties"]
|
||||
self.assertEqual(mappings["vector"]["type"], "knn_vector")
|
||||
self.assertEqual(mappings["vector"]["dimension"], 1536)
|
||||
self.client_mock.reset_mock()
|
||||
self.client_mock.indices.exists.return_value = True
|
||||
self.os_db.create_index()
|
||||
self.client_mock.indices.create.assert_not_called()
|
||||
|
||||
def test_insert(self):
|
||||
vectors = [[0.1] * 1536, [0.2] * 1536]
|
||||
payloads = [{"key1": "value1"}, {"key2": "value2"}]
|
||||
ids = ["id1", "id2"]
|
||||
with patch('mem0.vector_stores.opensearch.bulk') as mock_bulk:
|
||||
mock_bulk.return_value = (2, [])
|
||||
results = self.os_db.insert(vectors=vectors, payloads=payloads, ids=ids)
|
||||
mock_bulk.assert_called_once()
|
||||
actions = mock_bulk.call_args[0][1]
|
||||
self.assertEqual(actions[0]["_index"], "test_collection")
|
||||
self.assertEqual(actions[0]["_id"], "id1")
|
||||
self.assertEqual(actions[0]["_source"]["vector"], vectors[0])
|
||||
self.assertEqual(actions[0]["_source"]["metadata"], payloads[0])
|
||||
self.assertEqual(len(results), 2)
|
||||
self.assertEqual(results[0].id, "id1")
|
||||
self.assertEqual(results[0].payload, payloads[0])
|
||||
|
||||
def test_get(self):
|
||||
mock_response = {"_id": "id1", "_source": {"metadata": {"key1": "value1"}}}
|
||||
self.client_mock.get.return_value = mock_response
|
||||
result = self.os_db.get("id1")
|
||||
self.client_mock.get.assert_called_once_with(index="test_collection", id="id1")
|
||||
self.assertIsNotNone(result)
|
||||
self.assertEqual(result.id, "id1")
|
||||
self.assertEqual(result.payload, {"key1": "value1"})
|
||||
|
||||
def test_update(self):
|
||||
vector = [0.3] * 1536
|
||||
payload = {"key3": "value3"}
|
||||
self.os_db.update("id1", vector=vector, payload=payload)
|
||||
self.client_mock.update.assert_called_once()
|
||||
update_args = self.client_mock.update.call_args[1]
|
||||
self.assertEqual(update_args["index"], "test_collection")
|
||||
self.assertEqual(update_args["id"], "id1")
|
||||
self.assertEqual(update_args["body"], {"doc": {"vector": vector, "metadata": payload}})
|
||||
|
||||
def test_list_cols(self):
|
||||
self.client_mock.indices.get_alias.return_value = {"test_collection": {}}
|
||||
result = self.os_db.list_cols()
|
||||
self.client_mock.indices.get_alias.assert_called_once()
|
||||
self.assertEqual(result, ["test_collection"])
|
||||
|
||||
def test_search(self):
|
||||
mock_response = {"hits": {"hits": [{"_id": "id1", "_score": 0.8, "_source": {"vector": [0.1] * 1536, "metadata": {"key1": "value1"}}}]}}
|
||||
self.client_mock.search.return_value = mock_response
|
||||
query_vector = [0.1] * 1536
|
||||
results = self.os_db.search(query=query_vector, limit=5)
|
||||
self.client_mock.search.assert_called_once()
|
||||
search_args = self.client_mock.search.call_args[1]
|
||||
self.assertEqual(search_args["index"], "test_collection")
|
||||
body = search_args["body"]
|
||||
self.assertIn("knn", body["query"])
|
||||
self.assertIn("vector", body["query"]["knn"])
|
||||
self.assertEqual(body["query"]["knn"]["vector"]["vector"], query_vector)
|
||||
self.assertEqual(body["query"]["knn"]["vector"]["k"], 5)
|
||||
self.assertEqual(len(results), 1)
|
||||
self.assertEqual(results[0].id, "id1")
|
||||
self.assertEqual(results[0].score, 0.8)
|
||||
self.assertEqual(results[0].payload, {"key1": "value1"})
|
||||
|
||||
def test_delete(self):
|
||||
self.os_db.delete(vector_id="id1")
|
||||
self.client_mock.delete.assert_called_once_with(index="test_collection", id="id1")
|
||||
|
||||
def test_delete_col(self):
|
||||
self.os_db.delete_col()
|
||||
self.client_mock.indices.delete.assert_called_once_with(index="test_collection")
|
||||
Reference in New Issue
Block a user