Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6e65730b0e | ||
|
|
8452dd598f | ||
|
|
2556c5fe88 | ||
|
|
a4340b2336 | ||
|
|
f4dc5f6c71 | ||
|
|
32ebdaef2f | ||
|
|
4318663697 | ||
|
|
5606c3ffb8 | ||
|
|
c1aba35884 | ||
|
|
d9b48191de |
@@ -52,7 +52,7 @@ jobs:
|
||||
virtualenvs-in-project: true
|
||||
- name: Load cached venv
|
||||
id: cached-poetry-dependencies
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .venv
|
||||
key: venv-mem0-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
virtualenvs-in-project: true
|
||||
- name: Load cached venv
|
||||
id: cached-poetry-dependencies
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: .venv
|
||||
key: venv-embedchain-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
|
||||
|
||||
@@ -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 opensearch-py
|
||||
google-generativeai elasticsearch opensearch-py vecs
|
||||
|
||||
# Format code with ruff
|
||||
format:
|
||||
|
||||
@@ -8,16 +8,18 @@ Config in mem0 is a dictionary that specifies the settings for your embedding mo
|
||||
|
||||
## How to define configurations?
|
||||
|
||||
The config is defined as a Python dictionary with two main keys:
|
||||
The config is defined as an object (or 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
|
||||
- `config`: A nested object or dictionary containing provider-specific settings
|
||||
|
||||
|
||||
## How to use configurations?
|
||||
|
||||
Here's a general example of how to use the config with mem0:
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -36,6 +38,25 @@ m = Memory.from_config(config)
|
||||
m.add("Your text here", user_id="user", metadata={"category": "example"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
embedder: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: process.env.OPENAI_API_KEY || '',
|
||||
model: 'text-embedding-3-small',
|
||||
// Provider-specific settings go here
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Your text here", { userId: "user", metadata: { category: "example" } });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
@@ -47,21 +68,31 @@ Config is essential for:
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different embedders:
|
||||
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `model` | Embedding model to use |
|
||||
| `api_key` | API key of the provider |
|
||||
| `embedding_dims` | Dimensions of the embedding model |
|
||||
| `http_client_proxies` | Allow proxy server settings |
|
||||
| `ollama_base_url` | Base URL for the Ollama embedding model |
|
||||
| `model_kwargs` | Key-Value arguments for the Huggingface embedding model |
|
||||
| `azure_kwargs` | Key-Value arguments for the AzureOpenAI embedding model |
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
| Parameter | Description | Provider |
|
||||
|-----------|-------------|----------|
|
||||
| `model` | Embedding model to use | All |
|
||||
| `api_key` | API key of the provider | All |
|
||||
| `embedding_dims` | Dimensions of the embedding model | All |
|
||||
| `http_client_proxies` | Allow proxy server settings | All |
|
||||
| `ollama_base_url` | Base URL for the Ollama embedding model | Ollama |
|
||||
| `model_kwargs` | Key-Value arguments for the Huggingface embedding model | Huggingface |
|
||||
| `azure_kwargs` | Key-Value arguments for the AzureOpenAI embedding model | Azure OpenAI |
|
||||
| `openai_base_url` | Base URL for OpenAI API | OpenAI |
|
||||
| `vertex_credentials_json` | Path to the Google Cloud credentials JSON file for VertexAI | VertexAI |
|
||||
| `memory_add_embedding_type` | The type of embedding to use for the add memory action | VertexAI |
|
||||
| `memory_update_embedding_type` | The type of embedding to use for the update memory action | VertexAI |
|
||||
| `memory_search_embedding_type` | The type of embedding to use for the search memory action | VertexAI |
|
||||
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Provider |
|
||||
|-----------|-------------|----------|
|
||||
| `model` | Embedding model to use | All |
|
||||
| `apiKey` | API key of the provider | All |
|
||||
| `embeddingDims` | Dimensions of the embedding model | All |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Supported Embedding Models
|
||||
|
||||
|
||||
@@ -37,7 +37,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -23,7 +23,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -22,7 +22,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -18,7 +18,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -6,7 +6,8 @@ To use OpenAI embedding models, set the `OPENAI_API_KEY` environment variable. Y
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -22,15 +23,50 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="john")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
embedder: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: 'your-openai-api-key',
|
||||
model: 'text-embedding-3-large',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("I'm visiting Paris", { userId: "john" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring OpenAI embedder:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `text-embedding-3-small` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `api_key` | The OpenAI API key | `None` |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `text-embedding-3-small` |
|
||||
| `embeddingDims` | Dimensions of the embedding model | `1536` |
|
||||
| `apiKey` | The OpenAI API key | `None` |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -25,7 +25,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -25,7 +25,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("I'm visiting Paris", user_id="john")
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="john")
|
||||
```
|
||||
The embedding types can be one of the following:
|
||||
- SEMANTIC_SIMILARITY
|
||||
|
||||
@@ -10,6 +10,10 @@ Mem0 offers support for various embedding models, allowing users to choose the o
|
||||
|
||||
See the list of supported embedders below.
|
||||
|
||||
<Note>
|
||||
The following embedders are supported in the Python implementation. The TypeScript implementation currently only supports OpenAI.
|
||||
</Note>
|
||||
|
||||
<CardGroup cols={4}>
|
||||
<Card title="OpenAI" href="/components/embedders/models/openai"></Card>
|
||||
<Card title="Azure OpenAI" href="/components/embedders/models/azure_openai"></Card>
|
||||
|
||||
@@ -6,26 +6,40 @@ iconType: "solid"
|
||||
|
||||
## How to define configurations?
|
||||
|
||||
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
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
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
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
The `config` is defined as a TypeScript object with these keys:
|
||||
- `llm`: Specifies the LLM provider and its configuration (required)
|
||||
- `provider`: The name of the LLM (e.g., "openai", "groq")
|
||||
- `config`: A nested object containing provider-specific settings
|
||||
- `embedder`: Specifies the embedder provider and its configuration (optional)
|
||||
- `vectorStore`: Specifies the vector store provider and its configuration (optional)
|
||||
- `historyDbPath`: Path to the history database file (optional)
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Config Values Precedence
|
||||
|
||||
Config values are applied in the following order of precedence (from highest to lowest):
|
||||
|
||||
1. Values explicitly set in the `config` dictionary
|
||||
1. Values explicitly set in the `config` object/dictionary
|
||||
2. Environment variables (e.g., `OPENAI_API_KEY`, `OPENAI_API_BASE`)
|
||||
3. Default values defined in the LLM implementation
|
||||
|
||||
This means that values specified in the `config` dictionary will override corresponding environment variables, which in turn override default values.
|
||||
This means that values specified in the `config` will override corresponding environment variables, which in turn override default values.
|
||||
|
||||
## How to Use Config
|
||||
|
||||
Here's a general example of how to use the config with mem0:
|
||||
Here's a general example of how to use the config with Mem0:
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -44,39 +58,70 @@ m = Memory.from_config(config)
|
||||
m.add("Your text here", user_id="user", metadata={"category": "example"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
// Minimal configuration with just the LLM settings
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'your_chosen_provider',
|
||||
config: {
|
||||
// Provider-specific settings go here
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Your text here", { userId: "user123", metadata: { category: "example" } });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
1. Specifying which llm to use.
|
||||
1. Specifying which LLM to use.
|
||||
2. Providing necessary connection details (e.g., model, api_key, temperature).
|
||||
3. Ensuring proper initialization and connection to your chosen llm.
|
||||
3. Ensuring proper initialization and connection to your chosen LLM.
|
||||
|
||||
## Master List of All Params in Config
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different llms:
|
||||
Here's a comprehensive list of all parameters that can be used across different LLMs:
|
||||
|
||||
Here's the table based on the provided parameters:
|
||||
|
||||
| Parameter | Description | Provider |
|
||||
|----------------------|-----------------------------------------------|-------------------|
|
||||
| `model` | Embedding model to use | All |
|
||||
| `temperature` | Temperature of the model | All |
|
||||
| `api_key` | API key to use | All |
|
||||
| `max_tokens` | Tokens to generate | All |
|
||||
| `top_p` | Probability threshold for nucleus sampling | All |
|
||||
| `top_k` | Number of highest probability tokens to keep | All |
|
||||
| `http_client_proxies`| Allow proxy server settings | AzureOpenAI |
|
||||
| `models` | List of models | Openrouter |
|
||||
| `route` | Routing strategy | Openrouter |
|
||||
| `openrouter_base_url`| Base URL for Openrouter API | Openrouter |
|
||||
| `site_url` | Site URL | Openrouter |
|
||||
| `app_name` | Application name | Openrouter |
|
||||
| `ollama_base_url` | Base URL for Ollama API | Ollama |
|
||||
| `openai_base_url` | Base URL for OpenAI API | OpenAI |
|
||||
| `azure_kwargs` | Azure LLM args for initialization | AzureOpenAI |
|
||||
| `deepseek_base_url` | Base URL for DeepSeek API | DeepSeek |
|
||||
| `xai_base_url` | Base URL for XAI API | XAI |
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
| Parameter | Description | Provider |
|
||||
|----------------------|-----------------------------------------------|-------------------|
|
||||
| `model` | Embedding model to use | All |
|
||||
| `temperature` | Temperature of the model | All |
|
||||
| `api_key` | API key to use | All |
|
||||
| `max_tokens` | Tokens to generate | All |
|
||||
| `top_p` | Probability threshold for nucleus sampling | All |
|
||||
| `top_k` | Number of highest probability tokens to keep | All |
|
||||
| `http_client_proxies`| Allow proxy server settings | AzureOpenAI |
|
||||
| `models` | List of models | Openrouter |
|
||||
| `route` | Routing strategy | Openrouter |
|
||||
| `openrouter_base_url`| Base URL for Openrouter API | Openrouter |
|
||||
| `site_url` | Site URL | Openrouter |
|
||||
| `app_name` | Application name | Openrouter |
|
||||
| `ollama_base_url` | Base URL for Ollama API | Ollama |
|
||||
| `openai_base_url` | Base URL for OpenAI API | OpenAI |
|
||||
| `azure_kwargs` | Azure LLM args for initialization | AzureOpenAI |
|
||||
| `deepseek_base_url` | Base URL for DeepSeek API | DeepSeek |
|
||||
| `xai_base_url` | Base URL for XAI API | XAI |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Provider |
|
||||
|----------------------|-----------------------------------------------|-------------------|
|
||||
| `model` | Embedding model to use | All |
|
||||
| `temperature` | Temperature of the model | All |
|
||||
| `apiKey` | API key to use | All |
|
||||
| `maxTokens` | Tokens to generate | All |
|
||||
| `topP` | Probability threshold for nucleus sampling | All |
|
||||
| `topK` | Number of highest probability tokens to keep | All |
|
||||
| `openaiBaseUrl` | Base URL for OpenAI API | OpenAI |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Supported LLMs
|
||||
|
||||
For detailed information on configuring specific llms, please visit the [LLMs](./models) section. There you'll find information for each supported llm with provider-specific usage examples and configuration details.
|
||||
For detailed information on configuring specific LLMs, please visit the [LLMs](./models) section. There you'll find information for each supported LLM with provider-specific usage examples and configuration details.
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
---
|
||||
title: Anthropic
|
||||
---
|
||||
|
||||
To use anthropic's models, please set the `ANTHROPIC_API_KEY` which you find on their [Account Settings Page](https://console.anthropic.com/account/keys).
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -21,9 +26,41 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'anthropic',
|
||||
config: {
|
||||
apiKey: process.env.ANTHROPIC_API_KEY || '',
|
||||
model: 'claude-3-7-sonnet-latest',
|
||||
temperature: 0.1,
|
||||
maxTokens: 2000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
const messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
await memory.add(messages, { userId: "alice", metadata: { category: "movies" } });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `anthropic` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -30,7 +30,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -36,7 +36,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
We also support the new [OpenAI structured-outputs](https://platform.openai.com/docs/guides/structured-outputs/introduction) model.
|
||||
|
||||
@@ -26,7 +26,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
You can also configure the API base URL in the config:
|
||||
|
||||
@@ -25,7 +25,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
@@ -25,7 +25,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
---
|
||||
title: Groq
|
||||
---
|
||||
|
||||
[Groq](https://groq.com/) is the creator of the world's first Language Processing Unit (LPU), providing exceptional speed performance for AI workloads running on their LPU Inference Engine.
|
||||
|
||||
In order to use LLMs from Groq, go to their [platform](https://console.groq.com/keys) and get the API key. Set the API key as `GROQ_API_KEY` environment variable to use the model as given below in the example.
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -23,9 +28,41 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'groq',
|
||||
config: {
|
||||
apiKey: process.env.GROQ_API_KEY || '',
|
||||
model: 'mixtral-8x7b-32768',
|
||||
temperature: 0.1,
|
||||
maxTokens: 1000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
const messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
await memory.add(messages, { userId: "alice", metadata: { category: "movies" } });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `groq` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -20,7 +20,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
@@ -25,7 +25,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
@@ -20,7 +20,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
@@ -6,7 +6,8 @@ To use OpenAI LLM models, you have to set the `OPENAI_API_KEY` environment varia
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -35,9 +36,41 @@ config = {
|
||||
# }
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: process.env.OPENAI_API_KEY || '',
|
||||
model: 'gpt-4-turbo-preview',
|
||||
temperature: 0.2,
|
||||
maxTokens: 1500,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
const messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
await memory.add(messages, { userId: "alice", metadata: { category: "movies" } });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
We also support the new [OpenAI structured-outputs](https://platform.openai.com/docs/guides/structured-outputs/introduction) model.
|
||||
|
||||
```python
|
||||
@@ -59,7 +92,9 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
|
||||
<Note>
|
||||
OpenAI structured-outputs is currently only available in the Python implementation.
|
||||
</Note>
|
||||
|
||||
## Config
|
||||
|
||||
|
||||
@@ -21,7 +21,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
@@ -27,7 +27,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
@@ -14,20 +14,24 @@ For a comprehensive list of available parameters for llm configuration, please r
|
||||
|
||||
To view all supported llms, visit the [Supported LLMs](./models).
|
||||
|
||||
<Note>
|
||||
All LLMs are supported in Python. The following LLMs are also supported in TypeScript: **OpenAI**, **Anthropic**, and **Groq**.
|
||||
</Note>
|
||||
|
||||
<CardGroup cols={4}>
|
||||
<Card title="OpenAI" href="/components/llms/models/openai"></Card>
|
||||
<Card title="Ollama" href="/components/llms/models/ollama"></Card>
|
||||
<Card title="Azure OpenAI" href="/components/llms/models/azure_openai"></Card>
|
||||
<Card title="Anthropic" href="/components/llms/models/anthropic"></Card>
|
||||
<Card title="Together" href="/components/llms/models/together"></Card>
|
||||
<Card title="Groq" href="/components/llms/models/groq"></Card>
|
||||
<Card title="Litellm" href="/components/llms/models/litellm"></Card>
|
||||
<Card title="Mistral AI" href="/components/llms/models/mistral_ai"></Card>
|
||||
<Card title="Google AI" href="/components/llms/models/google_ai"></Card>
|
||||
<Card title="AWS bedrock" href="/components/llms/models/aws_bedrock"></Card>
|
||||
<Card title="Gemini" href="/components/llms/models/gemini"></Card>
|
||||
<Card title="DeepSeek" href="/components/llms/models/deepseek"></Card>
|
||||
<Card title="xAI" href="/components/llms/models/xAI"></Card>
|
||||
<Card title="OpenAI" href="/components/llms/models/openai" />
|
||||
<Card title="Ollama" href="/components/llms/models/ollama" />
|
||||
<Card title="Azure OpenAI" href="/components/llms/models/azure_openai" />
|
||||
<Card title="Anthropic" href="/components/llms/models/anthropic" />
|
||||
<Card title="Together" href="/components/llms/models/together" />
|
||||
<Card title="Groq" href="/components/llms/models/groq" />
|
||||
<Card title="Litellm" href="/components/llms/models/litellm" />
|
||||
<Card title="Mistral AI" href="/components/llms/models/mistral_ai" />
|
||||
<Card title="Google AI" href="/components/llms/models/google_ai" />
|
||||
<Card title="AWS bedrock" href="/components/llms/models/aws_bedrock" />
|
||||
<Card title="Gemini" href="/components/llms/models/gemini" />
|
||||
<Card title="DeepSeek" href="/components/llms/models/deepseek" />
|
||||
<Card title="xAI" href="/components/llms/models/xAI" />
|
||||
</CardGroup>
|
||||
|
||||
## Structured vs Unstructured Outputs
|
||||
|
||||
@@ -6,16 +6,17 @@ iconType: "solid"
|
||||
|
||||
## How to define configurations?
|
||||
|
||||
The `config` is defined as a Python dictionary with two main keys:
|
||||
The `config` is defined as an object 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
|
||||
- `provider`: The name of the vector database (e.g., "chroma", "pgvector", "qdrant", "milvus", "azure_ai_search")
|
||||
- `config`: A nested object containing provider-specific settings
|
||||
|
||||
## How to Use Config
|
||||
|
||||
Here's a general example of how to use the config with mem0:
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -34,6 +35,29 @@ m = Memory.from_config(config)
|
||||
m.add("Your text here", user_id="user", metadata={"category": "example"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
// Example for in-memory vector database (Only supported in TypeScript)
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const configMemory = {
|
||||
vector_store: {
|
||||
provider: 'memory',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
dimension: 1536,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(configMemory);
|
||||
await memory.add("Your text here", { userId: "user", metadata: { category: "example" } });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Note>
|
||||
The in-memory vector database is only supported in the TypeScript implementation.
|
||||
</Note>
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
@@ -46,6 +70,8 @@ Config is essential for:
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different vector databases:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `collection_name` | Name of the collection |
|
||||
@@ -60,6 +86,27 @@ Here's a comprehensive list of all parameters that can be used across different
|
||||
| `url` | Full URL for the server |
|
||||
| `api_key` | API key for the server |
|
||||
| `on_disk` | Enable persistent storage |
|
||||
| `connection_string` | PostgreSQL connection string (for Supabase/PGVector) |
|
||||
| `index_method` | Vector index method (for Supabase) |
|
||||
| `index_measure` | Distance measure for similarity search (for Supabase) |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description |
|
||||
|-----------|-------------|
|
||||
| `collectionName` | Name of the collection |
|
||||
| `embeddingModelDims` | Dimensions of the embedding model |
|
||||
| `dimension` | Dimensions of the embedding model (for memory provider) |
|
||||
| `host` | Host where the server is running |
|
||||
| `port` | Port where the server is running |
|
||||
| `url` | URL for the server |
|
||||
| `apiKey` | API key for the server |
|
||||
| `path` | Path for the database |
|
||||
| `onDisk` | Enable persistent storage |
|
||||
| `redisUrl` | URL for the Redis server |
|
||||
| `username` | Username for database connection |
|
||||
| `password` | Password for database connection |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Customizing Config
|
||||
|
||||
|
||||
@@ -22,7 +22,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -19,7 +19,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -29,7 +29,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -19,7 +19,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -29,7 +29,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -21,7 +21,13 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -20,13 +21,47 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
vectorStore: {
|
||||
provider: 'qdrant',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
embeddingModelDims: 1536,
|
||||
host: 'localhost',
|
||||
port: 6333,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
const messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
await memory.add(messages, { userId: "alice", metadata: { category: "movies" } });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Config
|
||||
|
||||
Let's see the available parameters for the `qdrant` config:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collection_name` | The name of the collection to store the vectors | `mem0` |
|
||||
@@ -37,4 +72,18 @@ Let's see the available parameters for the `qdrant` config:
|
||||
| `path` | Path for the qdrant database | `/tmp/qdrant` |
|
||||
| `url` | Full URL for the qdrant server | `None` |
|
||||
| `api_key` | API key for the qdrant server | `None` |
|
||||
| `on_disk` | For enabling persistent storage | `False` |
|
||||
| `on_disk` | For enabling persistent storage | `False` |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collectionName` | The name of the collection to store the vectors | `mem0` |
|
||||
| `embeddingModelDims` | Dimensions of the embedding model | `1536` |
|
||||
| `host` | The host where the Qdrant server is running | `None` |
|
||||
| `port` | The port where the Qdrant server is running | `None` |
|
||||
| `path` | Path for the Qdrant database | `/tmp/qdrant` |
|
||||
| `url` | Full URL for the Qdrant server | `None` |
|
||||
| `apiKey` | API key for the Qdrant server | `None` |
|
||||
| `onDisk` | For enabling persistent storage | `False` |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -12,7 +12,8 @@ docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:lat
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -31,15 +32,61 @@ config = {
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
vectorStore: {
|
||||
provider: 'redis',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
embeddingModelDims: 1536,
|
||||
redisUrl: 'redis://localhost:6379',
|
||||
username: 'your-redis-username',
|
||||
password: 'your-redis-password',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
const messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I’m not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
await memory.add(messages, { userId: "alice", metadata: { category: "movies" } });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Config
|
||||
|
||||
Let's see the available parameters for the `redis` config:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collection_name` | The name of the collection to store the vectors | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `redis_url` | The URL of the Redis server | `None` |
|
||||
| `redis_url` | The URL of the Redis server | `None` |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collectionName` | The name of the collection to store the vectors | `mem0` |
|
||||
| `embeddingModelDims` | Dimensions of the embedding model | `1536` |
|
||||
| `redisUrl` | The URL of the Redis server | `None` |
|
||||
| `username` | Username for Redis connection | `None` |
|
||||
| `password` | Password for Redis connection | `None` |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
@@ -0,0 +1,78 @@
|
||||
[Supabase](https://supabase.com/) is an open-source Firebase alternative that provides a PostgreSQL database with pgvector extension for vector similarity search. It offers a powerful and scalable solution for storing and querying vector embeddings.
|
||||
|
||||
Create a [Supabase](https://supabase.com/dashboard/projects) account and project, then get your connection string from Project Settings > Database. See the [docs](https://supabase.github.io/vecs/hosting/) for details.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "supabase",
|
||||
"config": {
|
||||
"connection_string": "postgresql://user:password@host:port/database",
|
||||
"collection_name": "memories",
|
||||
"index_method": "hnsw", # Optional: defaults to "auto"
|
||||
"index_measure": "cosine_distance" # Optional: defaults to "cosine_distance"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Supabase:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `connection_string` | PostgreSQL connection string (required) | None |
|
||||
| `collection_name` | Name for the vector collection | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `index_method` | Vector index method to use | `auto` |
|
||||
| `index_measure` | Distance measure for similarity search | `cosine_distance` |
|
||||
|
||||
### Index Methods
|
||||
|
||||
The following index methods are supported:
|
||||
|
||||
- `auto`: Automatically selects the best available index method
|
||||
- `hnsw`: Hierarchical Navigable Small World graph index (faster search, more memory usage)
|
||||
- `ivfflat`: Inverted File Flat index (good balance of speed and memory)
|
||||
|
||||
### Distance Measures
|
||||
|
||||
Available distance measures for similarity search:
|
||||
|
||||
- `cosine_distance`: Cosine similarity (recommended for most embedding models)
|
||||
- `l2_distance`: Euclidean distance
|
||||
- `l1_distance`: Manhattan distance
|
||||
- `max_inner_product`: Maximum inner product similarity
|
||||
|
||||
### Best Practices
|
||||
|
||||
1. **Index Method Selection**:
|
||||
- Use `hnsw` for fastest search performance when memory is not a constraint
|
||||
- Use `ivfflat` for a good balance of search speed and memory usage
|
||||
- Use `auto` if unsure, it will select the best method based on your data
|
||||
|
||||
2. **Distance Measure Selection**:
|
||||
- Use `cosine_distance` for most embedding models (OpenAI, Hugging Face, etc.)
|
||||
- Use `max_inner_product` if your vectors are normalized
|
||||
- Use `l2_distance` or `l1_distance` if working with raw feature vectors
|
||||
|
||||
3. **Connection String**:
|
||||
- Always use environment variables for sensitive information in the connection string
|
||||
- Format: `postgresql://user:password@host:port/database`
|
||||
@@ -10,6 +10,10 @@ Mem0 includes built-in support for various popular databases. Memory can utilize
|
||||
|
||||
See the list of supported vector databases below.
|
||||
|
||||
<Note>
|
||||
The following vector databases are supported in the Python implementation. The TypeScript implementation currently only supports Qdrant, Redis and in-memory vector database.
|
||||
</Note>
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Qdrant" href="/components/vectordbs/dbs/qdrant"></Card>
|
||||
<Card title="Chroma" href="/components/vectordbs/dbs/chroma"></Card>
|
||||
@@ -19,6 +23,7 @@ See the list of supported vector databases below.
|
||||
<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>
|
||||
<Card title="Supabase" href="/components/vectordbs/dbs/supabase"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
+3
-62
@@ -65,6 +65,7 @@
|
||||
"pages": [
|
||||
"open-source/quickstart",
|
||||
"open-source/python-quickstart",
|
||||
"open-source-typescript/quickstart",
|
||||
{
|
||||
"group": "Features",
|
||||
"icon": "wrench",
|
||||
@@ -127,7 +128,8 @@
|
||||
"components/vectordbs/dbs/azure_ai_search",
|
||||
"components/vectordbs/dbs/redis",
|
||||
"components/vectordbs/dbs/elasticsearch",
|
||||
"components/vectordbs/dbs/opensearch"
|
||||
"components/vectordbs/dbs/opensearch",
|
||||
"components/vectordbs/dbs/supabase"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -151,67 +153,6 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Node.js",
|
||||
"icon": "js",
|
||||
"pages": [
|
||||
"open-source-typescript/quickstart",
|
||||
{
|
||||
"group": "Features",
|
||||
"icon": "wrench",
|
||||
"pages": [
|
||||
"open-source-typescript/features/custom-prompts"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "LLMs",
|
||||
"icon": "brain",
|
||||
"pages": [
|
||||
"open-source-typescript/components/llms/overview",
|
||||
"open-source-typescript/components/llms/config",
|
||||
{
|
||||
"group": "Supported LLMs",
|
||||
"icon": "list",
|
||||
"pages": [
|
||||
"open-source-typescript/components/llms/models/openai",
|
||||
"open-source-typescript/components/llms/models/anthropic",
|
||||
"open-source-typescript/components/llms/models/groq"
|
||||
]
|
||||
}
|
||||
]
|
||||
},{
|
||||
"group": "Vector Databases",
|
||||
"icon": "database",
|
||||
"pages": [
|
||||
"open-source-typescript/components/vectordbs/overview",
|
||||
"open-source-typescript/components/vectordbs/config",
|
||||
{
|
||||
"group": "Supported Vector Databases",
|
||||
"icon": "server",
|
||||
"pages": [
|
||||
"open-source-typescript/components/vectordbs/dbs/qdrant",
|
||||
"open-source-typescript/components/vectordbs/dbs/redis"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Embedding Models",
|
||||
"icon": "layer-group",
|
||||
"pages": [
|
||||
"open-source-typescript/components/embedders/overview",
|
||||
"open-source-typescript/components/embedders/config",
|
||||
{
|
||||
"group": "Supported Embedding Models",
|
||||
"icon": "list",
|
||||
"pages": [
|
||||
"open-source-typescript/components/embedders/models/openai"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ const openaiClient = new OpenAI();
|
||||
const memory = new Memory();
|
||||
|
||||
async function chatWithMemories(message, userId = "default_user") {
|
||||
const relevantMemories = await memory.search(message, userId);
|
||||
const relevantMemories = await memory.search(message, { userId: userId });
|
||||
|
||||
const memoriesStr = relevantMemories.results
|
||||
.map(entry => `- ${entry.memory}`)
|
||||
@@ -52,7 +52,7 @@ ${memoriesStr}`;
|
||||
const assistantResponse = response.choices[0].message.content || "";
|
||||
|
||||
messages.push({ role: "assistant", content: assistantResponse });
|
||||
await memory.add(messages, userId);
|
||||
await memory.add(messages, { userId: userId });
|
||||
|
||||
return assistantResponse;
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@ To create an effective custom prompt:
|
||||
|
||||
Example of a custom prompt:
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
custom_prompt = """
|
||||
Please only extract entities containing customer support information, order details, and user information.
|
||||
Here are some few shot examples:
|
||||
@@ -39,12 +40,37 @@ Output: {{"facts" : ["Ordered red shirt, size medium", "Received blue shirt inst
|
||||
|
||||
Return the facts and customer information in a json format as shown above.
|
||||
"""
|
||||
|
||||
```
|
||||
|
||||
Here we initialize the custom prompt in the config.
|
||||
```typescript TypeScript
|
||||
const customPrompt = `
|
||||
Please only extract entities containing customer support information, order details, and user information.
|
||||
Here are some few shot examples:
|
||||
|
||||
```python
|
||||
Input: Hi.
|
||||
Output: {"facts" : []}
|
||||
|
||||
Input: The weather is nice today.
|
||||
Output: {"facts" : []}
|
||||
|
||||
Input: My order #12345 hasn't arrived yet.
|
||||
Output: {"facts" : ["Order #12345 not received"]}
|
||||
|
||||
Input: I am John Doe, and I would like to return the shoes I bought last week.
|
||||
Output: {"facts" : ["Customer name: John Doe", "Wants to return shoes", "Purchase made last week"]}
|
||||
|
||||
Input: I ordered a red shirt, size medium, but received a blue one instead.
|
||||
Output: {"facts" : ["Ordered red shirt, size medium", "Received blue shirt instead"]}
|
||||
|
||||
Return the facts and customer information in a json format as shown above.
|
||||
`;
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Here we initialize the custom prompt in the config:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
@@ -63,15 +89,40 @@ config = {
|
||||
m = Memory.from_config(config_dict=config, user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
version: 'v1.1',
|
||||
llm: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: process.env.OPENAI_API_KEY || '',
|
||||
model: 'gpt-4-turbo-preview',
|
||||
temperature: 0.2,
|
||||
maxTokens: 1500,
|
||||
},
|
||||
},
|
||||
customPrompt: customPrompt
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Example 1
|
||||
|
||||
In this example, we are adding a memory of a user ordering a laptop. As seen in the output, the custom prompt is used to extract the relevant information from the user's message.
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
```python Python
|
||||
m.add("Yesterday, I ordered a laptop, the order id is 12345", user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
await memory.add('Yesterday, I ordered a laptop, the order id is 12345', { userId: "user123" });
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
@@ -97,11 +148,16 @@ m.add("Yesterday, I ordered a laptop, the order id is 12345", user_id="alice")
|
||||
|
||||
In this example, we are adding a memory of a user liking to go on hikes. This add message is not specific to the use-case mentioned in the custom prompt.
|
||||
Hence, the memory is not added.
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
```python Python
|
||||
m.add("I like going to hikes", user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
await memory.add('I like going to hikes', { userId: "user123" });
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [],
|
||||
@@ -109,3 +165,5 @@ m.add("I like going to hikes", user_id="alice")
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The custom prompt will process both the user and assistant messages to extract relevant information according to the defined format.
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
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 configurations?
|
||||
|
||||
The config is defined as a TypeScript object 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 object containing provider-specific settings
|
||||
|
||||
## How to use configurations?
|
||||
|
||||
Here's a general example of how to use the config with Mem0:
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
embedder: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: 'your-openai-api-key',
|
||||
model: 'text-embedding-3-small',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Your text here", { userId: "user", metadata: { category: "example" } });
|
||||
```
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
1. Specifying which embedding model to use.
|
||||
2. Providing necessary connection details (e.g., model, api_key, embedding_dims).
|
||||
3. Ensuring proper initialization and connection to your chosen embedder.
|
||||
|
||||
## Master List of All Params in Config
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different embedders:
|
||||
|
||||
| Parameter | Description |
|
||||
|------------------------|--------------------------------------------------|
|
||||
| `model` | Embedding model to use |
|
||||
| `apiKey` | API key of the provider |
|
||||
| `embeddingDims` | Dimensions of the embedding model |
|
||||
|
||||
## Supported Embedding Models
|
||||
|
||||
For detailed information on configuring specific embedders, please visit the [Embedding Models](./models) section. There you'll find information for each supported embedder with provider-specific usage examples and configuration details.
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
title: OpenAI
|
||||
---
|
||||
|
||||
To use OpenAI embedding models, you need to provide the API key directly in your configuration. You can obtain the OpenAI API key from the [OpenAI Platform](https://platform.openai.com/account/api-keys).
|
||||
|
||||
### Usage
|
||||
|
||||
Here's how to configure OpenAI embedding models in your application:
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
embedder: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: 'your-openai-api-key',
|
||||
model: 'text-embedding-3-large',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("I'm visiting Paris", { userId: "john" });
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring the OpenAI embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
|------------------------|--------------------------------------------------|---------------|
|
||||
| `model` | The name of the embedding model to use | `text-embedding-3-small` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `api_key` | The OpenAI API key | `None` |
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
title: Overview
|
||||
icon: "info"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 offers support for various embedding models, allowing users to choose the one that best suits their needs.
|
||||
|
||||
## Supported Embedders
|
||||
|
||||
See the list of supported embedders below.
|
||||
|
||||
<CardGroup cols={1}>
|
||||
<Card title="OpenAI" href="/components/embedders/models/openai"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
To utilize a embedder, you must provide a configuration to customize its usage. If no configuration is supplied, a default configuration will be applied, and `OpenAI` will be used as the embedder.
|
||||
|
||||
For a comprehensive list of available parameters for embedder configuration, please refer to [Config](./config).
|
||||
@@ -1,85 +0,0 @@
|
||||
---
|
||||
title: Configurations
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## How to define configurations?
|
||||
|
||||
The `config` is defined as a TypeScript object 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 object containing provider-specific settings
|
||||
|
||||
### Config Values Precedence
|
||||
|
||||
Config values are applied in the following order of precedence (from highest to lowest):
|
||||
|
||||
1. Values explicitly set in the `config` object
|
||||
2. Environment variables (e.g., `OPENAI_API_KEY`, `OPENAI_API_BASE`)
|
||||
3. Default values defined in the LLM implementation
|
||||
|
||||
This means that values specified in the `config` object will override corresponding environment variables, which in turn override default values.
|
||||
|
||||
## How to Use Config
|
||||
|
||||
Here's a general example of how to use the config with Mem0:
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: process.env.OPENAI_API_KEY || '',
|
||||
model: 'gpt-4-turbo-preview',
|
||||
temperature: 0.2,
|
||||
maxTokens: 1500,
|
||||
},
|
||||
},
|
||||
embedder: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: process.env.OPENAI_API_KEY || '',
|
||||
model: 'text-embedding-3-small',
|
||||
},
|
||||
},
|
||||
vectorStore: {
|
||||
provider: 'memory',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
dimension: 1536,
|
||||
},
|
||||
},
|
||||
historyDbPath: 'memory.db',
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
memory.add("Your text here", { userId: "user123", metadata: { category: "example" } });
|
||||
```
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
1. Specifying which LLM to use.
|
||||
2. Providing necessary connection details (e.g., model, api_key, temperature).
|
||||
3. Ensuring proper initialization and connection to your chosen LLM.
|
||||
|
||||
## Master List of All Params in Config
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different LLMs:
|
||||
|
||||
| Parameter | Description | Provider |
|
||||
|----------------------|-----------------------------------------------|-------------------|
|
||||
| `model` | Embedding model to use | All |
|
||||
| `temperature` | Temperature of the model | All |
|
||||
| `apiKey` | API key to use | All |
|
||||
| `maxTokens` | Tokens to generate | All |
|
||||
| `topP` | Probability threshold for nucleus sampling | All |
|
||||
| `topK` | Number of highest probability tokens to keep | All |
|
||||
| `openaiBaseUrl` | Base URL for OpenAI API | OpenAI |
|
||||
|
||||
## Supported LLMs
|
||||
|
||||
For detailed information on configuring specific LLMs, please visit the [LLMs](./models) section. There you'll find information for each supported LLM with provider-specific usage examples and configuration details.
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
title: Anthropic
|
||||
---
|
||||
|
||||
To use Anthropic's models, please set the `ANTHROPIC_API_KEY`, which you can find on their [Account Settings Page](https://console.anthropic.com/account/keys).
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'anthropic',
|
||||
config: {
|
||||
apiKey: process.env.ANTHROPIC_API_KEY || '',
|
||||
model: 'claude-3-7-sonnet-latest',
|
||||
temperature: 0.1,
|
||||
maxTokens: 2000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Likes to play cricket on weekends", { userId: "alice", metadata: { category: "hobbies" } });
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `anthropic` config are present in the [Master List of All Params in Config](../config).
|
||||
@@ -1,32 +0,0 @@
|
||||
---
|
||||
title: Groq
|
||||
---
|
||||
|
||||
[Groq](https://groq.com/) is the creator of the world's first Language Processing Unit (LPU), providing exceptional speed performance for AI workloads running on their LPU Inference Engine.
|
||||
|
||||
In order to use LLMs from Groq, go to their [platform](https://console.groq.com/keys) and get the API key. Set the API key as `GROQ_API_KEY` environment variable to use the model as given below in the example.
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'groq',
|
||||
config: {
|
||||
apiKey: process.env.GROQ_API_KEY || '',
|
||||
model: 'mixtral-8x7b-32768',
|
||||
temperature: 0.1,
|
||||
maxTokens: 1000,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Likes to play cricket on weekends", { userId: "alice", metadata: { category: "hobbies" } });
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `groq` config are present in the [Master List of All Params in Config](../config).
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
title: OpenAI
|
||||
---
|
||||
|
||||
To use OpenAI LLM models, you need to set the `OPENAI_API_KEY` environment variable. You can obtain the OpenAI API key from the [OpenAI Platform](https://platform.openai.com/account/api-keys).
|
||||
|
||||
## Usage
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: process.env.OPENAI_API_KEY || '',
|
||||
model: 'gpt-4-turbo-preview',
|
||||
temperature: 0.2,
|
||||
maxTokens: 1500,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Likes to play cricket on weekends", { userId: "alice", metadata: { category: "hobbies" } });
|
||||
```
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `openai` config are present in the [Master List of All Params in Config](../config).
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
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.
|
||||
|
||||
## Usage
|
||||
|
||||
To use a llm, you must provide a configuration to customize its usage. If no configuration is supplied, a default configuration will be applied, and `OpenAI` will be used as the llm.
|
||||
|
||||
For a comprehensive list of available parameters for llm configuration, please refer to [Config](./config).
|
||||
|
||||
To view all supported llms, visit the [Supported LLMs](./models).
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="OpenAI" href="/open-source-typescript/components/llms/models/openai"></Card>
|
||||
<Card title="Anthropic" href="/open-source-typescript/components/llms/models/anthropic"></Card>
|
||||
<Card title="Groq" href="/open-source-typescript/components/llms/models/groq"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Structured vs Unstructured Outputs
|
||||
|
||||
Mem0 supports two types of OpenAI LLM formats, each with its own strengths and use cases:
|
||||
|
||||
### Structured Outputs
|
||||
|
||||
Structured outputs are LLMs that align with OpenAI's structured outputs model:
|
||||
|
||||
- **Optimized for:** Returning structured responses (e.g., JSON objects)
|
||||
- **Benefits:** Precise, easily parseable data
|
||||
- **Ideal for:** Data extraction, form filling, API responses
|
||||
- **Learn more:** [OpenAI Structured Outputs Guide](https://platform.openai.com/docs/guides/structured-outputs/introduction)
|
||||
|
||||
### Unstructured Outputs
|
||||
|
||||
Unstructured outputs correspond to OpenAI's standard, free-form text model:
|
||||
|
||||
- **Flexibility:** Returns open-ended, natural language responses
|
||||
- **Customization:** Use the `response_format` parameter to guide output
|
||||
- **Trade-off:** Less efficient than structured outputs for specific data needs
|
||||
- **Best for:** Creative writing, explanations, general conversation
|
||||
|
||||
Choose the format that best suits your application's requirements for optimal performance and usability.
|
||||
@@ -1,100 +0,0 @@
|
||||
---
|
||||
title: Configurations
|
||||
icon: "gear"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## How to define configurations?
|
||||
|
||||
The `config` is defined as a TypeScript object with two main keys:
|
||||
- `vectorStore`: Specifies the vector database provider and its configuration
|
||||
- `provider`: The name of the vector database (e.g., "chroma", "pgvector", "qdrant", "milvus", "azure_ai_search", "redis", "memory")
|
||||
- `config`: A nested object containing provider-specific settings
|
||||
|
||||
## In-Memory Storage Option
|
||||
|
||||
We also support an in-memory storage option for the vector store, which is useful for reduced overhead and faster access times. Here's how to configure it:
|
||||
|
||||
### Example for In-Memory Storage
|
||||
|
||||
```typescript
|
||||
const configMemory = {
|
||||
vector_store: {
|
||||
provider: 'memory',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
dimension: 1536,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(configMemory);
|
||||
await memory.add("Your text here", { userId: "user", metadata: { category: "example" } });
|
||||
```
|
||||
|
||||
## How to Use Config
|
||||
|
||||
Here's a general example of how to use the config with Mem0:
|
||||
|
||||
### Example for qdrant
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
vector_store: {
|
||||
provider: 'qdrant',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
embeddingModelDims: 1536,
|
||||
host: 'localhost',
|
||||
port: 6333,
|
||||
url: 'https://your-qdrant-url.com',
|
||||
apiKey: 'your-qdrant-api-key',
|
||||
onDisk: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Your text here", { userId: "user", metadata: { category: "example" } });
|
||||
```
|
||||
|
||||
## Why is Config Needed?
|
||||
|
||||
Config is essential for:
|
||||
1. Specifying which vector database to use.
|
||||
2. Providing necessary connection details (e.g., host, port, credentials).
|
||||
3. Customizing database-specific settings (e.g., collection name, path).
|
||||
4. Ensuring proper initialization and connection to your chosen vector store.
|
||||
|
||||
## Master List of All Params in Config
|
||||
|
||||
Here's a comprehensive list of all parameters that can be used across different vector databases:
|
||||
|
||||
| Parameter | Description |
|
||||
|------------------------|--------------------------------------|
|
||||
| `collectionName` | Name of the collection |
|
||||
| `dimension` | Dimensions of the embedding model |
|
||||
| `host` | Host where the server is running |
|
||||
| `port` | Port where the server is running |
|
||||
| `embeddingModelDims` | Dimensions of the embedding model |
|
||||
| `url` | URL for the Qdrant server |
|
||||
| `apiKey` | API key for the Qdrant server |
|
||||
| `path` | Path for the Qdrant server |
|
||||
| `onDisk` | Enable persistent storage (for Qdrant) |
|
||||
| `redisUrl` | URL for the Redis server |
|
||||
| `username` | Username for Redis connection |
|
||||
| `password` | Password for Redis connection |
|
||||
|
||||
## Customizing Config
|
||||
|
||||
Each vector database has its own specific configuration requirements. To customize the config for your chosen vector store:
|
||||
|
||||
1. Identify the vector database you want to use from [supported vector databases](./dbs).
|
||||
2. Refer to the `Config` section in the respective vector database's documentation.
|
||||
3. Include only the relevant parameters for your chosen database in the `config` object.
|
||||
|
||||
## Supported Vector Databases
|
||||
|
||||
For detailed information on configuring specific vector databases, please visit the [Supported Vector Databases](./dbs) section. There you'll find individual pages for each supported vector store with provider-specific usage examples and configuration details.
|
||||
@@ -1,44 +0,0 @@
|
||||
[pgvector](https://github.com/pgvector/pgvector) is open-source vector similarity search for Postgres. After connecting with Postgres, run `CREATE EXTENSION IF NOT EXISTS vector;` to create the vector extension.
|
||||
|
||||
### Usage
|
||||
|
||||
Here's how to configure pgvector in your application:
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
vector_store: {
|
||||
provider: 'pgvector',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
dimension: 1536,
|
||||
dbname: 'vectordb',
|
||||
user: 'postgres',
|
||||
password: 'postgres',
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
embeddingModelDims: 1536,
|
||||
hnsw: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Likes to play cricket on weekends", { userId: "alice", metadata: { category: "hobbies" } });
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here's the parameters available for configuring pgvector:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
|------------------------|--------------------------------------------------|---------------|
|
||||
| `dbname` | The name of the database | `postgres` |
|
||||
| `collectionName` | The name of the collection | `mem0` |
|
||||
| `embeddingModelDims` | Dimensions of the embedding model | `1536` |
|
||||
| `user` | Username to connect to the database | `None` |
|
||||
| `password` | Password to connect to the database | `None` |
|
||||
| `host` | The host where the Postgres server is running | `None` |
|
||||
| `port` | The port where the Postgres server is running | `None` |
|
||||
| `hnsw` | Enable HNSW indexing | `False` |
|
||||
@@ -1,42 +0,0 @@
|
||||
[Qdrant](https://qdrant.tech/) is an open-source vector search engine. It is designed to work with large-scale datasets and provides a high-performance search engine for vector data.
|
||||
|
||||
### Usage
|
||||
|
||||
Here's how to configure Qdrant in your application:
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
vector_store: {
|
||||
provider: 'qdrant',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
embeddingModelDims: 1536,
|
||||
host: 'localhost',
|
||||
port: 6333,
|
||||
url: 'https://your-qdrant-url.com',
|
||||
apiKey: 'your-qdrant-api-key',
|
||||
onDisk: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
await memory.add("Likes to play cricket on weekends", { userId: "alice", metadata: { category: "hobbies" } });
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Let's see the available parameters for the `qdrant` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
|------------------------|--------------------------------------------------|---------------|
|
||||
| `collectionName` | The name of the collection to store the vectors | `mem0` |
|
||||
| `embeddingModelDims` | Dimensions of the embedding model | `1536` |
|
||||
| `host` | The host where the Qdrant server is running | `None` |
|
||||
| `port` | The port where the Qdrant server is running | `None` |
|
||||
| `path` | Path for the Qdrant database | `/tmp/qdrant` |
|
||||
| `url` | Full URL for the Qdrant server | `None` |
|
||||
| `apiKey` | API key for the Qdrant server | `None` |
|
||||
| `onDisk` | For enabling persistent storage | `False` |
|
||||
@@ -1,47 +0,0 @@
|
||||
[Redis](https://redis.io/) is a scalable, real-time database that can store, search, and analyze vector data.
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
pip install redis redisvl
|
||||
```
|
||||
|
||||
Redis Stack using Docker:
|
||||
```bash
|
||||
docker run -d --name redis-stack -p 6379:6379 -p 8001:8001 redis/redis-stack:latest
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
Here's how to configure Redis in your application:
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
vector_store: {
|
||||
provider: 'redis',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
embeddingModelDims: 1536,
|
||||
redisUrl: 'redis://localhost:6379',
|
||||
username: 'your-redis-username',
|
||||
password: 'your-redis-password',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const memoryRedis = new Memory(config);
|
||||
await memoryRedis.add("Likes to play cricket on weekends", { userId: "alice", metadata: { category: "hobbies" } });
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Let's see the available parameters for the `redis` config:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
|------------------------|--------------------------------------------------|---------------|
|
||||
| `collectionName` | The name of the collection to store the vectors | `mem0` |
|
||||
| `embeddingModelDims` | Dimensions of the embedding model | `1536` |
|
||||
| `redisUrl` | The URL of the Redis server | `None` |
|
||||
| `username` | Username for Redis connection | `None` |
|
||||
| `password` | Password for Redis connection | `None` |
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
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.
|
||||
|
||||
## Supported Vector Databases
|
||||
|
||||
See the list of supported vector databases below.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Memory" href="/components/vectordbs/dbs/memory"></Card>
|
||||
<Card title="Qdrant" href="/components/vectordbs/dbs/qdrant"></Card>
|
||||
<Card title="Redis" href="/components/vectordbs/dbs/redis"></Card>
|
||||
<Card title="Pgvector" href="/components/vectordbs/dbs/pgvector"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
To utilize a vector database, you must provide a configuration to customize its usage. If no configuration is supplied, a default configuration will be applied, and `Memory` will be used as the vector database.
|
||||
|
||||
For a comprehensive list of available parameters for vector database configuration, please refer to [Config](./config).
|
||||
|
||||
## Common issues
|
||||
|
||||
### Using model with different dimensions
|
||||
|
||||
If you are using customized model, which is having different dimensions other than 1536
|
||||
for example 768, you may encounter below error:
|
||||
|
||||
`ValueError: shapes (0,1536) and (768,) not aligned: 1536 (dim 1) != 768 (dim 0)`
|
||||
|
||||
you could add `"embedding_model_dims": 768,` to the config of the vector_store to overcome this issue.
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
---
|
||||
title: Custom Prompts
|
||||
description: 'Enhance your product experience by adding custom prompts tailored to your needs'
|
||||
icon: "pencil"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Introduction to Custom Prompts
|
||||
|
||||
Custom prompts allow you to tailor the behavior of your Mem0 instance to specific use cases or domains.
|
||||
By defining a custom prompt, you can control how information is extracted, processed, and stored in your memory system.
|
||||
|
||||
To create an effective custom prompt:
|
||||
1. Be specific about the information to extract.
|
||||
2. Provide few-shot examples to guide the LLM.
|
||||
3. Ensure examples follow the format shown below.
|
||||
|
||||
Example of a custom prompt:
|
||||
|
||||
```typescript
|
||||
const customPrompt = `
|
||||
Please only extract entities containing customer support information, order details, and user information.
|
||||
Here are some few shot examples:
|
||||
|
||||
Input: Hi.
|
||||
Output: {"facts" : []}
|
||||
|
||||
Input: The weather is nice today.
|
||||
Output: {"facts" : []}
|
||||
|
||||
Input: My order #12345 hasn't arrived yet.
|
||||
Output: {"facts" : ["Order #12345 not received"]}
|
||||
|
||||
Input: I'm John Doe, and I'd like to return the shoes I bought last week.
|
||||
Output: {"facts" : ["Customer name: John Doe", "Wants to return shoes", "Purchase made last week"]}
|
||||
|
||||
Input: I ordered a red shirt, size medium, but received a blue one instead.
|
||||
Output: {"facts" : ["Ordered red shirt, size medium", "Received blue shirt instead"]}
|
||||
|
||||
Return the facts and customer information in a json format as shown above.
|
||||
`;
|
||||
```
|
||||
|
||||
Here we initialize the custom prompt in the config:
|
||||
|
||||
```typescript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
version: 'v1.1',
|
||||
embedder: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: process.env.OPENAI_API_KEY || '',
|
||||
model: 'text-embedding-3-small',
|
||||
},
|
||||
},
|
||||
vectorStore: {
|
||||
provider: 'memory',
|
||||
config: {
|
||||
collectionName: 'memories',
|
||||
dimension: 1536,
|
||||
},
|
||||
},
|
||||
llm: {
|
||||
provider: 'openai',
|
||||
config: {
|
||||
apiKey: process.env.OPENAI_API_KEY || '',
|
||||
model: 'gpt-4-turbo-preview',
|
||||
temperature: 0.2,
|
||||
maxTokens: 1500,
|
||||
},
|
||||
},
|
||||
customPrompt: customPrompt,
|
||||
historyDbPath: 'memory.db',
|
||||
};
|
||||
|
||||
const memory = new Memory(config);
|
||||
```
|
||||
|
||||
### Example 1
|
||||
|
||||
In this example, we are adding a memory of a user ordering a laptop. As seen in the output, the custom prompt is used to extract the relevant information from the user's message.
|
||||
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
await memory.add('Yesterday, I ordered a laptop, the order id is 12345', 'user123');
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "c03c9045-df76-4949-bbc5-d5dc1932aa5c",
|
||||
"memory": "Ordered a laptop",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
"memory": "Order ID: 12345",
|
||||
"metadata": {}
|
||||
},
|
||||
{
|
||||
"id": "e5f2a012-3b45-4c67-9d8e-123456789abc",
|
||||
"memory": "Order placed yesterday",
|
||||
"metadata": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Example 2
|
||||
|
||||
In this example, we are adding a memory of a user liking to go on hikes. This add message is not specific to the use-case mentioned in the custom prompt.
|
||||
Hence, the memory is not added.
|
||||
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
await memory.add('I like going to hikes', 'user123');
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": []
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
You can also use custom prompts with chat messages:
|
||||
|
||||
```typescript
|
||||
const messages = [
|
||||
{ role: 'user', content: 'Hi, I ordered item #54321 last week but haven\'t received it yet.' },
|
||||
{ role: 'assistant', content: 'I understand you\'re concerned about your order #54321. Let me help track that for you.' }
|
||||
];
|
||||
|
||||
await memory.add(messages, 'user123');
|
||||
```
|
||||
|
||||
The custom prompt will process both the user and assistant messages to extract relevant information according to the defined format.
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Node.js Guide
|
||||
title: Node SDK
|
||||
description: 'Get started with Mem0 quickly!'
|
||||
icon: "node"
|
||||
iconType: "solid"
|
||||
@@ -67,15 +67,14 @@ const memory = new Memory({
|
||||
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
// For a user
|
||||
const result = await memory.add('Hi, my name is John and I am a software', 'user123');
|
||||
console.log(result);
|
||||
const messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about a thriller movies? They can be quite engaging."},
|
||||
{"role": "user", "content": "I'm not a big fan of thriller movies but I love sci-fi movies."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
|
||||
// const messages = [
|
||||
// {"role": "user", "content": "Hi, I'm Alex. I like to play cricket on weekends."},
|
||||
// {"role": "assistant", "content": "Hello Alex! It's great to know that you enjoy playing cricket on weekends. I'll remember that for future reference."}
|
||||
// ]
|
||||
// await memory.add(messages, 'user123');
|
||||
await memory.add(messages, { userId: "user123", metadata: { category: "movie_recommendations" } });
|
||||
```
|
||||
|
||||
```json Output
|
||||
@@ -83,13 +82,24 @@ console.log(result);
|
||||
"results": [
|
||||
{
|
||||
"id": "c03c9045-df76-4949-bbc5-d5dc1932aa5c",
|
||||
"memory": "Name is John",
|
||||
"metadata": [Object]
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
"memory": "Is a software",
|
||||
"metadata": [Object]
|
||||
"memory": "User is not a big fan of thriller movies.",
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "475bde34-21e6-42ab-8bef-0ab84474f156",
|
||||
"memory": "User loves sci-fi movies.",
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -101,7 +111,7 @@ console.log(result);
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
// Get all memories
|
||||
const allMemories = await memory.getAll('user123');
|
||||
const allMemories = await memory.getAll({ userId: "user123" });
|
||||
console.log(allMemories)
|
||||
```
|
||||
|
||||
@@ -110,20 +120,35 @@ console.log(allMemories)
|
||||
"results": [
|
||||
{
|
||||
"id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"memory": "Name is Alex Jones",
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"hash": "1a271c007316c94377175ee80e746a19",
|
||||
"createdAt": "2025-02-27T16:33:20.557Z",
|
||||
"updatedAt": "2025-02-27T16:33:27.051Z",
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
},
|
||||
{
|
||||
"id": "475bde34-21e6-42ab-8bef-0ab84474f156",
|
||||
"memory": "Likes to play cricket on weekends",
|
||||
"memory": "User loves sci-fi movies.",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"createdAt": "2025-02-27T16:33:20.560Z",
|
||||
"updatedAt": undefined,
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
"memory": "User is not a big fan of thriller movies.",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"createdAt": "2025-02-27T16:33:20.560Z",
|
||||
"updatedAt": undefined,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
}
|
||||
]
|
||||
@@ -137,18 +162,20 @@ console.log(allMemories)
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
// Get a single memory by ID
|
||||
const singleMemory = await memory.get('6c1c11a2-4fbc-4a2b-8e8a-d60e67e57aaa');
|
||||
const singleMemory = await memory.get('892db2ae-06d9-49e5-8b3e-585ef9b85b8e');
|
||||
console.log(singleMemory);
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"id": "6c1c11a2-4fbc-4a2b-8e8a-d60e67e57aaa",
|
||||
"memory": "Name is Alex",
|
||||
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
|
||||
"createdAt": "2025-02-27T16:37:04.378Z",
|
||||
"id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"hash": "1a271c007316c94377175ee80e746a19",
|
||||
"createdAt": "2025-02-27T16:33:20.557Z",
|
||||
"updatedAt": undefined,
|
||||
"metadata": {},
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
}
|
||||
```
|
||||
@@ -158,7 +185,7 @@ console.log(singleMemory);
|
||||
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
const result = await memory.search('What do you know about me?', 'user123');
|
||||
const result = await memory.search('What do you know about me?', { userId: "user123" });
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
@@ -166,23 +193,39 @@ console.log(result);
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "28c3eee7-186e-4644-8c5d-13b306233d4e",
|
||||
"memory": "Name is Alex",
|
||||
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
|
||||
"createdAt": "2025-02-27T16:43:56.310Z",
|
||||
"id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"hash": "1a271c007316c94377175ee80e746a19",
|
||||
"createdAt": "2025-02-27T16:33:20.557Z",
|
||||
"updatedAt": undefined,
|
||||
"score": 0.08920719231944799,
|
||||
"metadata": {},
|
||||
"score": 0.38920719231944799,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
},
|
||||
{
|
||||
"id": "f3433da0-45f4-444f-a4bc-59a170890a1f",
|
||||
"memory": "Likes to play cricket on weekends",
|
||||
"id": "475bde34-21e6-42ab-8bef-0ab84474f156",
|
||||
"memory": "User loves sci-fi movies.",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"createdAt": "2025-02-27T16:43:56.314Z",
|
||||
"createdAt": "2025-02-27T16:33:20.560Z",
|
||||
"updatedAt": undefined,
|
||||
"score": 0.06869761478135689,
|
||||
"metadata": {},
|
||||
"score": 0.36869761478135689,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
"memory": "User is not a big fan of thriller movies.",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"createdAt": "2025-02-27T16:33:20.560Z",
|
||||
"updatedAt": undefined,
|
||||
"score": 0.33855272141248272,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
}
|
||||
]
|
||||
@@ -195,9 +238,8 @@ console.log(result);
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
const result = await memory.update(
|
||||
'6c1c11a2-4fbc-4a2b-8e8a-d60e67e57aaa',
|
||||
'I love India, it is my favorite country.',
|
||||
'user123'
|
||||
'892db2ae-06d9-49e5-8b3e-585ef9b85b8e',
|
||||
'I love India, it is my favorite country.'
|
||||
);
|
||||
console.log(result);
|
||||
```
|
||||
@@ -213,7 +255,7 @@ console.log(result);
|
||||
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
const history = await memory.history('d2cc4cef-e0c1-47dd-948a-677030482e9e');
|
||||
const history = await memory.history('892db2ae-06d9-49e5-8b3e-585ef9b85b8e');
|
||||
console.log(history);
|
||||
```
|
||||
|
||||
@@ -221,21 +263,21 @@ console.log(history);
|
||||
[
|
||||
{
|
||||
"id": 39,
|
||||
"memory_id": "d2cc4cef-e0c1-47dd-948a-677030482e9e",
|
||||
"previous_value": "Name is Alex",
|
||||
"new_value": "Name is Alex Jones",
|
||||
"memory_id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"previous_value": "User is planning to watch a movie tonight.",
|
||||
"new_value": "I love India, it is my favorite country.",
|
||||
"action": "UPDATE",
|
||||
"created_at": "2025-02-27T16:46:15.853Z",
|
||||
"updated_at": "2025-02-27T16:46:20.909Z",
|
||||
"created_at": "2025-02-27T16:33:20.557Z",
|
||||
"updated_at": "2025-02-27T16:33:27.051Z",
|
||||
"is_deleted": 0
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"memory_id": "d2cc4cef-e0c1-47dd-948a-677030482e9e",
|
||||
"memory_id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"previous_value": null,
|
||||
"new_value": "Name is Alex",
|
||||
"new_value": "User is planning to watch a movie tonight.",
|
||||
"action": "ADD",
|
||||
"created_at": "2025-02-27T16:46:15.853Z",
|
||||
"created_at": "2025-02-27T16:33:20.557Z",
|
||||
"updated_at": null,
|
||||
"is_deleted": 0
|
||||
}
|
||||
@@ -247,10 +289,10 @@ console.log(history);
|
||||
|
||||
```typescript
|
||||
// Delete a memory by id
|
||||
await memory.delete('bf4d4092-cf91-4181-bfeb-b6fa2ed3061b');
|
||||
await memory.delete('892db2ae-06d9-49e5-8b3e-585ef9b85b8e');
|
||||
|
||||
// Delete all memories for a user
|
||||
await memory.deleteAll('alice');
|
||||
await memory.deleteAll({ userId: "user123" });
|
||||
```
|
||||
|
||||
### Reset Memory
|
||||
|
||||
@@ -28,8 +28,7 @@ config = {
|
||||
"password": "xxx"
|
||||
},
|
||||
"custom_prompt": "Please only extract entities containing sports related relationships and nothing else.",
|
||||
},
|
||||
"version": "v1.1"
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config_dict=config)
|
||||
|
||||
@@ -38,8 +38,7 @@ allowfullscreen
|
||||
## Initialize Graph Memory
|
||||
|
||||
To initialize Graph Memory you'll need to set up your configuration with graph store providers.
|
||||
Currently, we support Neo4j as a graph store provider. You can setup [Neo4j](https://neo4j.com/) locally or use the hosted [Neo4j AuraDB](https://neo4j.com/product/auradb/).
|
||||
Moreover, you also need to set the version to `v1.1` (*prior versions are not supported*).
|
||||
Currently, we support Neo4j as a graph store provider. You can setup [Neo4j](https://neo4j.com/) locally or use the hosted [Neo4j AuraDB](https://neo4j.com/product/auradb/).
|
||||
|
||||
<Note>If you are using Neo4j locally, then you need to install [APOC plugins](https://neo4j.com/labs/apoc/4.1/installation/).</Note>
|
||||
|
||||
@@ -65,8 +64,7 @@ config = {
|
||||
"username": "neo4j",
|
||||
"password": "xxx"
|
||||
}
|
||||
},
|
||||
"version": "v1.1"
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config_dict=config)
|
||||
@@ -98,8 +96,7 @@ config = {
|
||||
"temperature": 0.0,
|
||||
}
|
||||
}
|
||||
},
|
||||
"version": "v1.1"
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config_dict=config)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: Python Guide
|
||||
title: Python SDK
|
||||
description: 'Get started with Mem0 quickly!'
|
||||
icon: "python"
|
||||
iconType: "solid"
|
||||
@@ -71,8 +71,7 @@ config = {
|
||||
"username": "neo4j",
|
||||
"password": "---"
|
||||
}
|
||||
},
|
||||
"version": "v1.1"
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config_dict=config)
|
||||
@@ -100,10 +99,6 @@ result = m.add("Likes to play cricket on weekends", user_id="alice", metadata={"
|
||||
{
|
||||
"results": [
|
||||
{"id": "bf4d4092-cf91-4181-bfeb-b6fa2ed3061b", "memory": "Likes to play cricket on weekends", "event": "ADD"}
|
||||
],
|
||||
"relations": [
|
||||
{"source": "alice", "relationship": "likes_to_play", "target": "cricket"},
|
||||
{"source": "alice", "relationship": "plays_on", "target": "weekends"}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -129,10 +124,6 @@ all_memories = m.get_all(user_id="alice")
|
||||
"updated_at": None,
|
||||
"user_id": "alice"
|
||||
}
|
||||
],
|
||||
"relations": [
|
||||
{"source": "alice", "relationship": "likes_to_play", "target": "cricket"},
|
||||
{"source": "alice", "relationship": "plays_on", "target": "weekends"}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -180,10 +171,6 @@ related_memories = m.search(query="What are Alice's hobbies?", user_id="alice")
|
||||
"updated_at": None,
|
||||
"user_id": "alice"
|
||||
}
|
||||
],
|
||||
"relations": [
|
||||
{"source": "alice", "relationship": "plays_on", "target": "weekends"},
|
||||
{"source": "alice", "relationship": "likes_to_play", "target": "cricket"}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -303,7 +290,7 @@ Mem0 offers extensive configuration options to customize its behavior according
|
||||
| Parameter | Description | Default |
|
||||
|------------------|--------------------------------------|----------------------------|
|
||||
| `history_db_path` | Path to the history database | "{mem0_dir}/history.db" |
|
||||
| `version` | API version | "v1.0" |
|
||||
| `version` | API version | "v1.1" |
|
||||
| `custom_prompt` | Custom prompt for memory processing | None |
|
||||
</Accordion>
|
||||
|
||||
|
||||
+2
-2
@@ -330,7 +330,7 @@ result = m.add("I like to drink coffee in the morning and go for a walk.", user_
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const result = memory.add("I like to drink coffee in the morning and go for a walk.", 'alice');
|
||||
const result = memory.add("I like to drink coffee in the morning and go for a walk.", { userId: "alice", metadata: { category: "preferences" } });
|
||||
```
|
||||
|
||||
```json Output
|
||||
@@ -361,7 +361,7 @@ related_memories = m.search("Should I drink coffee or tea?", user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const relatedMemories = memory.search("Should I drink coffee or tea?", "alice");
|
||||
const relatedMemories = memory.search("Should I drink coffee or tea?", { userId: "alice" });
|
||||
```
|
||||
|
||||
```json Output
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
Mem0 is a self-improving memory layer for LLM applications, enabling personalized AI experiences that save costs and delight users. We offer both cloud and open-source solutions to cater to different needs.
|
||||
|
||||
See the complete [OSS Docs](https://docs.mem0.ai/open-source-typescript/quickstart).
|
||||
See the complete [Platform API Reference](https://docs.mem0.ai/api-reference/overview).
|
||||
|
||||
## 1. Installation
|
||||
|
||||
For the open-source version, you can install the Mem0 package using npm:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mem0ai",
|
||||
"version": "2.0.0",
|
||||
"version": "2.0.1",
|
||||
"description": "The Memory Layer For Your AI Apps",
|
||||
"main": "./dist/index.js",
|
||||
"module": "./dist/index.mjs",
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
export * from "./memory";
|
||||
export * from "./memory/memory.types";
|
||||
export * from "./types";
|
||||
export * from "./embeddings/base";
|
||||
export * from "./embeddings/openai";
|
||||
@@ -9,4 +10,6 @@ export * from "./llms/anthropic";
|
||||
export * from "./llms/groq";
|
||||
export * from "./vector_stores/base";
|
||||
export * from "./vector_stores/memory";
|
||||
export * from "./vector_stores/qdrant";
|
||||
export * from "./vector_stores/redis";
|
||||
export * from "./utils/factory";
|
||||
|
||||
@@ -24,6 +24,12 @@ import { Embedder } from "../embeddings/base";
|
||||
import { LLM } from "../llms/base";
|
||||
import { VectorStore } from "../vector_stores/base";
|
||||
import { ConfigManager } from "../config/manager";
|
||||
import {
|
||||
AddMemoryOptions,
|
||||
SearchMemoryOptions,
|
||||
DeleteAllMemoryOptions,
|
||||
GetAllMemoryOptions,
|
||||
} from "./memory.types";
|
||||
|
||||
export class Memory {
|
||||
private config: MemoryConfig;
|
||||
@@ -69,13 +75,17 @@ export class Memory {
|
||||
|
||||
async add(
|
||||
messages: string | Message[],
|
||||
userId?: string,
|
||||
agentId?: string,
|
||||
runId?: string,
|
||||
metadata: Record<string, any> = {},
|
||||
filters: SearchFilters = {},
|
||||
prompt?: string,
|
||||
config: AddMemoryOptions,
|
||||
): Promise<SearchResult> {
|
||||
const {
|
||||
userId,
|
||||
agentId,
|
||||
runId,
|
||||
metadata = {},
|
||||
filters = {},
|
||||
prompt,
|
||||
} = config;
|
||||
|
||||
if (userId) filters.userId = metadata.userId = userId;
|
||||
if (agentId) filters.agentId = metadata.agentId = agentId;
|
||||
if (runId) filters.runId = metadata.runId = runId;
|
||||
@@ -87,7 +97,7 @@ export class Memory {
|
||||
}
|
||||
|
||||
const parsedMessages = Array.isArray(messages)
|
||||
? messages
|
||||
? (messages as Message[])
|
||||
: [{ role: "user", content: messages }];
|
||||
|
||||
const vectorStoreResult = await this.addToVectorStore(
|
||||
@@ -260,12 +270,10 @@ export class Memory {
|
||||
|
||||
async search(
|
||||
query: string,
|
||||
userId?: string,
|
||||
agentId?: string,
|
||||
runId?: string,
|
||||
limit: number = 100,
|
||||
filters: SearchFilters = {},
|
||||
config: SearchMemoryOptions,
|
||||
): Promise<SearchResult> {
|
||||
const { userId, agentId, runId, limit = 100, filters = {} } = config;
|
||||
|
||||
if (userId) filters.userId = userId;
|
||||
if (agentId) filters.agentId = agentId;
|
||||
if (runId) filters.runId = runId;
|
||||
@@ -322,10 +330,10 @@ export class Memory {
|
||||
}
|
||||
|
||||
async deleteAll(
|
||||
userId?: string,
|
||||
agentId?: string,
|
||||
runId?: string,
|
||||
config: DeleteAllMemoryOptions,
|
||||
): Promise<{ message: string }> {
|
||||
const { userId, agentId, runId } = config;
|
||||
|
||||
const filters: SearchFilters = {};
|
||||
if (userId) filters.userId = userId;
|
||||
if (agentId) filters.agentId = agentId;
|
||||
@@ -358,12 +366,9 @@ export class Memory {
|
||||
);
|
||||
}
|
||||
|
||||
async getAll(
|
||||
userId?: string,
|
||||
agentId?: string,
|
||||
runId?: string,
|
||||
limit: number = 100,
|
||||
): Promise<SearchResult> {
|
||||
async getAll(config: GetAllMemoryOptions): Promise<SearchResult> {
|
||||
const { userId, agentId, runId, limit = 100 } = config;
|
||||
|
||||
const filters: SearchFilters = {};
|
||||
if (userId) filters.userId = userId;
|
||||
if (agentId) filters.agentId = agentId;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { Message } from "../types";
|
||||
import { SearchFilters } from "../types";
|
||||
|
||||
export interface Entity {
|
||||
userId?: string;
|
||||
agentId?: string;
|
||||
runId?: string;
|
||||
}
|
||||
|
||||
export interface AddMemoryOptions extends Entity {
|
||||
metadata?: Record<string, any>;
|
||||
filters?: SearchFilters;
|
||||
prompt?: string;
|
||||
}
|
||||
|
||||
export interface SearchMemoryOptions extends Entity {
|
||||
query: string;
|
||||
limit?: number;
|
||||
filters?: SearchFilters;
|
||||
}
|
||||
|
||||
export interface GetAllMemoryOptions extends Entity {
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
export interface DeleteAllMemoryOptions extends Entity {}
|
||||
@@ -46,7 +46,7 @@ class MemoryConfig(BaseModel):
|
||||
)
|
||||
version: str = Field(
|
||||
description="The version of the API",
|
||||
default="v1.0",
|
||||
default="v1.1",
|
||||
)
|
||||
custom_prompt: Optional[str] = Field(
|
||||
description="Custom prompt for the memory",
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
from typing import Any, Dict, Optional
|
||||
from enum import Enum
|
||||
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
|
||||
class IndexMethod(str, Enum):
|
||||
AUTO = "auto"
|
||||
HNSW = "hnsw"
|
||||
IVFFLAT = "ivfflat"
|
||||
|
||||
|
||||
class IndexMeasure(str, Enum):
|
||||
COSINE = "cosine_distance"
|
||||
L2 = "l2_distance"
|
||||
L1 = "l1_distance"
|
||||
MAX_INNER_PRODUCT = "max_inner_product"
|
||||
|
||||
|
||||
class SupabaseConfig(BaseModel):
|
||||
connection_string: str = Field(..., description="PostgreSQL connection string")
|
||||
collection_name: str = Field("mem0", description="Name for the vector collection")
|
||||
embedding_model_dims: Optional[int] = Field(1536, description="Dimensions of the embedding model")
|
||||
index_method: Optional[IndexMethod] = Field(IndexMethod.AUTO, description="Index method to use")
|
||||
index_measure: Optional[IndexMeasure] = Field(IndexMeasure.COSINE, description="Distance measure to use")
|
||||
|
||||
@model_validator(mode="before")
|
||||
def check_connection_string(cls, values):
|
||||
conn_str = values.get("connection_string")
|
||||
if not conn_str or not conn_str.startswith("postgresql://"):
|
||||
raise ValueError("A valid PostgreSQL connection string must be provided")
|
||||
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)}. Please input only the following fields: {', '.join(allowed_fields)}"
|
||||
)
|
||||
return values
|
||||
+27
-30
@@ -46,7 +46,7 @@ class Memory(MemoryBase):
|
||||
|
||||
self.enable_graph = False
|
||||
|
||||
if self.api_version == "v1.1" and self.config.graph_store.config:
|
||||
if self.config.graph_store.config:
|
||||
from mem0.memory.graph_memory import MemoryGraph
|
||||
|
||||
self.graph = MemoryGraph(self.config)
|
||||
@@ -126,12 +126,7 @@ class Memory(MemoryBase):
|
||||
vector_store_result = future1.result()
|
||||
graph_result = future2.result()
|
||||
|
||||
if self.api_version == "v1.1":
|
||||
return {
|
||||
"results": vector_store_result,
|
||||
"relations": graph_result,
|
||||
}
|
||||
else:
|
||||
if self.api_version == "v1.0":
|
||||
warnings.warn(
|
||||
"The current add API output format is deprecated. "
|
||||
"To use the latest format, set `api_version='v1.1'`. "
|
||||
@@ -141,6 +136,14 @@ class Memory(MemoryBase):
|
||||
)
|
||||
return vector_store_result
|
||||
|
||||
if self.enable_graph:
|
||||
return {
|
||||
"results": vector_store_result,
|
||||
"relations": graph_result,
|
||||
}
|
||||
|
||||
return {"results": vector_store_result}
|
||||
|
||||
def _add_to_vector_store(self, messages, metadata, filters):
|
||||
parsed_messages = parse_messages(messages)
|
||||
|
||||
@@ -252,7 +255,7 @@ class Memory(MemoryBase):
|
||||
|
||||
def _add_to_graph(self, messages, filters):
|
||||
added_entities = []
|
||||
if self.api_version == "v1.1" and self.enable_graph:
|
||||
if self.enable_graph:
|
||||
if filters.get("user_id") is None:
|
||||
filters["user_id"] = "user"
|
||||
|
||||
@@ -324,11 +327,7 @@ class Memory(MemoryBase):
|
||||
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
future_memories = executor.submit(self._get_all_from_vector_store, filters, limit)
|
||||
future_graph_entities = (
|
||||
executor.submit(self.graph.get_all, filters, limit)
|
||||
if self.api_version == "v1.1" and self.enable_graph
|
||||
else None
|
||||
)
|
||||
future_graph_entities = executor.submit(self.graph.get_all, filters, limit) if self.enable_graph else None
|
||||
|
||||
concurrent.futures.wait(
|
||||
[future_memories, future_graph_entities] if future_graph_entities else [future_memories]
|
||||
@@ -337,12 +336,10 @@ class Memory(MemoryBase):
|
||||
all_memories = future_memories.result()
|
||||
graph_entities = future_graph_entities.result() if future_graph_entities else None
|
||||
|
||||
if self.api_version == "v1.1":
|
||||
if self.enable_graph:
|
||||
return {"results": all_memories, "relations": graph_entities}
|
||||
else:
|
||||
return {"results": all_memories}
|
||||
else:
|
||||
if self.enable_graph:
|
||||
return {"results": all_memories, "relations": graph_entities}
|
||||
|
||||
if self.api_version == "v1.0":
|
||||
warnings.warn(
|
||||
"The current get_all API output format is deprecated. "
|
||||
"To use the latest format, set `api_version='v1.1'`. "
|
||||
@@ -351,6 +348,8 @@ class Memory(MemoryBase):
|
||||
stacklevel=2,
|
||||
)
|
||||
return all_memories
|
||||
else:
|
||||
return {"results": all_memories}
|
||||
|
||||
def _get_all_from_vector_store(self, filters, limit):
|
||||
memories = self.vector_store.list(filters=filters, limit=limit)
|
||||
@@ -419,9 +418,7 @@ class Memory(MemoryBase):
|
||||
with concurrent.futures.ThreadPoolExecutor() as executor:
|
||||
future_memories = executor.submit(self._search_vector_store, query, filters, limit)
|
||||
future_graph_entities = (
|
||||
executor.submit(self.graph.search, query, filters, limit)
|
||||
if self.api_version == "v1.1" and self.enable_graph
|
||||
else None
|
||||
executor.submit(self.graph.search, query, filters, limit) if self.enable_graph else None
|
||||
)
|
||||
|
||||
concurrent.futures.wait(
|
||||
@@ -431,20 +428,20 @@ class Memory(MemoryBase):
|
||||
original_memories = future_memories.result()
|
||||
graph_entities = future_graph_entities.result() if future_graph_entities else None
|
||||
|
||||
if self.api_version == "v1.1":
|
||||
if self.enable_graph:
|
||||
return {"results": original_memories, "relations": graph_entities}
|
||||
else:
|
||||
return {"results": original_memories}
|
||||
else:
|
||||
if self.enable_graph:
|
||||
return {"results": original_memories, "relations": graph_entities}
|
||||
|
||||
if self.api_version == "v1.0":
|
||||
warnings.warn(
|
||||
"The current search API output format is deprecated. "
|
||||
"The current get_all API output format is deprecated. "
|
||||
"To use the latest format, set `api_version='v1.1'`. "
|
||||
"The current format will be removed in mem0ai 1.1.0 and later versions.",
|
||||
category=DeprecationWarning,
|
||||
stacklevel=2,
|
||||
)
|
||||
return original_memories
|
||||
else:
|
||||
return {"results": original_memories}
|
||||
|
||||
def _search_vector_store(self, query, filters, limit):
|
||||
embeddings = self.embedding_model.embed(query, "search")
|
||||
@@ -540,7 +537,7 @@ class Memory(MemoryBase):
|
||||
|
||||
logger.info(f"Deleted {len(memories)} memories")
|
||||
|
||||
if self.api_version == "v1.1" and self.enable_graph:
|
||||
if self.enable_graph:
|
||||
self.graph.delete_all(filters)
|
||||
|
||||
return {"message": "Memories deleted successfully!"}
|
||||
|
||||
@@ -70,6 +70,7 @@ class VectorStoreFactory:
|
||||
"redis": "mem0.vector_stores.redis.RedisDB",
|
||||
"elasticsearch": "mem0.vector_stores.elasticsearch.ElasticsearchDB",
|
||||
"opensearch": "mem0.vector_stores.opensearch.OpenSearchDB",
|
||||
"supabase": "mem0.vector_stores.supabase.Supabase",
|
||||
}
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -105,10 +105,10 @@ class ChromaDB(VectorStoreBase):
|
||||
chromadb.Collection: The created or retrieved collection.
|
||||
"""
|
||||
# Skip creating collection if already exists
|
||||
collections = self.list_cols()
|
||||
for collection in collections:
|
||||
if collection.name == name:
|
||||
logging.debug(f"Collection {name} already exists. Skipping creation.")
|
||||
collection_info = self.client.get_collection(name=name)
|
||||
if collection_info:
|
||||
logging.debug(f"Collection {name} already exists. Skipping creation.")
|
||||
return collection_info
|
||||
|
||||
collection = self.client.get_or_create_collection(
|
||||
name=name,
|
||||
|
||||
@@ -19,6 +19,7 @@ class VectorStoreConfig(BaseModel):
|
||||
"redis": "RedisDBConfig",
|
||||
"elasticsearch": "ElasticsearchConfig",
|
||||
"opensearch": "OpenSearchConfig",
|
||||
"supabase": "SupabaseConfig",
|
||||
}
|
||||
|
||||
@model_validator(mode="after")
|
||||
|
||||
@@ -0,0 +1,231 @@
|
||||
import logging
|
||||
import uuid
|
||||
from typing import List, Optional, Dict, Any
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
try:
|
||||
import vecs
|
||||
except ImportError:
|
||||
raise ImportError("The 'vecs' library is required. Please install it using 'pip install vecs'.")
|
||||
|
||||
from mem0.vector_stores.base import VectorStoreBase
|
||||
from mem0.configs.vector_stores.supabase import IndexMethod, IndexMeasure
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OutputData(BaseModel):
|
||||
id: Optional[str]
|
||||
score: Optional[float]
|
||||
payload: Optional[dict]
|
||||
|
||||
|
||||
class Supabase(VectorStoreBase):
|
||||
def __init__(
|
||||
self,
|
||||
connection_string: str,
|
||||
collection_name: str,
|
||||
embedding_model_dims: int,
|
||||
index_method: IndexMethod = IndexMethod.AUTO,
|
||||
index_measure: IndexMeasure = IndexMeasure.COSINE,
|
||||
):
|
||||
"""
|
||||
Initialize the Supabase vector store using vecs.
|
||||
|
||||
Args:
|
||||
connection_string (str): PostgreSQL connection string
|
||||
collection_name (str): Collection name
|
||||
embedding_model_dims (int): Dimension of the embedding vector
|
||||
index_method (IndexMethod): Index method to use. Defaults to AUTO.
|
||||
index_measure (IndexMeasure): Distance measure to use. Defaults to COSINE.
|
||||
"""
|
||||
self.db = vecs.create_client(connection_string)
|
||||
self.collection_name = collection_name
|
||||
self.embedding_model_dims = embedding_model_dims
|
||||
self.index_method = index_method
|
||||
self.index_measure = index_measure
|
||||
|
||||
collections = self.list_cols()
|
||||
if collection_name not in collections:
|
||||
self.create_col(embedding_model_dims)
|
||||
|
||||
def _preprocess_filters(self, filters: Optional[dict] = None) -> Optional[dict]:
|
||||
"""
|
||||
Preprocess filters to be compatible with vecs.
|
||||
|
||||
Args:
|
||||
filters (Dict, optional): Filters to preprocess. Multiple filters will be
|
||||
combined with AND logic.
|
||||
"""
|
||||
if filters is None:
|
||||
return None
|
||||
|
||||
if len(filters) == 1:
|
||||
# For single filter, keep the simple format
|
||||
key, value = next(iter(filters.items()))
|
||||
return {key: {"$eq": value}}
|
||||
|
||||
# For multiple filters, use $and clause
|
||||
return {"$and": [{key: {"$eq": value}} for key, value in filters.items()]}
|
||||
|
||||
def create_col(self, embedding_model_dims: Optional[int] = None) -> None:
|
||||
"""
|
||||
Create a new collection with vector support.
|
||||
Will also initialize vector search index.
|
||||
|
||||
Args:
|
||||
embedding_model_dims (int, optional): Dimension of the embedding vector.
|
||||
If not provided, uses the dimension specified in initialization.
|
||||
"""
|
||||
dims = embedding_model_dims or self.embedding_model_dims
|
||||
if not dims:
|
||||
raise ValueError(
|
||||
"embedding_model_dims must be provided either during initialization or when creating collection"
|
||||
)
|
||||
|
||||
logger.info(f"Creating new collection: {self.collection_name}")
|
||||
try:
|
||||
self.collection = self.db.get_or_create_collection(name=self.collection_name, dimension=dims)
|
||||
self.collection.create_index(method=self.index_method.value, measure=self.index_measure.value)
|
||||
logger.info(f"Successfully created collection {self.collection_name} with dimension {dims}")
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to create collection: {str(e)}")
|
||||
raise
|
||||
|
||||
def insert(
|
||||
self, vectors: List[List[float]], payloads: Optional[List[dict]] = None, ids: Optional[List[str]] = None
|
||||
):
|
||||
"""
|
||||
Insert vectors into the collection.
|
||||
|
||||
Args:
|
||||
vectors (List[List[float]]): List of vectors to insert
|
||||
payloads (List[Dict], optional): List of payloads corresponding to vectors
|
||||
ids (List[str], optional): List of IDs corresponding to vectors
|
||||
"""
|
||||
logger.info(f"Inserting {len(vectors)} vectors into collection {self.collection_name}")
|
||||
|
||||
if not ids:
|
||||
ids = [str(uuid.uuid4()) for _ in vectors]
|
||||
if not payloads:
|
||||
payloads = [{} for _ in vectors]
|
||||
|
||||
records = [(id, vector, payload) for id, vector, payload in zip(ids, vectors, payloads)]
|
||||
print(records)
|
||||
|
||||
self.collection.upsert(records)
|
||||
|
||||
def search(self, query: List[float], limit: int = 5, filters: Optional[dict] = None) -> List[OutputData]:
|
||||
"""
|
||||
Search for similar vectors.
|
||||
|
||||
Args:
|
||||
query (List[float]): Query vector
|
||||
limit (int, optional): Number of results to return. Defaults to 5.
|
||||
filters (Dict, optional): Filters to apply to the search. Defaults to None.
|
||||
|
||||
Returns:
|
||||
List[OutputData]: Search results
|
||||
"""
|
||||
filters = self._preprocess_filters(filters)
|
||||
print(filters)
|
||||
results = self.collection.query(
|
||||
data=query, limit=limit, filters=filters, include_metadata=True, include_value=True
|
||||
)
|
||||
print(results)
|
||||
|
||||
return [OutputData(id=str(result[0]), score=float(result[1]), payload=result[2]) for result in results]
|
||||
|
||||
def delete(self, vector_id: str):
|
||||
"""
|
||||
Delete a vector by ID.
|
||||
|
||||
Args:
|
||||
vector_id (str): ID of the vector to delete
|
||||
"""
|
||||
self.collection.delete([(vector_id,)])
|
||||
|
||||
def update(self, vector_id: str, vector: Optional[List[float]] = None, payload: Optional[dict] = None):
|
||||
"""
|
||||
Update a vector and/or its payload.
|
||||
|
||||
Args:
|
||||
vector_id (str): ID of the vector to update
|
||||
vector (List[float], optional): Updated vector
|
||||
payload (Dict, optional): Updated payload
|
||||
"""
|
||||
if vector is None:
|
||||
# If only updating metadata, we need to get the existing vector
|
||||
existing = self.get(vector_id)
|
||||
if existing and existing.payload:
|
||||
vector = existing.payload.get("vector", [])
|
||||
|
||||
if vector:
|
||||
self.collection.upsert([(vector_id, vector, payload or {})])
|
||||
|
||||
def get(self, vector_id: str) -> Optional[OutputData]:
|
||||
"""
|
||||
Retrieve a vector by ID.
|
||||
|
||||
Args:
|
||||
vector_id (str): ID of the vector to retrieve
|
||||
|
||||
Returns:
|
||||
Optional[OutputData]: Retrieved vector data or None if not found
|
||||
"""
|
||||
result = self.collection.fetch([(vector_id,)])
|
||||
if not result:
|
||||
return []
|
||||
|
||||
record = result[0]
|
||||
return OutputData(id=str(record.id), score=None, payload=record.metadata)
|
||||
|
||||
def list_cols(self) -> List[str]:
|
||||
"""
|
||||
List all collections.
|
||||
|
||||
Returns:
|
||||
List[str]: List of collection names
|
||||
"""
|
||||
return self.db.list_collections()
|
||||
|
||||
def delete_col(self):
|
||||
"""Delete the collection."""
|
||||
self.db.delete_collection(self.collection_name)
|
||||
|
||||
def col_info(self) -> dict:
|
||||
"""
|
||||
Get information about the collection.
|
||||
|
||||
Returns:
|
||||
Dict: Collection information including name and configuration
|
||||
"""
|
||||
info = self.collection.describe()
|
||||
return {
|
||||
"name": info.name,
|
||||
"count": info.vectors,
|
||||
"dimension": info.dimension,
|
||||
"index": {"method": info.index_method, "metric": info.distance_metric},
|
||||
}
|
||||
|
||||
def list(self, filters: Optional[dict] = None, limit: int = 100) -> List[OutputData]:
|
||||
"""
|
||||
List vectors in the collection.
|
||||
|
||||
Args:
|
||||
filters (Dict, optional): Filters to apply
|
||||
limit (int, optional): Maximum number of results to return. Defaults to 100.
|
||||
|
||||
Returns:
|
||||
List[OutputData]: List of vectors
|
||||
"""
|
||||
filters = self._preprocess_filters(filters)
|
||||
query = [0] * self.embedding_model_dims
|
||||
ids = self.collection.query(
|
||||
data=query, limit=limit, filters=filters, include_metadata=True, include_value=False
|
||||
)
|
||||
ids = [id[0] for id in ids]
|
||||
records = self.collection.fetch(ids=ids)
|
||||
|
||||
return [[OutputData(id=str(record[0]), score=None, payload=record[2]) for record in records]]
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "mem0ai"
|
||||
version = "0.1.58"
|
||||
version = "0.1.61"
|
||||
description = "Long-term memory for AI Agents"
|
||||
authors = ["Mem0 <founders@mem0.ai>"]
|
||||
exclude = [
|
||||
|
||||
+8
-4
@@ -41,10 +41,14 @@ def test_add(memory_instance, version, enable_graph):
|
||||
|
||||
result = memory_instance.add(messages=[{"role": "user", "content": "Test message"}], user_id="test_user")
|
||||
|
||||
assert "results" in result
|
||||
assert result["results"] == [{"memory": "Test memory", "event": "ADD"}]
|
||||
assert "relations" in result
|
||||
assert result["relations"] == []
|
||||
if enable_graph:
|
||||
assert "results" in result
|
||||
assert result["results"] == [{"memory": "Test memory", "event": "ADD"}]
|
||||
assert "relations" in result
|
||||
assert result["relations"] == []
|
||||
else:
|
||||
assert "results" in result
|
||||
assert result["results"] == [{"memory": "Test memory", "event": "ADD"}]
|
||||
|
||||
memory_instance._add_to_vector_store.assert_called_once_with(
|
||||
[{"role": "user", "content": "Test message"}], {"user_id": "test_user"}, {"user_id": "test_user"}
|
||||
|
||||
@@ -51,21 +51,21 @@ class TestQdrant(unittest.TestCase):
|
||||
|
||||
def test_search(self):
|
||||
query_vector = [0.1, 0.2]
|
||||
self.client_mock.search.return_value = [{"id": str(uuid.uuid4()), "score": 0.95, "payload": {"key": "value"}}]
|
||||
mock_point = MagicMock(id=str(uuid.uuid4()), score=0.95, payload={"key": "value"})
|
||||
self.client_mock.query_points.return_value = MagicMock(points=[mock_point])
|
||||
|
||||
results = self.qdrant.search(query=query_vector, limit=1)
|
||||
|
||||
self.client_mock.search.assert_called_once_with(
|
||||
self.client_mock.query_points.assert_called_once_with(
|
||||
collection_name="test_collection",
|
||||
query_vector=query_vector,
|
||||
query=query_vector,
|
||||
query_filter=None,
|
||||
limit=1,
|
||||
)
|
||||
|
||||
self.assertEqual(len(results), 1)
|
||||
self.assertIn("id", results[0])
|
||||
self.assertIn("score", results[0])
|
||||
self.assertIn("payload", results[0])
|
||||
self.assertEqual(results[0].payload, {"key": "value"})
|
||||
self.assertEqual(results[0].score, 0.95)
|
||||
|
||||
def test_delete(self):
|
||||
vector_id = str(uuid.uuid4())
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
from unittest.mock import Mock, patch
|
||||
|
||||
import pytest
|
||||
|
||||
from mem0.configs.vector_stores.supabase import IndexMeasure, IndexMethod
|
||||
from mem0.vector_stores.supabase import Supabase
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_vecs_client():
|
||||
with patch("vecs.create_client") as mock_client:
|
||||
yield mock_client
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def mock_collection():
|
||||
collection = Mock()
|
||||
collection.name = "test_collection"
|
||||
collection.vectors = 100
|
||||
collection.dimension = 1536
|
||||
collection.index_method = "hnsw"
|
||||
collection.distance_metric = "cosine_distance"
|
||||
collection.describe.return_value = collection
|
||||
return collection
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def supabase_instance(mock_vecs_client, mock_collection):
|
||||
# Set up the mock client to return our mock collection
|
||||
mock_vecs_client.return_value.get_or_create_collection.return_value = mock_collection
|
||||
mock_vecs_client.return_value.list_collections.return_value = ["test_collection"]
|
||||
|
||||
instance = Supabase(
|
||||
connection_string="postgresql://user:password@localhost:5432/test",
|
||||
collection_name="test_collection",
|
||||
embedding_model_dims=1536,
|
||||
index_method=IndexMethod.HNSW,
|
||||
index_measure=IndexMeasure.COSINE,
|
||||
)
|
||||
|
||||
# Manually set the collection attribute since we're mocking the initialization
|
||||
instance.collection = mock_collection
|
||||
return instance
|
||||
|
||||
|
||||
def test_create_col(supabase_instance, mock_vecs_client, mock_collection):
|
||||
supabase_instance.create_col(1536)
|
||||
|
||||
mock_vecs_client.return_value.get_or_create_collection.assert_called_with(
|
||||
name="test_collection",
|
||||
dimension=1536
|
||||
)
|
||||
mock_collection.create_index.assert_called_with(
|
||||
method="hnsw",
|
||||
measure="cosine_distance"
|
||||
)
|
||||
|
||||
|
||||
def test_insert_vectors(supabase_instance, mock_collection):
|
||||
vectors = [[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]
|
||||
payloads = [{"name": "vector1"}, {"name": "vector2"}]
|
||||
ids = ["id1", "id2"]
|
||||
|
||||
supabase_instance.insert(vectors=vectors, payloads=payloads, ids=ids)
|
||||
|
||||
expected_records = [
|
||||
("id1", [0.1, 0.2, 0.3], {"name": "vector1"}),
|
||||
("id2", [0.4, 0.5, 0.6], {"name": "vector2"})
|
||||
]
|
||||
mock_collection.upsert.assert_called_once_with(expected_records)
|
||||
|
||||
|
||||
def test_search_vectors(supabase_instance, mock_collection):
|
||||
mock_results = [
|
||||
("id1", 0.9, {"name": "vector1"}),
|
||||
("id2", 0.8, {"name": "vector2"})
|
||||
]
|
||||
mock_collection.query.return_value = mock_results
|
||||
|
||||
query = [0.1, 0.2, 0.3]
|
||||
filters = {"category": "test"}
|
||||
results = supabase_instance.search(query=query, limit=2, filters=filters)
|
||||
|
||||
mock_collection.query.assert_called_once_with(
|
||||
data=query,
|
||||
limit=2,
|
||||
filters={"category": {"$eq": "test"}},
|
||||
include_metadata=True,
|
||||
include_value=True
|
||||
)
|
||||
|
||||
assert len(results) == 2
|
||||
assert results[0].id == "id1"
|
||||
assert results[0].score == 0.9
|
||||
assert results[0].payload == {"name": "vector1"}
|
||||
|
||||
|
||||
def test_delete_vector(supabase_instance, mock_collection):
|
||||
vector_id = "id1"
|
||||
supabase_instance.delete(vector_id=vector_id)
|
||||
mock_collection.delete.assert_called_once_with([("id1",)])
|
||||
|
||||
|
||||
def test_update_vector(supabase_instance, mock_collection):
|
||||
vector_id = "id1"
|
||||
new_vector = [0.7, 0.8, 0.9]
|
||||
new_payload = {"name": "updated_vector"}
|
||||
|
||||
supabase_instance.update(vector_id=vector_id, vector=new_vector, payload=new_payload)
|
||||
mock_collection.upsert.assert_called_once_with([("id1", new_vector, new_payload)])
|
||||
|
||||
|
||||
def test_get_vector(supabase_instance, mock_collection):
|
||||
# Create a Mock object to represent the record
|
||||
mock_record = Mock()
|
||||
mock_record.id = "id1"
|
||||
mock_record.metadata = {"name": "vector1"}
|
||||
mock_record.values = [0.1, 0.2, 0.3]
|
||||
|
||||
# Set the fetch return value to a list containing our mock record
|
||||
mock_collection.fetch.return_value = [mock_record]
|
||||
|
||||
result = supabase_instance.get(vector_id="id1")
|
||||
|
||||
mock_collection.fetch.assert_called_once_with([("id1",)])
|
||||
assert result.id == "id1"
|
||||
assert result.payload == {"name": "vector1"}
|
||||
|
||||
|
||||
def test_list_vectors(supabase_instance, mock_collection):
|
||||
mock_query_results = [("id1", 0.9, {}), ("id2", 0.8, {})]
|
||||
mock_fetch_results = [
|
||||
("id1", [0.1, 0.2, 0.3], {"name": "vector1"}),
|
||||
("id2", [0.4, 0.5, 0.6], {"name": "vector2"})
|
||||
]
|
||||
|
||||
mock_collection.query.return_value = mock_query_results
|
||||
mock_collection.fetch.return_value = mock_fetch_results
|
||||
|
||||
results = supabase_instance.list(limit=2, filters={"category": "test"})
|
||||
|
||||
assert len(results[0]) == 2
|
||||
assert results[0][0].id == "id1"
|
||||
assert results[0][0].payload == {"name": "vector1"}
|
||||
assert results[0][1].id == "id2"
|
||||
assert results[0][1].payload == {"name": "vector2"}
|
||||
|
||||
|
||||
def test_col_info(supabase_instance, mock_collection):
|
||||
info = supabase_instance.col_info()
|
||||
|
||||
assert info == {
|
||||
"name": "test_collection",
|
||||
"count": 100,
|
||||
"dimension": 1536,
|
||||
"index": {
|
||||
"method": "hnsw",
|
||||
"metric": "cosine_distance"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_preprocess_filters(supabase_instance):
|
||||
# Test single filter
|
||||
single_filter = {"category": "test"}
|
||||
assert supabase_instance._preprocess_filters(single_filter) == {"category": {"$eq": "test"}}
|
||||
|
||||
# Test multiple filters
|
||||
multi_filter = {"category": "test", "type": "document"}
|
||||
assert supabase_instance._preprocess_filters(multi_filter) == {
|
||||
"$and": [
|
||||
{"category": {"$eq": "test"}},
|
||||
{"type": {"$eq": "document"}}
|
||||
]
|
||||
}
|
||||
|
||||
# Test None filters
|
||||
assert supabase_instance._preprocess_filters(None) is None
|
||||
Reference in New Issue
Block a user