Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78912928bc | ||
|
|
8bd0d2dc24 | ||
|
|
f0bdd2c341 | ||
|
|
bf0c4adc0c | ||
|
|
2cca50db80 | ||
|
|
b8e4d0980a | ||
|
|
3613e2f14a | ||
|
|
541030d69c | ||
|
|
f77a084d1b | ||
|
|
33abf772ce | ||
|
|
c3c9205ffa | ||
|
|
9f204dc557 | ||
|
|
0e98773efb | ||
|
|
4431bd7d51 | ||
|
|
0354ab0d6b | ||
|
|
6dfc193296 | ||
|
|
9be6850b9d | ||
|
|
d33547a77a | ||
|
|
d77bed2d5d | ||
|
|
9c89e0ec95 | ||
|
|
ca1ee2d2d7 | ||
|
|
05f9607282 | ||
|
|
d9236de4ed | ||
|
|
942727fec6 | ||
|
|
72396e307d | ||
|
|
881cf5b5a6 | ||
|
|
5327d6e50d | ||
|
|
15a3e20371 | ||
|
|
19d7beef43 | ||
|
|
8b789adb15 | ||
|
|
fd065fe9cc | ||
|
|
b5127f7c62 | ||
|
|
37d9fed690 | ||
|
|
31861e9acb | ||
|
|
07462adc9a | ||
|
|
616313b8b5 | ||
|
|
44f2490667 | ||
|
|
3cc794fb98 | ||
|
|
ff6b251c66 | ||
|
|
55df395fd6 | ||
|
|
244e60cea6 | ||
|
|
b480c71f0f | ||
|
|
309c8c18a6 | ||
|
|
f4d8647264 | ||
|
|
f95c4cbbe5 | ||
|
|
00c7cc432c | ||
|
|
91abc03880 | ||
|
|
9100e95175 | ||
|
|
cdb8dcdb9e | ||
|
|
2a79add7a5 | ||
|
|
9dfa9b4412 | ||
|
|
5509066925 | ||
|
|
3712522b14 | ||
|
|
93f34e4116 | ||
|
|
39e5cbfacc | ||
|
|
d30c78c5eb | ||
|
|
039756abbe | ||
|
|
cb38c2dae7 | ||
|
|
4dc9f6fad6 | ||
|
|
1b1f02eb57 | ||
|
|
1db1105cad | ||
|
|
91a28c7f04 | ||
|
|
a78e1894b1 | ||
|
|
83338295d8 | ||
|
|
aff70807c6 | ||
|
|
648c86b53d | ||
|
|
de0b2de9c2 | ||
|
|
e3f460fba4 | ||
|
|
fe7b336922 | ||
|
|
1033ab227c | ||
|
|
5ed15c3bcd | ||
|
|
c1f5a655ba | ||
|
|
72bb631bb5 | ||
|
|
2bf9286071 | ||
|
|
884b597312 | ||
|
|
f1471bcc55 | ||
|
|
9ae23f9c88 | ||
|
|
cbecbb7b64 | ||
|
|
f8ad0c2b2c | ||
|
|
d0da9a1ae0 | ||
|
|
bc4ab3db77 | ||
|
|
0eb53b9f27 | ||
|
|
3cef3ed95e | ||
|
|
45e5f2af93 | ||
|
|
32ba13b3ea | ||
|
|
69a91d5cbb | ||
|
|
2004427acd | ||
|
|
2517ccd489 | ||
|
|
9d0300f774 | ||
|
|
366d263e0b | ||
|
|
4321d24284 | ||
|
|
9cb2a13f3b | ||
|
|
5ec7889d9a | ||
|
|
b54845bcc9 | ||
|
|
1ae2747ff8 | ||
|
|
953a5a4a2d | ||
|
|
2b49c9eedd | ||
|
|
9db5f62262 | ||
|
|
a1bd4285db | ||
|
|
e77a10a8da | ||
|
|
e4307ae420 | ||
|
|
7c89d00079 | ||
|
|
563eaae5ee | ||
|
|
6733f78f81 | ||
|
|
c11637bd2f | ||
|
|
ff30cb8ddd | ||
|
|
2e853c3d22 | ||
|
|
3cc7013fde | ||
|
|
8e6a08aa83 | ||
|
|
8b9a8e5825 | ||
|
|
afc630272d | ||
|
|
e33008e3a4 | ||
|
|
7b516328a8 | ||
|
|
6d5889d98f | ||
|
|
ee66e0c954 | ||
|
|
1aed611539 | ||
|
|
6c2b131d6e | ||
|
|
2ffe9922f3 | ||
|
|
540ada489b | ||
|
|
65cffa0369 | ||
|
|
9f937943ba | ||
|
|
51a68bf7c5 | ||
|
|
92541d8955 | ||
|
|
0e0be18ecc | ||
|
|
66d3f9b93c | ||
|
|
b8f40f728f | ||
|
|
00a2ea9ff0 | ||
|
|
9545836469 | ||
|
|
3acd9e20da | ||
|
|
d48ecd52ef | ||
|
|
2fbea7705b | ||
|
|
d7a26bd0c3 | ||
|
|
e25dc4b504 | ||
|
|
dab3349990 | ||
|
|
6db87e8d07 | ||
|
|
faf811ee2d | ||
|
|
ee80a43810 | ||
|
|
4be426f762 | ||
|
|
ba9c61938b | ||
|
|
65f826e064 | ||
|
|
b43363cdf3 | ||
|
|
89e786a88e | ||
|
|
2d5062bd40 | ||
|
|
b89628322d | ||
|
|
6e4fb22a7c | ||
|
|
9c0954133f | ||
|
|
e9a0be66d8 | ||
|
|
192c33f190 | ||
|
|
75ca528666 | ||
|
|
e30e4967ae | ||
|
|
d3911b92cf | ||
|
|
92cfc1c8ef | ||
|
|
33fcc53e4b | ||
|
|
e761a1e865 | ||
|
|
f2ce92ebcc | ||
|
|
bbb812e0a0 | ||
|
|
9a302cef30 | ||
|
|
ae729da4d1 | ||
|
|
655ae794b6 | ||
|
|
1aef468ebe | ||
|
|
78baf7495d | ||
|
|
6cf7ac3e30 | ||
|
|
07d2f11081 | ||
|
|
c6fbba6a4d | ||
|
|
b701a50b51 | ||
|
|
5865d79de7 | ||
|
|
41a42da774 | ||
|
|
6d7ef3ae45 | ||
|
|
2c31a930a3 | ||
|
|
c7e2a71cd5 | ||
|
|
4237b9220b | ||
|
|
cabe29c7c7 | ||
|
|
80b7202db6 | ||
|
|
8c6d16a6f0 | ||
|
|
dd1f2989bc | ||
|
|
540ec1b816 | ||
|
|
728ef98d6e | ||
|
|
329d0cc945 | ||
|
|
0234c85be5 | ||
|
|
eca1e06711 | ||
|
|
2611343cbe | ||
|
|
8bde881e2c | ||
|
|
6fdc63504a | ||
|
|
23dbce4f59 |
@@ -25,22 +25,23 @@ jobs:
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
cd embedchain
|
||||
cd mem0
|
||||
poetry install
|
||||
|
||||
- name: Build a binary wheel and a source tarball
|
||||
run: |
|
||||
cd embedchain
|
||||
cd mem0
|
||||
poetry build
|
||||
|
||||
- name: Publish distribution 📦 to Test PyPI
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
repository_url: https://test.pypi.org/legacy/
|
||||
packages_dir: embedchain/dist/
|
||||
# TODO: Needs to setup mem0 repo on Test PyPI
|
||||
# - name: Publish distribution 📦 to Test PyPI
|
||||
# uses: pypa/gh-action-pypi-publish@release/v1
|
||||
# with:
|
||||
# repository_url: https://test.pypi.org/legacy/
|
||||
# packages_dir: dist/
|
||||
|
||||
- name: Publish distribution 📦 to PyPI
|
||||
if: startsWith(github.ref, 'refs/tags')
|
||||
uses: pypa/gh-action-pypi-publish@release/v1
|
||||
with:
|
||||
packages_dir: embedchain/dist/
|
||||
packages_dir: dist/
|
||||
|
||||
@@ -12,8 +12,9 @@ install:
|
||||
|
||||
install_all:
|
||||
poetry install
|
||||
poetry run pip install groq together boto3 litellm ollama chromadb sentence_transformers vertexai \
|
||||
google-generativeai elasticsearch opensearch-py vecs
|
||||
poetry run pip install groq together boto3 litellm ollama chromadb weaviate weaviate-client sentence_transformers vertexai \
|
||||
google-generativeai elasticsearch opensearch-py vecs pinecone pinecone-text faiss-cpu langchain-community \
|
||||
upstash-vector azure-search-documents
|
||||
|
||||
# Format code with ruff
|
||||
format:
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
<a href="https://mem0.ai">Learn more</a>
|
||||
·
|
||||
<a href="https://mem0.dev/DiG">Join Discord</a>
|
||||
·
|
||||
<a href="https://mem0.dev/demo">Demo</a>
|
||||
</p>
|
||||
</p>
|
||||
|
||||
@@ -79,7 +81,7 @@ npm install mem0ai
|
||||
|
||||
### Basic Usage
|
||||
|
||||
Mem0 requires an LLM to function, with `gpt-4o` from OpenAI as the default. However, it supports a variety of LLMs; for details, refer to our [Supported LLMs documentation](https://docs.mem0.ai/llms).
|
||||
Mem0 requires an LLM to function, with `gpt-4o-mini` from OpenAI as the default. However, it supports a variety of LLMs; for details, refer to our [Supported LLMs documentation](https://docs.mem0.ai/llms).
|
||||
|
||||
First step is to instantiate the memory:
|
||||
|
||||
@@ -93,7 +95,7 @@ memory = Memory()
|
||||
def chat_with_memories(message: str, user_id: str = "default_user") -> str:
|
||||
# Retrieve relevant memories
|
||||
relevant_memories = memory.search(query=message, user_id=user_id, limit=3)
|
||||
memories_str = "\n".join(f"- {entry['memory']}" for entry in relevant_memories)
|
||||
memories_str = "\n".join(f"- {entry['memory']}" for entry in relevant_memories["results"])
|
||||
|
||||
# Generate Assistant response
|
||||
system_prompt = f"You are a helpful AI. Answer the question based on query and memories.\nUser Memories:\n{memories_str}"
|
||||
@@ -129,15 +131,17 @@ For more advanced usage and API documentation, visit our [documentation](https:/
|
||||
|
||||
## Demos
|
||||
|
||||
- AI Companion: Experience personalized conversations with an AI that remembers your preferences and past interactions
|
||||
- Mem0 - ChatGPT with Memory: A personalized AI chat app powered by Mem0 that remembers your preferences, facts, and memories.
|
||||
|
||||
[AI Companion Demo](https://github.com/user-attachments/assets/3fc72023-a72c-4593-8be0-3cee3ba744da)
|
||||
[Mem0 - ChatGPT with Memory](https://github.com/user-attachments/assets/cebc4f8e-bdb9-4837-868d-13c5ab7bb433)
|
||||
|
||||
Try live [demo](https://mem0.dev/demo/)
|
||||
|
||||
<br/><br/>
|
||||
|
||||
- Mem0 Demo: A personalized AI chat app powered by Mem0 that remembers your preferences, facts, and memories.
|
||||
- AI Companion: Experience personalized conversations with an AI that remembers your preferences and past interactions
|
||||
|
||||
[Mem0 Demo](https://github.com/user-attachments/assets/cebc4f8e-bdb9-4837-868d-13c5ab7bb433)
|
||||
[AI Companion Demo](https://github.com/user-attachments/assets/3fc72023-a72c-4593-8be0-3cee3ba744da)
|
||||
|
||||
<br/><br/>
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
title: 'Feedback'
|
||||
openapi: post /v1/feedback/
|
||||
---
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: 'Get Memory Export'
|
||||
openapi: get /v1/exports/
|
||||
openapi: post /v1/exports/get
|
||||
---
|
||||
|
||||
Retrieve the latest structured memory export after submitting an export job. You can filter the export by `user_id`, `run_id`, `session_id`, or `app_id` to get the most recent export matching your filters.
|
||||
@@ -0,0 +1,328 @@
|
||||
---
|
||||
title: "Product Updates"
|
||||
mode: "wide"
|
||||
---
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
|
||||
<Update label="2025-04-16" description="v0.1.91">
|
||||
|
||||
**New Features:**
|
||||
- **LLM Integrations:** Added Azure OpenAI Embedding Model
|
||||
- **Examples:**
|
||||
- Added movie recommendation using grok3
|
||||
- Added Voice Assistant using Elevenlabs
|
||||
|
||||
**Improvements:**
|
||||
- **Documentation:**
|
||||
- Added keywords AI
|
||||
- Reformatted navbar page URLs
|
||||
- Updated changelog
|
||||
- Updated openai.mdx
|
||||
- **FAISS:** Silenced FAISS info logs
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-11" description="v0.1.90">
|
||||
|
||||
**New Features:**
|
||||
- **LLM Integrations:** Added Mistral AI as LLM provider
|
||||
|
||||
**Improvements:**
|
||||
- **Documentation:**
|
||||
- Updated changelog
|
||||
- Fixed memory exclusion example
|
||||
- Updated xAI documentation
|
||||
- Updated YouTube Chrome extension example documentation
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Core:** Fixed EmbedderFactory.create() in GraphMemory
|
||||
- **Azure OpenAI:** Added patch to fix Azure OpenAI
|
||||
- **Telemetry:** Fixed telemetry issue
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-11" description="v0.1.89">
|
||||
|
||||
**New Features:**
|
||||
- **Langchain Integration:** Added support for Langchain VectorStores
|
||||
- **Examples:**
|
||||
- Added personal assistant example
|
||||
- Added personal study buddy example
|
||||
- Added YouTube assistant Chrome extension example
|
||||
- Added agno example
|
||||
- Updated OpenAI Responses API examples
|
||||
- **Vector Store:** Added capability to store user_id in vector database
|
||||
- **Async Memory:** Added async support for OSS
|
||||
|
||||
**Improvements:**
|
||||
- **Documentation:** Updated formatting and examples
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-09" description="v0.1.87">
|
||||
|
||||
**New Features:**
|
||||
- **Upstash Vector:** Added support for Upstash Vector store
|
||||
|
||||
**Improvements:**
|
||||
- **Code Quality:** Removed redundant code lines
|
||||
- **Build:** Updated MAKEFILE
|
||||
- **Documentation:** Updated memory export documentation
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-07" description="v0.1.86">
|
||||
|
||||
**Improvements:**
|
||||
- **FAISS:** Added embedding_dims parameter to FAISS vector store
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-07" description="v0.1.84">
|
||||
|
||||
**New Features:**
|
||||
- **Langchain Embedder:** Added Langchain embedder integration
|
||||
|
||||
**Improvements:**
|
||||
- **Langchain LLM:** Updated Langchain LLM integration to directly pass the Langchain object LLM
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-07" description="v0.1.83">
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Langchain LLM:** Fixed issues with Langchain LLM integration
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-07" description="v0.1.82">
|
||||
|
||||
**New Features:**
|
||||
- **LLM Integrations:** Added support for Langchain LLMs, Google as new LLM and embedder
|
||||
- **Development:** Added development docker compose
|
||||
|
||||
**Improvements:**
|
||||
- **Output Format:** Set output_format='v1.1' and updated documentation
|
||||
|
||||
**Documentation:**
|
||||
- **Integrations:** Added LMStudio and Together.ai documentation
|
||||
- **API Reference:** Updated output_format documentation
|
||||
- **Integrations:** Added PipeCat integration documentation
|
||||
- **Integrations:** Added Flowise integration documentation for Mem0 memory setup
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Tests:** Fixed failing unit tests
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-02" description="v0.1.79">
|
||||
|
||||
**New Features:**
|
||||
- **FAISS Support:** Added FAISS vector store support
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-02" description="v0.1.78">
|
||||
|
||||
**New Features:**
|
||||
- **Livekit Integration:** Added Mem0 livekit example
|
||||
- **Evaluation:** Added evaluation framework and tools
|
||||
|
||||
**Documentation:**
|
||||
- **Multimodal:** Updated multimodal documentation
|
||||
- **Examples:** Added examples for email processing
|
||||
- **API Reference:** Updated API reference section
|
||||
- **Elevenlabs:** Added Elevenlabs integration example
|
||||
|
||||
**Bug Fixes:**
|
||||
- **OpenAI Environment Variables:** Fixed issues with OpenAI environment variables
|
||||
- **Deployment Errors:** Added `package.json` file to fix deployment errors
|
||||
- **Tools:** Fixed tools issues and improved formatting
|
||||
- **Docs:** Updated API reference section for `expiration date`
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-26" description="v0.1.77">
|
||||
|
||||
**Bug Fixes:**
|
||||
- **OpenAI Environment Variables:** Fixed issues with OpenAI environment variables
|
||||
- **Deployment Errors:** Added `package.json` file to fix deployment errors
|
||||
- **Tools:** Fixed tools issues and improved formatting
|
||||
- **Docs:** Updated API reference section for `expiration date`
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-19" description="v0.1.76">
|
||||
**New Features:**
|
||||
- **Supabase Vector Store:** Added support for Supabase Vector Store
|
||||
- **Supabase History DB:** Added Supabase History DB to run Mem0 OSS on Serverless
|
||||
- **Feedback Method:** Added feedback method to client
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Azure OpenAI:** Fixed issues with Azure OpenAI
|
||||
- **Azure AI Search:** Fixed test cases for Azure AI Search
|
||||
</Update>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="TypeScript">
|
||||
|
||||
<Update label="2025-04-17" description="v2.1.18">
|
||||
**Improvements:**
|
||||
- **Client:** Added support for custom instructions
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-15" description="v2.1.17">
|
||||
**New Features:**
|
||||
- **OSS SDK:** Added support for Langchain LLM
|
||||
- **OSS SDK:** Added support for Langchain Embedder
|
||||
- **OSS SDK:** Added support for Langchain Vector Store
|
||||
- **OSS SDK:** Added support for Azure OpenAI Embedder
|
||||
|
||||
|
||||
**Improvements:**
|
||||
- **OSS SDK:** Changed `model` in LLM and Embedder to use type any from `string` to use langchain llm models
|
||||
- **OSS SDK:** Added client to vector store config for langchain vector store
|
||||
- **OSS SDK:** - Updated Azure OpenAI to use new OpenAI SDK
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-11" description="v2.1.16-patch.1">
|
||||
**Bug Fixes:**
|
||||
- **Azure OpenAI:** Fixed issues with Azure OpenAI
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-11" description="v2.1.16">
|
||||
**New Features:**
|
||||
- **Azure OpenAI:** Added support for Azure OpenAI
|
||||
- **Mistral LLM:** Added Mistral LLM integration in OSS
|
||||
|
||||
**Improvements:**
|
||||
- **Zod:** Updated Zod to 3.24.1 to avoid conflicts with other packages
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-09" description="v2.1.15">
|
||||
**Improvements:**
|
||||
- **Client:** Added support for Mem0 to work with Chrome Extensions
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-01" description="v2.1.14">
|
||||
**New Features:**
|
||||
- **Mastra Example:** Added Mastra example
|
||||
- **Integrations:** Added Flowise integration documentation for Mem0 memory setup
|
||||
|
||||
**Improvements:**
|
||||
- **Demo:** Updated Demo Mem0AI
|
||||
- **Client:** Enhanced Ping method in Mem0 Client
|
||||
- **AI SDK:** Updated AI SDK implementation
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-29" description="v2.1.13">
|
||||
**Improvements:**
|
||||
- **Introuced `ping` method to check if API key is valid and populate org/project id**
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-29" description="AI SDK v1.0.0">
|
||||
**New Features:**
|
||||
- **Vercel AI SDK Update:** Support threshold and rerank
|
||||
|
||||
**Improvements:**
|
||||
- **Made add calls async to avoid blocking**
|
||||
- **Bump `mem0ai` to use `2.1.12`**
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-26" description="v2.1.12">
|
||||
**New Features:**
|
||||
- **Mem0 OSS:** Support infer param
|
||||
|
||||
**Improvements:**
|
||||
- **Updated Supabase TS Docs**
|
||||
- **Made package size smaller**
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-19" description="v2.1.11">
|
||||
**New Features:**
|
||||
- **Supabase Vector Store Integration**
|
||||
- **Feedback Method**
|
||||
</Update>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Platform">
|
||||
|
||||
<Update label="2025-04-12" description="">
|
||||
|
||||
**New Features:**
|
||||
- **Memory Management:**
|
||||
- Added ability to delete memories from Project level with filters
|
||||
- Added delete memories capability on Memories Page
|
||||
- **Memory Visualization:** Released V1 Graph Memory Visualization
|
||||
- **Graph Playground:** Enabled for @mem0.ai users
|
||||
- **Notifications:** Added email alerts to organization owners when new members join
|
||||
- **Memory Export:** Added date support for filtering memory exports
|
||||
|
||||
**Improvements:**
|
||||
- **Performance:**
|
||||
- Optimized graph for better performance
|
||||
- Optimized database calls in ADD method
|
||||
- **Analytics:** Added flagging of paid users in Posthog
|
||||
- **CI/CD:** Improved CI pipeline and fixed lint issues
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-10" description="">
|
||||
|
||||
**New Features:**
|
||||
- **Notifications:** Implemented email notifications for organization owners when new members join
|
||||
|
||||
**Improvements:**
|
||||
- **CI/CD:** Fixed Dockerfile for CI tests
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-09" description="">
|
||||
|
||||
**Improvements:**
|
||||
- **Integrations:** Updated chat model for Together Qwen
|
||||
- **Platform:** Removed older platforms
|
||||
- **Bug Fixes:** Fixed FILTER_MAPPING
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-03" description="">
|
||||
|
||||
**New Features:**
|
||||
- **Memory:** Added implicit memory capabilities
|
||||
- **API:** Improved implicit lambda and get_all v2 functionality
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-04-02" description="">
|
||||
|
||||
**New Features:**
|
||||
- **Integrations:** Added Clay integration
|
||||
|
||||
**Improvements:**
|
||||
- **Integrations:** Removed deepseek coder from Together
|
||||
- **API:** Added custom instructions for add v2
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-31" description="">
|
||||
|
||||
**Security:**
|
||||
- **Validation:** Added key validation in messages
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-28" description="">
|
||||
- **Updated Playground Prompt**
|
||||
- **Send Email on User Addition to Org/Proj**
|
||||
- **Fix Search Entity**
|
||||
</Update>
|
||||
|
||||
<Update label="2025-03-19" description="">
|
||||
- **General Stability & Performance Improvements**
|
||||
</Update>
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -84,6 +84,7 @@ Here's a comprehensive list of all parameters that can be used across different
|
||||
| `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 |
|
||||
| `lmstudio_base_url` | Base URL for LM Studio API | LM Studio |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Provider |
|
||||
|
||||
@@ -6,7 +6,8 @@ To use Azure OpenAI embedding models, set the `EMBEDDING_AZURE_OPENAI_API_KEY`,
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -46,6 +47,36 @@ messages = [
|
||||
m.add(messages, user_id="john")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
embedder: {
|
||||
provider: "azure_openai",
|
||||
config: {
|
||||
model: "text-embedding-3-large",
|
||||
modelProperties: {
|
||||
endpoint: "your-api-base-url",
|
||||
deployment: "your-deployment-name",
|
||||
apiVersion: "version-to-use",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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: "john" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Azure OpenAI embedder:
|
||||
|
||||
@@ -0,0 +1,146 @@
|
||||
---
|
||||
title: LangChain
|
||||
---
|
||||
|
||||
Mem0 supports LangChain as a provider to access a wide range of embedding models. LangChain is a framework for developing applications powered by language models, making it easy to integrate various embedding providers through a consistent interface.
|
||||
|
||||
For a complete list of available embedding models supported by LangChain, refer to the [LangChain Text Embedding documentation](https://python.langchain.com/docs/integrations/text_embedding/).
|
||||
|
||||
## Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
|
||||
# Set necessary environment variables for your chosen LangChain provider
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
# Initialize a LangChain embeddings model directly
|
||||
openai_embeddings = OpenAIEmbeddings(
|
||||
model="text-embedding-3-small",
|
||||
dimensions=1536
|
||||
)
|
||||
|
||||
# Pass the initialized model to the config
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "langchain",
|
||||
"config": {
|
||||
"model": openai_embeddings
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from "mem0ai";
|
||||
import { OpenAIEmbeddings } from "@langchain/openai";
|
||||
|
||||
const embeddings = new OpenAIEmbeddings();
|
||||
const config = {
|
||||
"embedder": {
|
||||
"provider": "langchain",
|
||||
"config": {
|
||||
"model": embeddings
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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." }
|
||||
]
|
||||
|
||||
memory.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Supported LangChain Embedding Providers
|
||||
|
||||
LangChain supports a wide range of embedding providers, including:
|
||||
|
||||
- OpenAI (`OpenAIEmbeddings`)
|
||||
- Cohere (`CohereEmbeddings`)
|
||||
- Google (`VertexAIEmbeddings`)
|
||||
- Hugging Face (`HuggingFaceEmbeddings`)
|
||||
- Sentence Transformers (`HuggingFaceEmbeddings`)
|
||||
- Azure OpenAI (`AzureOpenAIEmbeddings`)
|
||||
- Ollama (`OllamaEmbeddings`)
|
||||
- Together (`TogetherEmbeddings`)
|
||||
- And many more
|
||||
|
||||
You can use any of these model instances directly in your configuration. For a complete and up-to-date list of available embedding providers, refer to the [LangChain Text Embedding documentation](https://python.langchain.com/docs/integrations/text_embedding/).
|
||||
|
||||
## Provider-Specific Configuration
|
||||
|
||||
When using LangChain as an embedder provider, you'll need to:
|
||||
|
||||
1. Set the appropriate environment variables for your chosen embedding provider
|
||||
2. Import and initialize the specific model class you want to use
|
||||
3. Pass the initialized model instance to the config
|
||||
|
||||
### Examples with Different Providers
|
||||
|
||||
#### HuggingFace Embeddings
|
||||
|
||||
```python
|
||||
from langchain_huggingface import HuggingFaceEmbeddings
|
||||
|
||||
# Initialize a HuggingFace embeddings model
|
||||
hf_embeddings = HuggingFaceEmbeddings(
|
||||
model_name="BAAI/bge-small-en-v1.5",
|
||||
encode_kwargs={"normalize_embeddings": True}
|
||||
)
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "langchain",
|
||||
"config": {
|
||||
"model": hf_embeddings
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Ollama Embeddings
|
||||
|
||||
```python
|
||||
from langchain_ollama import OllamaEmbeddings
|
||||
|
||||
# Initialize an Ollama embeddings model
|
||||
ollama_embeddings = OllamaEmbeddings(
|
||||
model="nomic-embed-text"
|
||||
)
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "langchain",
|
||||
"config": {
|
||||
"model": ollama_embeddings
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
<Note>
|
||||
Make sure to install the necessary LangChain packages and any provider-specific dependencies.
|
||||
</Note>
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `langchain` embedder config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,38 @@
|
||||
You can use embedding models from LM Studio to run Mem0 locally.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "lmstudio",
|
||||
"config": {
|
||||
"model": "nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.f16.gguf"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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="john")
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Ollama embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the OpenAI model to use | `nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.f16.gguf` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `lmstudio_base_url` | Base URL for LM Studio connection | `http://localhost:1234/v1` |
|
||||
@@ -22,6 +22,8 @@ See the list of supported embedders below.
|
||||
<Card title="Gemini" href="/components/embedders/models/gemini"></Card>
|
||||
<Card title="Vertex AI" href="/components/embedders/models/vertexai"></Card>
|
||||
<Card title="Together" href="/components/embedders/models/together"></Card>
|
||||
<Card title="LM Studio" href="/components/embedders/models/lmstudio"></Card>
|
||||
<Card title="Langchain" href="/components/embedders/models/langchain"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -29,7 +29,7 @@ iconType: "solid"
|
||||
Config values are applied in the following order of precedence (from highest to lowest):
|
||||
|
||||
1. Values explicitly set in the `config` object/dictionary
|
||||
2. Environment variables (e.g., `OPENAI_API_KEY`, `OPENAI_API_BASE`)
|
||||
2. Environment variables (e.g., `OPENAI_API_KEY`, `OPENAI_BASE_URL`)
|
||||
3. Default values defined in the LLM implementation
|
||||
|
||||
This means that values specified in the `config` will override corresponding environment variables, which in turn override default values.
|
||||
@@ -108,6 +108,7 @@ Here's a comprehensive list of all parameters that can be used across different
|
||||
| `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 |
|
||||
| `lmstudio_base_url` | Base URL for LM Studio API | LM Studio |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Provider |
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
title: Azure OpenAI
|
||||
---
|
||||
|
||||
<Note> Mem0 Now Supports Azure OpenAI Models in TypeScript SDK </Note>
|
||||
|
||||
To use Azure OpenAI models, you have to set the `LLM_AZURE_OPENAI_API_KEY`, `LLM_AZURE_ENDPOINT`, `LLM_AZURE_DEPLOYMENT` and `LLM_AZURE_API_VERSION` environment variables. You can obtain the Azure API key from the [Azure](https://azure.microsoft.com/).
|
||||
|
||||
> **Note**: The following are currently unsupported with reasoning models `Parallel tool calling`,`temperature`, `top_p`, `presence_penalty`, `frequency_penalty`, `logprobs`, `top_logprobs`, `logit_bias`, `max_tokens`
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -45,7 +51,38 @@ messages = [
|
||||
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.
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'azure_openai',
|
||||
config: {
|
||||
apiKey: process.env.AZURE_OPENAI_API_KEY || '',
|
||||
modelProperties: {
|
||||
endpoint: 'https://your-api-base-url',
|
||||
deployment: 'your-deployment-name',
|
||||
modelName: 'your-model-name',
|
||||
apiVersion: 'version-to-use',
|
||||
// Any other parameters you want to pass to the Azure OpenAI API
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
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. Typescript SDK does not support the `azure_openai_structured` model yet.
|
||||
|
||||
```python
|
||||
import os
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
---
|
||||
title: LangChain
|
||||
---
|
||||
|
||||
Mem0 supports LangChain as a provider to access a wide range of LLM models. LangChain is a framework for developing applications powered by language models, making it easy to integrate various LLM providers through a consistent interface.
|
||||
|
||||
For a complete list of available chat models supported by LangChain, refer to the [LangChain Chat Models documentation](https://python.langchain.com/docs/integrations/chat).
|
||||
|
||||
## Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
from langchain_openai import ChatOpenAI
|
||||
|
||||
# Set necessary environment variables for your chosen LangChain provider
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
# Initialize a LangChain model directly
|
||||
openai_model = ChatOpenAI(
|
||||
model="gpt-4o",
|
||||
temperature=0.2,
|
||||
max_tokens=2000
|
||||
)
|
||||
|
||||
# Pass the initialized model to the config
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "langchain",
|
||||
"config": {
|
||||
"model": openai_model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from "mem0ai";
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
|
||||
const openai_model = new ChatOpenAI({
|
||||
model: "gpt-4o",
|
||||
temperature: 0.2,
|
||||
max_tokens: 2000
|
||||
})
|
||||
|
||||
const config = {
|
||||
"llm": {
|
||||
"provider": "langchain",
|
||||
"config": {
|
||||
"model": openai_model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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." }
|
||||
]
|
||||
|
||||
memory.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Supported LangChain Providers
|
||||
|
||||
LangChain supports a wide range of LLM providers, including:
|
||||
|
||||
- OpenAI (`ChatOpenAI`)
|
||||
- Anthropic (`ChatAnthropic`)
|
||||
- Google (`ChatGoogleGenerativeAI`, `ChatGooglePalm`)
|
||||
- Mistral (`ChatMistralAI`)
|
||||
- Ollama (`ChatOllama`)
|
||||
- Azure OpenAI (`AzureChatOpenAI`)
|
||||
- HuggingFace (`HuggingFaceChatEndpoint`)
|
||||
- And many more
|
||||
|
||||
You can use any of these model instances directly in your configuration. For a complete and up-to-date list of available providers, refer to the [LangChain Chat Models documentation](https://python.langchain.com/docs/integrations/chat).
|
||||
|
||||
## Provider-Specific Configuration
|
||||
|
||||
When using LangChain as a provider, you'll need to:
|
||||
|
||||
1. Set the appropriate environment variables for your chosen LLM provider
|
||||
2. Import and initialize the specific model class you want to use
|
||||
3. Pass the initialized model instance to the config
|
||||
|
||||
<Note>
|
||||
Make sure to install the necessary LangChain packages and any provider-specific dependencies.
|
||||
</Note>
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `langchain` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: LM Studio
|
||||
---
|
||||
|
||||
To use LM Studio with Mem0, you'll need to have LM Studio running locally with its server enabled. LM Studio provides a way to run local LLMs with an OpenAI-compatible API.
|
||||
|
||||
## Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key" # used for embedding model
|
||||
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "lmstudio",
|
||||
"config": {
|
||||
"model": "lmstudio-community/Meta-Llama-3.1-70B-Instruct-GGUF/Meta-Llama-3.1-70B-Instruct-IQ2_M.gguf",
|
||||
"temperature": 0.2,
|
||||
"max_tokens": 2000,
|
||||
"lmstudio_base_url": "http://localhost:1234/v1", # default LM Studio API URL
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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"})
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Running Completely Locally
|
||||
|
||||
You can also use LM Studio for both LLM and embedding to run Mem0 entirely locally:
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
# No external API keys needed!
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "lmstudio"
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "lmstudio"
|
||||
}
|
||||
}
|
||||
|
||||
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="alice123", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
<Note>
|
||||
When using LM Studio for both LLM and embedding, make sure you have:
|
||||
1. An LLM model loaded for generating responses
|
||||
2. An embedding model loaded for vector embeddings
|
||||
3. The server enabled with the correct endpoints accessible
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
To use LM Studio, you need to:
|
||||
1. Download and install [LM Studio](https://lmstudio.ai/)
|
||||
2. Start a local server from the "Server" tab
|
||||
3. Set the appropriate `lmstudio_base_url` in your configuration (default is usually http://localhost:1234/v1)
|
||||
</Note>
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `lmstudio` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -2,11 +2,12 @@
|
||||
title: Mistral AI
|
||||
---
|
||||
|
||||
To use mistral's models, please Obtain the Mistral AI api key from their [console](https://console.mistral.ai/). Set the `MISTRAL_API_KEY` environment variable to use the model as given below in the example.
|
||||
To use mistral's models, please obtain the Mistral AI api key from their [console](https://console.mistral.ai/). Set the `MISTRAL_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
|
||||
|
||||
@@ -34,6 +35,32 @@ messages = [
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'mistral',
|
||||
config: {
|
||||
apiKey: process.env.MISTRAL_API_KEY || '',
|
||||
model: 'mistral-tiny-latest', // Or 'mistral-small-latest', 'mistral-medium-latest', etc.
|
||||
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 `litellm` config are present in [Master List of All Params in Config](../config).
|
||||
@@ -92,10 +92,6 @@ config = {
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
<Note>
|
||||
OpenAI structured-outputs is currently only available in the Python implementation.
|
||||
</Note>
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `openai` config are present in [Master List of All Params in Config](../config).
|
||||
All available parameters for the `openai` config are present in [Master List of All Params in Config](../config).
|
||||
|
||||
@@ -19,7 +19,7 @@ config = {
|
||||
"llm": {
|
||||
"provider": "xai",
|
||||
"config": {
|
||||
"model": "grok-2-latest",
|
||||
"model": "grok-3-beta",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ To view all supported llms, visit the [Supported LLMs](./models).
|
||||
<Card title="Gemini" href="/components/llms/models/gemini" />
|
||||
<Card title="DeepSeek" href="/components/llms/models/deepseek" />
|
||||
<Card title="xAI" href="/components/llms/models/xAI" />
|
||||
<Card title="LM Studio" href="/components/llms/models/lmstudio" />
|
||||
<Card title="Langchain" href="/components/llms/models/langchain" />
|
||||
</CardGroup>
|
||||
|
||||
## Structured vs Unstructured Outputs
|
||||
|
||||
@@ -8,8 +8,9 @@ iconType: "solid"
|
||||
|
||||
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 object containing provider-specific settings
|
||||
- `provider`: The name of the vector database (e.g., "chroma", "pgvector", "qdrant", "milvus", "upstash_vector", "azure_ai_search", "vertex_ai_vector_search")
|
||||
- `config`: A nested dictionary containing provider-specific settings
|
||||
|
||||
|
||||
## How to Use Config
|
||||
|
||||
@@ -86,6 +87,12 @@ 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 |
|
||||
| `endpoint_id` | Endpoint ID (vertex_ai_vector_search) |
|
||||
| `index_id` | Index ID (vertex_ai_vector_search) |
|
||||
| `deployment_index_id` | Deployment index ID (vertex_ai_vector_search) |
|
||||
| `project_id` | Project ID (vertex_ai_vector_search) |
|
||||
| `project_number` | Project number (vertex_ai_vector_search) |
|
||||
| `vector_search_api_endpoint` | Vector search API endpoint (vertex_ai_vector_search) |
|
||||
| `connection_string` | PostgreSQL connection string (for Supabase/PGVector) |
|
||||
| `index_method` | Vector index method (for Supabase) |
|
||||
| `index_measure` | Distance measure for similarity search (for Supabase) |
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
---
|
||||
title: Azure AI Search
|
||||
---
|
||||
|
||||
[Azure AI Search](https://learn.microsoft.com/azure/search/search-what-is-azure-search/) (formerly known as "Azure Cognitive Search") provides secure information retrieval at scale over user-owned content in traditional and generative AI search applications.
|
||||
|
||||
## Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx" # This key is used for embedding purpose
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "azure_ai_search",
|
||||
"config": {
|
||||
"service_name": "ai-search-test",
|
||||
"api_key": "*****",
|
||||
"collection_name": "mem0",
|
||||
"embedding_model_dims": 1536
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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"})
|
||||
```
|
||||
|
||||
## Using binary compression for large vector collections
|
||||
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "azure_ai_search",
|
||||
"config": {
|
||||
"service_name": "ai-search-test",
|
||||
"api_key": "*****",
|
||||
"collection_name": "mem0",
|
||||
"embedding_model_dims": 1536,
|
||||
"compression_type": "binary",
|
||||
"use_float16": True # Use half precision for storage efficiency
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Using hybrid search
|
||||
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "azure_ai_search",
|
||||
"config": {
|
||||
"service_name": "ai-search-test",
|
||||
"api_key": "*****",
|
||||
"collection_name": "mem0",
|
||||
"embedding_model_dims": 1536,
|
||||
"hybrid_search": True,
|
||||
"vector_filter_mode": "postFilter"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration Parameters
|
||||
|
||||
| Parameter | Description | Default Value | Options |
|
||||
| --- | --- | --- | --- |
|
||||
| `service_name` | Azure AI Search service name | Required | - |
|
||||
| `api_key` | API key of the Azure AI Search service | Required | - |
|
||||
| `collection_name` | The name of the collection/index to store vectors | `mem0` | Any valid index name |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` | Any integer value |
|
||||
| `compression_type` | Type of vector compression to use | `none` | `none`, `scalar`, `binary` |
|
||||
| `use_float16` | Store vectors in half precision (Edm.Half) | `False` | `True`, `False` |
|
||||
| `vector_filter_mode` | Vector filter mode to use | `preFilter` | `postFilter`, `preFilter` |
|
||||
| `hybrid_search` | Use hybrid search | `False` | `True`, `False` |
|
||||
|
||||
## Notes on Configuration Options
|
||||
|
||||
- **compression_type**:
|
||||
- `none`: No compression, uses full vector precision
|
||||
- `scalar`: Scalar quantization with reasonable balance of speed and accuracy
|
||||
- `binary`: Binary quantization for maximum compression with some accuracy trade-off
|
||||
|
||||
- **vector_filter_mode**:
|
||||
- `preFilter`: Applies filters before vector search (faster)
|
||||
- `postFilter`: Applies filters after vector search (may provide better relevance)
|
||||
|
||||
- **use_float16**: Using half precision (float16) reduces storage requirements but may slightly impact accuracy. Useful for very large vector collections.
|
||||
|
||||
- **Filterable Fields**: The implementation automatically extracts `user_id`, `run_id`, and `agent_id` fields from payloads for filtering.
|
||||
@@ -1,44 +0,0 @@
|
||||
[Azure AI Search](https://learn.microsoft.com/en-us/azure/search/search-what-is-azure-search/) (formerly known as "Azure Cognitive Search") provides secure information retrieval at scale over user-owned content in traditional and generative AI search applications.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx" #this key is used for embedding purpose
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "azure_ai_search",
|
||||
"config": {
|
||||
"service_name": "ai-search-test",
|
||||
"api_key": "*****",
|
||||
"collection_name": "mem0",
|
||||
"embedding_model_dims": 1536 ,
|
||||
"use_compression": False
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
Let's see the available parameters for the `qdrant` config:
|
||||
service_name (str): Azure Cognitive Search service name.
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `service_name` | Azure AI Search service name | `None` |
|
||||
| `api_key` | API key of the Azure AI Search service | `None` |
|
||||
| `collection_name` | The name of the collection/index to store the vectors, it will be created automatically if not exist | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `use_compression` | Use scalar quantization vector compression | False |
|
||||
@@ -54,6 +54,7 @@ Let's see the available parameters for the `elasticsearch` config:
|
||||
| `password` | Password for basic authentication | `None` |
|
||||
| `verify_certs` | Whether to verify SSL certificates | `True` |
|
||||
| `auto_create_index` | Whether to automatically create the index | `True` |
|
||||
| `custom_search_query` | Function returning a custom search query | `None` |
|
||||
|
||||
### Features
|
||||
|
||||
@@ -62,3 +63,46 @@ Let's see the available parameters for the `elasticsearch` config:
|
||||
- Multiple authentication methods (Basic Auth, API Key)
|
||||
- Automatic index creation with optimized mappings for vector search
|
||||
- Memory isolation through payload filtering
|
||||
- Custom search query function to customize the search query
|
||||
|
||||
### Custom Search Query
|
||||
|
||||
The `custom_search_query` parameter allows you to customize the search query when `Memory.search` is called.
|
||||
|
||||
__Example__
|
||||
```python
|
||||
import os
|
||||
from typing import List, Optional, Dict
|
||||
from mem0 import Memory
|
||||
|
||||
def custom_search_query(query: List[float], limit: int, filters: Optional[Dict]) -> Dict:
|
||||
return {
|
||||
"knn": {
|
||||
"field": "vector",
|
||||
"query_vector": query,
|
||||
"k": limit,
|
||||
"num_candidates": limit * 2
|
||||
}
|
||||
}
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "elasticsearch",
|
||||
"config": {
|
||||
"collection_name": "mem0",
|
||||
"host": "localhost",
|
||||
"port": 9200,
|
||||
"embedding_model_dims": 1536,
|
||||
"custom_search_query": custom_search_query
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
It should be a function that takes the following parameters:
|
||||
- `query`: a query vector used in `Memory.search`
|
||||
- `limit`: a number of results used in `Memory.search`
|
||||
- `filters`: a dictionary of key-value pairs used in `Memory.search`. You can add custom pairs for the custom search query.
|
||||
|
||||
The function should return a query body for the Elasticsearch search API.
|
||||
@@ -0,0 +1,72 @@
|
||||
[FAISS](https://github.com/facebookresearch/faiss) is a library for efficient similarity search and clustering of dense vectors. It is designed to work with large-scale datasets and provides a high-performance search engine for vector data. FAISS is optimized for memory usage and search speed, making it an excellent choice for production environments.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "faiss",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"path": "/tmp/faiss_memories",
|
||||
"distance_strategy": "euclidean"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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"})
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
To use FAISS in your mem0 project, you need to install the appropriate FAISS package for your environment:
|
||||
|
||||
```bash
|
||||
# For CPU version
|
||||
pip install faiss-cpu
|
||||
|
||||
# For GPU version (requires CUDA)
|
||||
pip install faiss-gpu
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring FAISS:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collection_name` | The name of the collection | `mem0` |
|
||||
| `path` | Path to store FAISS index and metadata | `/tmp/faiss/<collection_name>` |
|
||||
| `distance_strategy` | Distance metric strategy to use (options: 'euclidean', 'inner_product', 'cosine') | `euclidean` |
|
||||
| `normalize_L2` | Whether to normalize L2 vectors (only applicable for euclidean distance) | `False` |
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
FAISS offers several advantages for vector search:
|
||||
|
||||
1. **Efficiency**: FAISS is optimized for memory usage and speed, making it suitable for large-scale applications.
|
||||
2. **Offline Support**: FAISS works entirely locally, with no need for external servers or API calls.
|
||||
3. **Storage Options**: Vectors can be stored in-memory for maximum speed or persisted to disk.
|
||||
4. **Multiple Index Types**: FAISS supports different index types optimized for various use cases (though mem0 currently uses the basic flat index).
|
||||
|
||||
### Distance Strategies
|
||||
|
||||
FAISS in mem0 supports three distance strategies:
|
||||
|
||||
- **euclidean**: L2 distance, suitable for most embedding models
|
||||
- **inner_product**: Dot product similarity, useful for some specialized embeddings
|
||||
- **cosine**: Cosine similarity, best for comparing semantic similarity regardless of vector magnitude
|
||||
|
||||
When using `cosine` or `inner_product` with normalized vectors, you may want to set `normalize_L2=True` for better results.
|
||||
@@ -0,0 +1,112 @@
|
||||
---
|
||||
title: LangChain
|
||||
---
|
||||
|
||||
Mem0 supports LangChain as a provider for vector store integration. LangChain provides a unified interface to various vector databases, making it easy to integrate different vector store providers through a consistent API.
|
||||
|
||||
<Note>
|
||||
When using LangChain as your vector store provider, you must set the collection name to "mem0". This is a required configuration for proper integration with Mem0.
|
||||
</Note>
|
||||
|
||||
## Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
from langchain_community.vectorstores import Chroma
|
||||
from langchain_openai import OpenAIEmbeddings
|
||||
|
||||
# Initialize a LangChain vector store
|
||||
embeddings = OpenAIEmbeddings()
|
||||
vector_store = Chroma(
|
||||
persist_directory="./chroma_db",
|
||||
embedding_function=embeddings,
|
||||
collection_name="mem0" # Required collection name
|
||||
)
|
||||
|
||||
# Pass the initialized vector store to the config
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "langchain",
|
||||
"config": {
|
||||
"client": vector_store
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from "mem0ai";
|
||||
import { OpenAIEmbeddings } from "@langchain/openai";
|
||||
import { MemoryVectorStore as LangchainMemoryStore } from "langchain/vectorstores/memory";
|
||||
|
||||
const embeddings = new OpenAIEmbeddings();
|
||||
const vectorStore = new LangchainVectorStore(embeddings);
|
||||
|
||||
const config = {
|
||||
"vector_store": {
|
||||
"provider": "langchain",
|
||||
"config": { "client": vectorStore }
|
||||
}
|
||||
}
|
||||
|
||||
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." }
|
||||
]
|
||||
|
||||
memory.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Supported LangChain Vector Stores
|
||||
|
||||
LangChain supports a wide range of vector store providers, including:
|
||||
|
||||
- Chroma
|
||||
- FAISS
|
||||
- Pinecone
|
||||
- Weaviate
|
||||
- Milvus
|
||||
- Qdrant
|
||||
- And many more
|
||||
|
||||
You can use any of these vector store instances directly in your configuration. For a complete and up-to-date list of available providers, refer to the [LangChain Vector Stores documentation](https://python.langchain.com/docs/integrations/vectorstores).
|
||||
|
||||
## Limitations
|
||||
|
||||
When using LangChain as a vector store provider, there are some limitations to be aware of:
|
||||
|
||||
1. **Bulk Operations**: The `get_all` and `delete_all` operations are not supported when using LangChain as the vector store provider. This is because LangChain's vector store interface doesn't provide standardized methods for these bulk operations across all providers.
|
||||
|
||||
2. **Provider-Specific Features**: Some advanced features may not be available depending on the specific vector store implementation you're using through LangChain.
|
||||
|
||||
## Provider-Specific Configuration
|
||||
|
||||
When using LangChain as a vector store provider, you'll need to:
|
||||
|
||||
1. Set the appropriate environment variables for your chosen vector store provider
|
||||
2. Import and initialize the specific vector store class you want to use
|
||||
3. Pass the initialized vector store instance to the config
|
||||
|
||||
<Note>
|
||||
Make sure to install the necessary LangChain packages and any provider-specific dependencies.
|
||||
</Note>
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `langchain` vector store config are present in [Master List of All Params in Config](../config).
|
||||
@@ -0,0 +1,92 @@
|
||||
[Pinecone](https://www.pinecone.io/) is a fully managed vector database designed for machine learning applications, offering high performance vector search with low latency at scale. It's particularly well-suited for semantic search, recommendation systems, and other AI-powered applications.
|
||||
|
||||
> **Note**: Before configuring Pinecone, you need to select an embedding model (e.g., OpenAI, Cohere, or custom models) and ensure the `embedding_model_dims` in your config matches your chosen model's dimensions. For example, OpenAI's text-embedding-3-small uses 1536 dimensions.
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
os.environ["PINECONE_API_KEY"] = "your-api-key"
|
||||
|
||||
# Example using serverless configuration
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "pinecone",
|
||||
"config": {
|
||||
"collection_name": "testing",
|
||||
"embedding_model_dims": 1536, # Matches OpenAI's text-embedding-3-small
|
||||
"serverless_config": {
|
||||
"cloud": "aws", # Choose between 'aws' or 'gcp' or 'azure'
|
||||
"region": "us-east-1"
|
||||
},
|
||||
"metric": "cosine"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 Pinecone:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collection_name` | Name of the index/collection | Required |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model (must match your chosen embedding model) | Required |
|
||||
| `client` | Existing Pinecone client instance | `None` |
|
||||
| `api_key` | API key for Pinecone | Environment variable: `PINECONE_API_KEY` |
|
||||
| `environment` | Pinecone environment | `None` |
|
||||
| `serverless_config` | Configuration for serverless deployment (AWS or GCP or Azure) | `None` |
|
||||
| `pod_config` | Configuration for pod-based deployment | `None` |
|
||||
| `hybrid_search` | Whether to enable hybrid search | `False` |
|
||||
| `metric` | Distance metric for vector similarity | `"cosine"` |
|
||||
| `batch_size` | Batch size for operations | `100` |
|
||||
|
||||
> **Important**: You must choose either `serverless_config` or `pod_config` for your deployment, but not both.
|
||||
|
||||
#### Serverless Config Example
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "pinecone",
|
||||
"config": {
|
||||
"collection_name": "memory_index",
|
||||
"embedding_model_dims": 1536, # For OpenAI's text-embedding-3-small
|
||||
"serverless_config": {
|
||||
"cloud": "aws", # or "gcp" or "azure"
|
||||
"region": "us-east-1" # Choose appropriate region
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Pod Config Example
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "pinecone",
|
||||
"config": {
|
||||
"collection_name": "memory_index",
|
||||
"embedding_model_dims": 1536, # For OpenAI's text-embedding-ada-002
|
||||
"pod_config": {
|
||||
"environment": "gcp-starter",
|
||||
"replicas": 1,
|
||||
"pod_type": "starter"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -4,7 +4,8 @@ Create a [Supabase](https://supabase.com/dashboard/projects) account and project
|
||||
|
||||
### Usage
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -32,10 +33,90 @@ messages = [
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript Typescript
|
||||
import { Memory } from "mem0ai/oss";
|
||||
|
||||
const config = {
|
||||
vectorStore: {
|
||||
provider: "supabase",
|
||||
config: {
|
||||
collectionName: "memories",
|
||||
embeddingModelDims: 1536,
|
||||
supabaseUrl: process.env.SUPABASE_URL || "",
|
||||
supabaseKey: process.env.SUPABASE_KEY || "",
|
||||
tableName: "memories",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
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>
|
||||
|
||||
### SQL Migrations for TypeScript Implementation
|
||||
|
||||
The following SQL migrations are required to enable the vector extension and create the memories table:
|
||||
|
||||
```sql
|
||||
-- Enable the vector extension
|
||||
create extension if not exists vector;
|
||||
|
||||
-- Create the memories table
|
||||
create table if not exists memories (
|
||||
id text primary key,
|
||||
embedding vector(1536),
|
||||
metadata jsonb,
|
||||
created_at timestamp with time zone default timezone('utc', now()),
|
||||
updated_at timestamp with time zone default timezone('utc', now())
|
||||
);
|
||||
|
||||
-- Create the vector similarity search function
|
||||
create or replace function match_vectors(
|
||||
query_embedding vector(1536),
|
||||
match_count int,
|
||||
filter jsonb default '{}'::jsonb
|
||||
)
|
||||
returns table (
|
||||
id text,
|
||||
similarity float,
|
||||
metadata jsonb
|
||||
)
|
||||
language plpgsql
|
||||
as $$
|
||||
begin
|
||||
return query
|
||||
select
|
||||
t.id::text,
|
||||
1 - (t.embedding <=> query_embedding) as similarity,
|
||||
t.metadata
|
||||
from memories t
|
||||
where case
|
||||
when filter::text = '{}'::text then true
|
||||
else t.metadata @> filter
|
||||
end
|
||||
order by t.embedding <=> query_embedding
|
||||
limit match_count;
|
||||
end;
|
||||
$$;
|
||||
```
|
||||
|
||||
Goto [Supabase](https://supabase.com/dashboard/projects) and run the above SQL migrations inside the SQL Editor.
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Supabase:
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `connection_string` | PostgreSQL connection string (required) | None |
|
||||
@@ -43,6 +124,17 @@ Here are the parameters available for configuring Supabase:
|
||||
| `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` |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `collectionName` | Name for the vector collection | `mem0` |
|
||||
| `embeddingModelDims` | Dimensions of the embedding model | `1536` |
|
||||
| `supabaseUrl` | Supabase URL | None |
|
||||
| `supabaseKey` | Supabase key | None |
|
||||
| `tableName` | Name for the vector table | `memories` |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
### Index Methods
|
||||
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
[Upstash Vector](https://upstash.com/docs/vector) is a serverless vector database with built-in embedding models.
|
||||
|
||||
### Usage with Upstash embeddings
|
||||
|
||||
You can enable the built-in embedding models by setting `enable_embeddings` to `True`. This allows you to use Upstash's embedding models for vectorization.
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["UPSTASH_VECTOR_REST_URL"] = "..."
|
||||
os.environ["UPSTASH_VECTOR_REST_TOKEN"] = "..."
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "upstash_vector",
|
||||
"enable_embeddings": True,
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
<Note>
|
||||
Setting `enable_embeddings` to `True` will bypass any external embedding provider you have configured.
|
||||
</Note>
|
||||
|
||||
### Usage with external embedding providers
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "..."
|
||||
os.environ["UPSTASH_VECTOR_REST_URL"] = "..."
|
||||
os.environ["UPSTASH_VECTOR_REST_TOKEN"] = "..."
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "upstash_vector",
|
||||
},
|
||||
"embedder": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "text-embedding-3-large"
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
m.add("Likes to play cricket on weekends", user_id="alice", metadata={"category": "hobbies"})
|
||||
```
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring Upstash Vector:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| ------------------- | ---------------------------------- | ------------- |
|
||||
| `url` | URL for the Upstash Vector index | `None` |
|
||||
| `token` | Token for the Upstash Vector index | `None` |
|
||||
| `client` | An `upstash_vector.Index` instance | `None` |
|
||||
| `collection_name` | The default namespace used | `""` |
|
||||
| `enable_embeddings` | Whether to use Upstash embeddings | `False` |
|
||||
|
||||
<Note>
|
||||
When `url` and `token` are not provided, the `UPSTASH_VECTOR_REST_URL` and
|
||||
`UPSTASH_VECTOR_REST_TOKEN` environment variables are used.
|
||||
</Note>
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
title: Vertex AI Vector Search
|
||||
---
|
||||
|
||||
|
||||
### Usage
|
||||
|
||||
To use Google Cloud Vertex AI Vector Search with `mem0`, you need to configure the `vector_store` in your `mem0` config:
|
||||
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["GEMINI_API_KEY"] = = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "vertex_ai_vector_search",
|
||||
"config": {
|
||||
"endpoint_id": "YOUR_ENDPOINT_ID", # Required: Vector Search endpoint ID
|
||||
"index_id": "YOUR_INDEX_ID", # Required: Vector Search index ID
|
||||
"deployment_index_id": "YOUR_DEPLOYMENT_INDEX_ID", # Required: Deployment-specific ID
|
||||
"project_id": "YOUR_PROJECT_ID", # Required: Google Cloud project ID
|
||||
"project_number": "YOUR_PROJECT_NUMBER", # Required: Google Cloud project number
|
||||
"region": "YOUR_REGION", # Optional: Defaults to GOOGLE_CLOUD_REGION
|
||||
"credentials_path": "path/to/credentials.json", # Optional: Defaults to GOOGLE_APPLICATION_CREDENTIALS
|
||||
"vector_search_api_endpoint": "YOUR_API_ENDPOINT" # Required for get operations
|
||||
}
|
||||
}
|
||||
}
|
||||
m = Memory.from_config(config)
|
||||
m.add("Your text here", user_id="user", metadata={"category": "example"})
|
||||
```
|
||||
|
||||
|
||||
### Required Parameters
|
||||
|
||||
| Parameter | Description | Required |
|
||||
|-----------|-------------|----------|
|
||||
| `endpoint_id` | Vector Search endpoint ID | Yes |
|
||||
| `index_id` | Vector Search index ID | Yes |
|
||||
| `deployment_index_id` | Deployment-specific index ID | Yes |
|
||||
| `project_id` | Google Cloud project ID | Yes |
|
||||
| `project_number` | Google Cloud project number | Yes |
|
||||
| `vector_search_api_endpoint` | Vector search API endpoint | Yes (for get operations) |
|
||||
| `region` | Google Cloud region | No (defaults to GOOGLE_CLOUD_REGION) |
|
||||
| `credentials_path` | Path to service account credentials | No (defaults to GOOGLE_APPLICATION_CREDENTIALS) |
|
||||
@@ -0,0 +1,47 @@
|
||||
[Weaviate](https://weaviate.io/) is an open-source vector search engine. It allows efficient storage and retrieval of high-dimensional vector embeddings, enabling powerful search and retrieval capabilities.
|
||||
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
pip install weaviate weaviate-client
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "sk-xx"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "weaviate",
|
||||
"config": {
|
||||
"collection_name": "test",
|
||||
"cluster_url": "http://localhost:8080",
|
||||
"auth_client_secret": None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 movie? 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
|
||||
|
||||
Let's see the available parameters for the `weaviate` config:
|
||||
|
||||
| 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` |
|
||||
| `cluster_url` | URL for the Weaviate server | `None` |
|
||||
| `auth_client_secret` | API key for Weaviate authentication | `None` |
|
||||
@@ -18,12 +18,18 @@ See the list of supported vector databases below.
|
||||
<Card title="Qdrant" href="/components/vectordbs/dbs/qdrant"></Card>
|
||||
<Card title="Chroma" href="/components/vectordbs/dbs/chroma"></Card>
|
||||
<Card title="Pgvector" href="/components/vectordbs/dbs/pgvector"></Card>
|
||||
<Card title="Upstash Vector" href="/components/vectordbs/dbs/upstash-vector"></Card>
|
||||
<Card title="Milvus" href="/components/vectordbs/dbs/milvus"></Card>
|
||||
<Card title="Azure AI Search" href="/components/vectordbs/dbs/azure_ai_search"></Card>
|
||||
<Card title="Pinecone" href="/components/vectordbs/dbs/pinecone"></Card>
|
||||
<Card title="Azure" href="/components/vectordbs/dbs/azure"></Card>
|
||||
<Card title="Redis" href="/components/vectordbs/dbs/redis"></Card>
|
||||
<Card title="Elasticsearch" href="/components/vectordbs/dbs/elasticsearch"></Card>
|
||||
<Card title="OpenSearch" href="/components/vectordbs/dbs/opensearch"></Card>
|
||||
<Card title="Supabase" href="/components/vectordbs/dbs/supabase"></Card>
|
||||
<Card title="Vertex AI" href="/components/vectordbs/dbs/vertex_ai"></Card>
|
||||
<Card title="Weaviate" href="/components/vectordbs/dbs/weaviate"></Card>
|
||||
<Card title="FAISS" href="/components/vectordbs/dbs/faiss"></Card>
|
||||
<Card title="LangChain" href="/components/vectordbs/dbs/langchain"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
"pages": [
|
||||
"features/platform-overview",
|
||||
"features/advanced-retrieval",
|
||||
"features/contextual-add",
|
||||
"features/multimodal-support",
|
||||
"features/selective-memory",
|
||||
"features/custom-categories",
|
||||
@@ -54,7 +55,9 @@
|
||||
"features/direct-import",
|
||||
"features/async-client",
|
||||
"features/memory-export",
|
||||
"features/webhooks"
|
||||
"features/webhooks",
|
||||
"features/graph-memory",
|
||||
"features/feedback-mechanism"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -70,8 +73,10 @@
|
||||
"group": "Features",
|
||||
"icon": "wrench",
|
||||
"pages": [
|
||||
"open-source/features/async-memory",
|
||||
"features/openai_compatibility",
|
||||
"features/custom-prompts",
|
||||
"features/custom-fact-extraction-prompt",
|
||||
"features/custom-update-memory-prompt",
|
||||
"open-source/multimodal-support",
|
||||
"open-source/features/rest-api"
|
||||
]
|
||||
@@ -106,7 +111,9 @@
|
||||
"components/llms/models/aws_bedrock",
|
||||
"components/llms/models/gemini",
|
||||
"components/llms/models/deepseek",
|
||||
"components/llms/models/xAI"
|
||||
"components/llms/models/xAI",
|
||||
"components/llms/models/lmstudio",
|
||||
"components/llms/models/langchain"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -125,11 +132,16 @@
|
||||
"components/vectordbs/dbs/chroma",
|
||||
"components/vectordbs/dbs/pgvector",
|
||||
"components/vectordbs/dbs/milvus",
|
||||
"components/vectordbs/dbs/azure_ai_search",
|
||||
"components/vectordbs/dbs/pinecone",
|
||||
"components/vectordbs/dbs/azure",
|
||||
"components/vectordbs/dbs/redis",
|
||||
"components/vectordbs/dbs/elasticsearch",
|
||||
"components/vectordbs/dbs/opensearch",
|
||||
"components/vectordbs/dbs/supabase"
|
||||
"components/vectordbs/dbs/supabase",
|
||||
"components/vectordbs/dbs/vertex_ai",
|
||||
"components/vectordbs/dbs/weaviate",
|
||||
"components/vectordbs/dbs/faiss",
|
||||
"components/vectordbs/dbs/langchain"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -149,7 +161,10 @@
|
||||
"components/embedders/models/ollama",
|
||||
"components/embedders/models/huggingface",
|
||||
"components/embedders/models/vertexai",
|
||||
"components/embedders/models/gemini"
|
||||
"components/embedders/models/gemini",
|
||||
"components/embedders/models/lmstudio",
|
||||
"components/embedders/models/together",
|
||||
"components/embedders/models/langchain"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -173,14 +188,24 @@
|
||||
"group": "💡 Examples",
|
||||
"icon": "lightbulb",
|
||||
"pages": [
|
||||
"examples/overview",
|
||||
"examples",
|
||||
"examples/mem0-demo",
|
||||
"examples/ai_companion_js",
|
||||
"examples/mem0-mastra",
|
||||
"examples/mem0-with-ollama",
|
||||
"examples/personal-ai-tutor",
|
||||
"examples/customer-support-agent",
|
||||
"examples/personal-travel-assistant",
|
||||
"examples/llama-index-mem0"
|
||||
"examples/llama-index-mem0",
|
||||
"examples/chrome-extension",
|
||||
"examples/document-writing",
|
||||
"examples/multimodal-demo",
|
||||
"examples/personalized-deep-research",
|
||||
"examples/mem0-agentic-tool",
|
||||
"examples/openai-inbuilt-tools",
|
||||
"examples/mem0-openai-voice-demo",
|
||||
"examples/email_processing",
|
||||
"examples/youtube-assistant"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -192,15 +217,22 @@
|
||||
"group": "Integrations",
|
||||
"icon": "plug",
|
||||
"pages": [
|
||||
"integrations/overview",
|
||||
"integrations",
|
||||
"integrations/vercel-ai-sdk",
|
||||
"integrations/flowise",
|
||||
"integrations/crewai",
|
||||
"integrations/autogen",
|
||||
"integrations/langchain",
|
||||
"integrations/langgraph",
|
||||
"integrations/llama-index",
|
||||
"integrations/langchain-tools",
|
||||
"integrations/dify"
|
||||
"integrations/dify",
|
||||
"integrations/mcp-server",
|
||||
"integrations/livekit",
|
||||
"integrations/elevenlabs",
|
||||
"integrations/pipecat",
|
||||
"integrations/agno",
|
||||
"integrations/keywords"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -213,7 +245,7 @@
|
||||
"group": "API Reference",
|
||||
"icon": "terminal",
|
||||
"pages": [
|
||||
"api-reference/overview",
|
||||
"api-reference",
|
||||
{
|
||||
"group": "Memory APIs",
|
||||
"icon": "microchip",
|
||||
@@ -231,7 +263,8 @@
|
||||
"api-reference/memory/batch-delete",
|
||||
"api-reference/memory/delete-memories",
|
||||
"api-reference/memory/create-memory-export",
|
||||
"api-reference/memory/get-memory-export"
|
||||
"api-reference/memory/get-memory-export",
|
||||
"api-reference/memory/feedback"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -254,6 +287,18 @@
|
||||
"api-reference/organization/delete-org"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Project APIs",
|
||||
"icon": "folder",
|
||||
"pages": [
|
||||
"api-reference/project/create-project",
|
||||
"api-reference/project/get-projects",
|
||||
"api-reference/project/get-project",
|
||||
"api-reference/project/get-project-members",
|
||||
"api-reference/project/add-project-member",
|
||||
"api-reference/project/delete-project"
|
||||
]
|
||||
},
|
||||
{
|
||||
"group": "Webhook APIs",
|
||||
"icon": "webhook",
|
||||
@@ -267,6 +312,19 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"tab": "Changelog",
|
||||
"icon": "clock",
|
||||
"groups": [
|
||||
{
|
||||
"group": "Product Updates",
|
||||
"icon": "rocket",
|
||||
"pages": [
|
||||
"changelog"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -277,7 +335,7 @@
|
||||
},
|
||||
{
|
||||
"anchor": "Demo",
|
||||
"href": "https://demo.mem0.ai",
|
||||
"href": "https://mem0.dev/demo",
|
||||
"icon": "play"
|
||||
},
|
||||
{
|
||||
@@ -327,6 +385,9 @@
|
||||
"posthog": {
|
||||
"apiKey": "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX",
|
||||
"apiHost": "https://mango.mem0.ai"
|
||||
},
|
||||
"intercom": {
|
||||
"appId": "jjv2r0tt"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
---
|
||||
title: Overview
|
||||
description: How to use mem0 in your existing applications?
|
||||
---
|
||||
|
||||
|
||||
With Mem0, you can create stateful LLM-based applications such as chatbots, virtual assistants, or AI agents. Mem0 enhances your applications by providing a memory layer that makes responses:
|
||||
|
||||
- More personalized
|
||||
- More reliable
|
||||
- Cost-effective by reducing the number of LLM interactions
|
||||
- More engaging
|
||||
- Enables long-term memory
|
||||
|
||||
Here are some examples of how Mem0 can be integrated into various applications:
|
||||
|
||||
## Examples
|
||||
|
||||
Explore how **Mem0** can power real-world applications and bring personalized, intelligent experiences to life:
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="AI Companion in Node.js" icon="node" href="/examples/ai_companion_js">
|
||||
Build a personalized AI Companion in **Node.js** that remembers conversations and adapts over time using Mem0.
|
||||
</Card>
|
||||
|
||||
<Card title="Mem0 with Ollama" icon="server" href="/examples/mem0-with-ollama">
|
||||
Run **Mem0 locally** with **Ollama** to create private, stateful AI experiences without relying on cloud APIs.
|
||||
</Card>
|
||||
|
||||
<Card title="Personal AI Tutor" icon="graduation-cap" href="/examples/personal-ai-tutor">
|
||||
Create an **AI Tutor** that adapts to student progress, learning style, and history — for a truly customized learning experience.
|
||||
</Card>
|
||||
|
||||
<Card title="Personal Travel Assistant" icon="plane" href="/examples/personal-travel-assistant">
|
||||
Develop a **Personal Travel Assistant** that remembers your preferences, past trips, and helps plan future adventures.
|
||||
</Card>
|
||||
|
||||
<Card title="Customer Support Agent" icon="headset" href="/examples/customer-support-agent">
|
||||
Build a **Customer Support AI** that recalls user preferences, past chats, and provides context-aware, efficient help.
|
||||
</Card>
|
||||
|
||||
<Card title="LlamaIndex + Mem0" icon="book-open" href="/examples/llama-index-mem0">
|
||||
Combine **LlamaIndex** and Mem0 to create a powerful **ReAct Agent** with persistent memory for smarter interactions.
|
||||
</Card>
|
||||
|
||||
<Card title="Chrome Extension" icon="puzzle-piece" href="/examples/chrome-extension">
|
||||
Add **long-term memory** to ChatGPT, Claude, or Perplexity via the **Mem0 Chrome Extension** — personalize your AI chats anywhere.
|
||||
</Card>
|
||||
|
||||
<Card title="YouTube Assistant" icon="puzzle-piece" href="/examples/youtube-assistant">
|
||||
Integrate **Mem0** into **YouTube's** native UI, providing personalized responses with video context.
|
||||
</Card>
|
||||
|
||||
<Card title="Document Writing Assistant" icon="pen" href="/examples/document-writing">
|
||||
Create a **Writing Assistant** that understands and adapts to your unique style, improving consistency and productivity.
|
||||
</Card>
|
||||
|
||||
<Card title="Multimodal AI Demo" icon="image" href="/examples/multimodal-demo">
|
||||
Supercharge AI with **Mem0's multimodal memory** — blend text, images, and more for richer, context-aware interactions.
|
||||
</Card>
|
||||
|
||||
<Card title="Personalized Research Agent" icon="magnifying-glass" href="/examples/personalized-deep-research">
|
||||
Build a **Deep Research AI** that remembers your research goals and compiles insights from vast information sources.
|
||||
</Card>
|
||||
|
||||
<Card title="Mem0 as an Agentic Tool" icon="robot" href="/examples/mem0-agentic-tool">
|
||||
Integrate Mem0's memory capabilities with OpenAI's Agents SDK to create AI agents with persistent memory.
|
||||
</Card>
|
||||
|
||||
<Card title="OpenAI Inbuilt Tools" icon="robot" href="/examples/openai-inbuilt-tools">
|
||||
Use Mem0's memory capabilities with OpenAI's Inbuilt Tools to create AI agents with persistent memory.
|
||||
</Card>
|
||||
|
||||
<Card title="Mem0 OpenAI Voice Demo" icon="microphone" href="/examples/mem0-openai-voice-demo">
|
||||
Use Mem0's memory capabilities with OpenAI's Inbuilt Tools to create AI agents with persistent memory.
|
||||
</Card>
|
||||
|
||||
<Card title="Email Processing" icon="envelope" href="/examples/email_processing">
|
||||
Use Mem0's memory capabilities to process emails and create AI agents with persistent memory.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,55 @@
|
||||
# Mem0 Chrome Extension
|
||||
|
||||
Enhance your AI interactions with **Mem0**, a Chrome extension that introduces a universal memory layer across platforms like `ChatGPT`, `Claude`, and `Perplexity`. Mem0 ensures seamless context sharing, making your AI experiences more personalized and efficient.
|
||||
|
||||
<Note>
|
||||
🎉 We now support Grok! The Mem0 Chrome Extension has been updated to work with Grok, bringing the same powerful memory capabilities to your Grok conversations.
|
||||
</Note>
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- **Universal Memory Layer**: Share context seamlessly across ChatGPT, Claude, Perplexity, and Grok.
|
||||
- **Smart Context Detection**: Automatically captures relevant information from your conversations.
|
||||
- **Intelligent Memory Retrieval**: Surfaces pertinent memories at the right time.
|
||||
- **One-Click Sync**: Easily synchronize with existing ChatGPT memories.
|
||||
- **Memory Dashboard**: Manage all your memories in one centralized location.
|
||||
|
||||
## Installation
|
||||
|
||||
You can install the Mem0 Chrome Extension using one of the following methods:
|
||||
|
||||
### Method 1: Chrome Web Store Installation
|
||||
|
||||
1. **Download the Extension**: Open Google Chrome and navigate to the [Mem0 Chrome Extension page](https://chromewebstore.google.com/detail/mem0/onihkkbipkfeijkadecaafbgagkhglop?hl=en).
|
||||
2. **Add to Chrome**: Click on the "Add to Chrome" button.
|
||||
3. **Confirm Installation**: In the pop-up dialog, click "Add extension" to confirm. The Mem0 icon should now appear in your Chrome toolbar.
|
||||
|
||||
### Method 2: Manual Installation
|
||||
|
||||
1. **Download the Extension**: Clone or download the extension files from the [Mem0 Chrome Extension GitHub repository](https://github.com/mem0ai/mem0-chrome-extension).
|
||||
2. **Access Chrome Extensions**: Open Google Chrome and navigate to `chrome://extensions`.
|
||||
3. **Enable Developer Mode**: Toggle the "Developer mode" switch in the top right corner.
|
||||
4. **Load Unpacked Extension**: Click "Load unpacked" and select the directory containing the extension files.
|
||||
5. **Confirm Installation**: The Mem0 Chrome Extension should now appear in your Chrome toolbar.
|
||||
|
||||
## Usage
|
||||
|
||||
1. **Locate the Mem0 Icon**: After installation, find the Mem0 icon in your Chrome toolbar.
|
||||
2. **Sign In**: Click the icon and sign in with your Google account.
|
||||
3. **Interact with AI Assistants**:
|
||||
- **ChatGPT and Perplexity**: Continue your conversations as usual; Mem0 operates seamlessly in the background.
|
||||
- **Claude**: Click the Mem0 button or use the shortcut `Ctrl + M` to activate memory functions.
|
||||
|
||||
## Configuration
|
||||
|
||||
- **API Key**: Obtain your API key from the Mem0 Dashboard to connect the extension to the Mem0 API.
|
||||
- **User ID**: This is your unique identifier in the Mem0 system. If not provided, it defaults to 'chrome-extension-user'.
|
||||
|
||||
## Demo Video
|
||||
|
||||
<iframe width="700" height="400" src="https://www.youtube.com/embed/dqenCMMlfwQ?si=zhGVrkq6IS_0Jwyj" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
## Privacy and Data Security
|
||||
|
||||
Your messages are sent to the Mem0 API for extracting and retrieving memories. Mem0 is committed to ensuring your data's privacy and security.
|
||||
@@ -94,8 +94,8 @@ You can fetch all the memories at any point in time using the following code:
|
||||
|
||||
```python
|
||||
memories = support_agent.get_memories(user_id=customer_id)
|
||||
for m in memories:
|
||||
print(m['text'])
|
||||
for m in memories['results']:
|
||||
print(m['memory'])
|
||||
```
|
||||
|
||||
### Key Points
|
||||
|
||||
@@ -0,0 +1,184 @@
|
||||
---
|
||||
title: Document Editing with Mem0
|
||||
---
|
||||
|
||||
This guide demonstrates how to leverage **Mem0** to edit documents efficiently, ensuring they align with your unique writing style and preferences.
|
||||
|
||||
## **Why Use Mem0?**
|
||||
|
||||
By integrating Mem0 into your workflow, you can streamline your document editing process with:
|
||||
|
||||
1. **Persistent Writing Preferences**: Mem0 stores and recalls your style preferences, ensuring consistency across all documents.
|
||||
2. **Automated Enhancements**: Your stored preferences guide document refinements, making edits seamless and efficient.
|
||||
3. **Scalability & Reusability**: Your writing style can be applied to multiple documents, saving time and effort.
|
||||
|
||||
---
|
||||
## **Setup**
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import MemoryClient
|
||||
|
||||
# Set up Mem0 client
|
||||
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
|
||||
client = MemoryClient()
|
||||
|
||||
# Define constants
|
||||
USER_ID = "content_writer"
|
||||
RUN_ID = "smart_editing_session"
|
||||
```
|
||||
|
||||
---
|
||||
## **Storing Your Writing Preferences in Mem0**
|
||||
|
||||
```python
|
||||
def store_writing_preferences():
|
||||
"""Store your writing preferences in Mem0."""
|
||||
|
||||
# Define writing preferences
|
||||
preferences = """My writing preferences:
|
||||
1. Use headings and sub-headings for structure.
|
||||
2. Keep paragraphs concise (8-10 sentences max).
|
||||
3. Incorporate specific numbers and statistics.
|
||||
4. Provide concrete examples.
|
||||
5. Use bullet points for clarity.
|
||||
6. Avoid jargon and buzzwords."""
|
||||
|
||||
# Store preferences in Mem0
|
||||
preference_message = [
|
||||
{"role": "user", "content": "Here are my writing style preferences"},
|
||||
{"role": "assistant", "content": preferences}
|
||||
]
|
||||
|
||||
response = client.add(preference_message, user_id=USER_ID, run_id=RUN_ID, metadata={"type": "preferences", "category": "writing_style"})
|
||||
|
||||
print("Writing preferences stored successfully.")
|
||||
return response
|
||||
```
|
||||
|
||||
---
|
||||
## **Editing Documents with Mem0**
|
||||
|
||||
```python
|
||||
def edit_document_based_on_preferences(original_content):
|
||||
"""Edit a document using Mem0-based stored preferences."""
|
||||
|
||||
# Retrieve stored preferences
|
||||
query = "What are my writing style preferences?"
|
||||
preferences_results = client.search(query, user_id=USER_ID, run_id=RUN_ID)
|
||||
|
||||
if not preferences_results:
|
||||
print("No writing preferences found.")
|
||||
return None
|
||||
|
||||
# Extract preferences
|
||||
preferences = ' '.join(memory["memory"] for memory in preferences_results)
|
||||
|
||||
# Apply stored preferences to refine the document
|
||||
edited_content = f"Applying stored preferences:\n{preferences}\n\nEdited Document:\n{original_content}"
|
||||
|
||||
return edited_content
|
||||
```
|
||||
|
||||
---
|
||||
## **Complete Workflow: Document Editing**
|
||||
|
||||
```python
|
||||
def document_editing_workflow(content):
|
||||
"""Automated workflow for editing a document based on writing preferences."""
|
||||
|
||||
# Step 1: Store writing preferences (if not already stored)
|
||||
store_writing_preferences()
|
||||
|
||||
# Step 2: Edit the document with Mem0 preferences
|
||||
edited_content = edit_document_based_on_preferences(content)
|
||||
|
||||
if not edited_content:
|
||||
return "Failed to edit document."
|
||||
|
||||
# Step 3: Display results
|
||||
print("\n=== ORIGINAL DOCUMENT ===\n")
|
||||
print(content)
|
||||
|
||||
print("\n=== EDITED DOCUMENT ===\n")
|
||||
print(edited_content)
|
||||
|
||||
return edited_content
|
||||
```
|
||||
|
||||
---
|
||||
## **Example Usage**
|
||||
|
||||
```python
|
||||
# Define your document
|
||||
original_content = """Project Proposal
|
||||
|
||||
The following proposal outlines our strategy for the Q3 marketing campaign.
|
||||
We believe this approach will significantly increase our market share.
|
||||
|
||||
Increase brand awareness
|
||||
Boost sales by 15%
|
||||
Expand our social media following
|
||||
|
||||
We plan to launch the campaign in July and continue through September.
|
||||
"""
|
||||
|
||||
# Run the workflow
|
||||
result = document_editing_workflow(original_content)
|
||||
```
|
||||
|
||||
---
|
||||
## **Expected Output**
|
||||
|
||||
Your document will be transformed into a structured, well-formatted version based on your preferences.
|
||||
|
||||
### **Original Document**
|
||||
```
|
||||
Project Proposal
|
||||
|
||||
The following proposal outlines our strategy for the Q3 marketing campaign.
|
||||
We believe this approach will significantly increase our market share.
|
||||
|
||||
Increase brand awareness
|
||||
Boost sales by 15%
|
||||
Expand our social media following
|
||||
|
||||
We plan to launch the campaign in July and continue through September.
|
||||
```
|
||||
|
||||
### **Edited Document**
|
||||
```
|
||||
# **Project Proposal**
|
||||
|
||||
## **Q3 Marketing Campaign Strategy**
|
||||
|
||||
This proposal outlines our strategy for the Q3 marketing campaign. We aim to significantly increase our market share with this approach.
|
||||
|
||||
### **Objectives**
|
||||
|
||||
- **Increase Brand Awareness**: Implement targeted advertising and community engagement to enhance visibility.
|
||||
- **Boost Sales by 15%**: Increase sales by 15% compared to Q2 figures.
|
||||
- **Expand Social Media Following**: Grow our social media audience by 20%.
|
||||
|
||||
### **Timeline**
|
||||
|
||||
- **Launch Date**: July
|
||||
- **Duration**: July – September
|
||||
|
||||
### **Key Actions**
|
||||
|
||||
- **Targeted Advertising**: Utilize platforms like Google Ads and Facebook to reach specific demographics.
|
||||
- **Community Engagement**: Host webinars and live Q&A sessions.
|
||||
- **Content Creation**: Produce engaging videos and infographics.
|
||||
|
||||
### **Supporting Data**
|
||||
|
||||
- **Previous Campaign Success**: Our Q2 campaign increased sales by 12%. We will refine similar strategies for Q3.
|
||||
- **Social Media Growth**: Last year, our Instagram followers grew by 25% during a similar campaign.
|
||||
|
||||
### **Conclusion**
|
||||
|
||||
We believe this strategy will effectively increase our market share. To achieve these goals, we need your support and collaboration. Let’s work together to make this campaign a success. Please review the proposal and provide your feedback by the end of the week.
|
||||
```
|
||||
|
||||
Mem0 creates a seamless, intelligent document editing experience—perfect for content creators, technical writers, and businesses alike!
|
||||
@@ -0,0 +1,186 @@
|
||||
---
|
||||
title: Email Processing with Mem0
|
||||
---
|
||||
|
||||
This guide demonstrates how to build an intelligent email processing system using Mem0's memory capabilities. You'll learn how to store, categorize, retrieve, and analyze emails to create a smart email management solution.
|
||||
|
||||
## Overview
|
||||
|
||||
Email overload is a common challenge for many professionals. By leveraging Mem0's memory capabilities, you can build an intelligent system that:
|
||||
|
||||
- Stores emails as searchable memories
|
||||
- Categorizes emails automatically
|
||||
- Retrieves relevant past conversations
|
||||
- Prioritizes messages based on importance
|
||||
- Generates summaries and action items
|
||||
|
||||
## Setup
|
||||
|
||||
Before you begin, ensure you have the required dependencies installed:
|
||||
|
||||
```bash
|
||||
pip install mem0ai openai
|
||||
```
|
||||
|
||||
## Implementation
|
||||
|
||||
### Basic Email Memory System
|
||||
|
||||
The following example shows how to create a basic email processing system with Mem0:
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import MemoryClient
|
||||
from email.parser import Parser
|
||||
|
||||
# Configure API keys
|
||||
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
|
||||
|
||||
# Initialize Mem0 client
|
||||
client = MemoryClient()
|
||||
|
||||
class EmailProcessor:
|
||||
def __init__(self):
|
||||
"""Initialize the Email Processor with Mem0 memory client"""
|
||||
self.client = client
|
||||
|
||||
def process_email(self, email_content, user_id):
|
||||
"""
|
||||
Process an email and store it in Mem0 memory
|
||||
|
||||
Args:
|
||||
email_content (str): Raw email content
|
||||
user_id (str): User identifier for memory association
|
||||
"""
|
||||
# Parse email
|
||||
parser = Parser()
|
||||
email = parser.parsestr(email_content)
|
||||
|
||||
# Extract email details
|
||||
sender = email['from']
|
||||
recipient = email['to']
|
||||
subject = email['subject']
|
||||
date = email['date']
|
||||
body = self._get_email_body(email)
|
||||
|
||||
# Create message object for Mem0
|
||||
message = {
|
||||
"role": "user",
|
||||
"content": f"Email from {sender}: {subject}\n\n{body}"
|
||||
}
|
||||
|
||||
# Create metadata for better retrieval
|
||||
metadata = {
|
||||
"email_type": "incoming",
|
||||
"sender": sender,
|
||||
"recipient": recipient,
|
||||
"subject": subject,
|
||||
"date": date
|
||||
}
|
||||
|
||||
# Store in Mem0 with appropriate categories
|
||||
response = self.client.add(
|
||||
messages=[message],
|
||||
user_id=user_id,
|
||||
metadata=metadata,
|
||||
categories=["email", "correspondence"],
|
||||
version="v2"
|
||||
)
|
||||
|
||||
return response
|
||||
|
||||
def _get_email_body(self, email):
|
||||
"""Extract the body content from an email"""
|
||||
# Simplified extraction - in real-world, handle multipart emails
|
||||
if email.is_multipart():
|
||||
for part in email.walk():
|
||||
if part.get_content_type() == "text/plain":
|
||||
return part.get_payload(decode=True).decode()
|
||||
else:
|
||||
return email.get_payload(decode=True).decode()
|
||||
|
||||
def search_emails(self, query, user_id):
|
||||
"""
|
||||
Search through stored emails
|
||||
|
||||
Args:
|
||||
query (str): Search query
|
||||
user_id (str): User identifier
|
||||
"""
|
||||
# Search Mem0 for relevant emails
|
||||
results = self.client.search(
|
||||
query=query,
|
||||
user_id=user_id,
|
||||
categories=["email"],
|
||||
output_format="v1.1",
|
||||
version="v2"
|
||||
)
|
||||
|
||||
return results
|
||||
|
||||
def get_email_thread(self, subject, user_id):
|
||||
"""
|
||||
Retrieve all emails in a thread based on subject
|
||||
|
||||
Args:
|
||||
subject (str): Email subject to match
|
||||
user_id (str): User identifier
|
||||
"""
|
||||
filters = {
|
||||
"AND": [
|
||||
{"user_id": user_id},
|
||||
{"categories": {"contains": "email"}},
|
||||
{"metadata": {"subject": {"contains": subject}}}
|
||||
]
|
||||
}
|
||||
|
||||
thread = self.client.get_all(
|
||||
version="v2",
|
||||
filters=filters,
|
||||
output_format="v1.1"
|
||||
)
|
||||
|
||||
return thread
|
||||
|
||||
# Initialize the processor
|
||||
processor = EmailProcessor()
|
||||
|
||||
# Example raw email
|
||||
sample_email = """From: alice@example.com
|
||||
To: bob@example.com
|
||||
Subject: Meeting Schedule Update
|
||||
Date: Mon, 15 Jul 2024 14:22:05 -0700
|
||||
|
||||
Hi Bob,
|
||||
|
||||
I wanted to update you on the schedule for our upcoming project meeting.
|
||||
We'll be meeting this Thursday at 2pm instead of Friday.
|
||||
|
||||
Could you please prepare your section of the presentation?
|
||||
|
||||
Thanks,
|
||||
Alice
|
||||
"""
|
||||
|
||||
# Process and store the email
|
||||
user_id = "bob@example.com"
|
||||
processor.process_email(sample_email, user_id)
|
||||
|
||||
# Later, search for emails about meetings
|
||||
meeting_emails = processor.search_emails("meeting schedule", user_id)
|
||||
print(f"Found {len(meeting_emails['results'])} relevant emails")
|
||||
```
|
||||
|
||||
## Key Features and Benefits
|
||||
|
||||
- **Long-term Email Memory**: Store and retrieve email conversations across long periods
|
||||
- **Semantic Search**: Find relevant emails even if they don't contain exact keywords
|
||||
- **Intelligent Categorization**: Automatically sort emails into meaningful categories
|
||||
- **Action Item Extraction**: Identify and track tasks mentioned in emails
|
||||
- **Priority Management**: Focus on important emails based on AI-determined priority
|
||||
- **Context Awareness**: Maintain thread context for more relevant interactions
|
||||
|
||||
## Conclusion
|
||||
|
||||
By combining Mem0's memory capabilities with email processing, you can create intelligent email management systems that help users organize, prioritize, and act on their inbox effectively. The advanced capabilities like automatic categorization, action item extraction, and priority management can significantly reduce the time spent on email management, allowing users to focus on more important tasks.
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
---
|
||||
title: Mem0 as an Agentic Tool
|
||||
---
|
||||
|
||||
Integrate Mem0's memory capabilities with OpenAI's Agents SDK to create AI agents with persistent memory.
|
||||
You can create agents that remember past conversations and use that context to provide better responses.
|
||||
|
||||
## Installation
|
||||
|
||||
First, install the required packages:
|
||||
```bash
|
||||
pip install mem0ai pydantic openai-agents
|
||||
```
|
||||
|
||||
You'll also need a custom agents framework for this implementation.
|
||||
|
||||
## Setting Up Environment Variables
|
||||
|
||||
Store your Mem0 API key as an environment variable:
|
||||
|
||||
```bash
|
||||
export MEM0_API_KEY="your_mem0_api_key"
|
||||
```
|
||||
|
||||
Or in your Python script:
|
||||
|
||||
```python
|
||||
import os
|
||||
os.environ["MEM0_API_KEY"] = "your_mem0_api_key"
|
||||
```
|
||||
|
||||
## Code Structure
|
||||
|
||||
The integration consists of three main components:
|
||||
|
||||
1. **Context Manager**: Defines user context for memory operations
|
||||
2. **Memory Tools**: Functions to add, search, and retrieve memories
|
||||
3. **Memory Agent**: An agent configured to use these memory tools
|
||||
|
||||
## Step-by-Step Implementation
|
||||
|
||||
### 1. Import Dependencies
|
||||
|
||||
```python
|
||||
from __future__ import annotations
|
||||
import os
|
||||
import asyncio
|
||||
from pydantic import BaseModel
|
||||
try:
|
||||
from mem0 import AsyncMemoryClient
|
||||
except ImportError:
|
||||
raise ImportError("mem0 is not installed. Please install it using 'pip install mem0ai'.")
|
||||
from agents import (
|
||||
Agent,
|
||||
ItemHelpers,
|
||||
MessageOutputItem,
|
||||
RunContextWrapper,
|
||||
Runner,
|
||||
ToolCallItem,
|
||||
ToolCallOutputItem,
|
||||
TResponseInputItem,
|
||||
function_tool,
|
||||
)
|
||||
```
|
||||
|
||||
### 2. Define Memory Context
|
||||
|
||||
```python
|
||||
class Mem0Context(BaseModel):
|
||||
user_id: str | None = None
|
||||
```
|
||||
|
||||
### 3. Initialize the Mem0 Client
|
||||
|
||||
```python
|
||||
client = AsyncMemoryClient(api_key=os.getenv("MEM0_API_KEY"))
|
||||
```
|
||||
|
||||
### 4. Create Memory Tools
|
||||
|
||||
#### Add to Memory
|
||||
|
||||
```python
|
||||
@function_tool
|
||||
async def add_to_memory(
|
||||
context: RunContextWrapper[Mem0Context],
|
||||
content: str,
|
||||
) -> str:
|
||||
"""
|
||||
Add a message to Mem0
|
||||
Args:
|
||||
content: The content to store in memory.
|
||||
"""
|
||||
messages = [{"role": "user", "content": content}]
|
||||
user_id = context.context.user_id or "default_user"
|
||||
await client.add(messages, user_id=user_id)
|
||||
return f"Stored message: {content}"
|
||||
```
|
||||
|
||||
#### Search Memory
|
||||
|
||||
```python
|
||||
@function_tool
|
||||
async def search_memory(
|
||||
context: RunContextWrapper[Mem0Context],
|
||||
query: str,
|
||||
) -> str:
|
||||
"""
|
||||
Search for memories in Mem0
|
||||
Args:
|
||||
query: The search query.
|
||||
"""
|
||||
user_id = context.context.user_id or "default_user"
|
||||
memories = await client.search(query, user_id=user_id, output_format="v1.1")
|
||||
results = '\n'.join([result["memory"] for result in memories["results"]])
|
||||
return str(results)
|
||||
```
|
||||
|
||||
#### Get All Memories
|
||||
|
||||
```python
|
||||
@function_tool
|
||||
async def get_all_memory(
|
||||
context: RunContextWrapper[Mem0Context],
|
||||
) -> str:
|
||||
"""Retrieve all memories from Mem0"""
|
||||
user_id = context.context.user_id or "default_user"
|
||||
memories = await client.get_all(user_id=user_id, output_format="v1.1")
|
||||
results = '\n'.join([result["memory"] for result in memories["results"]])
|
||||
return str(results)
|
||||
```
|
||||
|
||||
### 5. Configure the Memory Agent
|
||||
|
||||
```python
|
||||
memory_agent = Agent[Mem0Context](
|
||||
name="Memory Assistant",
|
||||
instructions="""You are a helpful assistant with memory capabilities. You can:
|
||||
1. Store new information using add_to_memory
|
||||
2. Search existing information using search_memory
|
||||
3. Retrieve all stored information using get_all_memory
|
||||
When users ask questions:
|
||||
- If they want to store information, use add_to_memory
|
||||
- If they're searching for specific information, use search_memory
|
||||
- If they want to see everything stored, use get_all_memory""",
|
||||
tools=[add_to_memory, search_memory, get_all_memory],
|
||||
)
|
||||
```
|
||||
|
||||
### 6. Implement the Main Runtime Loop
|
||||
|
||||
```python
|
||||
async def main():
|
||||
current_agent: Agent[Mem0Context] = memory_agent
|
||||
input_items: list[TResponseInputItem] = []
|
||||
context = Mem0Context()
|
||||
while True:
|
||||
user_input = input("Enter your message (or 'quit' to exit): ")
|
||||
if user_input.lower() == 'quit':
|
||||
break
|
||||
input_items.append({"content": user_input, "role": "user"})
|
||||
result = await Runner.run(current_agent, input_items, context=context)
|
||||
for new_item in result.new_items:
|
||||
agent_name = new_item.agent.name
|
||||
if isinstance(new_item, MessageOutputItem):
|
||||
print(f"{agent_name}: {ItemHelpers.text_message_output(new_item)}")
|
||||
elif isinstance(new_item, ToolCallItem):
|
||||
print(f"{agent_name}: Calling a tool")
|
||||
elif isinstance(new_item, ToolCallOutputItem):
|
||||
print(f"{agent_name}: Tool call output: {new_item.output}")
|
||||
else:
|
||||
print(f"{agent_name}: Skipping item: {new_item.__class__.__name__}")
|
||||
input_items = result.to_input_list()
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Storing Information
|
||||
|
||||
```
|
||||
User: Remember that my favorite color is blue
|
||||
Agent: Calling a tool
|
||||
Agent: Tool call output: Stored message: my favorite color is blue
|
||||
Agent: I've stored that your favorite color is blue in my memory. I'll remember that for future conversations.
|
||||
```
|
||||
|
||||
### Searching Memory
|
||||
|
||||
```
|
||||
User: What's my favorite color?
|
||||
Agent: Calling a tool
|
||||
Agent: Tool call output: my favorite color is blue
|
||||
Agent: Your favorite color is blue, based on what you've told me earlier.
|
||||
```
|
||||
|
||||
### Retrieving All Memories
|
||||
|
||||
```
|
||||
User: What do you know about me?
|
||||
Agent: Calling a tool
|
||||
Agent: Tool call output: favorite color is blue
|
||||
my birthday is on March 15
|
||||
Agent: Based on our previous conversations, I know that:
|
||||
1. Your favorite color is blue
|
||||
2. Your birthday is on March 15
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Custom User IDs
|
||||
|
||||
You can specify different user IDs to maintain separate memory stores for multiple users:
|
||||
|
||||
```python
|
||||
context = Mem0Context(user_id="user123")
|
||||
```
|
||||
|
||||
|
||||
## Resources
|
||||
|
||||
- [Mem0 Documentation](https://docs.mem0.ai)
|
||||
- [Mem0 Dashboard](https://app.mem0.ai/dashboard)
|
||||
- [API Reference](https://docs.mem0.ai/api-reference)
|
||||
@@ -13,6 +13,8 @@ You can create a personalized AI Companion using Mem0. This guide will walk you
|
||||
src="https://github.com/user-attachments/assets/cebc4f8e-bdb9-4837-868d-13c5ab7bb433"
|
||||
></video>
|
||||
|
||||
You can try the [Mem0 Demo](https://mem0.dev/demo) live here.
|
||||
|
||||
## Overview
|
||||
|
||||
The Personalized AI Companion leverages Mem0 to retain information across interactions, enabling a tailored learning experience. It creates memories for each user interaction and integrates with OpenAI's GPT models to provide detailed and context-aware responses to user queries.
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
---
|
||||
title: Mem0 with Mastra
|
||||
---
|
||||
|
||||
In this example you'll learn how to use the Mem0 to add long-term memory capabilities to [Mastra's agent](https://mastra.ai/) via tool-use.
|
||||
This memory integration can work alongside Mastra's [agent memory features](https://mastra.ai/docs/agents/01-agent-memory).
|
||||
|
||||
You can find the complete example code in the [Mastra repository](https://github.com/mastra-ai/mastra/tree/main/examples/memory-with-mem0).
|
||||
|
||||
## Overview
|
||||
|
||||
This guide will show you how to integrate Mem0 with Mastra to add long-term memory capabilities to your agents. We'll create tools that allow agents to save and retrieve memories using Mem0's API.
|
||||
|
||||
### Installation
|
||||
|
||||
1. **Install the Integration Package**
|
||||
|
||||
To install the Mem0 integration, run:
|
||||
|
||||
```bash
|
||||
npm install @mastra/mem0
|
||||
```
|
||||
|
||||
2. **Add the Integration to Your Project**
|
||||
|
||||
Create a new file for your integrations and import the integration:
|
||||
|
||||
```typescript integrations/index.ts
|
||||
import { Mem0Integration } from "@mastra/mem0";
|
||||
|
||||
export const mem0 = new Mem0Integration({
|
||||
config: {
|
||||
apiKey: process.env.MEM0_API_KEY!,
|
||||
userId: "alice",
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
3. **Use the Integration in Tools or Workflows**
|
||||
|
||||
You can now use the integration when defining tools for your agents or in workflows.
|
||||
|
||||
```typescript tools/index.ts
|
||||
import { createTool } from "@mastra/core";
|
||||
import { z } from "zod";
|
||||
import { mem0 } from "../integrations";
|
||||
|
||||
export const mem0RememberTool = createTool({
|
||||
id: "Mem0-remember",
|
||||
description:
|
||||
"Remember your agent memories that you've previously saved using the Mem0-memorize tool.",
|
||||
inputSchema: z.object({
|
||||
question: z
|
||||
.string()
|
||||
.describe("Question used to look up the answer in saved memories."),
|
||||
}),
|
||||
outputSchema: z.object({
|
||||
answer: z.string().describe("Remembered answer"),
|
||||
}),
|
||||
execute: async ({ context }) => {
|
||||
console.log(`Searching memory "${context.question}"`);
|
||||
const memory = await mem0.searchMemory(context.question);
|
||||
console.log(`\nFound memory "${memory}"\n`);
|
||||
|
||||
return {
|
||||
answer: memory,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
export const mem0MemorizeTool = createTool({
|
||||
id: "Mem0-memorize",
|
||||
description:
|
||||
"Save information to mem0 so you can remember it later using the Mem0-remember tool.",
|
||||
inputSchema: z.object({
|
||||
statement: z.string().describe("A statement to save into memory"),
|
||||
}),
|
||||
execute: async ({ context }) => {
|
||||
console.log(`\nCreating memory "${context.statement}"\n`);
|
||||
// to reduce latency memories can be saved async without blocking tool execution
|
||||
void mem0.createMemory(context.statement).then(() => {
|
||||
console.log(`\nMemory "${context.statement}" saved.\n`);
|
||||
});
|
||||
return { success: true };
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
4. **Create a new agent**
|
||||
|
||||
```typescript agents/index.ts
|
||||
import { openai } from '@ai-sdk/openai';
|
||||
import { Agent } from '@mastra/core/agent';
|
||||
import { mem0MemorizeTool, mem0RememberTool } from '../tools';
|
||||
|
||||
export const mem0Agent = new Agent({
|
||||
name: 'Mem0 Agent',
|
||||
instructions: `
|
||||
You are a helpful assistant that has the ability to memorize and remember facts using Mem0.
|
||||
`,
|
||||
model: openai('gpt-4o'),
|
||||
tools: { mem0RememberTool, mem0MemorizeTool },
|
||||
});
|
||||
```
|
||||
|
||||
5. **Run the agent**
|
||||
|
||||
```typescript index.ts
|
||||
import { Mastra } from '@mastra/core/mastra';
|
||||
import { createLogger } from '@mastra/core/logger';
|
||||
|
||||
import { mem0Agent } from './agents';
|
||||
|
||||
export const mastra = new Mastra({
|
||||
agents: { mem0Agent },
|
||||
logger: createLogger({
|
||||
name: 'Mastra',
|
||||
level: 'error',
|
||||
}),
|
||||
});
|
||||
```
|
||||
|
||||
In the example above:
|
||||
- We import the `@mastra/mem0` integration.
|
||||
- We define two tools that uses the Mem0 API client to create new memories and recall previously saved memories.
|
||||
- The tool accepts `question` as an input and returns the memory as a string.
|
||||
@@ -0,0 +1,538 @@
|
||||
---
|
||||
title: 'Mem0 with OpenAI Agents SDK for Voice'
|
||||
description: 'Integrate memory capabilities into your voice agents using Mem0 and OpenAI Agents SDK'
|
||||
---
|
||||
|
||||
# Building Voice Agents with Memory using Mem0 and OpenAI Agents SDK
|
||||
|
||||
This guide demonstrates how to combine OpenAI's Agents SDK for voice applications with Mem0's memory capabilities to create a voice assistant that remembers user preferences and past interactions.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, make sure you have:
|
||||
|
||||
1. Installed OpenAI Agents SDK with voice dependencies:
|
||||
```bash
|
||||
pip install 'openai-agents[voice]'
|
||||
```
|
||||
|
||||
2. Installed Mem0 SDK:
|
||||
```bash
|
||||
pip install mem0ai
|
||||
```
|
||||
|
||||
3. Installed other required dependencies:
|
||||
```bash
|
||||
pip install numpy sounddevice pydantic
|
||||
```
|
||||
|
||||
4. Set up your API keys:
|
||||
- OpenAI API key for the Agents SDK
|
||||
- Mem0 API key from the Mem0 Platform
|
||||
|
||||
## Code Breakdown
|
||||
|
||||
Let's break down the key components of this implementation:
|
||||
|
||||
### 1. Setting Up Dependencies and Environment
|
||||
|
||||
```python
|
||||
# OpenAI Agents SDK imports
|
||||
from agents import (
|
||||
Agent,
|
||||
function_tool
|
||||
)
|
||||
from agents.voice import (
|
||||
AudioInput,
|
||||
SingleAgentVoiceWorkflow,
|
||||
VoicePipeline
|
||||
)
|
||||
from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
|
||||
|
||||
# Mem0 imports
|
||||
from mem0 import AsyncMemoryClient
|
||||
|
||||
# Set up API keys (replace with your actual keys)
|
||||
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
|
||||
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
|
||||
|
||||
# Define a global user ID for simplicity
|
||||
USER_ID = "voice_user"
|
||||
|
||||
# Initialize Mem0 client
|
||||
mem0_client = AsyncMemoryClient()
|
||||
```
|
||||
|
||||
This section handles:
|
||||
- Importing required modules from OpenAI Agents SDK and Mem0
|
||||
- Setting up environment variables for API keys
|
||||
- Defining a simple user identification system (using a global variable)
|
||||
- Initializing the Mem0 client that will handle memory operations
|
||||
|
||||
### 2. Memory Tools with Function Decorators
|
||||
|
||||
The `@function_tool` decorator transforms Python functions into callable tools for the OpenAI agent. Here are the key memory tools:
|
||||
|
||||
#### Storing User Memories
|
||||
|
||||
```python
|
||||
import logging
|
||||
|
||||
# Set up logging at the top of your file
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
force=True
|
||||
)
|
||||
logger = logging.getLogger("memory_voice_agent")
|
||||
|
||||
# Then use logger in your function tools
|
||||
@function_tool
|
||||
async def save_memories(
|
||||
memory: str
|
||||
) -> str:
|
||||
"""Store a user memory in memory."""
|
||||
# This will be visible in your console
|
||||
logger.debug(f"Saving memory: {memory} for user {USER_ID}")
|
||||
|
||||
# Store the preference in Mem0
|
||||
memory_content = f"User memory - {memory}"
|
||||
await mem0_client.add(
|
||||
memory_content,
|
||||
user_id=USER_ID,
|
||||
)
|
||||
|
||||
return f"I've saved your memory: {memory}"
|
||||
```
|
||||
|
||||
This function:
|
||||
- Takes a memory string
|
||||
- Creates a formatted memory string
|
||||
- Stores it in Mem0 using the `add()` method
|
||||
- Includes metadata to categorize the memory for easier retrieval
|
||||
- Returns a confirmation message that the agent will speak
|
||||
|
||||
#### Finding Relevant Memories
|
||||
|
||||
```python
|
||||
@function_tool
|
||||
async def search_memories(
|
||||
query: str
|
||||
) -> str:
|
||||
"""
|
||||
Find memories relevant to the current conversation.
|
||||
Args:
|
||||
query: The search query to find relevant memories
|
||||
"""
|
||||
print(f"Finding memories related to: {query}")
|
||||
results = await mem0_client.search(
|
||||
query,
|
||||
user_id=USER_ID,
|
||||
limit=5,
|
||||
threshold=0.7, # Higher threshold for more relevant results
|
||||
output_format="v1.1"
|
||||
)
|
||||
|
||||
# Format and return the results
|
||||
if not results.get('results', []):
|
||||
return "I don't have any relevant memories about this topic."
|
||||
|
||||
memories = [f"• {result['memory']}" for result in results.get('results', [])]
|
||||
return "Here's what I remember that might be relevant:\n" + "\n".join(memories)
|
||||
```
|
||||
|
||||
This tool:
|
||||
- Takes a search query string
|
||||
- Passes it to Mem0's semantic search to find related memories
|
||||
- Sets a threshold for relevance to ensure quality results
|
||||
- Returns a formatted list of relevant memories or a default message
|
||||
|
||||
### 3. Creating the Voice Agent
|
||||
|
||||
```python
|
||||
def create_memory_voice_agent():
|
||||
# Create the agent with memory-enabled tools
|
||||
agent = Agent(
|
||||
name="Memory Assistant",
|
||||
instructions=prompt_with_handoff_instructions(
|
||||
"""You're speaking to a human, so be polite and concise.
|
||||
Always respond in clear, natural English.
|
||||
You have the ability to remember information about the user.
|
||||
Use the save_memories tool when the user shares an important information worth remembering.
|
||||
Use the search_memories tool when you need context from past conversations or user asks you to recall something.
|
||||
""",
|
||||
),
|
||||
model="gpt-4o",
|
||||
tools=[save_memories, search_memories],
|
||||
)
|
||||
|
||||
return agent
|
||||
```
|
||||
|
||||
This function:
|
||||
- Creates an OpenAI Agent with specific instructions
|
||||
- Configures it to use gpt-4o (you can use other models)
|
||||
- Registers the memory-related tools with the agent
|
||||
- Uses `prompt_with_handoff_instructions` to include standard voice agent behaviors
|
||||
|
||||
### 4. Microphone Recording Functionality
|
||||
|
||||
```python
|
||||
async def record_from_microphone(duration=5, samplerate=24000):
|
||||
"""Record audio from the microphone for a specified duration."""
|
||||
print(f"Recording for {duration} seconds...")
|
||||
|
||||
# Create a buffer to store the recorded audio
|
||||
frames = []
|
||||
|
||||
# Callback function to store audio data
|
||||
def callback(indata, frames_count, time_info, status):
|
||||
frames.append(indata.copy())
|
||||
|
||||
# Start recording
|
||||
with sd.InputStream(samplerate=samplerate, channels=1, callback=callback, dtype=np.int16):
|
||||
await asyncio.sleep(duration)
|
||||
|
||||
# Combine all frames into a single numpy array
|
||||
audio_data = np.concatenate(frames)
|
||||
return audio_data
|
||||
```
|
||||
|
||||
This function:
|
||||
- Creates a simple asynchronous microphone recording function
|
||||
- Uses the sounddevice library to capture audio input
|
||||
- Stores frames in a buffer during recording
|
||||
- Combines frames into a single numpy array when complete
|
||||
- Returns the audio data for processing
|
||||
|
||||
### 5. Main Loop and Voice Processing
|
||||
|
||||
```python
|
||||
async def main():
|
||||
# Create the agent
|
||||
agent = create_memory_voice_agent()
|
||||
|
||||
# Set up the voice pipeline
|
||||
pipeline = VoicePipeline(
|
||||
workflow=SingleAgentVoiceWorkflow(agent)
|
||||
)
|
||||
|
||||
# Configure TTS settings
|
||||
pipeline.config.tts_settings.voice = "alloy"
|
||||
pipeline.config.tts_settings.speed = 1.0
|
||||
|
||||
try:
|
||||
while True:
|
||||
# Get user input
|
||||
print("\nPress Enter to start recording (or 'q' to quit)...")
|
||||
user_input = input()
|
||||
if user_input.lower() == 'q':
|
||||
break
|
||||
|
||||
# Record and process audio
|
||||
audio_data = await record_from_microphone(duration=5)
|
||||
audio_input = AudioInput(buffer=audio_data)
|
||||
result = await pipeline.run(audio_input)
|
||||
|
||||
# Play response and handle events
|
||||
player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16)
|
||||
player.start()
|
||||
|
||||
agent_response = ""
|
||||
print("\nAgent response:")
|
||||
|
||||
async for event in result.stream():
|
||||
if event.type == "voice_stream_event_audio":
|
||||
player.write(event.data)
|
||||
elif event.type == "voice_stream_event_content":
|
||||
content = event.data
|
||||
agent_response += content
|
||||
print(content, end="", flush=True)
|
||||
|
||||
# Save the agent's response to memory
|
||||
if agent_response:
|
||||
try:
|
||||
await mem0_client.add(
|
||||
f"Agent response: {agent_response}",
|
||||
user_id=USER_ID,
|
||||
metadata={"type": "agent_response"}
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Failed to store memory: {e}")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nExiting...")
|
||||
```
|
||||
|
||||
This main function orchestrates the entire process:
|
||||
1. Creates the memory-enabled voice agent
|
||||
2. Sets up the voice pipeline with TTS settings
|
||||
3. Implements an interactive loop for recording and processing voice input
|
||||
4. Handles streaming of response events (both audio and text)
|
||||
5. Automatically saves the agent's responses to memory
|
||||
6. Includes proper error handling and exit mechanisms
|
||||
|
||||
## Create a Memory-Enabled Voice Agent
|
||||
|
||||
Now that we've explained each component, here's the complete implementation that combines OpenAI Agents SDK for voice with Mem0's memory capabilities:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import os
|
||||
import logging
|
||||
from typing import Optional, List, Dict, Any
|
||||
import numpy as np
|
||||
import sounddevice as sd
|
||||
from pydantic import BaseModel
|
||||
|
||||
# OpenAI Agents SDK imports
|
||||
from agents import (
|
||||
Agent,
|
||||
function_tool
|
||||
)
|
||||
from agents.voice import (
|
||||
AudioInput,
|
||||
SingleAgentVoiceWorkflow,
|
||||
VoicePipeline
|
||||
)
|
||||
from agents.extensions.handoff_prompt import prompt_with_handoff_instructions
|
||||
|
||||
# Mem0 imports
|
||||
from mem0 import AsyncMemoryClient
|
||||
|
||||
# Set up API keys (replace with your actual keys)
|
||||
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
|
||||
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
|
||||
|
||||
# Define a global user ID for simplicity
|
||||
USER_ID = "voice_user"
|
||||
|
||||
# Initialize Mem0 client
|
||||
mem0_client = AsyncMemoryClient()
|
||||
|
||||
# Create tools that utilize Mem0's memory
|
||||
@function_tool
|
||||
async def save_memories(
|
||||
memory: str
|
||||
) -> str:
|
||||
"""
|
||||
Store a user memory in memory.
|
||||
Args:
|
||||
memory: The memory to save
|
||||
"""
|
||||
print(f"Saving memory: {memory} for user {USER_ID}")
|
||||
|
||||
# Store the preference in Mem0
|
||||
memory_content = f"User memory - {memory}"
|
||||
await mem0_client.add(
|
||||
memory_content,
|
||||
user_id=USER_ID,
|
||||
)
|
||||
|
||||
return f"I've saved your memory: {memory}"
|
||||
|
||||
@function_tool
|
||||
async def search_memories(
|
||||
query: str
|
||||
) -> str:
|
||||
"""
|
||||
Find memories relevant to the current conversation.
|
||||
Args:
|
||||
query: The search query to find relevant memories
|
||||
"""
|
||||
print(f"Finding memories related to: {query}")
|
||||
results = await mem0_client.search(
|
||||
query,
|
||||
user_id=USER_ID,
|
||||
limit=5,
|
||||
threshold=0.7, # Higher threshold for more relevant results
|
||||
output_format="v1.1"
|
||||
)
|
||||
|
||||
# Format and return the results
|
||||
if not results.get('results', []):
|
||||
return "I don't have any relevant memories about this topic."
|
||||
|
||||
memories = [f"• {result['memory']}" for result in results.get('results', [])]
|
||||
return "Here's what I remember that might be relevant:\n" + "\n".join(memories)
|
||||
|
||||
# Create the agent with memory-enabled tools
|
||||
def create_memory_voice_agent():
|
||||
# Create the agent with memory-enabled tools
|
||||
agent = Agent(
|
||||
name="Memory Assistant",
|
||||
instructions=prompt_with_handoff_instructions(
|
||||
"""You're speaking to a human, so be polite and concise.
|
||||
Always respond in clear, natural English.
|
||||
You have the ability to remember information about the user.
|
||||
Use the save_memories tool when the user shares an important information worth remembering.
|
||||
Use the search_memories tool when you need context from past conversations or user asks you to recall something.
|
||||
""",
|
||||
),
|
||||
model="gpt-4o",
|
||||
tools=[save_memories, search_memories],
|
||||
)
|
||||
|
||||
return agent
|
||||
|
||||
async def record_from_microphone(duration=5, samplerate=24000):
|
||||
"""Record audio from the microphone for a specified duration."""
|
||||
print(f"Recording for {duration} seconds...")
|
||||
|
||||
# Create a buffer to store the recorded audio
|
||||
frames = []
|
||||
|
||||
# Callback function to store audio data
|
||||
def callback(indata, frames_count, time_info, status):
|
||||
frames.append(indata.copy())
|
||||
|
||||
# Start recording
|
||||
with sd.InputStream(samplerate=samplerate, channels=1, callback=callback, dtype=np.int16):
|
||||
await asyncio.sleep(duration)
|
||||
|
||||
# Combine all frames into a single numpy array
|
||||
audio_data = np.concatenate(frames)
|
||||
return audio_data
|
||||
|
||||
async def main():
|
||||
print("Starting Memory Voice Agent")
|
||||
|
||||
# Create the agent and context
|
||||
agent = create_memory_voice_agent()
|
||||
|
||||
# Set up the voice pipeline
|
||||
pipeline = VoicePipeline(
|
||||
workflow=SingleAgentVoiceWorkflow(agent)
|
||||
)
|
||||
|
||||
# Configure TTS settings
|
||||
pipeline.config.tts_settings.voice = "alloy"
|
||||
pipeline.config.tts_settings.speed = 1.0
|
||||
|
||||
try:
|
||||
while True:
|
||||
# Get user input
|
||||
print("\nPress Enter to start recording (or 'q' to quit)...")
|
||||
user_input = input()
|
||||
if user_input.lower() == 'q':
|
||||
break
|
||||
|
||||
# Record and process audio
|
||||
audio_data = await record_from_microphone(duration=5)
|
||||
audio_input = AudioInput(buffer=audio_data)
|
||||
|
||||
print("Processing your request...")
|
||||
|
||||
# Process the audio input
|
||||
result = await pipeline.run(audio_input)
|
||||
|
||||
# Create an audio player
|
||||
player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16)
|
||||
player.start()
|
||||
|
||||
# Store the agent's response for adding to memory
|
||||
agent_response = ""
|
||||
|
||||
print("\nAgent response:")
|
||||
# Play the audio stream as it comes in
|
||||
async for event in result.stream():
|
||||
if event.type == "voice_stream_event_audio":
|
||||
player.write(event.data)
|
||||
elif event.type == "voice_stream_event_content":
|
||||
# Accumulate and print the text response
|
||||
content = event.data
|
||||
agent_response += content
|
||||
print(content, end="", flush=True)
|
||||
|
||||
print("\n")
|
||||
|
||||
# Example of saving the conversation to Mem0 after completion
|
||||
if agent_response:
|
||||
try:
|
||||
await mem0_client.add(
|
||||
f"Agent response: {agent_response}",
|
||||
user_id=USER_ID,
|
||||
metadata={"type": "agent_response"}
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Failed to store memory: {e}")
|
||||
|
||||
except KeyboardInterrupt:
|
||||
print("\nExiting...")
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(main())
|
||||
```
|
||||
|
||||
## Key Features of This Implementation
|
||||
|
||||
This implementation offers several key features:
|
||||
|
||||
1. **Simplified User Management**: Uses a global `USER_ID` variable for simplicity, but can be extended to manage multiple users.
|
||||
|
||||
2. **Real Microphone Input**: Includes a `record_from_microphone()` function that captures actual voice input from your microphone.
|
||||
|
||||
3. **Interactive Voice Loop**: Implements a continuous interaction loop, allowing for multiple back-and-forth exchanges.
|
||||
|
||||
4. **Memory Management Tools**:
|
||||
- `save_memories`: Stores user memories in Mem0
|
||||
- `search_memories`: Searches for relevant past information
|
||||
|
||||
5. **Voice Configuration**: Demonstrates how to configure TTS settings for the voice response.
|
||||
|
||||
## Running the Example
|
||||
|
||||
To run this example:
|
||||
|
||||
1. Replace the placeholder API keys with your actual keys
|
||||
2. Make sure your microphone is properly connected
|
||||
3. Run the script with Python 3.8 or newer
|
||||
4. Press Enter to start recording, then speak your request
|
||||
5. Press 'q' to quit the application
|
||||
|
||||
The agent will listen to your request, process it through the OpenAI model, utilize Mem0 for memory operations as needed, and respond both through text output and voice speech.
|
||||
|
||||
## Best Practices for Voice Agents with Memory
|
||||
|
||||
1. **Optimizing Memory for Voice**: Keep memories concise and relevant for voice responses.
|
||||
|
||||
2. **Forgetting Mechanism**: Implement a way to delete or expire memories that are no longer relevant.
|
||||
|
||||
3. **Context Preservation**: Store enough context with each memory to make retrieval effective.
|
||||
|
||||
4. **Error Handling**: Implement robust error handling for memory operations, as voice interactions should continue smoothly even if memory operations fail.
|
||||
|
||||
## Conclusion
|
||||
|
||||
By combining OpenAI's Agents SDK with Mem0's memory capabilities, you can create voice agents that maintain persistent memory of user preferences and past interactions. This significantly enhances the user experience by making conversations more natural and personalized.
|
||||
|
||||
As you build your voice application, experiment with different memory strategies and filtering approaches to find the optimal balance between comprehensive memory and efficient retrieval for your specific use case.
|
||||
|
||||
## Debugging Function Tools
|
||||
|
||||
When working with the OpenAI Agents SDK, you might notice that regular `print()` statements inside `@function_tool` decorated functions don't appear in your console output. This is because the Agents SDK captures and redirects standard output when executing these functions.
|
||||
|
||||
To effectively debug your function tools, use Python's `logging` module instead:
|
||||
|
||||
```python
|
||||
import logging
|
||||
|
||||
# Set up logging at the top of your file
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
|
||||
force=True
|
||||
)
|
||||
logger = logging.getLogger("memory_voice_agent")
|
||||
|
||||
# Then use logger in your function tools
|
||||
@function_tool
|
||||
async def save_memories(
|
||||
memory: str
|
||||
) -> str:
|
||||
"""Store a user memory in memory."""
|
||||
# This will be visible in your console
|
||||
logger.debug(f"Saving memory: {memory} for user {USER_ID}")
|
||||
|
||||
# Rest of your function...
|
||||
```
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: Multimodal Demo with Mem0
|
||||
---
|
||||
|
||||
Enhance your AI interactions with **Mem0**'s multimodal capabilities. Mem0 now supports image understanding, allowing for richer context and more natural interactions across supported AI platforms.
|
||||
|
||||
> 🎉 Experience the power of multimodal AI! Test out Mem0's image understanding capabilities at [multimodal-demo.mem0.ai](https://multimodal-demo.mem0.ai)
|
||||
|
||||
## 🚀 Features
|
||||
|
||||
- **🖼️ Image Understanding**: Share and discuss images with AI assistants while maintaining context.
|
||||
- **🔍 Smart Visual Context**: Automatically capture and reference visual elements in conversations.
|
||||
- **🔗 Cross-Modal Memory**: Link visual and textual information seamlessly in your memory layer.
|
||||
- **📌 Cross-Session Recall**: Reference previously discussed visual content across different conversations.
|
||||
- **⚡ Seamless Integration**: Works naturally with existing chat interfaces for a smooth experience.
|
||||
|
||||
## 📖 How It Works
|
||||
|
||||
1. **📂 Upload Visual Content**: Simply drag and drop or paste images into your conversations.
|
||||
2. **💬 Natural Interaction**: Discuss the visual content naturally with AI assistants.
|
||||
3. **📚 Memory Integration**: Visual context is automatically stored and linked with your conversation history.
|
||||
4. **🔄 Persistent Recall**: Retrieve and reference past visual content effortlessly.
|
||||
|
||||
## Demo Video
|
||||
|
||||
<iframe width="700" height="400" src="https://www.youtube.com/embed/2Md5AEFVpmg?si=rXXupn6CiDUPJsi3" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
## 🔥 Try It Out
|
||||
|
||||
Visit [multimodal-demo.mem0.ai](https://multimodal-demo.mem0.ai) to experience Mem0's multimodal capabilities firsthand. Upload images and see how Mem0 understands and remembers visual context across your conversations.
|
||||
|
||||
@@ -0,0 +1,312 @@
|
||||
---
|
||||
title: OpenAI Inbuilt Tools
|
||||
---
|
||||
|
||||
Integrate Mem0’s memory capabilities with OpenAI’s Inbuilt Tools to create AI agents with persistent memory.
|
||||
|
||||
## Getting Started
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
npm install mem0ai openai zod
|
||||
```
|
||||
|
||||
## Environment Setup
|
||||
|
||||
Save your Mem0 and OpenAI API keys in a `.env` file:
|
||||
|
||||
```
|
||||
MEM0_API_KEY=your_mem0_api_key
|
||||
OPENAI_API_KEY=your_openai_api_key
|
||||
```
|
||||
|
||||
Get your Mem0 API key from the [Mem0 Dashboard](https://app.mem0.ai/dashboard/api-keys).
|
||||
|
||||
### Configuration
|
||||
|
||||
```javascript
|
||||
const mem0Config = {
|
||||
apiKey: process.env.MEM0_API_KEY,
|
||||
user_id: "sample-user",
|
||||
};
|
||||
|
||||
const openAIClient = new OpenAI();
|
||||
const mem0Client = new MemoryClient(mem0Config);
|
||||
```
|
||||
|
||||
### Adding Memories
|
||||
|
||||
Store user preferences, past interactions, or any relevant information:
|
||||
<CodeGroup>
|
||||
```javascript JavaScript
|
||||
async function addUserPreferences() {
|
||||
const mem0Client = new MemoryClient(mem0Config);
|
||||
|
||||
const userPreferences = "I Love BMW, Audi and Porsche. I Hate Mercedes. I love Red cars and Maroon cars. I have a budget of 120K to 150K USD. I like Audi the most.";
|
||||
|
||||
await mem0Client.add([{
|
||||
role: "user",
|
||||
content: userPreferences,
|
||||
}], mem0Config);
|
||||
}
|
||||
|
||||
await addUserPreferences();
|
||||
```
|
||||
|
||||
```json Output (Memories)
|
||||
[
|
||||
{
|
||||
"id": "ff9f3367-9e83-415d-b9c5-dc8befd9a4b4",
|
||||
"data": { "memory": "Loves BMW, Audi, and Porsche" },
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"id": "04172ce6-3d7b-45a3-b4a1-ee9798593cb4",
|
||||
"data": { "memory": "Hates Mercedes" },
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"id": "db363a5d-d258-4953-9e4c-777c120de34d",
|
||||
"data": { "memory": "Loves red cars and maroon cars" },
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"id": "5519aaad-a2ac-4c0d-81d7-0d55c6ecdba8",
|
||||
"data": { "memory": "Has a budget of 120K to 150K USD" },
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"id": "523b7693-7344-4563-922f-5db08edc8634",
|
||||
"data": { "memory": "Likes Audi the most" },
|
||||
"event": "ADD"
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
### Retrieving Memories
|
||||
|
||||
Search for relevant memories based on the current user input:
|
||||
|
||||
```javascript
|
||||
const relevantMemories = await mem0Client.search(userInput, mem0Config);
|
||||
```
|
||||
|
||||
### Structured Responses with Zod
|
||||
|
||||
Define structured response schemas to get consistent output formats:
|
||||
|
||||
```javascript
|
||||
// Define the schema for a car recommendation
|
||||
const CarSchema = z.object({
|
||||
car_name: z.string(),
|
||||
car_price: z.string(),
|
||||
car_url: z.string(),
|
||||
car_image: z.string(),
|
||||
car_description: z.string(),
|
||||
});
|
||||
|
||||
// Schema for a list of car recommendations
|
||||
const Cars = z.object({
|
||||
cars: z.array(CarSchema),
|
||||
});
|
||||
|
||||
// Create a function tool based on the schema
|
||||
const carRecommendationTool = zodResponsesFunction({
|
||||
name: "carRecommendations",
|
||||
parameters: Cars
|
||||
});
|
||||
|
||||
// Use the tool in your OpenAI request
|
||||
const response = await openAIClient.responses.create({
|
||||
model: "gpt-4o",
|
||||
tools: [{ type: "web_search_preview" }, carRecommendationTool],
|
||||
input: `${getMemoryString(relevantMemories)}\n${userInput}`,
|
||||
});
|
||||
```
|
||||
|
||||
### Using Web Search
|
||||
|
||||
Combine memory with web search for up-to-date recommendations:
|
||||
|
||||
```javascript
|
||||
const response = await openAIClient.responses.create({
|
||||
model: "gpt-4o",
|
||||
tools: [{ type: "web_search_preview" }, carRecommendationTool],
|
||||
input: `${getMemoryString(relevantMemories)}\n${userInput}`,
|
||||
});
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Complete Car Recommendation System
|
||||
|
||||
```javascript
|
||||
import MemoryClient from "mem0ai";
|
||||
import { OpenAI } from "openai";
|
||||
import { zodResponsesFunction } from "openai/helpers/zod";
|
||||
import { z } from "zod";
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
dotenv.config();
|
||||
|
||||
const mem0Config = {
|
||||
apiKey: process.env.MEM0_API_KEY,
|
||||
user_id: "sample-user",
|
||||
};
|
||||
|
||||
async function run() {
|
||||
// Responses without memories
|
||||
console.log("\n\nRESPONSES WITHOUT MEMORIES\n\n");
|
||||
await main();
|
||||
|
||||
// Adding sample memories
|
||||
await addSampleMemories();
|
||||
|
||||
// Responses with memories
|
||||
console.log("\n\nRESPONSES WITH MEMORIES\n\n");
|
||||
await main(true);
|
||||
}
|
||||
|
||||
// OpenAI Response Schema
|
||||
const CarSchema = z.object({
|
||||
car_name: z.string(),
|
||||
car_price: z.string(),
|
||||
car_url: z.string(),
|
||||
car_image: z.string(),
|
||||
car_description: z.string(),
|
||||
});
|
||||
|
||||
const Cars = z.object({
|
||||
cars: z.array(CarSchema),
|
||||
});
|
||||
|
||||
async function main(memory = false) {
|
||||
const openAIClient = new OpenAI();
|
||||
const mem0Client = new MemoryClient(mem0Config);
|
||||
|
||||
const input = "Suggest me some cars that I can buy today.";
|
||||
|
||||
const tool = zodResponsesFunction({ name: "carRecommendations", parameters: Cars });
|
||||
|
||||
// Store the user input as a memory
|
||||
await mem0Client.add([{
|
||||
role: "user",
|
||||
content: input,
|
||||
}], mem0Config);
|
||||
|
||||
// Search for relevant memories
|
||||
let relevantMemories = []
|
||||
if (memory) {
|
||||
relevantMemories = await mem0Client.search(input, mem0Config);
|
||||
}
|
||||
|
||||
const response = await openAIClient.responses.create({
|
||||
model: "gpt-4o",
|
||||
tools: [{ type: "web_search_preview" }, tool],
|
||||
input: `${getMemoryString(relevantMemories)}\n${input}`,
|
||||
});
|
||||
|
||||
console.log(response.output);
|
||||
}
|
||||
|
||||
async function addSampleMemories() {
|
||||
const mem0Client = new MemoryClient(mem0Config);
|
||||
|
||||
const myInterests = "I Love BMW, Audi and Porsche. I Hate Mercedes. I love Red cars and Maroon cars. I have a budget of 120K to 150K USD. I like Audi the most.";
|
||||
|
||||
await mem0Client.add([{
|
||||
role: "user",
|
||||
content: myInterests,
|
||||
}], mem0Config);
|
||||
}
|
||||
|
||||
const getMemoryString = (memories) => {
|
||||
const MEMORY_STRING_PREFIX = "These are the memories I have stored. Give more weightage to the question by users and try to answer that first. You have to modify your answer based on the memories I have provided. If the memories are irrelevant you can ignore them. Also don't reply to this section of the prompt, or the memories, they are only for your reference. The MEMORIES of the USER are: \n\n";
|
||||
const memoryString = memories.map((mem) => `${mem.memory}`).join("\n") ?? "";
|
||||
return memoryString.length > 0 ? `${MEMORY_STRING_PREFIX}${memoryString}` : "";
|
||||
};
|
||||
|
||||
run().catch(console.error);
|
||||
```
|
||||
|
||||
### Responses
|
||||
|
||||
<CodeGroup>
|
||||
```json Without Memories
|
||||
{
|
||||
"cars": [
|
||||
{
|
||||
"car_name": "Toyota Camry",
|
||||
"car_price": "$25,000",
|
||||
"car_url": "https://www.toyota.com/camry/",
|
||||
"car_image": "https://link-to-toyota-camry-image.com",
|
||||
"car_description": "Reliable mid-size sedan with great fuel efficiency."
|
||||
},
|
||||
{
|
||||
"car_name": "Honda Accord",
|
||||
"car_price": "$26,000",
|
||||
"car_url": "https://www.honda.com/accord/",
|
||||
"car_image": "https://link-to-honda-accord-image.com",
|
||||
"car_description": "Comfortable and spacious with advanced safety features."
|
||||
},
|
||||
{
|
||||
"car_name": "Ford Mustang",
|
||||
"car_price": "$28,000",
|
||||
"car_url": "https://www.ford.com/mustang/",
|
||||
"car_image": "https://link-to-ford-mustang-image.com",
|
||||
"car_description": "Iconic sports car with powerful engine options."
|
||||
},
|
||||
{
|
||||
"car_name": "Tesla Model 3",
|
||||
"car_price": "$38,000",
|
||||
"car_url": "https://www.tesla.com/model3",
|
||||
"car_image": "https://link-to-tesla-model3-image.com",
|
||||
"car_description": "Electric vehicle with advanced technology and long range."
|
||||
},
|
||||
{
|
||||
"car_name": "Chevrolet Equinox",
|
||||
"car_price": "$24,000",
|
||||
"car_url": "https://www.chevrolet.com/equinox/",
|
||||
"car_image": "https://link-to-chevron-equinox-image.com",
|
||||
"car_description": "Compact SUV with a spacious interior and user-friendly technology."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```json With Memories
|
||||
{
|
||||
"cars": [
|
||||
{
|
||||
"car_name": "Audi RS7",
|
||||
"car_price": "$118,500",
|
||||
"car_url": "https://www.audiusa.com/us/web/en/models/rs7/2023/overview.html",
|
||||
"car_image": "https://www.audiusa.com/content/dam/nemo/us/models/rs7/my23/gallery/1920x1080_AOZ_A717_191004.jpg",
|
||||
"car_description": "The Audi RS7 is a high-performance hatchback with a sleek design, powerful 591-hp twin-turbo V8, and luxurious interior. It's available in various colors including red."
|
||||
},
|
||||
{
|
||||
"car_name": "Porsche Panamera GTS",
|
||||
"car_price": "$129,300",
|
||||
"car_url": "https://www.porsche.com/usa/models/panamera/panamera-models/panamera-gts/",
|
||||
"car_image": "https://files.porsche.com/filestore/image/multimedia/noneporsche-panamera-gts-sample-m02-high/normal/8a6327c3-6c7f-4c6f-a9a8-fb9f58b21795;sP;twebp/porsche-normal.webp",
|
||||
"car_description": "The Porsche Panamera GTS is a luxury sports sedan with a 473-hp V8 engine, exquisite handling, and available in stunning red. Balances sportiness and comfort."
|
||||
},
|
||||
{
|
||||
"car_name": "BMW M5",
|
||||
"car_price": "$105,500",
|
||||
"car_url": "https://www.bmwusa.com/vehicles/m-models/m5/sedan/overview.html",
|
||||
"car_image": "https://www.bmwusa.com/content/dam/bmwusa/M/m5/2023/bmw-my23-m5-sapphire-black-twilight-purple-exterior-02.jpg",
|
||||
"car_description": "The BMW M5 is a powerhouse sedan with a 600-hp V8 engine, known for its great handling and luxury. It comes in several distinctive colors including maroon."
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Resources
|
||||
|
||||
- [Mem0 Documentation](https://docs.mem0.ai)
|
||||
- [Mem0 Dashboard](https://app.mem0.ai/dashboard)
|
||||
- [API Reference](https://docs.mem0.ai/api-reference)
|
||||
- [OpenAI Documentation](https://platform.openai.com/docs)
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
title: Overview
|
||||
description: How to use mem0 in your existing applications?
|
||||
---
|
||||
|
||||
|
||||
With Mem0, you can create stateful LLM-based applications such as chatbots, virtual assistants, or AI agents. Mem0 enhances your applications by providing a memory layer that makes responses:
|
||||
|
||||
- More personalized
|
||||
- More reliable
|
||||
- Cost-effective by reducing the number of LLM interactions
|
||||
- More engaging
|
||||
- Enables long-term memory
|
||||
|
||||
Here are some examples of how Mem0 can be integrated into various applications:
|
||||
|
||||
## Examples
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="AI Companion in Node.js" icon="square-6" href="/examples/ai_companion_js">
|
||||
Create a Personalized AI Companion using Mem0 in Node.js.
|
||||
</Card>
|
||||
<Card title="Mem0 with Ollama" icon="square-1" href="/examples/mem0-with-ollama">
|
||||
Run Mem0 locally with Ollama.
|
||||
</Card>
|
||||
<Card title="Personal AI Tutor" icon="square-2" href="/examples/personal-ai-tutor">
|
||||
Create a Personalized AI Tutor that adapts to student progress and learning preferences.
|
||||
</Card>
|
||||
<Card title="Personal Travel Assistant" icon="square-3" href="/examples/personal-travel-assistant">
|
||||
Build a Personalized AI Travel Assistant that understands your travel preferences and past itineraries.
|
||||
</Card>
|
||||
<Card title="Customer Support Agent" icon="square-4" href="/examples/customer-support-agent">
|
||||
Develop a Personal AI Assistant that remembers user preferences, past interactions, and context to provide personalized and efficient assistance.
|
||||
</Card>
|
||||
<Card title="LlamaIndex Mem0" icon="square-5" href="/examples/llama-index-mem0">
|
||||
Create a ReAct Agent with LlamaIndex which uses Mem0 as the memory store.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -20,6 +20,7 @@ pip install openai mem0ai
|
||||
Below is the complete code to create and interact with a Personalized AI Tutor using Mem0:
|
||||
|
||||
```python
|
||||
import os
|
||||
from openai import OpenAI
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -54,22 +55,21 @@ class PersonalAITutor:
|
||||
:param question: The question to ask the AI.
|
||||
:param user_id: Optional user ID to associate with the memory.
|
||||
"""
|
||||
# Start a streaming chat completion request to the AI
|
||||
stream = self.client.chat.completions.create(
|
||||
model="gpt-4",
|
||||
stream=True,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a personal AI Tutor."},
|
||||
{"role": "user", "content": question}
|
||||
]
|
||||
# Start a streaming response request to the AI
|
||||
response = self.client.responses.create(
|
||||
model="gpt-4o",
|
||||
instructions="You are a personal AI Tutor.",
|
||||
input=question,
|
||||
stream=True
|
||||
)
|
||||
|
||||
# Store the question in memory
|
||||
self.memory.add(question, user_id=user_id, metadata={"app_id": self.app_id})
|
||||
|
||||
# Print the response from the AI in real-time
|
||||
for chunk in stream:
|
||||
if chunk.choices[0].delta.content is not None:
|
||||
print(chunk.choices[0].delta.content, end="")
|
||||
for event in response:
|
||||
if event.type == "response.output_text.delta":
|
||||
print(event.delta, end="")
|
||||
|
||||
def get_memories(self, user_id=None):
|
||||
"""
|
||||
@@ -96,8 +96,8 @@ You can fetch all the memories at any point in time using the following code:
|
||||
|
||||
```python
|
||||
memories = ai_tutor.get_memories(user_id=user_id)
|
||||
for m in memories:
|
||||
print(m['text'])
|
||||
for m in memories['results']:
|
||||
print(m['memory'])
|
||||
```
|
||||
|
||||
### Key Points
|
||||
|
||||
@@ -63,18 +63,23 @@ class PersonalTravelAssistant:
|
||||
def ask_question(self, question, user_id):
|
||||
# Fetch previous related memories
|
||||
previous_memories = self.search_memories(question, user_id=user_id)
|
||||
prompt = question
|
||||
if previous_memories:
|
||||
prompt = f"User input: {question}\n Previous memories: {previous_memories}"
|
||||
self.messages.append({"role": "user", "content": prompt})
|
||||
|
||||
# Generate response using GPT-4o
|
||||
response = self.client.chat.completions.create(
|
||||
# Build the prompt
|
||||
system_message = "You are a personal AI Assistant."
|
||||
|
||||
if previous_memories:
|
||||
prompt = f"{system_message}\n\nUser input: {question}\nPrevious memories: {', '.join(previous_memories)}"
|
||||
else:
|
||||
prompt = f"{system_message}\n\nUser input: {question}"
|
||||
|
||||
# Generate response using Responses API
|
||||
response = self.client.responses.create(
|
||||
model="gpt-4o",
|
||||
messages=self.messages
|
||||
input=prompt
|
||||
)
|
||||
answer = response.choices[0].message.content
|
||||
self.messages.append({"role": "assistant", "content": answer})
|
||||
|
||||
# Extract answer from the response
|
||||
answer = response.output[0].content[0].text
|
||||
|
||||
# Store the question in memory
|
||||
self.memory.add(question, user_id=user_id)
|
||||
@@ -82,11 +87,11 @@ class PersonalTravelAssistant:
|
||||
|
||||
def get_memories(self, user_id):
|
||||
memories = self.memory.get_all(user_id=user_id)
|
||||
return [m['memory'] for m in memories['memories']]
|
||||
return [m['memory'] for m in memories['results']]
|
||||
|
||||
def search_memories(self, query, user_id):
|
||||
memories = self.memory.search(query, user_id=user_id)
|
||||
return [m['memory'] for m in memories['memories']]
|
||||
return [m['memory'] for m in memories['results']]
|
||||
|
||||
# Usage example
|
||||
user_id = "traveler_123"
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
title: Personalized Deep Research
|
||||
---
|
||||
|
||||
Deep Research is an intelligent agent that synthesizes large amounts of online data and completes complex research tasks, customized to your unique preferences and insights. Built on Mem0's technology, it enhances AI-driven online exploration with personalized memories.
|
||||
|
||||
## Overview
|
||||
|
||||
Deep Research leverages Mem0's memory capabilities to:
|
||||
- Synthesize large amounts of online data
|
||||
- Complete complex research tasks
|
||||
- Customize results to your preferences
|
||||
- Store and utilize personal insights
|
||||
- Maintain context across research sessions
|
||||
|
||||
## Demo
|
||||
|
||||
Watch Deep Research in action:
|
||||
|
||||
<iframe
|
||||
width="700"
|
||||
height="400"
|
||||
src="https://www.youtube.com/embed/8vQlCtXzF60?si=b8iTOgummAVzR7ia"
|
||||
title="YouTube video player"
|
||||
frameborder="0"
|
||||
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
|
||||
referrerpolicy="strict-origin-when-cross-origin"
|
||||
allowfullscreen
|
||||
></iframe>
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Visit [deep-research.mem0.ai](https://deep-research.mem0.ai/)
|
||||
2. Upload your resume (PDF or text) or manually enter information about yourself
|
||||
3. Enter your research topic
|
||||
4. Click "Start Research" to begin
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Personalized Research
|
||||
- Analyzes your background and expertise
|
||||
- Tailors research depth and complexity to your level
|
||||
- Incorporates your previous research context
|
||||
|
||||
### 2. Comprehensive Data Synthesis
|
||||
- Processes multiple online sources
|
||||
- Extracts relevant information
|
||||
- Provides coherent summaries
|
||||
|
||||
### 3. Memory Integration
|
||||
- Stores research findings for future reference
|
||||
- Maintains context across sessions
|
||||
- Links related research topics
|
||||
|
||||
### 4. Interactive Exploration
|
||||
- Allows real-time query refinement
|
||||
- Supports follow-up questions
|
||||
- Enables deep-diving into specific areas
|
||||
|
||||
## Use Cases
|
||||
|
||||
- **Academic Research**: Literature reviews, thesis research, paper writing
|
||||
- **Market Research**: Industry analysis, competitor research, trend identification
|
||||
- **Technical Research**: Technology evaluation, solution comparison
|
||||
- **Business Research**: Strategic planning, opportunity analysis
|
||||
|
||||
|
||||
## Try It Out
|
||||
|
||||
Experience AI-powered research personalization at [deep-research.mem0.ai](https://deep-research.mem0.ai/)
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
title: YouTube Assistant Extension
|
||||
---
|
||||
|
||||
Enhance your YouTube experience with Mem0's **YouTube Assistant**, a Chrome extension that brings AI-powered chat directly to your YouTube videos. Get instant, personalized answers about video content while leveraging your own knowledge and memories - all without leaving the page.
|
||||
|
||||
## Features
|
||||
|
||||
- **Contextual AI Chat**: Ask questions about videos you're watching
|
||||
- **Seamless Integration**: Chat interface sits alongside YouTube's native UI
|
||||
- **Memory Integration**: Personalized responses based on your knowledge through Mem0
|
||||
- **Real-Time Memory**: Memories are updated in real-time based on your interactions
|
||||
|
||||
## Demo Video
|
||||
|
||||
<video
|
||||
autoPlay
|
||||
muted
|
||||
loop
|
||||
playsInline
|
||||
width="700"
|
||||
height="400"
|
||||
src="https://github.com/user-attachments/assets/c0334ccd-311b-4dd7-8034-ef88204fc751"
|
||||
></video>
|
||||
|
||||
## Installation
|
||||
|
||||
This extension is not available on the Chrome Web Store yet. You can install it manually using below method:
|
||||
|
||||
### Manual Installation (Developer Mode)
|
||||
|
||||
1. **Download the Extension**: Clone or download the extension files from the [Mem0 GitHub repository](https://github.com/mem0ai/mem0/tree/main/examples).
|
||||
2. **Build**: Run `npm install` followed by `npm run build` to install the dependencies and build the extension.
|
||||
3. **Access Chrome Extensions**: Open Google Chrome and navigate to `chrome://extensions`.
|
||||
4. **Enable Developer Mode**: Toggle the "Developer mode" switch in the top right corner.
|
||||
5. **Load Unpacked Extension**: Click "Load unpacked" and select the directory containing the extension files.
|
||||
6. **Confirm Installation**: The Mem0 YouTube Assistant Extension should now appear in your Chrome toolbar.
|
||||
|
||||
## Setup
|
||||
|
||||
1. **Configure API Settings**: Click the extension icon and enter your OpenAI API key (required to use the extension)
|
||||
2. **Customize Settings**: Configure additional settings such as model, temperature, and memory settings
|
||||
3. **Navigate to YouTube**: Start using the assistant on any YouTube video
|
||||
4. **Memories**: Enter your Mem0 API key to enable personalized responses, and feed initial memories from settings
|
||||
|
||||
## Example Prompts
|
||||
|
||||
- "Can you summarize the main points of this video?"
|
||||
- "Explain the concept they just mentioned"
|
||||
- "How does this relate to what I already know?"
|
||||
- "What are some practical applications of this topic related to my work?"
|
||||
|
||||
|
||||
## Privacy and Data Security
|
||||
|
||||
Your API keys are stored locally in your browser. Your messages are sent to the Mem0 API for extracting and retrieving memories. Mem0 is committed to ensuring your data's privacy and security.
|
||||
@@ -84,9 +84,65 @@ iconType: "solid"
|
||||
- Include specific examples or cases rather than general definitions
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="How do I configure Mem0 for AWS Lambda?">
|
||||
When deploying Mem0 on AWS Lambda, you'll need to modify the storage directory configuration due to Lambda's file system restrictions. By default, Lambda only allows writing to the `/tmp` directory.
|
||||
|
||||
To configure Mem0 for AWS Lambda, set the `MEM0_DIR` environment variable to point to a writable directory in `/tmp`:
|
||||
|
||||
```bash
|
||||
MEM0_DIR=/tmp/.mem0
|
||||
```
|
||||
|
||||
If you're not using environment variables, you'll need to modify the storage path in your code:
|
||||
|
||||
```python
|
||||
# Change from
|
||||
home_dir = os.path.expanduser("~")
|
||||
mem0_dir = os.environ.get("MEM0_DIR") or os.path.join(home_dir, ".mem0")
|
||||
|
||||
# To
|
||||
mem0_dir = os.environ.get("MEM0_DIR", "/tmp/.mem0")
|
||||
```
|
||||
|
||||
Note that the `/tmp` directory in Lambda has a size limit of 512MB and its contents are not persistent between function invocations.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="How can I use metadata with Mem0?">
|
||||
Metadata is the recommended approach for incorporating additional information with Mem0. You can store any type of structured data as metadata during the `add` method, such as location, timestamp, weather conditions, user state, or application context. This enriches your memories with valuable contextual information that can be used for more precise retrieval and filtering.
|
||||
|
||||
During retrieval, you have two main approaches for using metadata:
|
||||
|
||||
1. **Pre-filtering**: Include metadata parameters in your initial search query to narrow down the memory pool
|
||||
2. **Post-processing**: Retrieve a broader set of memories based on query, then apply metadata filters to refine the results
|
||||
|
||||
Examples of useful metadata you might store:
|
||||
|
||||
- **Contextual information**: Location, time, device type, application state
|
||||
- **User attributes**: Preferences, skill levels, demographic information
|
||||
- **Interaction details**: Conversation topics, sentiment, urgency levels
|
||||
- **Custom tags**: Any domain-specific categorization relevant to your application
|
||||
|
||||
This flexibility allows you to create highly contextually aware AI applications that can adapt to specific user needs and situations. Metadata provides an additional dimension for memory retrieval, enabling more precise and relevant responses.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="How do I disable telemetry in Mem0?">
|
||||
To disable telemetry in Mem0, you can set the `MEM0_TELEMETRY` environment variable to `False`:
|
||||
|
||||
```bash
|
||||
MEM0_TELEMETRY=False
|
||||
```
|
||||
|
||||
You can also disable telemetry programmatically in your code:
|
||||
|
||||
```python
|
||||
import os
|
||||
os.environ["MEM0_TELEMETRY"] = "False"
|
||||
```
|
||||
|
||||
Setting this environment variable will prevent Mem0 from collecting and sending any usage data, ensuring complete privacy for your application.
|
||||
</Accordion>
|
||||
|
||||
</AccordionGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -14,23 +14,77 @@ Mem0's **Advanced Retrieval** feature delivers superior search results by levera
|
||||
client.search(query, keyword_search=True, user_id='alex')
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
# Search for memories about food preferences with keyword search enabled
|
||||
query = "What are my food preferences?"
|
||||
results = client.search(query, keyword_search=True, user_id='alex')
|
||||
|
||||
# Output might include:
|
||||
# - "Vegetarian. Allergic to nuts." (highly relevant)
|
||||
# - "Prefers spicy food and enjoys Thai cuisine" (relevant)
|
||||
# - "Mentioned disliking sea food during restaurant discussion" (keyword match)
|
||||
|
||||
# Without keyword_search=True, only the most relevant memories would be returned:
|
||||
# - "Vegetarian. Allergic to nuts." (highly relevant)
|
||||
# - "Prefers spicy food and enjoys Thai cuisine" (relevant)
|
||||
# The keyword-based match about "sea food" would be excluded
|
||||
```
|
||||
|
||||
2. **Reranking**
|
||||
|
||||
Reranking allows you to reorder the memories returned by the default search based on relevance. This parameter is set to `false` by default. When enabled, it reorders the memories based on the relevance score.
|
||||
Normal retrieval gives you memories sorted in order of their relevancy, but the order may not be perfect. Reranking uses a deep neural network to correct this order, ensuring the most relevant memories appear first. If you are concerned about the order of memories, or want that the best results always comes at top then use reranking. This parameter is set to `false` by default. When enabled, it reorders the memories based on a more accurate relevance score.
|
||||
|
||||
```python
|
||||
client.search(query, rerank=True, user_id='alex')
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```python
|
||||
# Search for travel plans with reranking enabled
|
||||
query = "What are my travel plans?"
|
||||
results = client.search(query, rerank=True, user_id='alex')
|
||||
|
||||
# Without reranking, results might be ordered like:
|
||||
# 1. "Traveled to France last year" (less relevant to current plans)
|
||||
# 2. "Planning a trip to Japan next month" (more relevant to current plans)
|
||||
# 3. "Interested in visiting Tokyo restaurants" (relevant to current plans)
|
||||
|
||||
# With reranking enabled, results would be reordered:
|
||||
# 1. "Planning a trip to Japan next month" (most relevant to current plans)
|
||||
# 2. "Interested in visiting Tokyo restaurants" (highly relevant to current plans)
|
||||
# 3. "Traveled to France last year" (less relevant to current plans)
|
||||
```
|
||||
|
||||
3. **Filtering**
|
||||
|
||||
Filtering enables you to narrow down the search results by applying specific criteria. This parameter is set to `false` by default. Activating it enhances search precision, potentially reducing recall by a small margin.
|
||||
Filtering allows you to narrow down search results by applying specific criterias. This parameter is set to `false` by default. When activated, it significantly enhances search precision by removing irrelevant memories, though it may slightly reduce recall. Filtering is particularly useful when you need highly specific information.
|
||||
|
||||
```python
|
||||
client.search(query, filter_memories=True, user_id='alex')
|
||||
```
|
||||
|
||||
**Note:** You can enable or disable these search modes by passing the respective parameters to the `search` method. There is no required sequence for these modes, and any combination can be used based on your needs.
|
||||
**Example:**
|
||||
```python
|
||||
# Search for dietary restrictions with filtering enabled
|
||||
query = "What are my dietary restrictions?"
|
||||
results = client.search(query, filter_memories=True, user_id='alex')
|
||||
|
||||
# Without filtering, results might include:
|
||||
# - "Vegetarian. Allergic to nuts." (directly relevant)
|
||||
# - "I enjoy cooking Italian food on weekends" (somewhat related to food)
|
||||
# - "Mentioned disliking seafood during restaurant discussion" (food-related)
|
||||
# - "Prefers to eat dinner at 7pm" (tangentially food-related)
|
||||
|
||||
# With filtering enabled, results would be focused:
|
||||
# - "Vegetarian. Allergic to nuts." (directly relevant)
|
||||
# - "Mentioned disliking seafood during restaurant discussion" (relevant restriction)
|
||||
#
|
||||
# The filtering process removes memories that are about food preferences
|
||||
# but not specifically about dietary restrictions
|
||||
```
|
||||
|
||||
<Note> You can enable or disable these search modes by passing the respective parameters to the `search` method. There is no required sequence for these modes, and any combination can be used based on your needs. </Note>
|
||||
|
||||
|
||||
### Latency Numbers
|
||||
|
||||
@@ -0,0 +1,205 @@
|
||||
---
|
||||
title: Contextual Add (ADD v2)
|
||||
icon: "square-plus"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 now supports an contextual add version (v2). To use it, set `version="v2"` during the add call. The default version is v1, which is deprecated now. We recommend migrating to `v2` for new applications.
|
||||
|
||||
## Key Differences Between v1 and v2
|
||||
|
||||
### Version 1 (Legacy)
|
||||
In v1 (default), users needed to pass either the entire conversation history or past k messages with each new message to generate properly contextualized memories. This approach required:
|
||||
|
||||
- Manually tracking and sending previous messages using a sliding window approach
|
||||
- Increased payload sizes as conversations grew longer, requiring careful window size management
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# First interaction
|
||||
messages1 = [
|
||||
{"role": "user", "content": "Hi, I'm Alex and I live in San Francisco."},
|
||||
{"role": "assistant", "content": "Hello Alex! Nice to meet you. San Francisco is a beautiful city."}
|
||||
]
|
||||
client.add(messages1, user_id="alex")
|
||||
|
||||
# Second interaction - must include previous messages for context
|
||||
messages2 = [
|
||||
{"role": "user", "content": "Hi, I'm Alex and I live in San Francisco."},
|
||||
{"role": "assistant", "content": "Hello Alex! Nice to meet you. San Francisco is a beautiful city."},
|
||||
{"role": "user", "content": "I like to eat sushi, and yesterday I went to Sunnyvale to eat sushi with my friends."},
|
||||
{"role": "assistant", "content": "Sushi is really a tasty choice. What did you do this weekend?"}
|
||||
]
|
||||
client.add(messages2, user_id="alex")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// First interaction
|
||||
const messages1 = [
|
||||
{"role": "user", "content": "Hi, I'm Alex and I live in San Francisco."},
|
||||
{"role": "assistant", "content": "Hello Alex! Nice to meet you. San Francisco is a beautiful city."}
|
||||
];
|
||||
client.add(messages1, { user_id: "alex" })
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
|
||||
// Second interaction - must include previous messages for context
|
||||
const messages2 = [
|
||||
{"role": "user", "content": "Hi, I'm Alex and I live in San Francisco."},
|
||||
{"role": "assistant", "content": "Hello Alex! Nice to meet you. San Francisco is a beautiful city."},
|
||||
{"role": "user", "content": "I like to eat sushi, and yesterday I went to Sunnyvale to eat sushi with my friends."},
|
||||
{"role": "assistant", "content": "Sushi is really a tasty choice. What did you do this weekend?"}
|
||||
];
|
||||
client.add(messages2, { user_id: "alex" })
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Version 2 (Recommended)
|
||||
In v2, Mem0 automatically manages conversation context. Users only need to send new messages, and the system will:
|
||||
|
||||
- Automatically retrieve relevant conversation history
|
||||
- Generate properly contextualized memories
|
||||
- Reduce payload sizes and simplify integration
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# First interaction
|
||||
messages1 = [
|
||||
{"role": "user", "content": "Hi, I'm Alex and I live in San Francisco."},
|
||||
{"role": "assistant", "content": "Hello Alex! Nice to meet you. San Francisco is a beautiful city."}
|
||||
]
|
||||
client.add(messages1, user_id="alex", version="v2")
|
||||
|
||||
# Second interaction - only need to send new messages
|
||||
messages2 = [
|
||||
{"role": "user", "content": "I like to eat sushi, and yesterday I went to Sunnyvale to eat sushi with my friends."},
|
||||
{"role": "assistant", "content": "Sushi is really a tasty choice. What did you do this weekend?"}
|
||||
]
|
||||
client.add(messages2, user_id="alex", version="v2")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// First interaction
|
||||
const messages1 = [
|
||||
{"role": "user", "content": "Hi, I'm Alex and I live in San Francisco."},
|
||||
{"role": "assistant", "content": "Hello Alex! Nice to meet you. San Francisco is a beautiful city."}
|
||||
];
|
||||
client.add(messages1, { user_id: "alex", version: "v2" })
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
|
||||
// Second interaction - only need to send new messages
|
||||
const messages2 = [
|
||||
{"role": "user", "content": "I like to eat sushi, and yesterday I went to Sunnyvale to eat sushi with my friends."},
|
||||
{"role": "assistant", "content": "Sushi is really a tasty choice. What did you do this weekend?"}
|
||||
];
|
||||
client.add(messages2, { user_id: "alex", version: "v2" })
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Benefits of Using v2
|
||||
|
||||
1. **Simplified Integration**: No need to track and manage conversation history
|
||||
2. **Reduced Payload Size**: Only send new messages, not the entire conversation
|
||||
3. **Improved Memory Quality**: Automatic context retrieval ensures better memory generation
|
||||
|
||||
## Understanding ID Parameters in v2
|
||||
|
||||
When using contextual add v2, you have different options for how to organize and retrieve memories:
|
||||
|
||||
### Using Only `user_id`
|
||||
|
||||
When you provide only a `user_id`:
|
||||
|
||||
- Memories are associated with this user's long-term memory store
|
||||
- The system will automatically retrieve relevant context from all of the user's previous conversations
|
||||
- These memories persist indefinitely across all of the user's sessions
|
||||
- Ideal for maintaining persistent user information (preferences, personal details, etc.)
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# Adding to long-term user memory
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm allergic to peanuts and shellfish."},
|
||||
{"role": "assistant", "content": "I've noted your allergies to peanuts and shellfish."}
|
||||
]
|
||||
client.add(messages, user_id="alex", version="v2")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// Adding to long-term user memory
|
||||
const messages = [
|
||||
{"role": "user", "content": "I'm allergic to peanuts and shellfish."},
|
||||
{"role": "assistant", "content": "I've noted your allergies to peanuts and shellfish."}
|
||||
];
|
||||
client.add(messages, { user_id: "alex", version: "v2" })
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Using `user_id` with `run_id`
|
||||
|
||||
When you provide both `user_id` and `run_id`:
|
||||
|
||||
- Memories are associated with a specific conversation session or interaction
|
||||
- The system will retrieve context primarily from this specific session
|
||||
- These memories are still tied to the user but are organized by the specific session
|
||||
- Ideal for maintaining context within a specific conversation flow or task
|
||||
- Helps prevent context from different conversations from interfering with each other
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# Adding to a specific conversation session
|
||||
messages = [
|
||||
{"role": "user", "content": "For this trip to Paris, I want to focus on art museums."},
|
||||
{"role": "assistant", "content": "Great! I'll help you plan your Paris trip with a focus on art museums."}
|
||||
]
|
||||
client.add(messages, user_id="alex", run_id="paris-trip-2024", version="v2")
|
||||
|
||||
# Later in the same conversation session
|
||||
messages2 = [
|
||||
{"role": "user", "content": "I'd like to visit the Louvre on Monday."},
|
||||
{"role": "assistant", "content": "The Louvre is a great choice for Monday. Would you like information about opening hours?"}
|
||||
]
|
||||
client.add(messages2, user_id="alex", run_id="paris-trip-2024", version="v2")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// Adding to a specific conversation session
|
||||
const messages = [
|
||||
{"role": "user", "content": "For this trip to Paris, I want to focus on art museums."},
|
||||
{"role": "assistant", "content": "Great! I'll help you plan your Paris trip with a focus on art museums."}
|
||||
];
|
||||
client.add(messages, { user_id: "alex", run_id: "paris-trip-2024", version: "v2" })
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
|
||||
// Later in the same conversation session
|
||||
const messages2 = [
|
||||
{"role": "user", "content": "I'd like to visit the Louvre on Monday."},
|
||||
{"role": "assistant", "content": "The Louvre is a great choice for Monday. Would you like information about opening hours?"}
|
||||
];
|
||||
client.add(messages2, { user_id: "alex", run_id: "paris-trip-2024", version: "v2" })
|
||||
.then(response => console.log(response))
|
||||
.catch(error => console.error(error));
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
Using `run_id` helps you organize memories into logical sessions or tasks, making it easier to maintain context for specific interactions while still associating everything with the user's overall profile.
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -1,25 +1,25 @@
|
||||
---
|
||||
title: Custom Prompts
|
||||
description: 'Enhance your product experience by adding custom prompts tailored to your needs'
|
||||
title: Custom Fact Extraction Prompt
|
||||
description: 'Enhance your product experience by adding custom fact extraction prompt tailored to your needs'
|
||||
icon: "pencil"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Introduction to Custom Prompts
|
||||
## Introduction to Custom Fact Extraction Prompt
|
||||
|
||||
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.
|
||||
Custom fact extraction prompt allow you to tailor the behavior of your Mem0 instance to specific use cases or domains.
|
||||
By defining it, you can control how information is extracted from the user's message.
|
||||
|
||||
To create an effective custom prompt:
|
||||
To create an effective custom fact extraction 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:
|
||||
Example of a custom fact extraction prompt:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
custom_prompt = """
|
||||
custom_fact_extraction_prompt = """
|
||||
Please only extract entities containing customer support information, order details, and user information.
|
||||
Here are some few shot examples:
|
||||
|
||||
@@ -67,7 +67,7 @@ Return the facts and customer information in a json format as shown above.
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Here we initialize the custom prompt in the config:
|
||||
Here we initialize the custom fact extraction prompt in the config:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
@@ -82,7 +82,7 @@ config = {
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
},
|
||||
"custom_prompt": custom_prompt,
|
||||
"custom_fact_extraction_prompt": custom_fact_extraction_prompt,
|
||||
"version": "v1.1"
|
||||
}
|
||||
|
||||
@@ -166,4 +166,4 @@ await memory.add('I like going to hikes', { userId: "user123" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The custom prompt will process both the user and assistant messages to extract relevant information according to the defined format.
|
||||
The custom fact extraction prompt will process both the user and assistant messages to extract relevant information according to the defined format.
|
||||
@@ -0,0 +1,239 @@
|
||||
---
|
||||
title: Custom Update Memory Prompt
|
||||
icon: "pencil"
|
||||
iconType: "solid"
|
||||
---
|
||||
Update memory prompt is a prompt used to determine the action to be performed on the memory.
|
||||
By customizing this prompt, you can control how the memory is updated.
|
||||
|
||||
|
||||
## Introduction
|
||||
Mem0 memory system compares the newly retrieved facts with the existing memory and determines the action to be performed on the memory.
|
||||
The kinds of actions are:
|
||||
- Add
|
||||
- Add the newly retrieved facts to the memory.
|
||||
- Update
|
||||
- Update the existing memory with the newly retrieved facts.
|
||||
- Delete
|
||||
- Delete the existing memory.
|
||||
- No Change
|
||||
- Do not make any changes to the memory.
|
||||
|
||||
### Example
|
||||
Example of a custom update memory prompt:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
UPDATE_MEMORY_PROMPT = """You are a smart memory manager which controls the memory of a system.
|
||||
You can perform four operations: (1) add into the memory, (2) update the memory, (3) delete from the memory, and (4) no change.
|
||||
|
||||
Based on the above four operations, the memory will change.
|
||||
|
||||
Compare newly retrieved facts with the existing memory. For each new fact, decide whether to:
|
||||
- ADD: Add it to the memory as a new element
|
||||
- UPDATE: Update an existing memory element
|
||||
- DELETE: Delete an existing memory element
|
||||
- NONE: Make no change (if the fact is already present or irrelevant)
|
||||
|
||||
There are specific guidelines to select which operation to perform:
|
||||
|
||||
1. **Add**: If the retrieved facts contain new information not present in the memory, then you have to add it by generating a new ID in the id field.
|
||||
- **Example**:
|
||||
- Old Memory:
|
||||
[
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "User is a software engineer"
|
||||
}
|
||||
]
|
||||
- Retrieved facts: ["Name is John"]
|
||||
- New Memory:
|
||||
{
|
||||
"memory" : [
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "User is a software engineer",
|
||||
"event" : "NONE"
|
||||
},
|
||||
{
|
||||
"id" : "1",
|
||||
"text" : "Name is John",
|
||||
"event" : "ADD"
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
|
||||
2. **Update**: If the retrieved facts contain information that is already present in the memory but the information is totally different, then you have to update it.
|
||||
If the retrieved fact contains information that conveys the same thing as the elements present in the memory, then you have to keep the fact which has the most information.
|
||||
Example (a) -- if the memory contains "User likes to play cricket" and the retrieved fact is "Loves to play cricket with friends", then update the memory with the retrieved facts.
|
||||
Example (b) -- if the memory contains "Likes cheese pizza" and the retrieved fact is "Loves cheese pizza", then you do not need to update it because they convey the same information.
|
||||
If the direction is to update the memory, then you have to update it.
|
||||
Please keep in mind while updating you have to keep the same ID.
|
||||
Please note to return the IDs in the output from the input IDs only and do not generate any new ID.
|
||||
- **Example**:
|
||||
- Old Memory:
|
||||
[
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "I really like cheese pizza"
|
||||
},
|
||||
{
|
||||
"id" : "1",
|
||||
"text" : "User is a software engineer"
|
||||
},
|
||||
{
|
||||
"id" : "2",
|
||||
"text" : "User likes to play cricket"
|
||||
}
|
||||
]
|
||||
- Retrieved facts: ["Loves chicken pizza", "Loves to play cricket with friends"]
|
||||
- New Memory:
|
||||
{
|
||||
"memory" : [
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "Loves cheese and chicken pizza",
|
||||
"event" : "UPDATE",
|
||||
"old_memory" : "I really like cheese pizza"
|
||||
},
|
||||
{
|
||||
"id" : "1",
|
||||
"text" : "User is a software engineer",
|
||||
"event" : "NONE"
|
||||
},
|
||||
{
|
||||
"id" : "2",
|
||||
"text" : "Loves to play cricket with friends",
|
||||
"event" : "UPDATE",
|
||||
"old_memory" : "User likes to play cricket"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
3. **Delete**: If the retrieved facts contain information that contradicts the information present in the memory, then you have to delete it. Or if the direction is to delete the memory, then you have to delete it.
|
||||
Please note to return the IDs in the output from the input IDs only and do not generate any new ID.
|
||||
- **Example**:
|
||||
- Old Memory:
|
||||
[
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "Name is John"
|
||||
},
|
||||
{
|
||||
"id" : "1",
|
||||
"text" : "Loves cheese pizza"
|
||||
}
|
||||
]
|
||||
- Retrieved facts: ["Dislikes cheese pizza"]
|
||||
- New Memory:
|
||||
{
|
||||
"memory" : [
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "Name is John",
|
||||
"event" : "NONE"
|
||||
},
|
||||
{
|
||||
"id" : "1",
|
||||
"text" : "Loves cheese pizza",
|
||||
"event" : "DELETE"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
4. **No Change**: If the retrieved facts contain information that is already present in the memory, then you do not need to make any changes.
|
||||
- **Example**:
|
||||
- Old Memory:
|
||||
[
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "Name is John"
|
||||
},
|
||||
{
|
||||
"id" : "1",
|
||||
"text" : "Loves cheese pizza"
|
||||
}
|
||||
]
|
||||
- Retrieved facts: ["Name is John"]
|
||||
- New Memory:
|
||||
{
|
||||
"memory" : [
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "Name is John",
|
||||
"event" : "NONE"
|
||||
},
|
||||
{
|
||||
"id" : "1",
|
||||
"text" : "Loves cheese pizza",
|
||||
"event" : "NONE"
|
||||
}
|
||||
]
|
||||
}
|
||||
"""
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Output format
|
||||
The prompt needs to guide the output to follow the structure as shown below:
|
||||
<CodeGroup>
|
||||
```json Add
|
||||
{
|
||||
"memory": [
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "This information is new",
|
||||
"event" : "ADD"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```json Update
|
||||
{
|
||||
"memory": [
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "This information replaces the old information",
|
||||
"event" : "UPDATE",
|
||||
"old_memory" : "Old information"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```json Delete
|
||||
{
|
||||
"memory": [
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "This information will be deleted",
|
||||
"event" : "DELETE"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
```json No Change
|
||||
{
|
||||
"memory": [
|
||||
{
|
||||
"id" : "0",
|
||||
"text" : "No changes for this information",
|
||||
"event" : "NONE"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
## custom update memory prompt vs custom prompt
|
||||
|
||||
| Feature | `custom_update_memory_prompt` | `custom_prompt` |
|
||||
|---------|-------------------------------|-----------------|
|
||||
| Use case | Determine the action to be performed on the memory | Extract the facts from messages |
|
||||
| Reference | Retrieved facts from messages and old memory | Messages |
|
||||
| Output | Action to be performed on the memory | Extracted facts |
|
||||
@@ -0,0 +1,62 @@
|
||||
---
|
||||
title: Feedback Mechanism
|
||||
icon: "thumbs-up"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0's **Feedback Mechanism** allows you to provide feedback on the memories generated by your application. This feedback is used to improve the accuracy of the memories and the search results.
|
||||
|
||||
## How it works
|
||||
|
||||
The feedback mechanism is a simple API that allows you to provide feedback on the memories generated by your application. The feedback is stored in the database and is used to improve the accuracy of the memories and the search results. Over time, Mem0 continuously learns from this feedback, refining its memory generation and search capabilities for better performance.
|
||||
|
||||
## Give Feedback
|
||||
|
||||
You can give feedback on a memory by calling the `feedback` method on the Mem0 client.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="your_api_key")
|
||||
|
||||
client.feedback(memory_id="your-memory-id", feedback="NEGATIVE", feedback_reason="I don't like this memory because it is not relevant.")
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
import MemoryClient from 'mem0ai';
|
||||
|
||||
const client = new MemoryClient({ apiKey: 'your-api-key'});
|
||||
|
||||
client.feedback({
|
||||
memory_id: "your-memory-id",
|
||||
feedback: "NEGATIVE",
|
||||
feedback_reason: "I don't like this memory because it is not relevant."
|
||||
})
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Feedback Types
|
||||
|
||||
The `feedback` parameter can be one of the following values:
|
||||
|
||||
- `POSITIVE`: The memory is useful.
|
||||
- `NEGATIVE`: The memory is not useful.
|
||||
- `VERY_NEGATIVE`: The memory is not useful at all.
|
||||
|
||||
## Parameters
|
||||
|
||||
The `feedback` method takes the following parameters:
|
||||
|
||||
- `memory_id`: The ID of the memory to give feedback on.
|
||||
- `feedback`: The feedback to give on the memory. (Optional)
|
||||
- `feedback_reason`: The reason for the feedback. (Optional)
|
||||
|
||||
The `feedback_reason` parameter is optional and can be used to provide a reason for the feedback.
|
||||
|
||||
<Note>
|
||||
You can pass `None` or `null` to the `feedback` and `feedback_reason` parameters to remove the feedback for a memory.
|
||||
</Note>
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
---
|
||||
title: Graph Memory
|
||||
icon: "circle-nodes"
|
||||
iconType: "solid"
|
||||
description: "Enable graph-based memory retrieval for more contextually relevant results"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Graph Memory enhances memory pipeline by creating relationships between entities in your data. It builds a network of interconnected information for more contextually relevant search results.
|
||||
|
||||
This feature allows your AI applications to understand connections between entities, providing richer context for responses. It's ideal for applications needing relationship tracking and nuanced information retrieval across related memories.
|
||||
|
||||
## How Graph Memory Works
|
||||
|
||||
The Graph Memory feature analyzes how each entity connects and relates to each other. When enabled:
|
||||
|
||||
1. Mem0 automatically builds a graph representation of entities
|
||||
2. Retrieval considers graph relationships between entities
|
||||
3. Results include entities that may be contextually important even if they're not direct semantic matches
|
||||
|
||||
## Using Graph Memory
|
||||
|
||||
To use Graph Memory, you need to enable it in your API calls by setting the `enable_graph=True` parameter. You'll also need to specify `output_format="v1.1"` to receive the enriched response format.
|
||||
|
||||
### Adding Memories with Graph Memory
|
||||
|
||||
When adding new memories, enable Graph Memory to automatically build relationships with existing memories:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(
|
||||
api_key="your-api-key",
|
||||
org_id="your-org-id",
|
||||
project_id="your-project-id"
|
||||
)
|
||||
|
||||
messages = [
|
||||
{"role": "user", "content": "My name is Joseph"},
|
||||
{"role": "assistant", "content": "Hello Joseph, it's nice to meet you!"},
|
||||
{"role": "user", "content": "I'm from Seattle and I work as a software engineer"}
|
||||
]
|
||||
|
||||
# Enable graph memory when adding
|
||||
client.add(
|
||||
messages,
|
||||
user_id="joseph",
|
||||
version="v1",
|
||||
enable_graph=True,
|
||||
output_format="v1.1"
|
||||
)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
import { MemoryClient } from "mem0";
|
||||
|
||||
const client = new MemoryClient({
|
||||
apiKey: "your-api-key",
|
||||
orgId: "your-org-id",
|
||||
projectId: "your-project-id"
|
||||
});
|
||||
|
||||
const messages = [
|
||||
{ role: "user", content: "My name is Joseph" },
|
||||
{ role: "assistant", content: "Hello Joseph, it's nice to meet you!" },
|
||||
{ role: "user", content: "I'm from Seattle and I work as a software engineer" }
|
||||
];
|
||||
|
||||
// Enable graph memory when adding
|
||||
await client.add({
|
||||
messages,
|
||||
userId: "joseph",
|
||||
version: "v1",
|
||||
enableGraph: true,
|
||||
outputFormat: "v1.1"
|
||||
});
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"memory": "Name is Joseph",
|
||||
"event": "ADD",
|
||||
"id": "4a5a417a-fa10-43b5-8c53-a77c45e80438"
|
||||
},
|
||||
{
|
||||
"memory": "Is from Seattle",
|
||||
"event": "ADD",
|
||||
"id": "8d268d0f-5452-4714-b27d-ae46f676a49d"
|
||||
},
|
||||
{
|
||||
"memory": "Is a software engineer",
|
||||
"event": "ADD",
|
||||
"id": "5f0a184e-ddea-4fe6-9b92-692d6a901df8"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
The graph memory would look like this:
|
||||
|
||||
<Frame>
|
||||
<img src="/images/graph-platform.png" alt="Graph Memory Visualization showing relationships between entities" />
|
||||
</Frame>
|
||||
|
||||
<Caption>Graph Memory creates a network of relationships between entities, enabling more contextual retrieval</Caption>
|
||||
|
||||
|
||||
<Note>
|
||||
Response for the graph memory's `add` operation will not be available directly in the response.
|
||||
As adding graph memories is an asynchronous operation due to heavy processing,
|
||||
you can use the `get_all()` endpoint to retrieve the memory with the graph metadata.
|
||||
</Note>
|
||||
|
||||
|
||||
### Searching with Graph Memory
|
||||
|
||||
When searching memories, Graph Memory helps retrieve entities that are contextually important even if they're not direct semantic matches.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# Search with graph memory enabled
|
||||
results = client.search(
|
||||
"what is my name?",
|
||||
user_id="joseph",
|
||||
enable_graph=True,
|
||||
output_format="v1.1"
|
||||
)
|
||||
|
||||
print(results)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// Search with graph memory enabled
|
||||
const results = await client.search({
|
||||
query: "what is my name?",
|
||||
userId: "joseph",
|
||||
enableGraph: true,
|
||||
outputFormat: "v1.1"
|
||||
});
|
||||
|
||||
console.log(results);
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "4a5a417a-fa10-43b5-8c53-a77c45e80438",
|
||||
"memory": "Name is Joseph",
|
||||
"user_id": "joseph",
|
||||
"metadata": null,
|
||||
"categories": ["personal_details"],
|
||||
"immutable": false,
|
||||
"created_at": "2025-03-19T09:09:00.146390-07:00",
|
||||
"updated_at": "2025-03-19T09:09:00.146404-07:00",
|
||||
"score": 0.3621795393335552
|
||||
},
|
||||
{
|
||||
"id": "8d268d0f-5452-4714-b27d-ae46f676a49d",
|
||||
"memory": "Is from Seattle",
|
||||
"user_id": "joseph",
|
||||
"metadata": null,
|
||||
"categories": ["personal_details"],
|
||||
"immutable": false,
|
||||
"created_at": "2025-03-19T09:09:00.170680-07:00",
|
||||
"updated_at": "2025-03-19T09:09:00.170692-07:00",
|
||||
"score": 0.31212713194651254
|
||||
}
|
||||
],
|
||||
"relations": [
|
||||
{
|
||||
"source": "joseph",
|
||||
"source_type": "person",
|
||||
"relationship": "name",
|
||||
"target": "joseph",
|
||||
"target_type": "person",
|
||||
"score": 0.39
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
### Retrieving All Memories with Graph Memory
|
||||
|
||||
When retrieving all memories, Graph Memory provides additional relationship context:
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# Get all memories with graph context
|
||||
memories = client.get_all(
|
||||
user_id="joseph",
|
||||
enable_graph=True,
|
||||
output_format="v1.1"
|
||||
)
|
||||
|
||||
print(memories)
|
||||
```
|
||||
|
||||
```javascript JavaScript
|
||||
// Get all memories with graph context
|
||||
const memories = await client.getAll({
|
||||
userId: "joseph",
|
||||
enableGraph: true,
|
||||
outputFormat: "v1.1"
|
||||
});
|
||||
|
||||
console.log(memories);
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "5f0a184e-ddea-4fe6-9b92-692d6a901df8",
|
||||
"memory": "Is a software engineer",
|
||||
"user_id": "joseph",
|
||||
"metadata": null,
|
||||
"categories": ["professional_details"],
|
||||
"immutable": false,
|
||||
"created_at": "2025-03-19T09:09:00.194116-07:00",
|
||||
"updated_at": "2025-03-19T09:09:00.194128-07:00",
|
||||
},
|
||||
{
|
||||
"id": "8d268d0f-5452-4714-b27d-ae46f676a49d",
|
||||
"memory": "Is from Seattle",
|
||||
"user_id": "joseph",
|
||||
"metadata": null,
|
||||
"categories": ["personal_details"],
|
||||
"immutable": false,
|
||||
"created_at": "2025-03-19T09:09:00.170680-07:00",
|
||||
"updated_at": "2025-03-19T09:09:00.170692-07:00",
|
||||
},
|
||||
{
|
||||
"id": "4a5a417a-fa10-43b5-8c53-a77c45e80438",
|
||||
"memory": "Name is Joseph",
|
||||
"user_id": "joseph",
|
||||
"metadata": null,
|
||||
"categories": ["personal_details"],
|
||||
"immutable": false,
|
||||
"created_at": "2025-03-19T09:09:00.146390-07:00",
|
||||
"updated_at": "2025-03-19T09:09:00.146404-07:00",
|
||||
}
|
||||
],
|
||||
"relations": [
|
||||
{
|
||||
"source": "joseph",
|
||||
"source_type": "person",
|
||||
"relationship": "name",
|
||||
"target": "joseph",
|
||||
"target_type": "person"
|
||||
},
|
||||
{
|
||||
"source": "joseph",
|
||||
"source_type": "person",
|
||||
"relationship": "city",
|
||||
"target": "seattle",
|
||||
"target_type": "city"
|
||||
},
|
||||
{
|
||||
"source": "joseph",
|
||||
"source_type": "person",
|
||||
"relationship": "job",
|
||||
"target": "software engineer",
|
||||
"target_type": "job"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## Best Practices
|
||||
|
||||
- Enable Graph Memory for applications where understanding context and relationships between memories is important
|
||||
- Graph Memory works best with a rich history of related conversations
|
||||
- Consider Graph Memory for long-running assistants that need to track evolving information
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
Graph Memory requires additional processing and may increase response times slightly for very large memory stores. However, for most use cases, the improved retrieval quality outweighs the minimal performance impact.
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
|
||||
@@ -71,13 +71,39 @@ Here's an example schema for extracting professional profile information:
|
||||
|
||||
### Submit Export Job
|
||||
|
||||
You can optionally provide additional instructions to guide how memories are processed and structured during export using the `export_instructions` parameter.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
# Basic export request
|
||||
response = client.create_memory_export(
|
||||
schema=json_schema,
|
||||
user_id="user123"
|
||||
user_id="alice"
|
||||
)
|
||||
|
||||
# Export with custom instructions
|
||||
export_instructions = """
|
||||
1. Create a comprehensive profile with detailed information in each category
|
||||
2. Only mark fields as "None" when absolutely no relevant information exists
|
||||
3. Base all information directly on the user's memories
|
||||
4. When contradictions exist, prioritize the most recent information
|
||||
5. Clearly distinguish between factual statements and inferences
|
||||
"""
|
||||
|
||||
# For create operation, using only user_id filter as requested
|
||||
filters = {
|
||||
"AND": [
|
||||
{"user_id": "alex"}
|
||||
]
|
||||
}
|
||||
|
||||
response = client.create_memory_export(
|
||||
schema=json_schema,
|
||||
filters=filters,
|
||||
export_instructions=export_instructions # Optional
|
||||
)
|
||||
|
||||
print(response)
|
||||
```
|
||||
|
||||
@@ -87,7 +113,8 @@ curl -X POST "https://api.mem0.ai/v1/memories/export/" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"schema": {json_schema},
|
||||
"user_id": "user123"
|
||||
"user_id": "alice",
|
||||
"export_instructions": "1. Create a comprehensive profile with detailed information\n2. Only mark fields as \"None\" when absolutely no relevant information exists"
|
||||
}'
|
||||
```
|
||||
|
||||
@@ -107,12 +134,20 @@ Once the export job is complete, you can retrieve the structured data:
|
||||
<CodeGroup>
|
||||
|
||||
```python Python
|
||||
response = client.get_memory_export(user_id="user123")
|
||||
# Corrected date range (assuming you meant July 10 to July 20)
|
||||
filters = {
|
||||
"AND": [
|
||||
{"created_at": {"gte": "2024-07-10", "lte": "2024-07-20"}},
|
||||
{"user_id": "alex"}
|
||||
]
|
||||
}
|
||||
|
||||
response = client.get_memory_export(filters=filters)
|
||||
print(response)
|
||||
```
|
||||
|
||||
```bash cURL
|
||||
curl -X GET "https://api.mem0.ai/v1/memories/export/?user_id=user123" \
|
||||
curl -X GET "https://api.mem0.ai/v1/memories/export/?user_id=alice" \
|
||||
-H "Authorization: Token your-api-key"
|
||||
```
|
||||
|
||||
@@ -137,6 +172,7 @@ You can apply various filters to customize which memories are included in the ex
|
||||
- `agent_id`: Filter memories by specific agent
|
||||
- `run_id`: Filter memories by specific run
|
||||
- `session_id`: Filter memories by specific session
|
||||
- `created_at`: Filter memories by date
|
||||
|
||||
<Note>
|
||||
The export process may take some time to complete, especially when dealing with a large number of memories or complex schemas.
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
---
|
||||
title: Multimodal Support
|
||||
description: Integrate images into your interactions with Mem0
|
||||
description: Integrate images and documents into your interactions with Mem0
|
||||
icon: "image"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
Mem0 extends its capabilities beyond text by supporting multimodal data, including images. With this feature, users can seamlessly integrate images into their interactions—allowing Mem0 to extract relevant information from visual content and enrich the memory system.
|
||||
Mem0 extends its capabilities beyond text by supporting multimodal data, including images and documents. With this feature, users can seamlessly integrate visual and document content into their interactions—allowing Mem0 to extract relevant information from various media types and enrich the memory system.
|
||||
|
||||
## How It Works
|
||||
|
||||
When a user submits an image, Mem0 processes it to extract textual information and other pertinent details. These details are then added to the user's memory, enhancing the system's ability to understand and recall visual inputs.
|
||||
When a user submits an image or document, Mem0 processes it to extract textual information and other pertinent details. These details are then added to the user's memory, enhancing the system's ability to understand and recall multimodal inputs.
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import MemoryClient
|
||||
|
||||
@@ -44,6 +44,34 @@ messages = [
|
||||
client.add(messages, user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import MemoryClient from "mem0ai";
|
||||
|
||||
const client = new MemoryClient();
|
||||
|
||||
const messages = [
|
||||
{
|
||||
role: "user",
|
||||
content: "Hi, my name is Alice."
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
content: "Nice to meet you, Alice! What do you like to eat?"
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: {
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
await client.add(messages, { user_id: "alice" })
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
@@ -62,11 +90,18 @@ client.add(messages, user_id="alice")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Image Integration Methods
|
||||
## Supported Media Types
|
||||
|
||||
Mem0 supports incorporating images into user interactions using two primary methods: by providing an image URL or by using a Base64-encoded image. The examples below demonstrate both approaches.
|
||||
Mem0 currently supports the following media types:
|
||||
|
||||
## 1. Using an Image URL (Recommended)
|
||||
1. **Images** - JPG, PNG, and other common image formats
|
||||
2. **Documents** - MDX, TXT, and PDF files
|
||||
|
||||
## Integration Methods
|
||||
|
||||
### 1. Images
|
||||
|
||||
#### Using an Image URL (Recommended)
|
||||
|
||||
You can include an image by providing its direct URL. This method is simple and efficient for online images.
|
||||
|
||||
@@ -87,10 +122,12 @@ image_message = {
|
||||
client.add([image_message], user_id="alice")
|
||||
```
|
||||
|
||||
## 2. Using Base64 Image Encoding for Local Files
|
||||
#### Using Base64 Image Encoding for Local Files
|
||||
|
||||
For local images—or when embedding the image directly is preferable—you can use a Base64-encoded string.
|
||||
```python
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import base64
|
||||
|
||||
# Path to the image file
|
||||
@@ -113,7 +150,155 @@ image_message = {
|
||||
client.add([image_message], user_id="alice")
|
||||
```
|
||||
|
||||
Using these methods, you can seamlessly incorporate images into your interactions, further enhancing Mem0's multimodal capabilities.
|
||||
```typescript TypeScript
|
||||
import MemoryClient from "mem0ai";
|
||||
import fs from 'fs';
|
||||
|
||||
const imagePath = 'path/to/your/image.jpg';
|
||||
|
||||
const base64Image = fs.readFileSync(imagePath, { encoding: 'base64' });
|
||||
|
||||
const imageMessage = {
|
||||
role: "user",
|
||||
content: {
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: `data:image/jpeg;base64,${base64Image}`
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await client.add([imageMessage], { user_id: "alice" })
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### 2. Text Documents (MDX/TXT)
|
||||
|
||||
Mem0 supports both online and local text documents in MDX or TXT format.
|
||||
|
||||
#### Using a Document URL
|
||||
|
||||
```python
|
||||
# Define the document URL
|
||||
document_url = "https://www.w3.org/TR/2003/REC-PNG-20031110/iso_8859-1.txt"
|
||||
|
||||
# Create the message dictionary with the document URL
|
||||
document_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "mdx_url",
|
||||
"mdx_url": {
|
||||
"url": document_url
|
||||
}
|
||||
}
|
||||
}
|
||||
client.add([document_message], user_id="alice")
|
||||
```
|
||||
|
||||
#### Using Base64 Encoding for Local Documents
|
||||
|
||||
```python
|
||||
import base64
|
||||
|
||||
# Path to the document file
|
||||
document_path = "path/to/your/document.txt"
|
||||
|
||||
# Function to convert file to Base64
|
||||
def file_to_base64(file_path):
|
||||
with open(file_path, "rb") as file:
|
||||
return base64.b64encode(file.read()).decode('utf-8')
|
||||
|
||||
# Encode the document in Base64
|
||||
base64_document = file_to_base64(document_path)
|
||||
|
||||
# Create the message dictionary with the Base64-encoded document
|
||||
document_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "mdx_url",
|
||||
"mdx_url": {
|
||||
"url": base64_document
|
||||
}
|
||||
}
|
||||
}
|
||||
client.add([document_message], user_id="alice")
|
||||
```
|
||||
|
||||
### 3. PDF Documents
|
||||
|
||||
Mem0 supports PDF documents via URL.
|
||||
|
||||
```python
|
||||
# Define the PDF URL
|
||||
pdf_url = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
|
||||
|
||||
# Create the message dictionary with the PDF URL
|
||||
pdf_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "pdf_url",
|
||||
"pdf_url": {
|
||||
"url": pdf_url
|
||||
}
|
||||
}
|
||||
}
|
||||
client.add([pdf_message], user_id="alice")
|
||||
```
|
||||
|
||||
## Complete Example with Multiple File Types
|
||||
|
||||
Here's a comprehensive example showing how to work with different file types:
|
||||
|
||||
```python
|
||||
import base64
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient()
|
||||
|
||||
def file_to_base64(file_path):
|
||||
with open(file_path, "rb") as file:
|
||||
return base64.b64encode(file.read()).decode('utf-8')
|
||||
|
||||
# Example 1: Using an image URL
|
||||
image_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": "https://example.com/sample-image.jpg"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Example 2: Using a text document URL
|
||||
text_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "mdx_url",
|
||||
"mdx_url": {
|
||||
"url": "https://www.w3.org/TR/2003/REC-PNG-20031110/iso_8859-1.txt"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Example 3: Using a PDF URL
|
||||
pdf_message = {
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "pdf_url",
|
||||
"pdf_url": {
|
||||
"url": "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Add each message to the memory system
|
||||
client.add([image_message], user_id="alice")
|
||||
client.add([text_message], user_id="alice")
|
||||
client.add([pdf_message], user_id="alice")
|
||||
```
|
||||
|
||||
Using these methods, you can seamlessly incorporate various media types into your interactions, further enhancing Mem0's multimodal capabilities.
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
|
||||
@@ -12,6 +12,9 @@ Learn about the key features and capabilities that make Mem0 a powerful platform
|
||||
<Card title="Advanced Retrieval" icon="magnifying-glass" href="/features/advanced-retrieval">
|
||||
Superior search results using state-of-the-art algorithms, including keyword search, reranking, and filtering capabilities.
|
||||
</Card>
|
||||
<Card title="Contextual Add" icon="square-plus" href="/features/contextual-add">
|
||||
Only send your latest conversation history - we automatically retrieve the rest and generate properly contextualized memories.
|
||||
</Card>
|
||||
<Card title="Multimodal Support" icon="photo-film" href="/features/multimodal-support">
|
||||
Process and analyze various types of content including images.
|
||||
</Card>
|
||||
@@ -33,6 +36,9 @@ Learn about the key features and capabilities that make Mem0 a powerful platform
|
||||
<Card title="Memory Export" icon="file-export" href="/features/memory-export">
|
||||
Export memories in structured formats using customizable Pydantic schemas.
|
||||
</Card>
|
||||
<Card title="Graph Memory" icon="graph" href="/features/graph-memory">
|
||||
Add memories in the form of nodes and edges in a graph database and search for related memories.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## Getting Help
|
||||
|
||||
@@ -93,7 +93,7 @@ messages = [
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
client.add(messages, user_id="alice", includes=includes)
|
||||
client.add(messages, user_id="alice", excludes=excludes)
|
||||
```
|
||||
|
||||
```json Stored Memories
|
||||
|
||||
|
After Width: | Height: | Size: 72 KiB |
@@ -198,4 +198,126 @@ Here are the available integrations for Mem0:
|
||||
>
|
||||
Build AI applications with persistent memory using Dify and Mem0.
|
||||
</Card>
|
||||
<Card
|
||||
title="MCP Server"
|
||||
icon={
|
||||
<svg
|
||||
viewBox="0 0 180 180"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path
|
||||
d="M45 45 L135 45 M45 90 L135 90 M45 135 L135 135"
|
||||
stroke="currentColor"
|
||||
strokeWidth="12"
|
||||
strokeLinecap="round"
|
||||
fill="none"
|
||||
/>
|
||||
</svg>
|
||||
}
|
||||
href="/integrations/mcp-server"
|
||||
>
|
||||
Integrate Mem0 as an MCP Server in Cursor.
|
||||
</Card>
|
||||
<Card
|
||||
title="Livekit"
|
||||
icon={
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<text
|
||||
x="12"
|
||||
y="16"
|
||||
fontFamily="Arial"
|
||||
fontSize="12"
|
||||
textAnchor="middle"
|
||||
fill="currentColor"
|
||||
fontWeight="bold"
|
||||
>
|
||||
LK
|
||||
</text>
|
||||
</svg>
|
||||
}
|
||||
href="/integrations/livekit"
|
||||
>
|
||||
Integrate Mem0 with Livekit for voice agents.
|
||||
</Card>
|
||||
<Card
|
||||
title="ElevenLabs"
|
||||
icon={
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<rect width="24" height="24" fill="white"/>
|
||||
<rect x="8" y="4" width="2" height="16" fill="black"/>
|
||||
<rect x="14" y="4" width="2" height="16" fill="black"/>
|
||||
</svg>
|
||||
}
|
||||
href="/integrations/elevenlabs"
|
||||
>
|
||||
Build voice agents with memory using ElevenLabs Conversational AI.
|
||||
</Card>
|
||||
<Card
|
||||
title="Pipecat"
|
||||
icon={
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
>
|
||||
<path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8z" fill="currentColor"/>
|
||||
<circle cx="8.5" cy="9" r="1.5" fill="currentColor"/>
|
||||
<circle cx="15.5" cy="9" r="1.5" fill="currentColor"/>
|
||||
<path d="M12 16c1.66 0 3-1.34 3-3H9c0 1.66 1.34 3 3 3z" fill="currentColor"/>
|
||||
<path d="M17.5 12c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5z" fill="currentColor"/>
|
||||
<path d="M6.5 12c-.83 0-1.5-.67-1.5-1.5S5.67 9 6.5 9s1.5.67 1.5 1.5S7.33 12 6.5 12z" fill="currentColor"/>
|
||||
</svg>
|
||||
}
|
||||
href="/integrations/pipecat"
|
||||
>
|
||||
Build conversational AI agents with memory using Pipecat.
|
||||
</Card>
|
||||
<Card
|
||||
title="Agno"
|
||||
icon={
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path d="M8 4h8v12h8" stroke="currentColor" strokeWidth="2" fill="none" transform="rotate(15, 12, 12)"/>
|
||||
</svg>
|
||||
}
|
||||
href="/integrations/agno"
|
||||
>
|
||||
Build autonomous agents with memory using Agno framework.
|
||||
</Card>
|
||||
<Card
|
||||
title="Keywords AI"
|
||||
icon={
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.07513 1.1863C9.21663 1.07722 9.39144 1.01009 9.56624 1.01009C9.83261 1.01009 10.0823 1.12756 10.2405 1.33734L15.0101 7.4964V12.4136L16.4335 13.8401C16.7582 14.1673 16.7582 14.7043 16.4335 15.0316C16.1089 15.3588 15.5762 15.3588 15.2515 15.0316L13.3453 13.1016V8.07538L8.92529 2.36944V2.36105C8.64228 2.00024 8.70887 1.4716 9.07513 1.1863ZM18.976 14.4133C18.8344 14.3778 18.7003 14.3042 18.5894 14.1925L16.9163 12.5059C16.7249 12.3129 16.6416 12.0528 16.6749 11.8094V6.88385H16.6499L11.8553 0.691225C11.7282 0.529117 11.6716 0.333133 11.6803 0.140562C11.134 0.0481292 10.5726 0 10 0C4.47715 0 0 4.47715 0 10C0 15.5228 4.47715 20 10 20C13.9387 20 17.3456 17.7229 18.976 14.4133Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
}
|
||||
href="/integrations/keywords"
|
||||
>
|
||||
Build AI applications with persistent memory and comprehensive LLM observability.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,173 @@
|
||||
---
|
||||
title: Agno
|
||||
---
|
||||
|
||||
Integrate [**Mem0**](https://github.com/mem0ai/mem0) with [Agno](https://github.com/agno-ai/agno), a Python framework for building autonomous agents. This integration enables Agno agents to access persistent memory across conversations, enhancing context retention and personalization.
|
||||
|
||||
## Overview
|
||||
|
||||
1. 🧠 Store and retrieve memories from Mem0 within Agno agents
|
||||
2. 🖼️ Support for multimodal interactions (text and images)
|
||||
3. 🔍 Semantic search for relevant past conversations
|
||||
4. 🌐 Personalized responses based on user history
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before setting up Mem0 with Agno, ensure you have:
|
||||
|
||||
1. Installed the required packages:
|
||||
```bash
|
||||
pip install agno-ai mem0ai
|
||||
```
|
||||
|
||||
2. Valid API keys:
|
||||
- [Mem0 API Key](https://app.mem0.ai/dashboard/api-keys)
|
||||
- OpenAI API Key (for the agent model)
|
||||
|
||||
## Integration Example
|
||||
|
||||
The following example demonstrates how to create an Agno agent with Mem0 memory integration, including support for image processing:
|
||||
|
||||
```python
|
||||
import base64
|
||||
from pathlib import Path
|
||||
from typing import Optional
|
||||
|
||||
from agno.agent import Agent
|
||||
from agno.media import Image
|
||||
from agno.models.openai import OpenAIChat
|
||||
from mem0 import MemoryClient
|
||||
|
||||
|
||||
# Initialize the Mem0 client
|
||||
client = MemoryClient()
|
||||
|
||||
# Define the agent
|
||||
agent = Agent(
|
||||
name="Personal Agent",
|
||||
model=OpenAIChat(id="gpt-4"),
|
||||
description="You are a helpful personal agent that helps me with day to day activities."
|
||||
"You can process both text and images.",
|
||||
markdown=True
|
||||
)
|
||||
|
||||
|
||||
def chat_user(
|
||||
user_input: Optional[str] = None,
|
||||
user_id: str = "user_123",
|
||||
image_path: Optional[str] = None
|
||||
) -> str:
|
||||
"""
|
||||
Handle user input with memory integration, supporting both text and images.
|
||||
|
||||
Args:
|
||||
user_input: The user's text input
|
||||
user_id: Unique identifier for the user
|
||||
image_path: Path to an image file if provided
|
||||
|
||||
Returns:
|
||||
The agent's response as a string
|
||||
"""
|
||||
if image_path:
|
||||
# Convert image to base64
|
||||
with open(image_path, "rb") as image_file:
|
||||
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
|
||||
|
||||
# Create message objects for text and image
|
||||
messages = []
|
||||
|
||||
if user_input:
|
||||
messages.append({
|
||||
"role": "user",
|
||||
"content": user_input
|
||||
})
|
||||
|
||||
messages.append({
|
||||
"role": "user",
|
||||
"content": {
|
||||
"type": "image_url",
|
||||
"image_url": {
|
||||
"url": f"data:image/jpeg;base64,{base64_image}"
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
# Store messages in memory
|
||||
client.add(messages, user_id=user_id)
|
||||
print("✅ Image and text stored in memory.")
|
||||
|
||||
if user_input:
|
||||
# Search for relevant memories
|
||||
memories = client.search(user_input, user_id=user_id)
|
||||
memory_context = "\n".join(f"- {m['memory']}" for m in memories)
|
||||
|
||||
# Construct the prompt
|
||||
prompt = f"""
|
||||
You are a helpful personal assistant who helps users with their day-to-day activities and keeps track of everything.
|
||||
|
||||
Your task is to:
|
||||
1. Analyze the given image (if present) and extract meaningful details to answer the user's question.
|
||||
2. Use your past memory of the user to personalize your answer.
|
||||
3. Combine the image content and memory to generate a helpful, context-aware response.
|
||||
|
||||
Here is what I remember about the user:
|
||||
{memory_context}
|
||||
|
||||
User question:
|
||||
{user_input}
|
||||
"""
|
||||
# Get response from agent
|
||||
if image_path:
|
||||
response = agent.run(prompt, images=[Image(filepath=Path(image_path))])
|
||||
else:
|
||||
response = agent.run(prompt)
|
||||
|
||||
# Store the interaction in memory
|
||||
client.add(f"User: {user_input}\nAssistant: {response.content}", user_id=user_id)
|
||||
return response.content
|
||||
|
||||
return "No user input or image provided."
|
||||
|
||||
|
||||
# Example Usage
|
||||
if __name__ == "__main__":
|
||||
response = chat_user(
|
||||
"This is the picture of what I brought with me in the trip to Bahamas",
|
||||
image_path="travel_items.jpeg",
|
||||
user_id="user_123"
|
||||
)
|
||||
print(response)
|
||||
```
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. Multimodal Memory Storage
|
||||
|
||||
The integration supports storing both text and image data:
|
||||
|
||||
- **Text Storage**: Conversation history is saved in a structured format
|
||||
- **Image Analysis**: Agents can analyze images and store visual information
|
||||
- **Combined Context**: Memory retrieval combines both text and visual data
|
||||
|
||||
### 2. Personalized Agent Responses
|
||||
|
||||
Improve your agent's context awareness:
|
||||
|
||||
- **Memory Retrieval**: Semantic search finds relevant past interactions
|
||||
- **User Preferences**: Personalize responses based on stored user information
|
||||
- **Continuity**: Maintain conversation threads across multiple sessions
|
||||
|
||||
### 3. Flexible Configuration
|
||||
|
||||
Customize the integration to your needs:
|
||||
|
||||
- **User Identification**: Organize memories by user ID
|
||||
- **Memory Search**: Configure search relevance and result count
|
||||
- **Memory Formatting**: Support for various OpenAI message formats
|
||||
|
||||
## Help & Resources
|
||||
|
||||
- [Agno Documentation](https://docs.agno.com/introduction)
|
||||
- [Mem0 Platform](https://app.mem0.ai/)
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,454 @@
|
||||
---
|
||||
title: ElevenLabs
|
||||
---
|
||||
|
||||
Create voice-based conversational AI agents with memory capabilities by integrating ElevenLabs and Mem0. This integration enables persistent, context-aware voice interactions that remember past conversations.
|
||||
|
||||
## Overview
|
||||
|
||||
In this guide, we'll build a voice agent that:
|
||||
1. Uses ElevenLabs Conversational AI for voice interaction
|
||||
2. Leverages Mem0 to store and retrieve memories from past conversations
|
||||
3. Provides personalized responses based on user history
|
||||
|
||||
## Setup and Configuration
|
||||
|
||||
Install necessary libraries:
|
||||
|
||||
```bash
|
||||
pip install elevenlabs mem0 python-dotenv
|
||||
```
|
||||
|
||||
Configure your environment variables:
|
||||
|
||||
<Note>You'll need both an ElevenLabs API key and a Mem0 API key to use this integration.</Note>
|
||||
|
||||
```bash
|
||||
# Create a .env file with these variables
|
||||
AGENT_ID=your-agent-id
|
||||
USER_ID=unique-user-identifier
|
||||
ELEVENLABS_API_KEY=your-elevenlabs-api-key
|
||||
MEM0_API_KEY=your-mem0-api-key
|
||||
```
|
||||
|
||||
## Integration Code Breakdown
|
||||
|
||||
Let's break down the implementation into manageable parts:
|
||||
|
||||
### 1. Imports and Environment Setup
|
||||
|
||||
First, we import required libraries and set up the environment:
|
||||
|
||||
```python
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
from mem0 import AsyncMemoryClient
|
||||
|
||||
from elevenlabs.client import ElevenLabs
|
||||
from elevenlabs.conversational_ai.conversation import Conversation
|
||||
from elevenlabs.conversational_ai.default_audio_interface import DefaultAudioInterface
|
||||
from elevenlabs.conversational_ai.conversation import ClientTools
|
||||
```
|
||||
|
||||
These imports provide:
|
||||
- Standard Python libraries for system operations and signal handling
|
||||
- `AsyncMemoryClient` from Mem0 for memory operations
|
||||
- ElevenLabs components for voice interaction
|
||||
|
||||
### 2. Environment Variables and Validation
|
||||
|
||||
Next, we validate the required environment variables:
|
||||
|
||||
```python
|
||||
def main():
|
||||
# Required environment variables
|
||||
AGENT_ID = os.environ.get('AGENT_ID')
|
||||
USER_ID = os.environ.get('USER_ID')
|
||||
API_KEY = os.environ.get('ELEVENLABS_API_KEY')
|
||||
MEM0_API_KEY = os.environ.get('MEM0_API_KEY')
|
||||
|
||||
# Validate required environment variables
|
||||
if not AGENT_ID:
|
||||
sys.stderr.write("AGENT_ID environment variable must be set\n")
|
||||
sys.exit(1)
|
||||
|
||||
if not USER_ID:
|
||||
sys.stderr.write("USER_ID environment variable must be set\n")
|
||||
sys.exit(1)
|
||||
|
||||
if not API_KEY:
|
||||
sys.stderr.write("ELEVENLABS_API_KEY not set, assuming the agent is public\n")
|
||||
|
||||
if not MEM0_API_KEY:
|
||||
sys.stderr.write("MEM0_API_KEY environment variable must be set\n")
|
||||
sys.exit(1)
|
||||
|
||||
# Set up Mem0 API key in the environment
|
||||
os.environ['MEM0_API_KEY'] = MEM0_API_KEY
|
||||
```
|
||||
|
||||
This section:
|
||||
- Retrieves required environment variables
|
||||
- Performs validation to ensure required variables are present
|
||||
- Exits the application with an error message if required variables are missing
|
||||
- Sets the Mem0 API key in the environment for the Mem0 client to use
|
||||
|
||||
### 3. Client Initialization
|
||||
|
||||
Initialize both the ElevenLabs and Mem0 clients:
|
||||
|
||||
```python
|
||||
# Initialize ElevenLabs client
|
||||
client = ElevenLabs(api_key=API_KEY)
|
||||
|
||||
# Initialize memory client and tools
|
||||
client_tools = ClientTools()
|
||||
mem0_client = AsyncMemoryClient()
|
||||
```
|
||||
|
||||
Here we:
|
||||
- Create an ElevenLabs client with the API key
|
||||
- Initialize a ClientTools object for registering function tools
|
||||
- Create an AsyncMemoryClient instance for Mem0 interactions
|
||||
|
||||
### 4. Memory Function Definitions
|
||||
|
||||
Define the two key memory functions that will be registered as tools:
|
||||
|
||||
```python
|
||||
# Define memory-related functions for the agent
|
||||
async def add_memories(parameters):
|
||||
"""Add a message to the memory store"""
|
||||
message = parameters.get("message")
|
||||
await mem0_client.add(
|
||||
messages=message,
|
||||
user_id=USER_ID,
|
||||
output_format="v1.1",
|
||||
version="v2"
|
||||
)
|
||||
return "Memory added successfully"
|
||||
|
||||
async def retrieve_memories(parameters):
|
||||
"""Retrieve relevant memories based on the input message"""
|
||||
message = parameters.get("message")
|
||||
|
||||
# Set up filters to retrieve memories for this specific user
|
||||
filters = {
|
||||
"AND": [
|
||||
{
|
||||
"user_id": USER_ID
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Search for relevant memories using the message as a query
|
||||
results = await mem0_client.search(
|
||||
query=message,
|
||||
version="v2",
|
||||
filters=filters
|
||||
)
|
||||
|
||||
# Extract and join the memory texts
|
||||
memories = ' '.join([result["memory"] for result in results])
|
||||
print("[ Memories ]", memories)
|
||||
|
||||
if memories:
|
||||
return memories
|
||||
return "No memories found"
|
||||
```
|
||||
|
||||
These functions:
|
||||
|
||||
#### `add_memories`:
|
||||
- Takes a message parameter containing information to remember
|
||||
- Stores the message in Mem0 using the `add` method
|
||||
- Associates the memory with the specific USER_ID
|
||||
- Returns a success message to the agent
|
||||
|
||||
#### `retrieve_memories`:
|
||||
- Takes a message parameter as the search query
|
||||
- Sets up filters to only retrieve memories for the current user
|
||||
- Uses semantic search to find relevant memories
|
||||
- Joins all retrieved memories into a single text
|
||||
- Prints retrieved memories to the console for debugging
|
||||
- Returns the memories or a "No memories found" message if none are found
|
||||
|
||||
### 5. Registering Memory Functions as Tools
|
||||
|
||||
Register the memory functions with the ElevenLabs ClientTools system:
|
||||
|
||||
```python
|
||||
# Register the memory functions as tools for the agent
|
||||
client_tools.register("addMemories", add_memories, is_async=True)
|
||||
client_tools.register("retrieveMemories", retrieve_memories, is_async=True)
|
||||
```
|
||||
|
||||
This allows the ElevenLabs agent to:
|
||||
- Access these functions through function calling
|
||||
- Wait for asynchronous results (is_async=True)
|
||||
- Call these functions by name ("addMemories" and "retrieveMemories")
|
||||
|
||||
### 6. Conversation Setup
|
||||
|
||||
Configure the conversation with ElevenLabs:
|
||||
|
||||
```python
|
||||
# Initialize the conversation
|
||||
conversation = Conversation(
|
||||
client,
|
||||
AGENT_ID,
|
||||
# Assume auth is required when API_KEY is set
|
||||
requires_auth=bool(API_KEY),
|
||||
audio_interface=DefaultAudioInterface(),
|
||||
client_tools=client_tools,
|
||||
callback_agent_response=lambda response: print(f"Agent: {response}"),
|
||||
callback_agent_response_correction=lambda original, corrected: print(f"Agent: {original} -> {corrected}"),
|
||||
callback_user_transcript=lambda transcript: print(f"User: {transcript}"),
|
||||
# callback_latency_measurement=lambda latency: print(f"Latency: {latency}ms"),
|
||||
)
|
||||
```
|
||||
|
||||
This sets up the conversation with:
|
||||
- The ElevenLabs client and Agent ID
|
||||
- Authentication requirements based on API key presence
|
||||
- DefaultAudioInterface for handling audio I/O
|
||||
- The client_tools with our memory functions
|
||||
- Callback functions for:
|
||||
- Displaying agent responses
|
||||
- Showing corrected responses (when the agent self-corrects)
|
||||
- Displaying user transcripts for debugging
|
||||
- (Commented out) Latency measurements
|
||||
|
||||
### 7. Conversation Management
|
||||
|
||||
Start and manage the conversation:
|
||||
|
||||
```python
|
||||
# Start the conversation
|
||||
print(f"Starting conversation with user_id: {USER_ID}")
|
||||
conversation.start_session()
|
||||
|
||||
# Handle Ctrl+C to gracefully end the session
|
||||
signal.signal(signal.SIGINT, lambda sig, frame: conversation.end_session())
|
||||
|
||||
# Wait for the conversation to end and get the conversation ID
|
||||
conversation_id = conversation.wait_for_session_end()
|
||||
print(f"Conversation ID: {conversation_id}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
```
|
||||
|
||||
This final section:
|
||||
- Prints a message indicating the conversation has started
|
||||
- Starts the conversation session
|
||||
- Sets up a signal handler to gracefully end the session on Ctrl+C
|
||||
- Waits for the session to end and gets the conversation ID
|
||||
- Prints the conversation ID for reference
|
||||
|
||||
## Memory Tools Overview
|
||||
|
||||
This integration provides two key memory functions to your conversational AI agent:
|
||||
|
||||
### 1. Adding Memories (`addMemories`)
|
||||
|
||||
The `addMemories` tool allows your agent to store important information during a conversation, including:
|
||||
- User preferences
|
||||
- Important facts shared by the user
|
||||
- Decisions or commitments made during the conversation
|
||||
- Action items to follow up on
|
||||
|
||||
When the agent identifies information worth remembering, it calls this function to store it in the Mem0 database with the appropriate user ID.
|
||||
|
||||
#### How it works:
|
||||
1. The agent identifies information that should be remembered
|
||||
2. It formats the information as a message string
|
||||
3. It calls the `addMemories` function with this message
|
||||
4. The function stores the memory in Mem0 linked to the user's ID
|
||||
5. Later conversations can retrieve this memory
|
||||
|
||||
#### Example usage in agent prompt:
|
||||
```
|
||||
When the user shares important information like preferences or personal details,
|
||||
use the addMemories function to store this information for future reference.
|
||||
```
|
||||
|
||||
### 2. Retrieving Memories (`retrieveMemories`)
|
||||
|
||||
The `retrieveMemories` tool allows your agent to search for and retrieve relevant memories from previous conversations. The agent can:
|
||||
- Search for context related to the current topic
|
||||
- Recall user preferences
|
||||
- Remember previous interactions on similar topics
|
||||
- Create continuity across multiple sessions
|
||||
|
||||
#### How it works:
|
||||
1. The agent needs context for the current conversation
|
||||
2. It calls `retrieveMemories` with the current conversation topic or question
|
||||
3. The function performs a semantic search in Mem0
|
||||
4. Relevant memories are returned to the agent
|
||||
5. The agent incorporates these memories into its response
|
||||
|
||||
#### Example usage in agent prompt:
|
||||
```
|
||||
At the beginning of each conversation turn, use retrieveMemories to check if we've
|
||||
discussed this topic before or if the user has shared relevant preferences.
|
||||
```
|
||||
|
||||
## Configuring Your ElevenLabs Agent
|
||||
|
||||
To enable your agent to effectively use memory:
|
||||
|
||||
1. Add function calling capabilities to your agent in the ElevenLabs platform:
|
||||
- Go to your agent settings in the ElevenLabs platform
|
||||
- Navigate to the "Tools" section
|
||||
- Enable function calling for your agent
|
||||
- Add the memory tools as described below
|
||||
|
||||
2. Add the `addMemories` and `retrieveMemories` tools to your agent with these specifications:
|
||||
|
||||
For `addMemories`:
|
||||
```json
|
||||
{
|
||||
"name": "addMemories",
|
||||
"description": "Stores important information from the conversation to remember for future interactions",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "The important information to remember"
|
||||
}
|
||||
},
|
||||
"required": ["message"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For `retrieveMemories`:
|
||||
```json
|
||||
{
|
||||
"name": "retrieveMemories",
|
||||
"description": "Retrieves relevant information from past conversations",
|
||||
"parameters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"description": "The query to search for in past memories"
|
||||
}
|
||||
},
|
||||
"required": ["message"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Update your agent's prompt to instruct it to use these memory functions. For example:
|
||||
|
||||
```
|
||||
You are a helpful voice assistant that remembers past conversations with the user.
|
||||
|
||||
You have access to memory tools that allow you to remember important information:
|
||||
- Use retrieveMemories at the beginning of the conversation to recall relevant context from prior conversations
|
||||
- Use addMemories to store new important information such as:
|
||||
* User preferences
|
||||
* Personal details the user shares
|
||||
* Important decisions made
|
||||
* Tasks or follow-ups promised to the user
|
||||
|
||||
Before responding to complex questions, always check for relevant memories first.
|
||||
When the user shares important information, make sure to store it for future reference.
|
||||
```
|
||||
|
||||
## Example Conversation Flow
|
||||
|
||||
Here's how a typical conversation with memory might flow:
|
||||
|
||||
1. **User speaks**: "Hi, do you remember my favorite color?"
|
||||
|
||||
2. **Agent retrieves memories**:
|
||||
```python
|
||||
# Agent calls retrieve_memories
|
||||
memories = retrieve_memories({"message": "user's favorite color"})
|
||||
# If found: "The user's favorite color is blue"
|
||||
```
|
||||
|
||||
3. **Agent processes with context**:
|
||||
- If memories found: Prepares a personalized response
|
||||
- If no memories: Prepares to ask and store the information
|
||||
|
||||
4. **Agent responds**:
|
||||
- With memory: "Yes, your favorite color is blue!"
|
||||
- Without memory: "I don't think you've told me your favorite color before. What is it?"
|
||||
|
||||
5. **User responds**: "It's actually green."
|
||||
|
||||
6. **Agent stores new information**:
|
||||
```python
|
||||
# Agent calls add_memories
|
||||
add_memories({"message": "The user's favorite color is green"})
|
||||
```
|
||||
|
||||
7. **Agent confirms**: "Thanks, I'll remember that your favorite color is green."
|
||||
|
||||
## Example Use Cases
|
||||
|
||||
- **Personal Assistant** - Remember user preferences, past requests, and important dates
|
||||
```
|
||||
User: "What restaurants did I say I liked last time?"
|
||||
Agent: *retrieves memories* "You mentioned enjoying Bella Italia and The Golden Dragon."
|
||||
```
|
||||
|
||||
- **Customer Support** - Recall previous issues a customer has had
|
||||
```
|
||||
User: "I'm having that same problem again!"
|
||||
Agent: *retrieves memories* "Is this related to the login issue you reported last week?"
|
||||
```
|
||||
|
||||
- **Educational AI** - Track student progress and tailor teaching accordingly
|
||||
```
|
||||
User: "Let's continue our math lesson."
|
||||
Agent: *retrieves memories* "Last time we were working on quadratic equations. Would you like to continue with that?"
|
||||
```
|
||||
|
||||
- **Healthcare Assistant** - Remember symptoms, medications, and health concerns
|
||||
```
|
||||
User: "Have I told you about my allergy medication?"
|
||||
Agent: *retrieves memories* "Yes, you mentioned you're taking Claritin for your pollen allergies."
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- **Missing API Keys**:
|
||||
- Error: "API_KEY environment variable must be set"
|
||||
- Solution: Ensure all environment variables are set correctly in your .env file or system environment
|
||||
|
||||
- **Connection Issues**:
|
||||
- Error: "Failed to connect to API"
|
||||
- Solution: Check your network connection and API key permissions. Verify the API keys are valid and have the necessary permissions.
|
||||
|
||||
- **Empty Memory Results**:
|
||||
- Symptom: Agent always responds with "No memories found"
|
||||
- Solution: This is normal for new users. The memory database builds up over time as conversations occur. It's also possible your query isn't semantically similar to stored memories - try different phrasing.
|
||||
|
||||
- **Agent Not Using Memories**:
|
||||
- Symptom: The agent retrieves memories but doesn't incorporate them in responses
|
||||
- Solution: Update the agent's prompt to explicitly instruct it to use the retrieved memories in its responses
|
||||
|
||||
## Conclusion
|
||||
|
||||
By integrating ElevenLabs Conversational AI with Mem0, you can create voice agents that maintain context across conversations and provide personalized responses based on user history. This powerful combination enables:
|
||||
|
||||
- More natural, context-aware conversations
|
||||
- Personalized user experiences that improve over time
|
||||
- Reduced need for users to repeat information
|
||||
- Long-term relationship building between users and AI agents
|
||||
|
||||
## Help
|
||||
|
||||
- For more details on ElevenLabs, visit the [ElevenLabs Conversational AI Documentation](https://elevenlabs.io/docs/api-reference/conversational-ai)
|
||||
- For Mem0 documentation, refer to the [Mem0 Platform](https://app.mem0.ai/)
|
||||
- If you need further assistance, please feel free to reach out to us through the following methods:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,126 @@
|
||||
---
|
||||
title: Flowise
|
||||
---
|
||||
|
||||
The [**Mem0 Memory**](https://github.com/mem0ai/mem0) integration with [Flowise](https://github.com/FlowiseAI/Flowise) enables persistent memory capabilities for your AI chatflows. [Flowise](https://flowiseai.com/) is an open-source low-code tool for developers to build customized LLM orchestration flows & AI agents using a drag & drop interface.
|
||||
|
||||
## Overview
|
||||
|
||||
1. 🧠 Provides persistent memory storage for Flowise chatflows
|
||||
2. 🔄 Seamless integration with existing Flowise templates
|
||||
3. 🚀 Compatible with various LLM nodes in Flowise
|
||||
4. 📝 Supports custom memory configurations
|
||||
5. ⚡ Easy to set up and manage
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before setting up Mem0 with Flowise, ensure you have:
|
||||
|
||||
1. [Flowise installed](https://github.com/FlowiseAI/Flowise#⚡quick-start) (NodeJS >= 18.15.0 required):
|
||||
```bash
|
||||
npm install -g flowise
|
||||
npx flowise start
|
||||
```
|
||||
|
||||
2. Access to the Flowise UI at http://localhost:3000
|
||||
3. Basic familiarity with [Flowise's LLM orchestration](https://flowiseai.com/#features) concepts
|
||||
|
||||
## Setup and Configuration
|
||||
|
||||
### 1. Set Up Flowise
|
||||
|
||||
1. Open the Flowise application and create a new canvas, or select a template from the Flowise marketplace.
|
||||
2. In this example, we use the **Conversation Chain** template.
|
||||
3. Replace the default **Buffer Memory** with **Mem0 Memory**.
|
||||
|
||||

|
||||
|
||||
### 2. Obtain Your Mem0 API Key
|
||||
|
||||
1. Navigate to the [Mem0 API Key dashboard](https://app.mem0.ai/dashboard/api-keys).
|
||||
2. Generate or copy your existing Mem0 API Key.
|
||||
|
||||

|
||||
|
||||
### 3. Configure Mem0 Credentials
|
||||
|
||||
1. Enter the **Mem0 API Key** in the Mem0 Credentials section.
|
||||
2. Configure additional settings as needed:
|
||||
|
||||
```typescript
|
||||
{
|
||||
"apiKey": "m0-xxx",
|
||||
"userId": "user-123", // Optional: Specify user ID
|
||||
"projectId": "proj-xxx", // Optional: Specify project ID
|
||||
"orgId": "org-xxx" // Optional: Specify organization ID
|
||||
}
|
||||
```
|
||||
|
||||
<figure>
|
||||
<img src="https://raw.githubusercontent.com/FlowiseAI/FlowiseDocs/main/en/.gitbook/assets/mem0/creds.png" alt="Mem0 Credentials" />
|
||||
<figcaption>Configure API Credentials</figcaption>
|
||||
</figure>
|
||||
|
||||
## Memory Features
|
||||
|
||||
### 1. Basic Memory Storage
|
||||
|
||||
Test your memory configuration:
|
||||
|
||||
1. Save your Flowise configuration
|
||||
2. Run a test chat and store some information
|
||||
3. Verify the stored memories in the [Mem0 Dashboard](https://app.mem0.ai/dashboard/requests)
|
||||
|
||||

|
||||
|
||||
### 2. Memory Retention
|
||||
|
||||
Validate memory persistence:
|
||||
|
||||
1. Clear the chat history in Flowise
|
||||
2. Ask a question about previously stored information
|
||||
3. Confirm that the AI remembers the context
|
||||
|
||||

|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### Memory Settings
|
||||
|
||||

|
||||
|
||||
Available settings include:
|
||||
|
||||
1. **Search Only Mode**: Enable memory retrieval without creating new memories
|
||||
2. **Mem0 Entities**: Configure identifiers:
|
||||
- `user_id`: Unique identifier for each user
|
||||
- `run_id`: Specific conversation session ID
|
||||
- `app_id`: Application identifier
|
||||
- `agent_id`: AI agent identifier
|
||||
3. **Project ID**: Assign memories to specific projects
|
||||
4. **Organization ID**: Organize memories by organization
|
||||
|
||||
### Platform Configuration
|
||||
|
||||
Additional settings available in [Mem0 Project Settings](https://app.mem0.ai/dashboard/project-settings):
|
||||
|
||||
1. **Custom Instructions**: Define memory extraction rules
|
||||
2. **Expiration Date**: Set automatic memory cleanup periods
|
||||
|
||||

|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **User Identification**: Use consistent `user_id` values for reliable memory retrieval
|
||||
2. **Memory Organization**: Utilize projects and organizations for better memory management
|
||||
3. **Regular Maintenance**: Monitor and clean up unused memories periodically
|
||||
|
||||
## Help & Resources
|
||||
|
||||
- [Flowise Documentation](https://flowiseai.com/docs)
|
||||
- [Flowise GitHub Repository](https://github.com/FlowiseAI/Flowise)
|
||||
- [Flowise Website](https://flowiseai.com/)
|
||||
- [Mem0 Platform](https://app.mem0.ai/)
|
||||
- Need assistance? Reach out through:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -0,0 +1,140 @@
|
||||
---
|
||||
title: Keywords AI
|
||||
---
|
||||
|
||||
Build AI applications with persistent memory and comprehensive LLM observability by integrating Mem0 with Keywords AI.
|
||||
|
||||
## Overview
|
||||
|
||||
Mem0 is a self-improving memory layer for LLM applications, enabling personalized AI experiences that save costs and delight users. Keywords AI provides complete LLM observability.
|
||||
|
||||
Combining Mem0 with Keywords AI allows you to:
|
||||
1. Add persistent memory to your AI applications
|
||||
2. Track interactions across sessions
|
||||
3. Monitor memory usage and retrieval with Keywords AI observability
|
||||
4. Optimize token usage and reduce costs
|
||||
|
||||
<Note>
|
||||
You can get your Mem0 API key, user_id, and org_id from the [Mem0 dashboard](https://app.mem0.ai/). These are required for proper integration.
|
||||
</Note>
|
||||
|
||||
## Setup and Configuration
|
||||
|
||||
Install the necessary libraries:
|
||||
|
||||
```bash
|
||||
pip install mem0 keywordsai-sdk
|
||||
```
|
||||
|
||||
Set up your environment variables:
|
||||
|
||||
```python
|
||||
import os
|
||||
|
||||
# Set your API keys
|
||||
os.environ["MEM0_API_KEY"] = "your-mem0-api-key"
|
||||
os.environ["KEYWORDSAI_API_KEY"] = "your-keywords-api-key"
|
||||
os.environ["KEYWORDSAI_BASE_URL"] = "https://api.keywordsai.co/api/"
|
||||
```
|
||||
|
||||
## Basic Integration Example
|
||||
|
||||
Here's a simple example of using Mem0 with Keywords AI:
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
import os
|
||||
|
||||
# Configuration
|
||||
api_key = os.getenv("MEM0_API_KEY")
|
||||
keywordsai_api_key = os.getenv("KEYWORDSAI_API_KEY")
|
||||
base_url = os.getenv("KEYWORDSAI_BASE_URL") # "https://api.keywordsai.co/api/"
|
||||
|
||||
# Set up Mem0 with Keywords AI as the LLM provider
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"temperature": 0.0,
|
||||
"api_key": keywordsai_api_key,
|
||||
"openai_base_url": base_url,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
# Initialize Memory
|
||||
memory = Memory.from_config(config_dict=config)
|
||||
|
||||
# Add a memory
|
||||
result = memory.add(
|
||||
"I like to take long walks on weekends.",
|
||||
user_id="alice",
|
||||
metadata={"category": "hobbies"},
|
||||
)
|
||||
|
||||
print(result)
|
||||
```
|
||||
|
||||
## Advanced Integration with OpenAI SDK
|
||||
|
||||
For more advanced use cases, you can integrate Keywords AI with Mem0 through the OpenAI SDK:
|
||||
|
||||
```python
|
||||
from openai import OpenAI
|
||||
import os
|
||||
import json
|
||||
|
||||
# Initialize client
|
||||
client = OpenAI(
|
||||
api_key=os.environ.get("KEYWORDSAI_API_KEY"),
|
||||
base_url=os.environ.get("KEYWORDSAI_BASE_URL"),
|
||||
)
|
||||
|
||||
# Sample conversation messages
|
||||
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."}
|
||||
]
|
||||
|
||||
# Add memory and generate a response
|
||||
response = client.chat.completions.create(
|
||||
model="openai/gpt-4o",
|
||||
messages=messages,
|
||||
extra_body={
|
||||
"mem0_params": {
|
||||
"user_id": "test_user",
|
||||
"org_id": "org_1",
|
||||
"api_key": os.environ.get("MEM0_API_KEY"),
|
||||
"add_memories": {
|
||||
"messages": messages,
|
||||
},
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
print(json.dumps(response.model_dump(), indent=4))
|
||||
```
|
||||
|
||||
For detailed information on this integration, refer to the official [Keywords AI Mem0 integration documentation](https://docs.keywordsai.co/integration/development-frameworks/mem0).
|
||||
|
||||
## Key Features
|
||||
|
||||
1. **Memory Integration**: Store and retrieve relevant information from past interactions
|
||||
2. **LLM Observability**: Track memory usage and retrieval patterns with Keywords AI
|
||||
3. **Session Persistence**: Maintain context across multiple user sessions
|
||||
4. **Cost Optimization**: Reduce token usage through efficient memory retrieval
|
||||
|
||||
## Conclusion
|
||||
|
||||
Integrating Mem0 with Keywords AI provides a powerful combination for building AI applications with persistent memory and comprehensive observability. This integration enables more personalized user experiences while providing insights into your application's memory usage.
|
||||
|
||||
## Help
|
||||
|
||||
For more information on using Mem0 and Keywords AI together, refer to:
|
||||
- [Mem0 Documentation](https://docs.mem0.ai)
|
||||
- [Keywords AI Documentation](https://docs.keywordsai.co)
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -95,7 +95,7 @@ add_input = {
|
||||
{"role": "user", "content": "Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts."},
|
||||
{"role": "assistant", "content": "Hello Alex! I've noted that you're a vegetarian and have a nut allergy."}
|
||||
],
|
||||
"user_id": "alex123",
|
||||
"user_id": "alex",
|
||||
"output_format": "v1.1",
|
||||
"metadata": {"food": "vegan"}
|
||||
}
|
||||
@@ -173,7 +173,7 @@ search_input = {
|
||||
"filters": {
|
||||
"AND": [
|
||||
{"created_at": {"gte": "2024-07-20", "lte": "2024-12-10"}},
|
||||
{"user_id": "alex123"}
|
||||
{"user_id": "alex"}
|
||||
]
|
||||
},
|
||||
"version": "v2"
|
||||
@@ -186,7 +186,7 @@ result = search_tool.invoke(search_input)
|
||||
{
|
||||
"id": "1a75e827-7eca-45ea-8c5c-cfd43299f061",
|
||||
"memory": "Name is Alex",
|
||||
"user_id": "alex123",
|
||||
"user_id": "alex",
|
||||
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
@@ -255,7 +255,7 @@ get_all_input = {
|
||||
"version": "v2",
|
||||
"filters": {
|
||||
"AND": [
|
||||
{"user_id": "alex123"},
|
||||
{"user_id": "alex"},
|
||||
{"created_at": {"gte": "2024-07-01", "lte": "2024-12-31"}}
|
||||
]
|
||||
},
|
||||
@@ -274,7 +274,7 @@ get_all_result = get_all_tool.invoke(get_all_input)
|
||||
{
|
||||
"id": "1a75e827-7eca-45ea-8c5c-cfd43299f061",
|
||||
"memory": "Name is Alex",
|
||||
"user_id": "alex123",
|
||||
"user_id": "alex",
|
||||
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
@@ -288,7 +288,7 @@ get_all_result = get_all_tool.invoke(get_all_input)
|
||||
{
|
||||
"id": "91509588-0b39-408a-8df3-84b3bce8c521",
|
||||
"memory": "Is a vegetarian",
|
||||
"user_id": "alex123",
|
||||
"user_id": "alex",
|
||||
"hash": "ce6b1c84586772ab9995a9477032df99",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
@@ -303,7 +303,7 @@ get_all_result = get_all_tool.invoke(get_all_input)
|
||||
{
|
||||
"id": "8d74f7a0-6107-4589-bd6f-210f6bf4fbbb",
|
||||
"memory": "Is allergic to nuts",
|
||||
"user_id": "alex123",
|
||||
"user_id": "alex",
|
||||
"hash": "7873cd0e5a29c513253d9fad038e758b",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
|
||||
@@ -0,0 +1,353 @@
|
||||
---
|
||||
title: Livekit
|
||||
---
|
||||
|
||||
This guide demonstrates how to create a memory-enabled voice assistant using LiveKit, Deepgram, OpenAI, and Mem0, focusing on creating an intelligent, context-aware travel planning agent.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, make sure you have:
|
||||
|
||||
1. Installed Livekit Agents SDK with voice dependencies of silero and deepgram:
|
||||
```bash
|
||||
pip install livekit \
|
||||
livekit-agents \
|
||||
livekit-plugins-silero \
|
||||
livekit-plugins-deepgram \
|
||||
livekit-plugins-openai
|
||||
```
|
||||
|
||||
2. Installed Mem0 SDK:
|
||||
```bash
|
||||
pip install mem0ai
|
||||
```
|
||||
|
||||
3. Set up your API keys in a `.env` file:
|
||||
```sh
|
||||
LIVEKIT_URL=your_livekit_url
|
||||
LIVEKIT_API_KEY=your_livekit_api_key
|
||||
LIVEKIT_API_SECRET=your_livekit_api_secret
|
||||
DEEPGRAM_API_KEY=your_deepgram_api_key
|
||||
MEM0_API_KEY=your_mem0_api_key
|
||||
OPENAI_API_KEY=your_openai_api_key
|
||||
```
|
||||
|
||||
> **Note**: Make sure to have a Livekit and Deepgram account. You can find these variables `LIVEKIT_URL` , `LIVEKIT_API_KEY` and `LIVEKIT_API_SECRET` from [LiveKit Cloud Console](https://cloud.livekit.io/) and for more information you can refer this website [LiveKit Documentation](https://docs.livekit.io/home/cloud/keys-and-tokens/). For `DEEPGRAM_API_KEY` you can get from [Deepgram Console](https://console.deepgram.com/) refer this website [Deepgram Documentation](https://developers.deepgram.com/docs/create-additional-api-keys) for more details.
|
||||
|
||||
## Code Breakdown
|
||||
|
||||
Let's break down the key components of this implementation:
|
||||
|
||||
### 1. Setting Up Dependencies and Environment
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
from typing import List, Dict, Any, Annotated
|
||||
|
||||
import aiohttp
|
||||
from dotenv import load_dotenv
|
||||
from livekit.agents import (
|
||||
AutoSubscribe,
|
||||
JobContext,
|
||||
JobProcess,
|
||||
WorkerOptions,
|
||||
cli,
|
||||
llm,
|
||||
metrics,
|
||||
)
|
||||
from livekit import rtc, api
|
||||
from livekit.agents.pipeline import VoicePipelineAgent
|
||||
from livekit.plugins import deepgram, openai, silero
|
||||
from mem0 import AsyncMemoryClient
|
||||
|
||||
# Load environment variables
|
||||
load_dotenv()
|
||||
|
||||
# Configure logging
|
||||
logger = logging.getLogger("memory-assistant")
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
# Define a global user ID for simplicity
|
||||
USER_ID = "voice_user"
|
||||
|
||||
# Initialize Mem0 client
|
||||
mem0 = AsyncMemoryClient()
|
||||
```
|
||||
|
||||
This section handles:
|
||||
- Importing required modules
|
||||
- Loading environment variables
|
||||
- Setting up logging
|
||||
- Extracting user identification
|
||||
- Initializing the Mem0 client
|
||||
|
||||
### 2. Memory Enrichment Function
|
||||
|
||||
```python
|
||||
async def _enrich_with_memory(agent: VoicePipelineAgent, chat_ctx: llm.ChatContext):
|
||||
"""Add memories and Augment chat context with relevant memories"""
|
||||
if not chat_ctx.messages:
|
||||
return
|
||||
|
||||
# Store user message in Mem0
|
||||
user_msg = chat_ctx.messages[-1]
|
||||
await mem0.add(
|
||||
[{"role": "user", "content": user_msg.content}],
|
||||
user_id=USER_ID
|
||||
)
|
||||
|
||||
# Search for relevant memories
|
||||
results = await mem0.search(
|
||||
user_msg.content,
|
||||
user_id=USER_ID,
|
||||
)
|
||||
|
||||
# Augment context with retrieved memories
|
||||
if results:
|
||||
memories = ' '.join([result["memory"] for result in results])
|
||||
logger.info(f"Enriching with memory: {memories}")
|
||||
|
||||
rag_msg = llm.ChatMessage.create(
|
||||
text=f"Relevant Memory: {memories}\n",
|
||||
role="assistant",
|
||||
)
|
||||
|
||||
# Modify chat context with retrieved memories
|
||||
chat_ctx.messages[-1] = rag_msg
|
||||
chat_ctx.messages.append(user_msg)
|
||||
```
|
||||
|
||||
This function:
|
||||
- Stores user messages in Mem0
|
||||
- Performs semantic search for relevant memories
|
||||
- Augments the chat context with retrieved memories
|
||||
- Enables contextually aware responses
|
||||
|
||||
### 3. Prewarm and Entrypoint Functions
|
||||
|
||||
```python
|
||||
def prewarm_process(proc: JobProcess):
|
||||
# Preload silero VAD in memory to speed up session start
|
||||
proc.userdata["vad"] = silero.VAD.load()
|
||||
|
||||
async def entrypoint(ctx: JobContext):
|
||||
# Connect to LiveKit room
|
||||
await ctx.connect(auto_subscribe=AutoSubscribe.AUDIO_ONLY)
|
||||
|
||||
# Wait for participant
|
||||
participant = await ctx.wait_for_participant()
|
||||
|
||||
# Initialize Mem0 client
|
||||
mem0 = AsyncMemoryClient()
|
||||
|
||||
# Define initial system context
|
||||
initial_ctx = llm.ChatContext().append(
|
||||
role="system",
|
||||
text=(
|
||||
"""
|
||||
You are a helpful voice assistant.
|
||||
You are a travel guide named George and will help the user to plan a travel trip of their dreams.
|
||||
You should help the user plan for various adventures like work retreats, family vacations or solo backpacking trips.
|
||||
You should be careful to not suggest anything that would be dangerous, illegal or inappropriate.
|
||||
You can remember past interactions and use them to inform your answers.
|
||||
Use semantic memory retrieval to provide contextually relevant responses.
|
||||
"""
|
||||
),
|
||||
)
|
||||
|
||||
# Create VoicePipelineAgent with memory capabilities
|
||||
agent = VoicePipelineAgent(
|
||||
chat_ctx=initial_ctx,
|
||||
vad=silero.VAD.load(),
|
||||
stt=deepgram.STT(),
|
||||
llm=openai.LLM(model="gpt-4o-mini"),
|
||||
tts=openai.TTS(),
|
||||
before_llm_cb=_enrich_with_memory,
|
||||
)
|
||||
|
||||
# Start agent and initial greeting
|
||||
agent.start(ctx.room, participant)
|
||||
await agent.say(
|
||||
"Hello! I'm George. Can I help you plan an upcoming trip? ",
|
||||
allow_interruptions=True
|
||||
)
|
||||
|
||||
# Run the application
|
||||
if __name__ == "__main__":
|
||||
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint, prewarm_fnc=prewarm_process))
|
||||
```
|
||||
|
||||
The entrypoint function:
|
||||
- Connects to LiveKit room
|
||||
- Initializes Mem0 memory client
|
||||
- Sets up initial system context
|
||||
- Creates a VoicePipelineAgent with memory enrichment
|
||||
- Starts the agent with an initial greeting
|
||||
|
||||
## Create a Memory-Enabled Voice Agent
|
||||
|
||||
Now that we've explained each component, here's the complete implementation that combines OpenAI Agents SDK for voice with Mem0's memory capabilities:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import logging
|
||||
import os
|
||||
from typing import List, Dict, Any, Annotated
|
||||
|
||||
import aiohttp
|
||||
from dotenv import load_dotenv
|
||||
from livekit.agents import (
|
||||
AutoSubscribe,
|
||||
JobContext,
|
||||
JobProcess,
|
||||
WorkerOptions,
|
||||
cli,
|
||||
llm,
|
||||
metrics,
|
||||
)
|
||||
from livekit import rtc, api
|
||||
from livekit.agents.pipeline import VoicePipelineAgent
|
||||
from livekit.plugins import deepgram, openai, silero
|
||||
from mem0 import AsyncMemoryClient
|
||||
|
||||
# Load environment variables
|
||||
load_dotenv()
|
||||
|
||||
# Configure logging
|
||||
logger = logging.getLogger("memory-assistant")
|
||||
logger.setLevel(logging.INFO)
|
||||
|
||||
# Define a global user ID for simplicity
|
||||
USER_ID = "voice_user"
|
||||
|
||||
# Initialize Mem0 memory client
|
||||
mem0 = AsyncMemoryClient()
|
||||
|
||||
def prewarm_process(proc: JobProcess):
|
||||
# Preload silero VAD in memory to speed up session start
|
||||
proc.userdata["vad"] = silero.VAD.load()
|
||||
|
||||
async def entrypoint(ctx: JobContext):
|
||||
# Connect to LiveKit room
|
||||
await ctx.connect(auto_subscribe=AutoSubscribe.AUDIO_ONLY)
|
||||
|
||||
# Wait for participant
|
||||
participant = await ctx.wait_for_participant()
|
||||
|
||||
async def _enrich_with_memory(agent: VoicePipelineAgent, chat_ctx: llm.ChatContext):
|
||||
"""Add memories and Augment chat context with relevant memories"""
|
||||
if not chat_ctx.messages:
|
||||
return
|
||||
|
||||
# Store user message in Mem0
|
||||
user_msg = chat_ctx.messages[-1]
|
||||
await mem0.add(
|
||||
[{"role": "user", "content": user_msg.content}],
|
||||
user_id=USER_ID
|
||||
)
|
||||
|
||||
# Search for relevant memories
|
||||
results = await mem0.search(
|
||||
user_msg.content,
|
||||
user_id=USER_ID,
|
||||
)
|
||||
|
||||
# Augment context with retrieved memories
|
||||
if results:
|
||||
memories = ' '.join([result["memory"] for result in results])
|
||||
logger.info(f"Enriching with memory: {memories}")
|
||||
|
||||
rag_msg = llm.ChatMessage.create(
|
||||
text=f"Relevant Memory: {memories}\n",
|
||||
role="assistant",
|
||||
)
|
||||
|
||||
# Modify chat context with retrieved memories
|
||||
chat_ctx.messages[-1] = rag_msg
|
||||
chat_ctx.messages.append(user_msg)
|
||||
|
||||
# Define initial system context
|
||||
initial_ctx = llm.ChatContext().append(
|
||||
role="system",
|
||||
text=(
|
||||
"""
|
||||
You are a helpful voice assistant.
|
||||
You are a travel guide named George and will help the user to plan a travel trip of their dreams.
|
||||
You should help the user plan for various adventures like work retreats, family vacations or solo backpacking trips.
|
||||
You should be careful to not suggest anything that would be dangerous, illegal or inappropriate.
|
||||
You can remember past interactions and use them to inform your answers.
|
||||
Use semantic memory retrieval to provide contextually relevant responses.
|
||||
"""
|
||||
),
|
||||
)
|
||||
|
||||
# Create VoicePipelineAgent with memory capabilities
|
||||
agent = VoicePipelineAgent(
|
||||
chat_ctx=initial_ctx,
|
||||
vad=silero.VAD.load(),
|
||||
stt=deepgram.STT(),
|
||||
llm=openai.LLM(model="gpt-4o-mini"),
|
||||
tts=openai.TTS(),
|
||||
before_llm_cb=_enrich_with_memory,
|
||||
)
|
||||
|
||||
# Start agent and initial greeting
|
||||
agent.start(ctx.room, participant)
|
||||
await agent.say(
|
||||
"Hello! I'm George. Can I help you plan an upcoming trip? ",
|
||||
allow_interruptions=True
|
||||
)
|
||||
|
||||
# Run the application
|
||||
if __name__ == "__main__":
|
||||
cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint, prewarm_fnc=prewarm_process))
|
||||
```
|
||||
|
||||
## Key Features of This Implementation
|
||||
|
||||
1. **Semantic Memory Retrieval**: Uses Mem0 to store and retrieve contextually relevant memories
|
||||
2. **Voice Interaction**: Leverages LiveKit for voice communication
|
||||
3. **Intelligent Context Management**: Augments conversations with past interactions
|
||||
4. **Travel Planning Specialization**: Focused on creating a helpful travel guide assistant
|
||||
|
||||
## Running the Example
|
||||
|
||||
To run this example:
|
||||
|
||||
1. Install all required dependencies
|
||||
2. Set up your `.env` file with the necessary API keys
|
||||
3. Ensure your microphone and audio setup are configured
|
||||
4. Run the script with Python 3.11 or newer and with the following command:
|
||||
```sh
|
||||
python mem0-livekit-voice-agent.py start
|
||||
```
|
||||
5. After the script starts, you can interact with the voice agent using [Livekit's Agent Platform](https://agents-playground.livekit.io/) and Connect to the agent inorder to start conversations.
|
||||
|
||||
## Best Practices for Voice Agents with Memory
|
||||
|
||||
1. **Context Preservation**: Store enough context with each memory for effective retrieval
|
||||
2. **Privacy Considerations**: Implement secure memory management
|
||||
3. **Relevant Memory Filtering**: Use semantic search to retrieve only the most pertinent memories
|
||||
4. **Error Handling**: Implement robust error handling for memory operations
|
||||
|
||||
## Debugging Function Tools
|
||||
|
||||
- To run the script in debug mode simply start the assistant with `dev` mode:
|
||||
```sh
|
||||
python mem0-livekit-voice-agent.py dev
|
||||
```
|
||||
|
||||
- When working with memory-enabled voice agents, use Python's `logging` module for effective debugging:
|
||||
|
||||
```python
|
||||
import logging
|
||||
|
||||
# Set up logging
|
||||
logging.basicConfig(
|
||||
level=logging.DEBUG,
|
||||
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
|
||||
)
|
||||
logger = logging.getLogger("memory_voice_agent")
|
||||
```
|
||||
@@ -0,0 +1,60 @@
|
||||
---
|
||||
title: MCP Server
|
||||
---
|
||||
|
||||
## Integrating mem0 as an MCP Server in Cursor
|
||||
[mem0](https://github.com/mem0ai/mem0-mcp) is a powerful tool designed to enhance AI-driven workflows, particularly in code generation and contextual memory. In this guide, we'll walk through integrating mem0 as an **MCP (Model Context Protocol) server** within [Cursor](https://cursor.sh/), an AI-powered coding editor.
|
||||
|
||||
## Prerequisites
|
||||
Before proceeding, ensure you have the following installed:
|
||||
- Cursor IDE
|
||||
- Python (>=3.8)
|
||||
- Git
|
||||
- [mem0-mcp](https://github.com/mem0ai/mem0-mcp) (Clone the repository and set up as per the instructions in the README)
|
||||
|
||||
|
||||
## Configuring Cursor to use mem0 as an MCP Server
|
||||
|
||||
1. **Open Cursor.**
|
||||
2. **Navigate to `Settings` > `Cursor Settings` > `Features` > `MCP Servers`.**
|
||||
3. **Add a new provider using the MCP server:**
|
||||
- Click on **`Add new MCP server`**
|
||||
- Provide a name for the server, e.g. `mem0` and select type as `sse`
|
||||
- Enter the **SSE Endpoint**: `http://0.0.0.0:8080/sse`
|
||||
4. **Save and Restart Cursor** to apply changes.
|
||||
|
||||
## Demo
|
||||
<iframe width="560" height="315" src="https://www.youtube.com/embed/fWa6KX7cpG8?si=cmJDz2sQevGnItSI" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
|
||||
|
||||
## Using mem0 in Cursor
|
||||
Once integrated, mem0 can assist with contextual memory and AI-driven coding enhancements. Some key functionalities include:
|
||||
|
||||
### 1. Storing Coding Preferences
|
||||
Mem0 can store and manage coding preferences, including:
|
||||
- Complete code snippets with dependencies
|
||||
- Language/framework versions
|
||||
- Documentation and comments
|
||||
- Best practices and example usage
|
||||
|
||||
### 2. Retrieving Stored Preferences
|
||||
Access all stored coding references to:
|
||||
- Review implementations
|
||||
- Maintain consistency in coding practices
|
||||
|
||||
### 3. Semantic Search for Preferences
|
||||
Use natural language queries to find:
|
||||
- Code snippets
|
||||
- Technical documentation
|
||||
- Best practices
|
||||
- Setup guides
|
||||
|
||||
## Benefits of Using mem0 in Cursor
|
||||
- **Persistent Context Storage**: Retain and reuse coding insights across sessions.
|
||||
- **Seamless Integration**: Works directly within Cursor as an MCP server.
|
||||
- **Efficient Search**: Retrieve relevant coding insights using semantic search.
|
||||
|
||||
## Conclusion
|
||||
By integrating mem0 as an MCP server within Cursor, you enhance your development workflow with AI-powered memory and context-aware assistance. Follow the steps above to set up and start leveraging mem0 in your coding environment.
|
||||
|
||||
For more details on MCP integration, refer to Cursor's [Model Context Protocol documentation](https://docs.cursor.com/context/model-context-protocol).
|
||||
|
||||
@@ -0,0 +1,218 @@
|
||||
---
|
||||
title: 'Pipecat'
|
||||
description: 'Integrate Mem0 with Pipecat for conversational memory in AI agents'
|
||||
---
|
||||
|
||||
# Pipecat Integration
|
||||
|
||||
Mem0 seamlessly integrates with [Pipecat](https://pipecat.ai), providing long-term memory capabilities for conversational AI agents. This integration allows your Pipecat-powered applications to remember past conversations and provide personalized responses based on user history.
|
||||
|
||||
## Installation
|
||||
|
||||
To use Mem0 with Pipecat, install the required dependencies:
|
||||
|
||||
```bash
|
||||
pip install "pipecat-ai[mem0]"
|
||||
```
|
||||
|
||||
You'll also need to set up your Mem0 API key as an environment variable:
|
||||
|
||||
```bash
|
||||
export MEM0_API_KEY=your_mem0_api_key
|
||||
```
|
||||
|
||||
You can obtain a Mem0 API key by signing up at [mem0.ai](https://mem0.ai).
|
||||
|
||||
## Configuration
|
||||
|
||||
Mem0 integration is provided through the `Mem0MemoryService` class in Pipecat. Here's how to configure it:
|
||||
|
||||
```python
|
||||
from pipecat.services.mem0 import Mem0MemoryService
|
||||
|
||||
memory = Mem0MemoryService(
|
||||
api_key=os.getenv("MEM0_API_KEY"), # Your Mem0 API key
|
||||
user_id="unique_user_id", # Unique identifier for the end user
|
||||
agent_id="my_agent", # Identifier for the agent using the memory
|
||||
run_id="session_123", # Optional: specific conversation session ID
|
||||
params={ # Optional: configuration parameters
|
||||
"search_limit": 10, # Maximum memories to retrieve per query
|
||||
"search_threshold": 0.1, # Relevance threshold (0.0 to 1.0)
|
||||
"system_prompt": "Here are your past memories:", # Custom prefix for memories
|
||||
"add_as_system_message": True, # Add memories as system (True) or user (False) message
|
||||
"position": 1, # Position in context to insert memories
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Pipeline Integration
|
||||
|
||||
The `Mem0MemoryService` should be positioned between your context aggregator and LLM service in the Pipecat pipeline:
|
||||
|
||||
```python
|
||||
pipeline = Pipeline([
|
||||
transport.input(),
|
||||
stt, # Speech-to-text for audio input
|
||||
user_context, # User context aggregator
|
||||
memory, # Mem0 Memory service enhances context here
|
||||
llm, # LLM for response generation
|
||||
tts, # Optional: Text-to-speech
|
||||
transport.output(),
|
||||
assistant_context # Assistant context aggregator
|
||||
])
|
||||
```
|
||||
|
||||
## Example: Voice Agent with Memory
|
||||
|
||||
Here's a complete example of a Pipecat voice agent with Mem0 memory integration:
|
||||
|
||||
```python
|
||||
import asyncio
|
||||
import os
|
||||
from fastapi import FastAPI, WebSocket
|
||||
|
||||
from pipecat.frames.frames import TextFrame
|
||||
from pipecat.pipeline.pipeline import Pipeline
|
||||
from pipecat.pipeline.task import PipelineTask
|
||||
from pipecat.pipeline.runner import PipelineRunner
|
||||
from pipecat.services.mem0 import Mem0MemoryService
|
||||
from pipecat.services.openai import OpenAILLMService, OpenAIUserContextAggregator, OpenAIAssistantContextAggregator
|
||||
from pipecat.transports.network.fastapi_websocket import (
|
||||
FastAPIWebsocketTransport,
|
||||
FastAPIWebsocketParams
|
||||
)
|
||||
from pipecat.serializers.protobuf import ProtobufFrameSerializer
|
||||
from pipecat.audio.vad.silero import SileroVADAnalyzer
|
||||
from pipecat.services.whisper import WhisperSTTService
|
||||
|
||||
app = FastAPI()
|
||||
|
||||
@app.websocket("/chat")
|
||||
async def websocket_endpoint(websocket: WebSocket):
|
||||
await websocket.accept()
|
||||
|
||||
# Basic setup with minimal configuration
|
||||
user_id = "user123"
|
||||
|
||||
# WebSocket transport
|
||||
transport = FastAPIWebsocketTransport(
|
||||
websocket=websocket,
|
||||
params=FastAPIWebsocketParams(
|
||||
audio_out_enabled=True,
|
||||
vad_enabled=True,
|
||||
vad_analyzer=SileroVADAnalyzer(),
|
||||
vad_audio_passthrough=True,
|
||||
serializer=ProtobufFrameSerializer(),
|
||||
)
|
||||
)
|
||||
|
||||
# Core services
|
||||
user_context = OpenAIUserContextAggregator()
|
||||
assistant_context = OpenAIAssistantContextAggregator()
|
||||
stt = WhisperSTTService(api_key=os.getenv("OPENAI_API_KEY"))
|
||||
|
||||
# Memory service - the key component
|
||||
memory = Mem0MemoryService(
|
||||
api_key=os.getenv("MEM0_API_KEY"),
|
||||
user_id=user_id,
|
||||
agent_id="fastapi_memory_bot"
|
||||
)
|
||||
|
||||
# LLM for response generation
|
||||
llm = OpenAILLMService(
|
||||
api_key=os.getenv("OPENAI_API_KEY"),
|
||||
model="gpt-3.5-turbo",
|
||||
system_prompt="You are a helpful assistant that remembers past conversations."
|
||||
)
|
||||
|
||||
# Simple pipeline
|
||||
pipeline = Pipeline([
|
||||
transport.input(),
|
||||
stt, # Speech-to-text for audio input
|
||||
user_context,
|
||||
memory, # Memory service enhances context here
|
||||
llm,
|
||||
transport.output(),
|
||||
assistant_context
|
||||
])
|
||||
|
||||
# Run the pipeline
|
||||
runner = PipelineRunner()
|
||||
task = PipelineTask(pipeline)
|
||||
|
||||
# Event handlers for WebSocket connections
|
||||
@transport.event_handler("on_client_connected")
|
||||
async def on_client_connected(transport, client):
|
||||
# Send welcome message when client connects
|
||||
await task.queue_frame(TextFrame("Hello! I'm a memory bot. I'll remember our conversation."))
|
||||
|
||||
@transport.event_handler("on_client_disconnected")
|
||||
async def on_client_disconnected(transport, client):
|
||||
# Clean up when client disconnects
|
||||
await task.cancel()
|
||||
|
||||
await runner.run(task)
|
||||
|
||||
if __name__ == "__main__":
|
||||
import uvicorn
|
||||
uvicorn.run(app, host="0.0.0.0", port=8000)
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
When integrated with Pipecat, Mem0 provides two key functionalities:
|
||||
|
||||
### 1. Message Storage
|
||||
|
||||
All conversation messages are automatically stored in Mem0 for future reference:
|
||||
- Captures the full message history from context frames
|
||||
- Associates messages with the specified user, agent, and run IDs
|
||||
- Stores metadata to enable efficient retrieval
|
||||
|
||||
### 2. Memory Retrieval
|
||||
|
||||
When a new user message is detected:
|
||||
1. The message is used as a search query to find relevant past memories
|
||||
2. Relevant memories are retrieved from Mem0's database
|
||||
3. Memories are formatted and added to the conversation context
|
||||
4. The enhanced context is passed to the LLM for response generation
|
||||
|
||||
## Additional Configuration Options
|
||||
|
||||
### Memory Search Parameters
|
||||
|
||||
You can customize how memories are retrieved and used:
|
||||
|
||||
```python
|
||||
memory = Mem0MemoryService(
|
||||
api_key=os.getenv("MEM0_API_KEY"),
|
||||
user_id="user123",
|
||||
params={
|
||||
"search_limit": 5, # Retrieve up to 5 memories
|
||||
"search_threshold": 0.2, # Higher threshold for more relevant matches
|
||||
"api_version": "v2", # Mem0 API version
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
### Memory Presentation Options
|
||||
|
||||
Control how memories are presented to the LLM:
|
||||
|
||||
```python
|
||||
memory = Mem0MemoryService(
|
||||
api_key=os.getenv("MEM0_API_KEY"),
|
||||
user_id="user123",
|
||||
params={
|
||||
"system_prompt": "Previous conversations with this user:",
|
||||
"add_as_system_message": True, # Add as system message instead of user message
|
||||
"position": 0, # Insert at the beginning of the context
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
## Resources
|
||||
|
||||
- [Mem0 Pipecat Integration](https://docs.pipecat.ai/server/services/memory/mem0)
|
||||
- [Pipecat Documentation](https://docs.pipecat.ai)
|
||||
|
||||
@@ -10,7 +10,6 @@ The [**Mem0 AI SDK Provider**](https://www.npmjs.com/package/@mem0/vercel-ai-pro
|
||||
|
||||
## Overview
|
||||
|
||||
In this guide, we'll create a Travel Agent AI that:
|
||||
1. 🧠 Offers persistent memory storage for conversational AI
|
||||
2. 🔄 Enables smooth integration with the Vercel AI SDK
|
||||
3. 🚀 Ensures compatibility with multiple LLM providers
|
||||
@@ -191,6 +190,20 @@ npm install @mem0/vercel-ai-provider
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
### 5. Get sources from memory
|
||||
|
||||
```typescript
|
||||
const { text, sources } = await generateText({
|
||||
model: mem0("gpt-4-turbo"),
|
||||
prompt: "Suggest me a good car to buy!",
|
||||
});
|
||||
|
||||
console.log(sources);
|
||||
```
|
||||
|
||||
The same can be done for `streamText` as well.
|
||||
|
||||
|
||||
## Key Features
|
||||
|
||||
- `createMem0()`: Initializes a new Mem0 provider instance.
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
# Mem0
|
||||
|
||||
## High Level
|
||||
|
||||
[What is Mem0?](https://docs.mem0.ai/overview): consider using Mem0, when building conversational AI agents with memory. The page discusses the main reasons to use Mem0: Context Management, Smart Retrieval System, Simple API Integration and Dual Storage Architecture(vector and graph database).
|
||||
[How is Mem0 different from traditional RAG?](https://docs.mem0.ai/faqs#how-mem0-is-different-from-traditional-rag): Mem0's memory for LLMs offers superior entity relationship understanding, contextual continuity, and adaptive learning compared to RAG. It retains information across sessions, dynamically updates with new data, and personalizes interactions, making it ideal for context-aware AI applications.
|
||||
|
||||
## Concepts
|
||||
|
||||
[Memory Types](https://docs.mem0.ai/core-concepts/memory-types): Mem0 implements both short-term memory (for conversation history and immediate context) and long-term memory (for persistent storage of factual, episodic, and semantic information) to maintain context and personalization across interactions.
|
||||
[Memory Operations](https://docs.mem0.ai/core-concepts/memory-operations): Two core operations power Mem0's functionality: `add` Processes and stores conversations through information extraction, conflict resolution, and dual storage and `search` Retrieves relevant memories using semantic search with query processing and result ranking
|
||||
[Information Processing](https://docs.mem0.ai/core-concepts/memory-operations): When adding memories, Mem0 uses LLMs to extract relevant information, identify entities and relationships, and resolve conflicts with existing data.
|
||||
[Storage Architecture](https://docs.mem0.ai/core-concepts/memory-types): Mem0 combines vector embeddings for semantic information storage with efficient retrieval mechanisms, enabling fast access to relevant past interactions while maintaining user-specific context across sessions.
|
||||
|
||||
## How-to guides
|
||||
|
||||
### Installation
|
||||
|
||||
[Mem0 Installation](https://docs.mem0.ai/quickstart): Mem0 offers two installation options: Mem0 Platform (Managed Solution) and Mem0 OSS.
|
||||
[How to: install Mem0 Platform (Managed Solution)](https://docs.mem0.ai/quickstart#mem0-platform-managed-solution): The easiest way to get started with Mem0 is to use the managed platform. This approach eliminates the need to set up and maintain your own infrastructure.
|
||||
[How to: install Mem0 OSS](https://docs.mem0.ai/quickstart#mem0-open-source): If you prefer to manage your own infrastructure, you can install Mem0 OSS. This option requires setting up your own infrastructure and managing your own vector database.
|
||||
|
||||
## Platform
|
||||
|
||||
### Usage
|
||||
|
||||
[Initialize Client](https://docs.mem0.ai/platform/quickstart#3-instantiate-client): Mem0 gives two ways to initialize the client: Synchronous -> MemoryClient and Asynchronous -> AsyncMemoryClient.
|
||||
[How to: add memories](https://docs.mem0.ai/platform/quickstart#4-1-create-memories): Add memories to Mem0 using messages or a simple string. The `add` method allows adding memories to a specific memory by providing `user_id`, `agent_id`, `run_id`, or `app_id`.
|
||||
[How to: search memories](https://docs.mem0.ai/platform/quickstart#4-2-search-memories): Search memories in Mem0 by passing a query string and optional parameters. The `search` method returns a list of memories sorted by relevance. Csutom filters can also be passed to make the search more specific.
|
||||
[How to: get all memories](https://docs.mem0.ai/platform/quickstart#4-4-get-all-memories): Get all the memories by passing a `user_id`, `agent_id`, `run_id`, or `app_id`. Also custom filters can be passed to filter the memories.
|
||||
[How to: get memory history](https://docs.mem0.ai/platform/quickstart#4-5-get-memory-history): Get the history of a specific memory by passing `memory_id` after adding memories using the `add` method.
|
||||
[How to: update memory](https://docs.mem0.ai/platform/quickstart#4-6-update-memory): Update a memory by passing `memory_id` after adding memories using the `add` method.
|
||||
[How to: delete memory](https://docs.mem0.ai/platform/quickstart#4-7-delete-memories): Delete memories by passing `memory_id` after adding memories using the `add` method.
|
||||
[How to: reset client](https://docs.mem0.ai/platform/quickstart#4-8-reset-client): Reset the client where all the memories, users, agents, sessions and runs are deleted.
|
||||
[How to: batch update memories](https://docs.mem0.ai/platform/quickstart#4-9-batch-update-memories): Batch update memories by passing a list of memories to the `batch_update` method.
|
||||
[How to: batch delete memories](https://docs.mem0.ai/platform/quickstart#4-10-batch-delete-memories): Batch delete memories by passing a list of memories to the `batch_delete` method.
|
||||
|
||||
## Features
|
||||
|
||||
[Graph Memory](https://docs.mem0.ai/features/graph-memory): Mem0's graph memory system builds relationships between entities in your data, enabling contextually relevant retrieval by analyzing connections between information points - activate it with `enable_graph=True` to enhance search results beyond direct semantic matches, ideal for applications tracking evolving relationships.
|
||||
[Advanced Retrieval](https://docs.mem0.ai/features/advanced-retrieval): Mem0 offers enhanced search capabilities through three advanced retrieval modes: keyword search (improves recall by matching specific terms), reranking (ensures most relevant results appear first using neural networks), and filtering (narrows results by specific criteria) - each can be enabled independently or in combination to optimize search precision and relevance.
|
||||
[Multimodal Support](https://docs.mem0.ai/features/multimodal-support): Mem0 extends beyond text by supporting images and documents (JPG, PNG, MDX, TXT, PDF), allowing users to integrate visual and document content through direct URLs or Base64 encoding, enhancing the memory system's ability to understand and recall information from various media types.
|
||||
[Memory Customization](https://docs.mem0.ai/features/selective-memory): Mem0 enables selective memory storage through inclusion and exclusion rules, allowing users to focus on relevant information (like specific topics) while omitting irrelevant data (such as food preferences), resulting in more efficient, accurate, and privacy-conscious AI interactions.
|
||||
[Custom Categories](https://docs.mem0.ai/features/custom-categories): Mem0 allows setting custom categories at both project level and during individual API calls, overriding default categories (like personal_details, family, sports) with more specific ones to improve memory categorization accuracy - simply provide a list of category dictionaries with descriptive definitions when adding memories.
|
||||
[Async Client](https://docs.mem0.ai/features/async-client): Mem0 provides an AsyncMemoryClient for non-blocking operations, offering the same functionality as the synchronous client (add, search, get_all, delete, etc.) but with async/await support, making it ideal for high-concurrency applications that need to perform memory operations without blocking execution.
|
||||
[Memory Export](https://docs.mem0.ai/features/memory-export): Mem0 enables exporting memories in structured formats using customizable Pydantic schemas, allowing you to transform stored memories into specific data structures by defining schemas, submitting export jobs with optional processing instructions, and retrieving the formatted data with various filtering options.
|
||||
|
||||
## OSS
|
||||
|
||||
### Usage
|
||||
|
||||
#### Python
|
||||
|
||||
[Initialize python client](https://docs.mem0.ai/open-source/python-quickstart#installation): Install Mem0 with `pip install mem0ai`, then initialize the client with `from mem0 import Memory; m = Memory()` (requires OpenAI API key). For advanced usage, configure with custom parameters or enable graph memory with `Memory(enable_graph=True)`.
|
||||
[Configuration Parameters](https://docs.mem0.ai/open-source/python-quickstart#configuration-parameters): Mem0 offers extensive configuration options for vector stores (provider, host, port), LLMs (provider, model, temperature, API keys), embedders (provider, model), graph stores (provider, URL, credentials), and general settings (history path, API version, custom prompts) - all customizable through a comprehensive configuration dictionary.
|
||||
[How to: add memories](https://docs.mem0.ai/open-source/python-quickstart#store-a-memory): Add memories to Mem0 using the Python OSS client's `add` method with messages or a simple string. This method allows adding memories to a specific memory by providing `user_id`, `agent_id`, `run_id`, or `app_id`.
|
||||
[How to: search memories](https://docs.mem0.ai/open-source/python-quickstart#search-memories): Search memories in Mem0 using the Python OSS client by passing a query string and optional parameters. The `search` method returns a list of memories sorted by relevance. Custom filters can also be passed to make the search more specific.
|
||||
[How to: get all memories](https://docs.mem0.ai/open-source/python-quickstart#retrieve-memories): Get all the memories using the Python OSS client by passing a `user_id`, `agent_id`, `run_id`, or `app_id`. Also custom filters can be passed to filter the memories.
|
||||
[How to: get memory history](https://docs.mem0.ai/open-source/python-quickstart#memory-history): Get the history of a specific memory in the Python OSS client by passing `memory_id` after adding memories using the `add` method.
|
||||
[How to: update memory](https://docs.mem0.ai/open-source/python-quickstart#update-a-memory): Update a memory in the Python OSS client by passing `memory_id` after adding memories using the `add` method.
|
||||
[How to: delete memory](https://docs.mem0.ai/open-source/python-quickstart#delete-memory): Delete memories in the Python OSS client by passing `memory_id` after adding memories using the `add` method.
|
||||
|
||||
#### Node.js
|
||||
|
||||
[Initialize node client](https://docs.mem0.ai/open-source/node-quickstart#installation): Install Mem0 with `npm install mem0ai`, then initialize the client with `import { Memory } from 'mem0ai'; const m = new Memory();` (requires OpenAI API key). For advanced usage, configure with custom parameters or enable graph memory with `new Memory({ enableGraph: true })`.
|
||||
[How to: add memories](https://docs.mem0.ai/open-source/node-quickstart#store-a-memory): Add memories to Mem0 using the Node.js OSS client's `add` method with messages or a simple string. This method allows adding memories to a specific memory by providing `user_id`, `agent_id`, `run_id`, or `app_id`.
|
||||
[How to: search memories](https://docs.mem0.ai/open-source/node-quickstart#search-memories): Search memories in Mem0 using the Node.js OSS client by passing a query string and optional parameters. The `search` method returns a list of memories sorted by relevance. Custom filters can also be passed to make the search more specific.
|
||||
[How to: get all memories](https://docs.mem0.ai/open-source/node-quickstart#retrieve-memories): Get all the memories using the Node.js OSS client by passing a `user_id`, `agent_id`, `run_id`, or `app_id`. Also custom filters can be passed to filter the memories.
|
||||
[How to: get memory history](https://docs.mem0.ai/open-source/node-quickstart#memory-history): Get the history of a specific memory in the Node.js OSS client by passing `memory_id` after adding memories using the `add` method.
|
||||
[How to: update memory](https://docs.mem0.ai/open-source/node-quickstart#update-a-memory): Update a memory in the Node.js OSS client by passing `memory_id` after adding memories using the `add` method.
|
||||
[How to: delete memory](https://docs.mem0.ai/open-source/node-quickstart#delete-memory): Delete memories in the Node.js OSS client by passing `memory_id` after adding memories using the `add` method.
|
||||
|
||||
### Features
|
||||
|
||||
[OpenAI Compatibility](https://docs.mem0.ai/features/openai_compatibility): Mem0 offers seamless integration with OpenAI-compatible APIs, allowing developers to enhance conversational agents with structured memory by initializing with a Mem0 API key (or locally without one), supporting various LLM providers, and enabling personalized responses through user context persistence across interactions with parameters like user_id, agent_id, and custom filters.
|
||||
[Custom Fact Extraction Prompt](https://docs.mem0.ai/features/custom-fact-extraction-prompt): Mem0 enables custom fact extraction prompts to tailor information extraction for specific use cases by defining domain-specific examples and formats, allowing precise control over what information is extracted from messages - simply provide a custom prompt with few-shot examples in the config when initializing the Memory client.
|
||||
[Custom Update Memory Prompt](https://docs.mem0.ai/features/custom-update-memory-prompt): Mem0 enables customizing the update memory prompt to control how memories are modified by comparing newly retrieved facts with existing memories and determining appropriate actions (add, update, delete, or no change) based on custom logic and examples provided in the prompt configuration.
|
||||
[REST API Server](https://docs.mem0.ai/open-source/features/rest-api): Mem0 provides a FastAPI-based REST API server that supports core operations (create/retrieve/search/update/delete memories) with OpenAPI documentation at /docs, easily deployable via Docker Compose with pre-configured databases (postgres pgvector, neo4j) - just set OPENAI_API_KEY to get started.
|
||||
[Graph Memory](https://docs.mem0.ai/open-source/graph_memory/overview): Mem0's open-source graph memory system enables building and querying relationships between entities by installing with `pip install "mem0ai[graph]"` and configuring a graph store provider (like Neo4j) - this allows for more contextual memory retrieval by combining vector and graph-based approaches to track evolving relationships between information points.
|
||||
|
||||
### Components
|
||||
|
||||
#### LLMs
|
||||
|
||||
[OpenAI](https://docs.mem0.ai/components/llms/models/openai): Integrate OpenAI LLM models by setting OPENAI_API_KEY and configuring the Memory client with provider settings - supports both standard models (like gpt-4) and structured-outputs, with options for temperature, max tokens and Openrouter integration.
|
||||
[Anthropic](https://docs.mem0.ai/components/llms/models/anthropic): Integrate Anthropic LLM models by setting ANTHROPIC_API_KEY from your Account Settings Page and configuring the Memory client with provider settings - supports models like claude-3-7-sonnet-latest with customizable temperature and max_tokens parameters.
|
||||
[Google AI](https://docs.mem0.ai/components/llms/models/google_AI): Integrate Gemini LLM models by setting GEMINI_API_KEY from Google Maker Suite and configuring the Memory client with litellm provider - supports models like gemini-pro with customizable temperature and max_tokens parameters.
|
||||
[Groq](https://docs.mem0.ai/components/llms/models/groq): Integrate Groq's Language Processing Unit (LPU) optimized models by setting GROQ_API_KEY and configuring the Memory client with provider settings - supports models like mixtral-8x7b-32768 with customizable temperature and max_tokens parameters for high-performance AI inference.
|
||||
[Together](https://docs.mem0.ai/components/llms/models/together): Integrate Together LLM models by setting TOGETHER_API_KEY and configuring the Memory client with provider settings - supports both standard models (like together-llama-3-8b-instant) and structured-outputs, with options for temperature, max tokens and Openrouter integration.
|
||||
[Deepseek](https://docs.mem0.ai/components/llms/models/deepseek): Integrate Deepseek LLM models by setting DEEPSEEK_API_KEY and configuring the Memory client with provider settings - supports both standard models (like deepseek-chat) and structured-outputs, with options for temperature, max tokens and Openrouter integration.
|
||||
[xAI](https://docs.mem0.ai/components/llms/models/xai): Integrate xAI LLM models by setting XAI_API_KEY and configuring the Memory client with provider settings - supports both standard models (like xai-chat) and structured-outputs, with options for temperature, max tokens and Openrouter integration.
|
||||
[LM Studio](https://docs.mem0.ai/components/llms/models/lmstudio): Run Mem0 locally with LM Studio by configuring the Memory client with provider settings and a local LM Studio server - supports using LM Studio for both LLM inference and embeddings, requiring no external API keys when running fully locally with appropriate models loaded.
|
||||
[Ollama](https://docs.mem0.ai/components/llms/models/ollama): Run Mem0 locally with Ollama LLM models by configuring the Memory client with provider settings like model (e.g. mixtral:8x7b), temperature and max_tokens - supports tool calling and requires only OpenAI API key for embeddings.
|
||||
[AWS Bedrock](https://docs.mem0.ai/components/llms/models/aws_bedrock): Integrate AWS Bedrock LLM models by setting AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY and configuring the Memory client with provider settings - supports both standard models (like bedrock-anthropic-claude-3-5-sonnet) and structured-outputs, with options for temperature, max tokens and Openrouter integration.
|
||||
[Azure OpenAI](https://docs.mem0.ai/components/llms/models/azure_openai): Integrate Azure OpenAI LLM models by setting LLM_AZURE_OPENAI_API_KEY, LLM_AZURE_ENDPOINT, LLM_AZURE_DEPLOYMENT and LLM_AZURE_API_VERSION environment variables and configuring the Memory client with provider settings - supports both standard and structured-output models with customizable deployment, API version, endpoint and headers (note: some features like parallel tool calling and temperature are currently unsupported).
|
||||
[LiteLLM](https://docs.mem0.ai/components/llms/models/litellm): Integrate LiteLLM LLM models by setting LITELLM_API_KEY and configuring the Memory client with provider settings - supports both standard models (like llama3.1:8b) and structured-outputs, with options for temperature, max tokens and Openrouter integration.
|
||||
[Mistral](https://docs.mem0.ai/components/llms/models/mistral): Integrate Mistral LLM models by setting MISTRAL_API_KEY and configuring the Memory client with provider settings - supports both standard models (like mistral-large-latest) and structured-outputs, with options for temperature, max tokens and Openrouter integration.
|
||||
|
||||
#### Embedders
|
||||
|
||||
[OpenAI](https://docs.mem0.ai/components/embedders/models/openai): Integrate OpenAI embedding models by setting OPENAI_API_KEY and configuring the Memory client with provider settings - supports models like text-embedding-3-small (default) and text-embedding-3-large with customizable dimensions.
|
||||
[Azure OpenAI](https://docs.mem0.ai/components/embedders/models/azure_openai): Integrate Azure OpenAI embedding models by setting EMBEDDING_AZURE_OPENAI_API_KEY, EMBEDDING_AZURE_ENDPOINT, EMBEDDING_AZURE_DEPLOYMENT and EMBEDDING_AZURE_API_VERSION environment variables and configuring the Memory client with provider settings - supports models like text-embedding-3-large with customizable dimensions and Azure-specific configurations through azure_kwargs.
|
||||
[Vertex AI](https://docs.mem0.ai/components/embedders/models/google_ai): Integrate Google Cloud's Vertex AI embedding models by setting GOOGLE_APPLICATION_CREDENTIALS environment variable to your service account credentials JSON file and configuring the Memory client with provider settings - supports models like text-embedding-004 with customizable embedding types (RETRIEVAL_DOCUMENT, RETRIEVAL_QUERY, etc.) and dimensions.
|
||||
[Groq](https://docs.mem0.ai/components/embedders/models/groq): Integrate Groq embedding models by setting GROQ_API_KEY and configuring the Memory client with provider settings - supports models like text-embedding-3-small (default) and text-embedding-3-large with customizable dimensions.
|
||||
[Hugging Face](https://docs.mem0.ai/components/embedders/models/hugging_face): Run Mem0 locally with Hugging Face embedding models by configuring the Memory client with provider settings like model (e.g. multi-qa-MiniLM-L6-cos-v1), embedding dimensions and model_kwargs - requires only OpenAI API key for LLM functionality.
|
||||
[Ollama](https://docs.mem0.ai/components/embedders/models/ollama): Run Mem0 locally with Ollama embedding models by configuring the Memory client with provider settings like model (e.g. nomic-embed-text), embedding dimensions (default 512) and custom base URL - requires only OpenAI API key for LLM functionality.
|
||||
[Gemini](https://docs.mem0.ai/components/embedders/models/gemini): Integrate Gemini embedding models by setting GOOGLE_API_KEY and configuring the Memory client with provider settings - supports models like text-embedding-004 with customizable dimensions (default 768) and requires OpenAI API key for LLM functionality.
|
||||
|
||||
#### Vector Stores
|
||||
|
||||
[Qdrant](https://docs.mem0.ai/components/vectordbs/dbs/qdrant): Integrate Qdrant vector database by configuring the Memory client with provider settings like collection_name, host, port, and other parameters - supports both local and remote deployments with options for persistent storage and custom client configurations.
|
||||
[Pinecone](https://docs.mem0.ai/components/vectordbs/dbs/pinecone): Integrate Pinecone's managed vector database by configuring the Memory client with serverless or pod deployment options, supporting high-performance vector search with customizable embedding dimensions, distance metrics, and cloud providers (AWS/GCP/Azure) - requires PINECONE_API_KEY and matching embedding model dimensions (e.g. 1536 for OpenAI).
|
||||
[Milvus](https://docs.mem0.ai/components/vectordbs/dbs/milvus): Integrate Milvus open-source vector database by configuring the Memory client with provider settings like url (default localhost:19530), token (for Zilliz cloud), collection_name, embedding_model_dims (default 1536) and metric_type - supports both local and cloud deployments for AI applications of any scale.
|
||||
[Weaviate](https://docs.mem0.ai/components/vectordbs/dbs/weaviate): Integrate Weaviate open-source vector search engine by configuring the Memory client with provider settings like collection_name (default: mem0), cluster_url, auth_client_secret and embedding_model_dims (default: 1536) - enables efficient storage and retrieval of high-dimensional vector embeddings.
|
||||
[Chroma](https://docs.mem0.ai/components/vectordbs/dbs/chroma): Integrate Chroma AI-native open-source vector database by configuring the Memory client with provider settings like collection_name (default: mem0), path (default: db), host, port, and client - enables simple storage and search of embeddings with focus on speed and ease of use.
|
||||
[Faiss](https://docs.mem0.ai/components/vectordbs/dbs/faiss): Integrate Faiss, a high-performance library for similarity search and clustering of dense vectors, by configuring the Memory client with settings like collection_name, path, and distance_strategy (euclidean/cosine/inner_product) - supports efficient local vector search with in-memory or persistent storage options and is optimized for large-scale production use.
|
||||
[PGVector](https://docs.mem0.ai/components/vectordbs/dbs/pgvector): Integrate Postgres vector similarity search by configuring the Memory client with database connection settings (user, password, host, port), collection name, embedding dimensions and indexing options (diskann/hnsw) - requires creating vector extension in Postgres and supports both local and cloud deployments.
|
||||
[Elasticsearch](https://docs.mem0.ai/components/vectordbs/dbs/elasticsearch): Integrate Elasticsearch vector database by configuring host, port, collection name and authentication settings - supports k-NN vector search, cloud/local deployments, custom search queries, and requires `pip install elasticsearch>=8.0.0`.
|
||||
[Redis](https://docs.mem0.ai/components/vectordbs/dbs/redis): Integrate Redis vector database for real-time vector storage and search by configuring collection name, embedding dimensions (default 1536), and Redis URL - supports both local Docker deployment and remote Redis Stack instances.
|
||||
[Supabase](https://docs.mem0.ai/components/vectordbs/dbs/supabase): Integrate Supabase's PostgreSQL database with pgvector extension by configuring connection string, collection name, and optional index settings (hnsw/ivfflat) - enables efficient vector similarity search with support for different distance measures (cosine/l2/l1) and requires SQL migrations to enable vector functionality.
|
||||
[Azure AI Search](https://docs.mem0.ai/components/vectordbs/dbs/azure): Integrate Azure AI Search (formerly Azure Cognitive Search) by configuring service_name, api_key and collection_name - supports vector compression (none/scalar/binary), hybrid search modes, and customizable vector dimensions with automatic extraction of filterable fields like user_id.
|
||||
[Vertex AI Search](https://docs.mem0.ai/components/vectordbs/dbs/vertex_ai): Integrate Google Cloud's Vertex AI Vector Search by configuring endpoint_id, index_id, deployment_index_id, project details and optional region/credentials - enables efficient vector similarity search through Google Cloud's managed service with support for both get and search operations.
|
||||
@@ -0,0 +1,169 @@
|
||||
---
|
||||
title: Async Memory
|
||||
description: 'Asynchronous memory for Mem0'
|
||||
icon: "bolt"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## AsyncMemory
|
||||
|
||||
The `AsyncMemory` class is a direct asynchronous interface to Mem0's in-process memory operations. Unlike the memory, which interacts with an API, `AsyncMemory` works directly with the underlying storage systems. This makes it ideal for applications where you want to embed Mem0 directly into your codebase.
|
||||
|
||||
### Initialization
|
||||
|
||||
To use `AsyncMemory`, import it from the `mem0.memory` module:
|
||||
|
||||
```python Python
|
||||
import asyncio
|
||||
from mem0 import AsyncMemory
|
||||
|
||||
# Initialize with default configuration
|
||||
memory = AsyncMemory()
|
||||
|
||||
# Or initialize with custom configuration
|
||||
from mem0.configs.base import MemoryConfig
|
||||
custom_config = MemoryConfig(
|
||||
# Your custom configuration here
|
||||
)
|
||||
memory = AsyncMemory(config=custom_config)
|
||||
```
|
||||
|
||||
### Key Features
|
||||
|
||||
1. **Non-blocking Operations** - All memory operations use `asyncio` to avoid blocking the event loop
|
||||
2. **Concurrent Processing** - Parallel execution of vector store and graph operations
|
||||
3. **Efficient Resource Utilization** - Better handling of I/O bound operations
|
||||
4. **Compatible with Async Frameworks** - Seamless integration with FastAPI, aiohttp, and other async frameworks
|
||||
|
||||
### Methods
|
||||
|
||||
All methods in `AsyncMemory` have the same parameters as the synchronous `Memory` class but are designed to be used with `async/await`.
|
||||
|
||||
#### Create memories
|
||||
|
||||
Add a new memory asynchronously:
|
||||
|
||||
```python Python
|
||||
await memory.add(
|
||||
messages=[
|
||||
{"role": "user", "content": "I'm travelling to SF"},
|
||||
{"role": "assistant", "content": "That's great to hear!"}
|
||||
],
|
||||
user_id="alice"
|
||||
)
|
||||
```
|
||||
|
||||
#### Retrieve memories
|
||||
|
||||
Retrieve memories related to a query:
|
||||
|
||||
```python Python
|
||||
await memory.search(
|
||||
query="Where am I travelling?",
|
||||
user_id="alice"
|
||||
)
|
||||
```
|
||||
|
||||
#### List memories
|
||||
|
||||
List all memories for a `user_id`, `agent_id`, or `run_id`:
|
||||
|
||||
```python Python
|
||||
await memory.get_all(user_id="alice")
|
||||
```
|
||||
|
||||
#### Get specific memory
|
||||
|
||||
Retrieve a specific memory by its ID:
|
||||
|
||||
```python Python
|
||||
await memory.get(memory_id="memory-id-here")
|
||||
```
|
||||
|
||||
#### Update memory
|
||||
|
||||
Update an existing memory by ID:
|
||||
|
||||
```python Python
|
||||
await memory.update(
|
||||
memory_id="memory-id-here",
|
||||
data="I'm travelling to Seattle"
|
||||
)
|
||||
```
|
||||
|
||||
#### Delete memory
|
||||
|
||||
Delete a specific memory by ID:
|
||||
|
||||
```python Python
|
||||
await memory.delete(memory_id="memory-id-here")
|
||||
```
|
||||
|
||||
#### Delete all memories
|
||||
|
||||
Delete all memories for a specific user, agent, or run:
|
||||
|
||||
```python Python
|
||||
await memory.delete_all(user_id="alice")
|
||||
```
|
||||
|
||||
Note: At least one filter (user_id, agent_id, or run_id) is required when using delete_all.
|
||||
|
||||
#### Memory History
|
||||
|
||||
Get the history of changes for a specific memory:
|
||||
|
||||
```python Python
|
||||
await memory.history(memory_id="memory-id-here")
|
||||
```
|
||||
|
||||
### Example: Concurrent Usage with Other APIs
|
||||
|
||||
`AsyncMemory` can be effectively combined with other async operations. Here's an example showing how to use it alongside OpenAI API calls in separate threads:
|
||||
|
||||
```python Python
|
||||
import asyncio
|
||||
from openai import AsyncOpenAI
|
||||
from mem0 import AsyncMemory
|
||||
|
||||
async_openai_client = AsyncOpenAI()
|
||||
async_memory = AsyncMemory()
|
||||
|
||||
async def chat_with_memories(message: str, user_id: str = "default_user") -> str:
|
||||
# Retrieve relevant memories
|
||||
search_result = await async_memory.search(query=message, user_id=user_id, limit=3)
|
||||
relevant_memories = search_result["results"]
|
||||
memories_str = "\n".join(f"- {entry['memory']}" for entry in relevant_memories)
|
||||
|
||||
# Generate Assistant response
|
||||
system_prompt = f"You are a helpful AI. Answer the question based on query and memories.\nUser Memories:\n{memories_str}"
|
||||
messages = [{"role": "system", "content": system_prompt}, {"role": "user", "content": message}]
|
||||
response = await async_openai_client.chat.completions.create(model="gpt-4o-mini", messages=messages)
|
||||
assistant_response = response.choices[0].message.content
|
||||
|
||||
# Create new memories from the conversation
|
||||
messages.append({"role": "assistant", "content": assistant_response})
|
||||
await async_memory.add(messages, user_id=user_id)
|
||||
|
||||
return assistant_response
|
||||
|
||||
async def async_main():
|
||||
print("Chat with AI (type 'exit' to quit)")
|
||||
while True:
|
||||
user_input = input("You: ").strip()
|
||||
if user_input.lower() == 'exit':
|
||||
print("Goodbye!")
|
||||
break
|
||||
response = await chat_with_memories(user_input)
|
||||
print(f"AI: {response}")
|
||||
|
||||
def main():
|
||||
asyncio.run(async_main())
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
If you have any questions or need further assistance, please don't hesitate to reach out:
|
||||
|
||||
<Snippet file="get-help.mdx" />
|
||||
@@ -7,7 +7,7 @@ iconType: "solid"
|
||||
Mem0 provides a REST API server (written using FastAPI). Users can perform all operations through REST endpoints. The API also includes OpenAPI documentation, accessible at `/docs` when the server is running.
|
||||
|
||||
<Frame caption="APIs supported by Mem0 REST API Server">
|
||||
<img src="/images/rest-api-server.png" />
|
||||
<img src="/images/rest-api-server.png"/>
|
||||
</Frame>
|
||||
|
||||
## Features
|
||||
@@ -23,67 +23,90 @@ Mem0 provides a REST API server (written using FastAPI). Users can perform all o
|
||||
## Running Locally
|
||||
|
||||
<Tabs>
|
||||
<Tab title="With Docker">
|
||||
<Tab title="With Docker Compose">
|
||||
The Development Docker Compose comes pre-configured with postgres pgvector, neo4j and a `server/history/history.db` volume for the history database.
|
||||
|
||||
1. Create a `.env` file in the current directory and set your environment variables. For example:
|
||||
The only required environment variable to run the server is `OPENAI_API_KEY`.
|
||||
|
||||
```txt
|
||||
OPENAI_API_KEY=your-openai-api-key
|
||||
```
|
||||
1. Create a `.env` file in the `server/` directory and set your environment variables. For example:
|
||||
|
||||
2. Either pull the docker image from docker hub or build the docker image locally.
|
||||
```txt
|
||||
OPENAI_API_KEY=your-openai-api-key
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Pull from Docker Hub">
|
||||
2. Run the Docker container using Docker Compose:
|
||||
|
||||
```bash
|
||||
docker pull mem0/mem0-api-server
|
||||
```
|
||||
```bash
|
||||
cd server
|
||||
docker compose up
|
||||
```
|
||||
|
||||
</Tab>
|
||||
3. Access the API at http://localhost:8888.
|
||||
|
||||
<Tab title="Build Locally">
|
||||
4. Making changes to the server code or the library code will automatically reload the server.
|
||||
</Tab>
|
||||
|
||||
```bash
|
||||
docker build -t mem0-api-server .
|
||||
```
|
||||
<Tab title="With Docker">
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
1. Create a `.env` file in the current directory and set your environment variables. For example:
|
||||
|
||||
3. Run the Docker container:
|
||||
```txt
|
||||
OPENAI_API_KEY=your-openai-api-key
|
||||
```
|
||||
|
||||
``` bash
|
||||
docker run -p 8000:8000 mem0-api-server --env-file .env
|
||||
```
|
||||
2. Either pull the docker image from docker hub or build the docker image locally.
|
||||
|
||||
4. Access the API at http://localhost:8000.
|
||||
<Tabs>
|
||||
<Tab title="Pull from Docker Hub">
|
||||
|
||||
</Tab>
|
||||
```bash
|
||||
docker pull mem0/mem0-api-server
|
||||
```
|
||||
|
||||
<Tab title="Without Docker">
|
||||
</Tab>
|
||||
|
||||
1. Create a `.env` file in the current directory and set your environment variables. For example:
|
||||
<Tab title="Build Locally">
|
||||
|
||||
```txt
|
||||
OPENAI_API_KEY=your-openai-api-key
|
||||
```
|
||||
```bash
|
||||
docker build -t mem0-api-server .
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
3. Run the Docker container:
|
||||
|
||||
3. Start the FastAPI server:
|
||||
``` bash
|
||||
docker run -p 8000:8000 mem0-api-server --env-file .env
|
||||
```
|
||||
|
||||
```bash
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
4. Access the API at http://localhost:8000.
|
||||
|
||||
4. Access the API at http://localhost:8000.
|
||||
</Tab>
|
||||
|
||||
</Tab>
|
||||
<Tab title="Without Docker">
|
||||
|
||||
1. Create a `.env` file in the current directory and set your environment variables. For example:
|
||||
|
||||
```txt
|
||||
OPENAI_API_KEY=your-openai-api-key
|
||||
```
|
||||
|
||||
2. Install dependencies:
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
3. Start the FastAPI server:
|
||||
|
||||
```bash
|
||||
uvicorn main:app --reload
|
||||
```
|
||||
|
||||
4. Access the API at http://localhost:8000.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -16,23 +16,43 @@ Users can add a customized prompt that will be used to extract specific entities
|
||||
This allows for more targeted and relevant information extraction based on the user's needs.
|
||||
Here's an example of how to add a customized prompt:
|
||||
|
||||
```python
|
||||
from mem0 import Memory
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"graph_store": {
|
||||
"provider": "neo4j",
|
||||
"config": {
|
||||
"url": "neo4j+s://xxx",
|
||||
"username": "neo4j",
|
||||
"password": "xxx"
|
||||
},
|
||||
"custom_prompt": "Please only extract entities containing sports related relationships and nothing else.",
|
||||
config = {
|
||||
"graph_store": {
|
||||
"provider": "neo4j",
|
||||
"config": {
|
||||
"url": "neo4j+s://xxx",
|
||||
"username": "neo4j",
|
||||
"password": "xxx"
|
||||
},
|
||||
"custom_prompt": "Please only extract entities containing sports related relationships and nothing else.",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config_dict=config)
|
||||
```
|
||||
m = Memory.from_config(config_dict=config)
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from "mem0ai/oss";
|
||||
|
||||
const config = {
|
||||
graphStore: {
|
||||
provider: "neo4j",
|
||||
config: {
|
||||
url: "neo4j+s://xxx",
|
||||
username: "neo4j",
|
||||
password: "xxx",
|
||||
},
|
||||
customPrompt: "Please only extract entities containing sports related relationships and nothing else.",
|
||||
}
|
||||
}
|
||||
|
||||
const memory = new Memory(config);
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
If you want to use a managed version of Mem0, please check out [Mem0](https://mem0.dev/pd). If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
|
||||
@@ -9,14 +9,24 @@ Mem0 now supports **Graph Memory**.
|
||||
With Graph Memory, users can now create and utilize complex relationships between pieces of information, allowing for more nuanced and context-aware responses.
|
||||
This integration enables users to leverage the strengths of both vector-based and graph-based approaches, resulting in more accurate and comprehensive information retrieval and generation.
|
||||
|
||||
<Note>
|
||||
NodeSDK now supports Graph Memory. 🎉
|
||||
</Note>
|
||||
|
||||
## Installation
|
||||
|
||||
To use Mem0 with Graph Memory support, install it using pip:
|
||||
|
||||
```bash
|
||||
<CodeGroup>
|
||||
```bash Python
|
||||
pip install "mem0ai[graph]"
|
||||
```
|
||||
|
||||
```bash TypeScript
|
||||
npm install mem0ai
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
This command installs Mem0 along with the necessary dependencies for graph functionality.
|
||||
|
||||
Try Graph Memory on Google Colab.
|
||||
@@ -42,7 +52,6 @@ Currently, we support Neo4j as a graph store provider. You can setup [Neo4j](htt
|
||||
|
||||
<Note>If you are using Neo4j locally, then you need to install [APOC plugins](https://neo4j.com/labs/apoc/4.1/installation/).</Note>
|
||||
|
||||
|
||||
User can also customize the LLM for Graph Memory from the [Supported LLM list](https://docs.mem0.ai/components/llms/overview) with three levels of configuration:
|
||||
|
||||
1. **Main Configuration**: If `llm` is set in the main config, it will be used for all graph operations.
|
||||
@@ -53,7 +62,7 @@ Here's how you can do it:
|
||||
|
||||
|
||||
<CodeGroup>
|
||||
```python Basic
|
||||
```python Python
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
@@ -70,9 +79,25 @@ config = {
|
||||
m = Memory.from_config(config_dict=config)
|
||||
```
|
||||
|
||||
```python Advanced (Custom LLM)
|
||||
from mem0 import Memory
|
||||
```typescript TypeScript
|
||||
import { Memory } from "mem0ai/oss";
|
||||
|
||||
const config = {
|
||||
enableGraph: true,
|
||||
graphStore: {
|
||||
provider: "neo4j",
|
||||
config: {
|
||||
url: "neo4j+s://xxx",
|
||||
username: "neo4j",
|
||||
password: "xxx",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const memory = new Memory(config);
|
||||
```
|
||||
|
||||
```python Python (Advanced)
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
@@ -101,22 +126,61 @@ config = {
|
||||
|
||||
m = Memory.from_config(config_dict=config)
|
||||
```
|
||||
|
||||
```typescript TypeScript (Advanced)
|
||||
const config = {
|
||||
llm: {
|
||||
provider: "openai",
|
||||
config: {
|
||||
model: "gpt-4o",
|
||||
temperature: 0.2,
|
||||
max_tokens: 2000,
|
||||
}
|
||||
},
|
||||
enableGraph: true,
|
||||
graphStore: {
|
||||
provider: "neo4j",
|
||||
config: {
|
||||
url: "neo4j+s://xxx",
|
||||
username: "neo4j",
|
||||
password: "xxx",
|
||||
},
|
||||
llm: {
|
||||
provider: "openai",
|
||||
config: {
|
||||
model: "gpt-4o-mini",
|
||||
temperature: 0.0,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const memory = new Memory(config);
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
<Note>
|
||||
If you are using NodeSDK, you need to pass `enableGraph` as `true` in the `config` object.
|
||||
</Note>
|
||||
|
||||
## Graph Operations
|
||||
The Mem0's graph supports the following operations:
|
||||
|
||||
### Add Memories
|
||||
|
||||
<Note>
|
||||
If you are using Mem0 with Graph Memory, it is recommended to pass `user_id`. The default value of `user_id` (in case of graph memory) is `user`.
|
||||
If you are using Mem0 with Graph Memory, it is recommended to pass `user_id`. Use `userId` in NodeSDK.
|
||||
</Note>
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
```python Python
|
||||
m.add("I like pizza", user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.add("I like pizza", { userId: "alice" });
|
||||
```
|
||||
|
||||
```json Output
|
||||
{'message': 'ok'}
|
||||
```
|
||||
@@ -126,10 +190,14 @@ m.add("I like pizza", user_id="alice")
|
||||
### Get all memories
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
```python Python
|
||||
m.get_all(user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.getAll({ userId: "alice" });
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
'memories': [
|
||||
@@ -157,10 +225,14 @@ m.get_all(user_id="alice")
|
||||
### Search Memories
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
```python Python
|
||||
m.search("tell me my name.", user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.search("tell me my name.", { userId: "alice" });
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
'memories': [
|
||||
@@ -187,10 +259,16 @@ m.search("tell me my name.", user_id="alice")
|
||||
|
||||
|
||||
### Delete all Memories
|
||||
```python
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
m.delete_all(user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.deleteAll({ userId: "alice" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
# Example Usage
|
||||
Here's an example of how to use Mem0's graph operations:
|
||||
@@ -206,64 +284,110 @@ Below are the steps to add memories and visualize the graph:
|
||||
<Steps>
|
||||
<Step title="Add memory 'I like going to hikes'">
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
m.add("I like going to hikes", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.add("I like going to hikes", { userId: "alice123" });
|
||||
```
|
||||
</CodeGroup>
|
||||

|
||||
|
||||
</Step>
|
||||
<Step title="Add memory 'I love to play badminton'">
|
||||
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
m.add("I love to play badminton", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.add("I love to play badminton", { userId: "alice123" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Add memory 'I hate playing badminton'">
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
m.add("I hate playing badminton", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.add("I hate playing badminton", { userId: "alice123" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Add memory 'My friend name is john and john has a dog named tommy'">
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
m.add("My friend name is john and john has a dog named tommy", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.add("My friend name is john and john has a dog named tommy", { userId: "alice123" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Add memory 'My name is Alice'">
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
m.add("My name is Alice", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.add("My name is Alice", { userId: "alice123" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Add memory 'John loves to hike and Harry loves to hike as well'">
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
m.add("John loves to hike and Harry loves to hike as well", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.add("John loves to hike and Harry loves to hike as well", { userId: "alice123" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Add memory 'My friend peter is the spiderman'">
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
m.add("My friend peter is the spiderman", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.add("My friend peter is the spiderman", { userId: "alice123" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||

|
||||
|
||||
</Step>
|
||||
@@ -274,10 +398,14 @@ m.add("My friend peter is the spiderman", user_id="alice123")
|
||||
### Search Memories
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
```python Python
|
||||
m.search("What is my name?", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.search("What is my name?", { userId: "alice123" });
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
'memories': [...],
|
||||
@@ -297,10 +425,14 @@ Below graph visualization shows what nodes and relationships are fetched from th
|
||||

|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
```python Python
|
||||
m.search("Who is spiderman?", user_id="alice123")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
memory.search("Who is spiderman?", { userId: "alice123" });
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
'memories': [...],
|
||||
|
||||
@@ -10,11 +10,25 @@ Mem0 extends its capabilities beyond text by supporting multimodal data, includi
|
||||
|
||||
When a user provides an image, Mem0 processes the image to extract textual information and relevant details, which are then added to the user's memory. This feature enhances the system's ability to understand and remember details based on visual inputs.
|
||||
|
||||
<Note>
|
||||
To enable multimodal support, you must set `enable_vision = True` in your configuration. The `vision_details` parameter can be set to "auto" (default), "low", or "high" to control the level of detail in image processing.
|
||||
</Note>
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
from mem0 import Memory
|
||||
|
||||
client = Memory()
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"enable_vision": True,
|
||||
"vision_details": "high"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
client = Memory.from_config(config=config)
|
||||
|
||||
messages = [
|
||||
{
|
||||
@@ -40,6 +54,34 @@ messages = [
|
||||
client.add(messages, user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory, Message } from "mem0ai/oss";
|
||||
|
||||
const client = new Memory();
|
||||
|
||||
const messages: Message[] = [
|
||||
{
|
||||
role: "user",
|
||||
content: "Hi, my name is Alice."
|
||||
},
|
||||
{
|
||||
role: "assistant",
|
||||
content: "Nice to meet you, Alice! What do you like to eat?"
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: {
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
|
||||
}
|
||||
}
|
||||
},
|
||||
]
|
||||
|
||||
await client.add(messages, { userId: "alice" })
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
@@ -66,6 +108,7 @@ Mem0 allows you to add images to user interactions through two primary methods:
|
||||
|
||||
You can include an image by passing its direct URL. This method is simple and efficient for online images.
|
||||
|
||||
<CodeGroup>
|
||||
```python
|
||||
# Define the image URL
|
||||
image_url = "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg"
|
||||
@@ -82,11 +125,33 @@ image_message = {
|
||||
}
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory, Message } from "mem0ai/oss";
|
||||
|
||||
const client = new Memory();
|
||||
|
||||
const imageUrl = "https://www.superhealthykids.com/wp-content/uploads/2021/10/best-veggie-pizza-featured-image-square-2.jpg";
|
||||
|
||||
const imageMessage: Message = {
|
||||
role: "user",
|
||||
content: {
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: imageUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await client.add([imageMessage], { userId: "alice" })
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## 2. Using Base64 Image Encoding for Local Files
|
||||
|
||||
For local images or scenarios where embedding the image directly is preferable, you can use a Base64-encoded string.
|
||||
|
||||
```python
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import base64
|
||||
|
||||
# Path to the image file
|
||||
@@ -108,11 +173,95 @@ image_message = {
|
||||
}
|
||||
```
|
||||
|
||||
By utilizing these methods, you can effectively incorporate images into user interactions, enhancing the multimodal capabilities of your Mem0 instance.
|
||||
```typescript TypeScript
|
||||
import { Memory, Message } from "mem0ai/oss";
|
||||
|
||||
<Note>
|
||||
Currently, we support only OpenAI models for image description.
|
||||
</Note>
|
||||
const client = new Memory();
|
||||
|
||||
const imagePath = "path/to/your/image.jpg";
|
||||
|
||||
const base64Image = fs.readFileSync(imagePath, { encoding: 'base64' });
|
||||
|
||||
const imageMessage: Message = {
|
||||
role: "user",
|
||||
content: {
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: `data:image/jpeg;base64,${base64Image}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
await client.add([imageMessage], { userId: "alice" })
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## 3. OpenAI-Compatible Message Format
|
||||
|
||||
You can also use the OpenAI-compatible format to combine text and images in a single message:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import base64
|
||||
|
||||
# Path to the image file
|
||||
image_path = "path/to/your/image.jpg"
|
||||
|
||||
# Encode the image in Base64
|
||||
with open(image_path, "rb") as image_file:
|
||||
base64_image = base64.b64encode(image_file.read()).decode("utf-8")
|
||||
|
||||
# Create the message using OpenAI-compatible format
|
||||
message = {
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "text",
|
||||
"text": "What is in this image?",
|
||||
},
|
||||
{
|
||||
"type": "image_url",
|
||||
"image_url": {"url": f"data:image/jpeg;base64,{base64_image}"},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
# Add the message to memory
|
||||
client.add([message], user_id="alice")
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory, Message } from "mem0ai/oss";
|
||||
|
||||
const client = new Memory();
|
||||
|
||||
const imagePath = "path/to/your/image.jpg";
|
||||
|
||||
const base64Image = fs.readFileSync(imagePath, { encoding: 'base64' });
|
||||
|
||||
const message: Message = {
|
||||
role: "user",
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: "What is in this image?",
|
||||
},
|
||||
{
|
||||
type: "image_url",
|
||||
image_url: {
|
||||
url: `data:image/jpeg;base64,${base64Image}`
|
||||
}
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
await client.add([message], { userId: "alice" })
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
This format allows you to combine text and images in a single message, making it easier to provide context along with visual content.
|
||||
|
||||
By utilizing these methods, you can effectively incorporate images into user interactions, enhancing the multimodal capabilities of your Mem0 instance.
|
||||
|
||||
If you have any questions, please feel free to reach out to us using one of the following methods:
|
||||
|
||||
|
||||
@@ -74,14 +74,14 @@ const messages = [
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
|
||||
await memory.add(messages, { userId: "user123", metadata: { category: "movie_recommendations" } });
|
||||
await memory.add(messages, { userId: "alice", metadata: { category: "movie_recommendations" } });
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "c03c9045-df76-4949-bbc5-d5dc1932aa5c",
|
||||
"id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
@@ -111,7 +111,7 @@ await memory.add(messages, { userId: "user123", metadata: { category: "movie_rec
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
// Get all memories
|
||||
const allMemories = await memory.getAll({ userId: "user123" });
|
||||
const allMemories = await memory.getAll({ userId: "alice" });
|
||||
console.log(allMemories)
|
||||
```
|
||||
|
||||
@@ -127,7 +127,7 @@ console.log(allMemories)
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
"userId": "alice"
|
||||
},
|
||||
{
|
||||
"id": "475bde34-21e6-42ab-8bef-0ab84474f156",
|
||||
@@ -138,7 +138,7 @@ console.log(allMemories)
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
"userId": "alice"
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
@@ -149,7 +149,7 @@ console.log(allMemories)
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
"userId": "alice"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -176,7 +176,7 @@ console.log(singleMemory);
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
"userId": "alice"
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -185,7 +185,7 @@ console.log(singleMemory);
|
||||
|
||||
<CodeGroup>
|
||||
```typescript Code
|
||||
const result = await memory.search('What do you know about me?', { userId: "user123" });
|
||||
const result = await memory.search('What do you know about me?', { userId: "alice" });
|
||||
console.log(result);
|
||||
```
|
||||
|
||||
@@ -202,7 +202,7 @@ console.log(result);
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
"userId": "alice"
|
||||
},
|
||||
{
|
||||
"id": "475bde34-21e6-42ab-8bef-0ab84474f156",
|
||||
@@ -214,7 +214,7 @@ console.log(result);
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
"userId": "alice"
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
@@ -226,7 +226,7 @@ console.log(result);
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"userId": "user123"
|
||||
"userId": "alice"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -263,23 +263,23 @@ console.log(history);
|
||||
[
|
||||
{
|
||||
"id": 39,
|
||||
"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.",
|
||||
"memoryId": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"previousValue": "User is planning to watch a movie tonight.",
|
||||
"newValue": "I love India, it is my favorite country.",
|
||||
"action": "UPDATE",
|
||||
"created_at": "2025-02-27T16:33:20.557Z",
|
||||
"updated_at": "2025-02-27T16:33:27.051Z",
|
||||
"is_deleted": 0
|
||||
"createdAt": "2025-02-27T16:33:20.557Z",
|
||||
"updatedAt": "2025-02-27T16:33:27.051Z",
|
||||
"isDeleted": 0
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"memory_id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"previous_value": null,
|
||||
"new_value": "User is planning to watch a movie tonight.",
|
||||
"memoryId": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"previousValue": null,
|
||||
"newValue": "User is planning to watch a movie tonight.",
|
||||
"action": "ADD",
|
||||
"created_at": "2025-02-27T16:33:20.557Z",
|
||||
"updated_at": null,
|
||||
"is_deleted": 0
|
||||
"createdAt": "2025-02-27T16:33:20.557Z",
|
||||
"updatedAt": null,
|
||||
"isDeleted": 0
|
||||
}
|
||||
]
|
||||
```
|
||||
@@ -292,7 +292,7 @@ console.log(history);
|
||||
await memory.delete('892db2ae-06d9-49e5-8b3e-585ef9b85b8e');
|
||||
|
||||
// Delete all memories for a user
|
||||
await memory.deleteAll({ userId: "user123" });
|
||||
await memory.deleteAll({ userId: "alice" });
|
||||
```
|
||||
|
||||
### Reset Memory
|
||||
@@ -301,6 +301,56 @@ await memory.deleteAll({ userId: "user123" });
|
||||
await memory.reset(); // Reset all memories
|
||||
```
|
||||
|
||||
### History Store
|
||||
|
||||
Mem0 TypeScript SDK support history stores to run on a serverless environment:
|
||||
|
||||
We recommend using `Supabase` as a history store for serverless environments or disable history store to run on a serverless environment.
|
||||
|
||||
<CodeGroup>
|
||||
```typescript Supabase
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const memory = new Memory({
|
||||
historyStore: {
|
||||
provider: 'supabase',
|
||||
config: {
|
||||
supabaseUrl: process.env.SUPABASE_URL || '',
|
||||
supabaseKey: process.env.SUPABASE_KEY || '',
|
||||
tableName: 'memory_history',
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
```typescript Disable History
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const memory = new Memory({
|
||||
disableHistory: true,
|
||||
});
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
Mem0 uses SQLite as a default history store.
|
||||
|
||||
#### Create Memory History Table in Supabase
|
||||
|
||||
You may need to create a memory history table in Supabase to store the history of memories. Use the following SQL command in `SQL Editor` on the Supabase project dashboard to create a memory history table:
|
||||
|
||||
```sql
|
||||
create table memory_history (
|
||||
id text primary key,
|
||||
memory_id text not null,
|
||||
previous_value text,
|
||||
new_value text,
|
||||
action text not null,
|
||||
created_at timestamp with time zone default timezone('utc', now()),
|
||||
updated_at timestamp with time zone,
|
||||
is_deleted integer default 0
|
||||
);
|
||||
```
|
||||
|
||||
## Configuration Parameters
|
||||
|
||||
Mem0 offers extensive configuration options to customize its behavior according to your needs. These configurations span across different components like vector stores, language models, embedders, and graph stores.
|
||||
@@ -327,6 +377,15 @@ Mem0 offers extensive configuration options to customize its behavior according
|
||||
| `openaiBaseUrl` | Base URL for OpenAI API | OpenAI |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Graph Store Configuration">
|
||||
| Parameter | Description | Default |
|
||||
|-------------|---------------------------------|-------------|
|
||||
| `provider` | Graph store provider (e.g., "neo4j") | "neo4j" |
|
||||
| `url` | Connection URL | env.NEO4J_URL |
|
||||
| `username` | Authentication username | env.NEO4J_USERNAME |
|
||||
| `password` | Authentication password | env.NEO4J_PASSWORD |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Embedder Configuration">
|
||||
| Parameter | Description | Default |
|
||||
|-------------|---------------------------------|------------------------------|
|
||||
@@ -343,6 +402,14 @@ Mem0 offers extensive configuration options to customize its behavior according
|
||||
| `customPrompt` | Custom prompt for memory processing | None |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="History Table Configuration">
|
||||
| Parameter | Description | Default |
|
||||
|------------------|--------------------------------------|----------------------------|
|
||||
| `provider` | History store provider | "sqlite" |
|
||||
| `config` | History store configuration | None (Defaults to SQLite) |
|
||||
| `disableHistory` | Disable history store | false |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Complete Configuration Example">
|
||||
```typescript
|
||||
const config = {
|
||||
@@ -368,7 +435,15 @@ const config = {
|
||||
model: 'gpt-4-turbo-preview',
|
||||
},
|
||||
},
|
||||
historyDbPath: 'memory.db',
|
||||
historyStore: {
|
||||
provider: 'supabase',
|
||||
config: {
|
||||
supabaseUrl: process.env.SUPABASE_URL || '',
|
||||
supabaseKey: process.env.SUPABASE_KEY || '',
|
||||
tableName: 'memories',
|
||||
},
|
||||
},
|
||||
disableHistory: false, // This is false by default
|
||||
customPrompt: "I'm a virtual assistant. I'm here to help you with your queries.",
|
||||
}
|
||||
```
|
||||
|
||||
@@ -22,8 +22,22 @@ pip install mem0ai
|
||||
<Tabs>
|
||||
<Tab title="Basic">
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
m = Memory()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Async">
|
||||
```python
|
||||
import os
|
||||
from mem0 import AsyncMemory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
m = AsyncMemory()
|
||||
```
|
||||
</Tab>
|
||||
<Tab title="Advanced">
|
||||
@@ -42,8 +56,11 @@ docker run -p 6333:6333 -p 6334:6334 \
|
||||
Then, instantiate memory with qdrant server:
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "qdrant",
|
||||
@@ -61,8 +78,11 @@ m = Memory.from_config(config)
|
||||
<Tab title="Advanced (Graph Memory)">
|
||||
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
config = {
|
||||
"graph_store": {
|
||||
"provider": "neo4j",
|
||||
@@ -85,20 +105,47 @@ m = Memory.from_config(config_dict=config)
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
# For a user
|
||||
result = 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."}
|
||||
]
|
||||
|
||||
# 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."}
|
||||
# ]
|
||||
# client.add(messages, user_id="alice")
|
||||
# Store inferred memories (default behavior)
|
||||
result = m.add(messages, user_id="alice", metadata={"category": "movie_recommendations"})
|
||||
|
||||
# Store raw messages without inference
|
||||
# result = m.add(messages, user_id="alice", metadata={"category": "movie_recommendations"}, infer=False)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{"id": "bf4d4092-cf91-4181-bfeb-b6fa2ed3061b", "memory": "Likes to play cricket on weekends", "event": "ADD"}
|
||||
{
|
||||
"id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
"memory": "User is not a big fan of thriller movies.",
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"id": "475bde34-21e6-42ab-8bef-0ab84474f156",
|
||||
"memory": "User loves sci-fi movies.",
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"event": "ADD"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
@@ -115,14 +162,38 @@ all_memories = m.get_all(user_id="alice")
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"hash": "1a271c007316c94377175ee80e746a19",
|
||||
"created_at": "2025-02-27T16:33:20.557Z",
|
||||
"updated_at": "2025-02-27T16:33:27.051Z",
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"user_id": "alice"
|
||||
},
|
||||
{
|
||||
"id": "bf4d4092-cf91-4181-bfeb-b6fa2ed3061b",
|
||||
"memory": "Likes to play cricket on weekends",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"metadata": {"category": "hobbies"},
|
||||
"created_at": "2024-10-28T12:32:07.744891-07:00",
|
||||
"updated_at": None,
|
||||
"user_id": "alice"
|
||||
"id": "475bde34-21e6-42ab-8bef-0ab84474f156",
|
||||
"memory": "User loves sci-fi movies.",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"created_at": "2025-02-27T16:33:20.560Z",
|
||||
"updated_at": None,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"user_id": "alice"
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
"memory": "User is not a big fan of thriller movies.",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"created_at": "2025-02-27T16:33:20.560Z",
|
||||
"updated_at": None,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"user_id": "alice"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -135,18 +206,20 @@ all_memories = m.get_all(user_id="alice")
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
# Get a single memory by ID
|
||||
specific_memory = m.get("bf4d4092-cf91-4181-bfeb-b6fa2ed3061b")
|
||||
specific_memory = m.get("892db2ae-06d9-49e5-8b3e-585ef9b85b8e")
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"id": "bf4d4092-cf91-4181-bfeb-b6fa2ed3061b",
|
||||
"memory": "Likes to play cricket on weekends",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"metadata": {"category": "hobbies"},
|
||||
"created_at": "2024-10-28T12:32:07.744891-07:00",
|
||||
"updated_at": None,
|
||||
"user_id": "alice"
|
||||
"id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"hash": "1a271c007316c94377175ee80e746a19",
|
||||
"created_at": "2025-02-27T16:33:20.557Z",
|
||||
"updated_at": None,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"user_id": "alice"
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -155,23 +228,49 @@ specific_memory = m.get("bf4d4092-cf91-4181-bfeb-b6fa2ed3061b")
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
related_memories = m.search(query="What are Alice's hobbies?", user_id="alice")
|
||||
related_memories = m.search(query="What do you know about me?", user_id="alice")
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "bf4d4092-cf91-4181-bfeb-b6fa2ed3061b",
|
||||
"memory": "Likes to play cricket on weekends",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"metadata": {"category": "hobbies"},
|
||||
"score": 0.30808347,
|
||||
"created_at": "2024-10-28T12:32:07.744891-07:00",
|
||||
"updated_at": None,
|
||||
"user_id": "alice"
|
||||
}
|
||||
]
|
||||
"results": [
|
||||
{
|
||||
"id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"memory": "User is planning to watch a movie tonight.",
|
||||
"hash": "1a271c007316c94377175ee80e746a19",
|
||||
"created_at": "2025-02-27T16:33:20.557Z",
|
||||
"updated_at": None,
|
||||
"score": 0.38920719231944799,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"user_id": "alice"
|
||||
},
|
||||
{
|
||||
"id": "475bde34-21e6-42ab-8bef-0ab84474f156",
|
||||
"memory": "User loves sci-fi movies.",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"created_at": "2025-02-27T16:33:20.560Z",
|
||||
"updated_at": None,
|
||||
"score": 0.36869761478135689,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"user_id": "alice"
|
||||
},
|
||||
{
|
||||
"id": "cbb1fe73-0bf1-4067-8c1f-63aa53e7b1a4",
|
||||
"memory": "User is not a big fan of thriller movies.",
|
||||
"hash": "285d07801ae42054732314853e9eadd7",
|
||||
"created_at": "2025-02-27T16:33:20.560Z",
|
||||
"updated_at": None,
|
||||
"score": 0.33855272141248272,
|
||||
"metadata": {
|
||||
"category": "movie_recommendations"
|
||||
},
|
||||
"user_id": "alice"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -180,7 +279,7 @@ related_memories = m.search(query="What are Alice's hobbies?", user_id="alice")
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
result = m.update(memory_id="bf4d4092-cf91-4181-bfeb-b6fa2ed3061b", data="Likes to play tennis on weekends")
|
||||
result = m.update(memory_id="892db2ae-06d9-49e5-8b3e-585ef9b85b8e", data="I love India, it is my favorite country.")
|
||||
```
|
||||
|
||||
```json Output
|
||||
@@ -192,29 +291,31 @@ result = m.update(memory_id="bf4d4092-cf91-4181-bfeb-b6fa2ed3061b", data="Likes
|
||||
|
||||
<CodeGroup>
|
||||
```python Code
|
||||
history = m.history(memory_id="bf4d4092-cf91-4181-bfeb-b6fa2ed3061b")
|
||||
history = m.history(memory_id="892db2ae-06d9-49e5-8b3e-585ef9b85b8e")
|
||||
```
|
||||
|
||||
```json Output
|
||||
[
|
||||
{
|
||||
"id": "96d2821d-e551-4089-aa57-9398c421d450",
|
||||
"memory_id": "bf4d4092-cf91-4181-bfeb-b6fa2ed3061b",
|
||||
"old_memory": None,
|
||||
"new_memory": "Likes to play cricket on weekends",
|
||||
"event": "ADD",
|
||||
"created_at": "2024-10-28T12:32:07.744891-07:00",
|
||||
"updated_at": None
|
||||
},
|
||||
{
|
||||
"id": "3db4cb58-c0f1-4dd0-b62a-8123068ebfe7",
|
||||
"memory_id": "bf4d4092-cf91-4181-bfeb-b6fa2ed3061b",
|
||||
"old_memory": "Likes to play cricket on weekends",
|
||||
"new_memory": "Likes to play tennis on weekends",
|
||||
"event": "UPDATE",
|
||||
"created_at": "2024-10-28T12:32:07.744891-07:00",
|
||||
"updated_at": "2024-10-28T13:05:46.987978-07:00"
|
||||
}
|
||||
{
|
||||
"id": 39,
|
||||
"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:33:20.557Z",
|
||||
"updated_at": "2025-02-27T16:33:27.051Z",
|
||||
"is_deleted": 0
|
||||
},
|
||||
{
|
||||
"id": 37,
|
||||
"memory_id": "892db2ae-06d9-49e5-8b3e-585ef9b85b8e",
|
||||
"previous_value": null,
|
||||
"new_value": "User is planning to watch a movie tonight.",
|
||||
"action": "ADD",
|
||||
"created_at": "2025-02-27T16:33:20.557Z",
|
||||
"updated_at": null,
|
||||
"is_deleted": 0
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -223,7 +324,7 @@ history = m.history(memory_id="bf4d4092-cf91-4181-bfeb-b6fa2ed3061b")
|
||||
|
||||
```python
|
||||
# Delete a memory by id
|
||||
m.delete(memory_id="bf4d4092-cf91-4181-bfeb-b6fa2ed3061b")
|
||||
m.delete(memory_id="892db2ae-06d9-49e5-8b3e-585ef9b85b8e")
|
||||
# Delete all memories for a user
|
||||
m.delete_all(user_id="alice")
|
||||
```
|
||||
@@ -291,7 +392,8 @@ Mem0 offers extensive configuration options to customize its behavior according
|
||||
|------------------|--------------------------------------|----------------------------|
|
||||
| `history_db_path` | Path to the history database | "{mem0_dir}/history.db" |
|
||||
| `version` | API version | "v1.1" |
|
||||
| `custom_prompt` | Custom prompt for memory processing | None |
|
||||
| `custom_fact_extraction_prompt` | Custom prompt for memory processing | None |
|
||||
| `custom_update_memory_prompt` | Custom prompt for update memory | None |
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Complete Configuration Example">
|
||||
@@ -328,7 +430,8 @@ config = {
|
||||
},
|
||||
"history_db_path": "/path/to/history.db",
|
||||
"version": "v1.1",
|
||||
"custom_prompt": "Optional custom prompt for memory processing"
|
||||
"custom_fact_extraction_prompt": "Optional custom prompt for fact extraction for memory",
|
||||
"custom_update_memory_prompt": "Optional custom prompt for update memory"
|
||||
}
|
||||
```
|
||||
</Accordion>
|
||||
|
||||
@@ -379,7 +379,118 @@
|
||||
}
|
||||
},
|
||||
"/v1/exports/": {
|
||||
"get": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"exports"
|
||||
],
|
||||
"summary": "Create an export job with schema",
|
||||
"description": "Create a structured export of memories based on a provided schema.",
|
||||
"operationId": "exports_create",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["schema"],
|
||||
"properties": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"description": "Schema definition for the export"
|
||||
},
|
||||
"filters": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_id": {"type": "string"},
|
||||
"agent_id": {"type": "string"},
|
||||
"app_id": {"type": "string"},
|
||||
"run_id": {"type": "string"}
|
||||
},
|
||||
"description": "Filters to apply while exporting memories. Available fields are: user_id, agent_id, app_id, run_id."
|
||||
},
|
||||
"org_id": {
|
||||
"type": "string",
|
||||
"description": "Filter exports by organization ID"
|
||||
},
|
||||
"project_id": {
|
||||
"type": "string",
|
||||
"description": "Filter exports by project ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Export created successfully",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Memory export request received. The export will be ready in a few seconds."
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"example": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
},
|
||||
"required": ["message", "id"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Schema is required and must be a valid object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-code-samples": [
|
||||
{
|
||||
"lang": "Python",
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\njson_schema = {pydantic_json_schema}\nfilters = {\n \"AND\": [\n {\"user_id\": \"alex\"}\n ]\n}\n\nresponse = client.create_memory_export(\n schema=json_schema,\n filters=filters\n)\nprint(response)"
|
||||
},
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst jsonSchema = {pydantic_json_schema};\nconst filters = {\n AND: [\n {user_id: 'alex'}\n ]\n};\n\nclient.createMemoryExport({\n schema: jsonSchema,\n filters: filters\n})\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
"source": "curl --request POST \\\n --url 'https://api.mem0.ai/v1/exports/' \\\n --header 'Authorization: Token <api-key>' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"schema\": {pydantic_json_schema},\n \"filters\": {\n \"AND\": [\n {\"user_id\": \"alex\"}\n ]\n }\n }'"
|
||||
},
|
||||
{
|
||||
"lang": "Go",
|
||||
"source": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\turl := \"https://api.mem0.ai/v1/exports/\"\n\n\tfilters := map[string]interface{}{\n\t\t\"AND\": []map[string]interface{}{\n\t\t\t{\"user_id\": \"alex\"},\n\t\t},\n\t}\n\n\tdata := map[string]interface{}{\n\t\t\"schema\": map[string]interface{}{}, // Your schema here\n\t\t\"filters\": filters,\n\t}\n\n\tjsonData, _ := json.Marshal(data)\n\n\treq, _ := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\treq.Header.Add(\"Content-Type\", \"application/json\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(string(body))\n}"
|
||||
},
|
||||
{
|
||||
"lang": "PHP",
|
||||
"source": "<?php\n\n$curl = curl_init();\n\n$filters = [\n 'AND' => [\n ['user_id' => 'alex']\n ]\n];\n\n$data = array(\n \"schema\" => array(), // Your schema here\n \"filters\" => $filters\n);\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/v1/exports/\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"POST\",\n CURLOPT_POSTFIELDS => json_encode($data),\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\",\n \"Content-Type: application/json\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
|
||||
},
|
||||
{
|
||||
"lang": "Java",
|
||||
"source": "import com.mashape.unirest.http.HttpResponse;\nimport com.mashape.unirest.http.JsonNode;\nimport com.mashape.unirest.http.Unirest;\nimport org.json.JSONObject;\nimport org.json.JSONArray;\n\nJSONObject filters = new JSONObject()\n .put(\"AND\", new JSONArray()\n .put(new JSONObject().put(\"user_id\", \"alex\")));\n\nJSONObject data = new JSONObject()\n .put(\"schema\", new JSONObject()) // Your schema here\n .put(\"filters\", filters);\n\nHttpResponse<JsonNode> response = Unirest.post(\"https://api.mem0.ai/v1/exports/\")\n .header(\"Authorization\", \"Token <api-key>\")\n .header(\"Content-Type\", \"application/json\")\n .body(data.toString())\n .asJson();"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/exports/get": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"exports"
|
||||
],
|
||||
@@ -388,36 +499,20 @@
|
||||
"operationId": "exports_list",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "user_id",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Filter exports by user ID"
|
||||
},
|
||||
{
|
||||
"name": "run_id",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Filter exports by run ID"
|
||||
},
|
||||
{
|
||||
"name": "session_id",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Filter exports by session ID"
|
||||
},
|
||||
{
|
||||
"name": "app_id",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "string"
|
||||
},
|
||||
"description": "Filter exports by app ID"
|
||||
"name": "filters",
|
||||
"in": "query",
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"user_id": {"type": "string"},
|
||||
"agent_id": {"type": "string"},
|
||||
"app_id": {"type": "string"},
|
||||
"run_id": {"type": "string"},
|
||||
"created_at": {"type": "string"},
|
||||
"updated_at": {"type": "string"}
|
||||
},
|
||||
"description": "Filters to apply while exporting memories. Available fields are: user_id, agent_id, app_id, run_id, created_at, updated_at."
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "org_id",
|
||||
@@ -484,145 +579,30 @@
|
||||
"x-code-samples": [
|
||||
{
|
||||
"lang": "Python",
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"project_id\")\n\nresponse = client.get_memory_export(user_id=\"your_user_id\")\nprint(response)"
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"project_id\")\n\nfilters = {\n \"AND\": [\n {\"created_at\": {\"gte\": \"2024-07-10\", \"lte\": \"2024-07-20\"}},\n {\"user_id\": \"alex\"}\n ]\n}\n\nresponse = client.get_memory_export(filters=filters)\nprint(response)"
|
||||
},
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\n// Get memory export\nclient.getMemoryExport({ user_id: \"your_user_id\" })\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
"lang": "JavaScript",
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst filters = {\n AND: [\n {created_at: {gte: \"2024-07-10\", lte: \"2024-07-20\"}},\n {user_id: \"alex\"}\n ]\n};\n\n// Get memory export\nclient.getMemoryExport({ filters })\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
"source": "curl --request GET \\\n --url 'https://api.mem0.ai/v1/exports/?user_id=your_user_id' \\\n --header 'Authorization: Token <api-key>'"
|
||||
"source": "curl --request GET \\\n --url 'https://api.mem0.ai/v1/exports/?filters={\"AND\":[{\"created_at\":{\"gte\":\"2024-07-10\",\"lte\":\"2024-07-20\"}},{\"user_id\":\"alex\"}]}' \\\n --header 'Authorization: Token <api-key>'"
|
||||
},
|
||||
{
|
||||
"lang": "Go",
|
||||
"source": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\turl := \"https://api.mem0.ai/v1/exports/?user_id=your_user_id\"\n\n\treq, _ := http.NewRequest(\"GET\", url, nil)\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(string(body))\n}"
|
||||
"source": "package main\n\nimport (\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\tfilters := `{\"AND\":[{\"created_at\":{\"gte\":\"2024-07-10\",\"lte\":\"2024-07-20\"}},{\"user_id\":\"alex\"}]}`\n\turl := fmt.Sprintf(\"https://api.mem0.ai/v1/exports/?filters=%s\", filters)\n\n\treq, _ := http.NewRequest(\"GET\", url, nil)\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(string(body))\n}"
|
||||
},
|
||||
{
|
||||
"lang": "PHP",
|
||||
"source": "<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/v1/exports/?user_id=your_user_id\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"GET\",\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
|
||||
"source": "<?php\n\n$curl = curl_init();\n\n$filters = urlencode('{\"AND\":[{\"created_at\":{\"gte\":\"2024-07-10\",\"lte\":\"2024-07-20\"}},{\"user_id\":\"alex\"}]}');\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/v1/exports/?filters=\" . $filters,\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"GET\",\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
|
||||
},
|
||||
{
|
||||
"lang": "Java",
|
||||
"source": "HttpResponse<String> response = Unirest.get(\"https://api.mem0.ai/v1/exports/?user_id=your_user_id\")\n .header(\"Authorization\", \"Token <api-key>\")\n .asString();"
|
||||
"source": "String filters = \"{\\\"AND\\\":[{\\\"created_at\\\":{\\\"gte\\\":\\\"2024-07-10\\\",\\\"lte\\\":\\\"2024-07-20\\\"}},{\\\"user_id\\\":\\\"alex\\\"}]}\";\n\nHttpResponse<String> response = Unirest.get(\"https://api.mem0.ai/v1/exports/?filters=\" + filters)\n .header(\"Authorization\", \"Token <api-key>\")\n .asString();"
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"tags": [
|
||||
"exports"
|
||||
],
|
||||
"summary": "Create an export job with schema",
|
||||
"description": "Create a structured export of memories based on a provided schema.",
|
||||
"operationId": "exports_create",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"required": ["schema"],
|
||||
"properties": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"description": "Schema definition for the export"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "string",
|
||||
"description": "Filter exports by user ID"
|
||||
},
|
||||
"run_id": {
|
||||
"type": "string",
|
||||
"description": "Filter exports by run ID"
|
||||
},
|
||||
"session_id": {
|
||||
"type": "string",
|
||||
"description": "Filter exports by session ID"
|
||||
},
|
||||
"app_id": {
|
||||
"type": "string",
|
||||
"description": "Filter exports by app ID"
|
||||
},
|
||||
"org_id": {
|
||||
"type": "string",
|
||||
"description": "Filter exports by organization ID"
|
||||
},
|
||||
"project_id": {
|
||||
"type": "string",
|
||||
"description": "Filter exports by project ID"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Export created successfully",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Memory export request received. The export will be ready in a few seconds."
|
||||
},
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"example": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
},
|
||||
"required": ["message", "id"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Schema is required and must be a valid object"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"x-code-samples": [
|
||||
{
|
||||
"lang": "Python",
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\njson_schema = {pydantic_json_schema}\n\nresponse = client.create_memory_export(\n schema=json_schema,\n user_id=\"your_user_id\"\n)\nprint(response)"
|
||||
},
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst jsonSchema = {pydantic_json_schema};\n\nclient.createMemoryExport({\n schema: jsonSchema,\n user_id: \"your_user_id\"\n})\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
"source": "curl --request POST \\\n --url 'https://api.mem0.ai/v1/exports/' \\\n --header 'Authorization: Token <api-key>' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"schema\": {pydantic_json_schema},\n \"user_id\": \"your_user_id\"\n }'"
|
||||
},
|
||||
{
|
||||
"lang": "Go",
|
||||
"source": "package main\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\turl := \"https://api.mem0.ai/v1/exports/\"\n\n\tdata := map[string]interface{}{\n\t\t\"schema\": map[string]interface{}{}, // Your schema here\n\t\t\"user_id\": \"user123\",\n\t}\n\n\tjsonData, _ := json.Marshal(data)\n\n\treq, _ := http.NewRequest(\"POST\", url, bytes.NewBuffer(jsonData))\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\treq.Header.Add(\"Content-Type\", \"application/json\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(string(body))\n}"
|
||||
},
|
||||
{
|
||||
"lang": "PHP",
|
||||
"source": "<?php\n\n$curl = curl_init();\n\n$data = array(\n \"schema\" => array(), // Your schema here\n \"user_id\" => \"your_user_id\"\n);\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/v1/exports/\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"POST\",\n CURLOPT_POSTFIELDS => json_encode($data),\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\",\n \"Content-Type: application/json\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
|
||||
},
|
||||
{
|
||||
"lang": "Java",
|
||||
"source": "import com.mashape.unirest.http.HttpResponse;\nimport com.mashape.unirest.http.JsonNode;\nimport com.mashape.unirest.http.Unirest;\nimport org.json.JSONObject;\n\nJSONObject data = new JSONObject()\n .put(\"schema\", new JSONObject()) // Your schema here\n .put(\"user_id\", \"your_user_id\");\n\nHttpResponse<JsonNode> response = Unirest.post(\"https://api.mem0.ai/v1/exports/\")\n .header(\"Authorization\", \"Token <api-key>\")\n .header(\"Content-Type\", \"application/json\")\n .body(data.toString())\n .asJson();"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/v1/memories/": {
|
||||
"get": {
|
||||
@@ -783,6 +763,14 @@
|
||||
"title": "Immutable",
|
||||
"default": false
|
||||
},
|
||||
"expiration_date": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The date and time when the memory will expire. Format: YYYY-MM-DD",
|
||||
"title": "Expiration date",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
},
|
||||
"organization": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -932,27 +920,27 @@
|
||||
"x-code-samples": [
|
||||
{
|
||||
"lang": "Python",
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nmessages = [\n {\"role\": \"user\", \"content\": \"<user-message>\"},\n {\"role\": \"assistant\", \"content\": \"<assistant-response>\"}\n]\n\nclient.add(messages, user_id=\"<user-id>\")"
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\n\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nmessages = [\n {\"role\": \"user\", \"content\": \"<user-message>\"},\n {\"role\": \"assistant\", \"content\": \"<assistant-response>\"}\n]\n\nclient.add(messages, user_id=\"<user-id>\", version=\"v2\")"
|
||||
},
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst messages = [\n { role: \"user\", content: \"Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts.\" },\n { role: \"assistant\", content: \"Hello Alex! I've noted that you're a vegetarian and have a nut allergy. I'll keep this in mind for any food-related recommendations or discussions.\" }\n];\n\nclient.add(messages, { user_id: \"<user_id>\" })\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst messages = [\n { role: \"user\", content: \"Hi, I'm Alex. I'm a vegetarian and I'm allergic to nuts.\" },\n { role: \"assistant\", content: \"Hello Alex! I've noted that you're a vegetarian and have a nut allergy. I'll keep this in mind for any food-related recommendations or discussions.\" }\n];\n\nclient.add(messages, { user_id: \"<user_id>\", version: \"v2\" })\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
"source": "curl --request POST \\\n --url https://api.mem0.ai/v1/memories/ \\\n --header 'Authorization: Token <api-key>' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"messages\": [\n {}\n ],\n \"agent_id\": \"<string>\",\n \"user_id\": \"<string>\",\n \"app_id\": \"<string>\",\n \"run_id\": \"<string>\",\n \"metadata\": {},\n \"includes\": \"<string>\",\n \"excludes\": \"<string>\",\n \"infer\": true,\n \"custom_categories\": {}, \n \"org_id\": \"<string>\",\n \"project_id\": \"<string>\"\n}'"
|
||||
"source": "curl --request POST \\\n --url https://api.mem0.ai/v1/memories/ \\\n --header 'Authorization: Token <api-key>' \\\n --header 'Content-Type: application/json' \\\n --data '{\n \"messages\": [\n {}\n ],\n \"agent_id\": \"<string>\",\n \"user_id\": \"<string>\",\n \"app_id\": \"<string>\",\n \"run_id\": \"<string>\",\n \"metadata\": {},\n \"includes\": \"<string>\",\n \"excludes\": \"<string>\",\n \"infer\": true,\n \"custom_categories\": {}, \n \"org_id\": \"<string>\",\n \"project_id\": \"<string>\",\n \"version\": \"v2\"\n}'"
|
||||
},
|
||||
{
|
||||
"lang": "Go",
|
||||
"source": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\turl := \"https://api.mem0.ai/v1/memories/\"\n\n\tpayload := strings.NewReader(\"{\n \\\"messages\\\": [\n {}\n ],\n \\\"agent_id\\\": \\\"<string>\\\",\n \\\"user_id\\\": \\\"<string>\\\",\n \\\"app_id\\\": \\\"<string>\\\",\n \\\"run_id\\\": \\\"<string>\\\",\n \\\"metadata\\\": {},\n \\\"includes\\\": \\\"<string>\\\",\n \\\"excludes\\\": \\\"<string>\\\",\n \\\"infer\\\": true,\n \\\"custom_categories\\\": {},\n \\\"org_id\\\": \\\"<string>\\\",\n \\\"project_id\\\": \\\"<string>\"\n}\")\n\n\treq, _ := http.NewRequest(\"POST\", url, payload)\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\treq.Header.Add(\"Content-Type\", \"application/json\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(res)\n\tfmt.Println(string(body))\n\n}"
|
||||
"source": "package main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\t\"net/http\"\n\t\"io/ioutil\"\n)\n\nfunc main() {\n\n\turl := \"https://api.mem0.ai/v1/memories/\"\n\n\tpayload := strings.NewReader(\"{\n \\\"messages\\\": [\n {}\n ],\n \\\"agent_id\\\": \\\"<string>\\\",\n \\\"user_id\\\": \\\"<string>\\\",\n \\\"app_id\\\": \\\"<string>\\\",\n \\\"run_id\\\": \\\"<string>\\\",\n \\\"metadata\\\": {},\n \\\"includes\\\": \\\"<string>\\\",\n \\\"excludes\\\": \\\"<string>\\\",\n \\\"infer\\\": true,\n \\\"custom_categories\\\": {},\n \\\"org_id\\\": \\\"<string>\\\",\n \\\"project_id\\\": \\\"<string>\",\n \\\"version\\\": \"v2\"\n}\")\n\n\treq, _ := http.NewRequest(\"POST\", url, payload)\n\n\treq.Header.Add(\"Authorization\", \"Token <api-key>\")\n\treq.Header.Add(\"Content-Type\", \"application/json\")\n\n\tres, _ := http.DefaultClient.Do(req)\n\n\tdefer res.Body.Close()\n\tbody, _ := ioutil.ReadAll(res.Body)\n\n\tfmt.Println(res)\n\tfmt.Println(string(body))\n\n}"
|
||||
},
|
||||
{
|
||||
"lang": "PHP",
|
||||
"source": "<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/v1/memories/\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"POST\",\n CURLOPT_POSTFIELDS => \"{\n \\\"messages\\\": [\n {}\n ],\n \\\"agent_id\\\": \\\"<string>\\\",\n \\\"user_id\\\": \\\"<string>\\\",\n \\\"app_id\\\": \\\"<string>\\\",\n \\\"run_id\\\": \\\"<string>\\\",\n \\\"metadata\\\": {},\n \\\"includes\\\": \\\"<string>\\\",\n \\\"excludes\\\": \\\"<string>\\\",\n \\\"infer\\\": true,\n \\\"custom_categories\\\": {}, \n \\\"org_id\\\": \\\"<string>\\\",\n \\\"project_id\\\": \\\"<string>\"\n}\",\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\",\n \"Content-Type: application/json\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
|
||||
"source": "<?php\n\n$curl = curl_init();\n\ncurl_setopt_array($curl, [\n CURLOPT_URL => \"https://api.mem0.ai/v1/memories/\",\n CURLOPT_RETURNTRANSFER => true,\n CURLOPT_ENCODING => \"\",\n CURLOPT_MAXREDIRS => 10,\n CURLOPT_TIMEOUT => 30,\n CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,\n CURLOPT_CUSTOMREQUEST => \"POST\",\n CURLOPT_POSTFIELDS => \"{\n \\\"messages\\\": [\n {}\n ],\n \\\"agent_id\\\": \\\"<string>\\\",\n \\\"user_id\\\": \\\"<string>\\\",\n \\\"app_id\\\": \\\"<string>\\\",\n \\\"run_id\\\": \\\"<string>\\\",\n \\\"metadata\\\": {},\n \\\"includes\\\": \\\"<string>\\\",\n \\\"excludes\\\": \\\"<string>\\\",\n \\\"infer\\\": true,\n \\\"custom_categories\\\": {}, \n \\\"org_id\\\": \\\"<string>\\\",\n \\\"project_id\\\": \\\"<string>\",\n \\\"version\\\": \"v2\"\n}\",\n CURLOPT_HTTPHEADER => [\n \"Authorization: Token <api-key>\",\n \"Content-Type: application/json\"\n ],\n]);\n\n$response = curl_exec($curl);\n$err = curl_error($curl);\n\ncurl_close($curl);\n\nif ($err) {\n echo \"cURL Error #:\" . $err;\n} else {\n echo $response;\n}"
|
||||
},
|
||||
{
|
||||
"lang": "Java",
|
||||
"source": "HttpResponse<String> response = Unirest.post(\"https://api.mem0.ai/v1/memories/\")\n .header(\"Authorization\", \"Token <api-key>\")\n .header(\"Content-Type\", \"application/json\")\n .body(\"{\n \\\"messages\\\": [\n {}\n ],\n \\\"agent_id\\\": \\\"<string>\\\",\n \\\"user_id\\\": \\\"<string>\\\",\n \\\"app_id\\\": \\\"<string>\\\",\n \\\"run_id\\\": \\\"<string>\\\",\n \\\"metadata\\\": {},\n \\\"includes\\\": \\\"<string>\\\",\n \\\"excludes\\\": \\\"<string>\\\",\n \\\"infer\\\": true,\n \\\"custom_categories\\\": {}, \n \\\"org_id\\\": \\\"<string>\\\",\n \\\"project_id\\\": \\\"<string>\"\n}\")\n .asString();"
|
||||
"source": "HttpResponse<String> response = Unirest.post(\"https://api.mem0.ai/v1/memories/\")\n .header(\"Authorization\", \"Token <api-key>\")\n .header(\"Content-Type\", \"application/json\")\n .body(\"{\n \\\"messages\\\": [\n {}\n ],\n \\\"agent_id\\\": \\\"<string>\\\",\n \\\"user_id\\\": \\\"<string>\\\",\n \\\"app_id\\\": \\\"<string>\\\",\n \\\"run_id\\\": \\\"<string>\\\",\n \\\"metadata\\\": {},\n \\\"includes\\\": \\\"<string>\\\",\n \\\"excludes\\\": \\\"<string>\\\",\n \\\"infer\\\": true,\n \\\"custom_categories\\\": {}, \n \\\"org_id\\\": \\\"<string>\\\",\n \\\"project_id\\\": \\\"<string>\",\n \\\"version\\\": \"v2\"\n}\")\n .asString();"
|
||||
}
|
||||
],
|
||||
"x-codegen-request-body-name": "data"
|
||||
@@ -1183,6 +1171,14 @@
|
||||
"title": "Immutable",
|
||||
"default": false
|
||||
},
|
||||
"expiration_date": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The date and time when the memory will expire. Format: YYYY-MM-DD",
|
||||
"title": "Expiration date",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
},
|
||||
"organization": {
|
||||
"type": "string"
|
||||
},
|
||||
@@ -1233,7 +1229,7 @@
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
"source": "curl -X POST 'https://api.mem0.ai/v2/memories/' \\\n-H 'Authorization: Token your-api-key' \\\n-H 'Content-Type: application/json' \\\n-d '{\n \"filters\": {\n \"AND\": [\n { \"user_id\": \"alex\" },\n { \"created_at\": { \"gte\": \"2024-07-01\", \"lte\": \"2024-07-31\" } }\n ]\n }\n}'"
|
||||
"source": "curl -X POST 'https://api.mem0.ai/v2/memories/' \\\n-H 'Authorization: Token your-api-key' \\\n-H 'Content-Type: application/json' \\\n-d '{\n \"filters\": {\n \"AND\": [\n { \"user_id\": \"alex\" },\n { \"created_at\": { \"gte\": \"2024-07-01\", \"lte\": \"2024-07-31\" } }\n ]\n },\n \"org_id\": \"your-org-id\",\n \"project_id\": \"your-project-id\"\n}'"
|
||||
},
|
||||
{
|
||||
"lang": "Go",
|
||||
@@ -1324,6 +1320,14 @@
|
||||
"title": "Immutable",
|
||||
"default": false
|
||||
},
|
||||
"expiration_date": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The date and time when the memory will expire. Format: YYYY-MM-DD",
|
||||
"title": "Expiration date",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
@@ -1367,11 +1371,11 @@
|
||||
"x-code-samples": [
|
||||
{
|
||||
"lang": "Python",
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nquery = \"Your search query here\"\n\nresults = client.search(query, user_id=\"<user_id>\", output_format=\"v1.0\")\nprint(results)"
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\", org_id=\"your_org_id\", project_id=\"your_project_id\")\n\nquery = \"Your search query here\"\n\nresults = client.search(query, user_id=\"<user_id>\", output_format=\"v1.1\")\nprint(results)"
|
||||
},
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst query = \"Your search query here\";\n\nclient.search(query, { user_id: \"<user_id>\", output_format: \"v1.0\" })\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\nconst query = \"Your search query here\";\n\nclient.search(query, { user_id: \"<user_id>\", output_format: \"v1.1\" })\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
@@ -1451,6 +1455,14 @@
|
||||
"title": "Immutable",
|
||||
"default": false
|
||||
},
|
||||
"expiration_date": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"description": "The date and time when the memory will expire. Format: YYYY-MM-DD",
|
||||
"title": "Expiration date",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
},
|
||||
"created_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
@@ -1761,7 +1773,7 @@
|
||||
},
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "const options = {\n method: 'PUT',\n headers: {\n 'Authorization': 'Token <api-key>',\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({\n text: 'Your updated memory text here'\n })\n};\n\nfetch('https://api.mem0.ai/v1/memories/{memory_id}/', options)\n .then(response => response.json())\n .then(response => console.log(response))\n .catch(err => console.error(err));"
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm i mem0ai\n\nimport MemoryClient from 'mem0ai';\nconst client = new MemoryClient({ apiKey: \"your-api-key\" });\n\n// Update a specific memory\nconst memory_id=<memory_id>\nconst message=\"Your updated memory message here\"\nclient.update(memory_id, message)\n .then(result => console.log(result))\n .catch(error => console.error(error));"
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
@@ -2074,6 +2086,95 @@
|
||||
"x-codegen-request-body-name": "data"
|
||||
}
|
||||
},
|
||||
"/v1/feedback/": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"feedback"
|
||||
],
|
||||
"description": "Submit feedback for a memory.",
|
||||
"operationId": "submit_feedback",
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"required": [
|
||||
"memory_id"
|
||||
],
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memory_id": {
|
||||
"type": "string",
|
||||
"description": "ID of the memory to provide feedback for"
|
||||
},
|
||||
"feedback": {
|
||||
"type": "string",
|
||||
"enum": ["POSITIVE", "NEGATIVE", "VERY_NEGATIVE"],
|
||||
"nullable": true,
|
||||
"description": "Type of feedback"
|
||||
},
|
||||
"feedback_reason": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Reason for the feedback"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Successful operation",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Feedback ID"
|
||||
},
|
||||
"feedback": {
|
||||
"type": "string",
|
||||
"enum": ["POSITIVE", "NEGATIVE", "VERY_NEGATIVE"],
|
||||
"nullable": true,
|
||||
"description": "Type of feedback"
|
||||
},
|
||||
"feedback_reason": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Reason for the feedback"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Invalid request"
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized"
|
||||
}
|
||||
},
|
||||
"x-code-samples": [
|
||||
{
|
||||
"lang": "Python",
|
||||
"source": "# To use the Python SDK, install the package:\n# pip install mem0ai\n\nfrom mem0 import MemoryClient\nclient = MemoryClient(api_key=\"your_api_key\")\n\n# Submit feedback for a memory\nfeedback = client.feedback(memory_id=\"memory_id\", feedback=\"POSITIVE\")\nprint(feedback)"
|
||||
},
|
||||
{
|
||||
"lang": "JavaScript",
|
||||
"source": "// To use the JavaScript SDK, install the package:\n// npm install mem0ai\n\nimport MemoryClient from 'mem0ai';\n\nconst client = new MemoryClient({ apiKey: 'your-api-key'});\n\nclient.feedback({\n memory_id: \"your-memory-id\", \n feedback: \"NEGATIVE\", \n feedback_reason: \"I don't like this memory because it is not relevant.\"\n})"
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
"source": "curl --request POST \\\n --url https://api.mem0.ai/v1/feedback/ \\\n --header 'Authorization: Token <api-key>' \\\n --header 'Content-Type: application/json' \\\n --data '{\"memory_id\": \"memory_id\", \"feedback\": \"POSITIVE\"}'"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v1/orgs/organizations/": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -3112,7 +3213,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"type": "string",
|
||||
"example": "Unauthorized to create projects in this organization."
|
||||
}
|
||||
}
|
||||
@@ -3478,7 +3579,7 @@
|
||||
"description": "Unauthorized to modify this project",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
@@ -4069,7 +4170,7 @@
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
"source": "curl -X PUT \"https://api.mem0.ai/v1/memories/batch/\" \\\n -H \"Authorization: Token your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"memories\": [\n {\n \"memory_id\": \"285ed74b-6e05-4043-b16b-3abd5b533496\",\n \"text\": \"Watches football\"\n },\n {\n \"memory_id\": \"2c9bd859-d1b7-4d33-a6b8-94e0147c4f07\",\n \"text\": \"Likes to travel\"\n }\n ]\n }'"
|
||||
"source": "curl -X PUT \"https://api.mem0.ai/v1/batch/\" \\\n -H \"Authorization: Token your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"memories\": [\n {\n \"memory_id\": \"285ed74b-6e05-4043-b16b-3abd5b533496\",\n \"text\": \"Watches football\"\n },\n {\n \"memory_id\": \"2c9bd859-d1b7-4d33-a6b8-94e0147c4f07\",\n \"text\": \"Likes to travel\"\n }\n ]\n }'"
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -4146,7 +4247,7 @@
|
||||
},
|
||||
{
|
||||
"lang": "cURL",
|
||||
"source": "curl -X DELETE \"https://api.mem0.ai/v1/memories/batch/\" \\\n -H \"Authorization: Token your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"delete_memories\": [\n {\n \"memory_id\": \"285ed74b-6e05-4043-b16b-3abd5b533496\"\n },\n {\n \"memory_id\": \"2c9bd859-d1b7-4d33-a6b8-94e0147c4f07\"\n }\n ]\n }'"
|
||||
"source": "curl -X DELETE \"https://api.mem0.ai/v1/batch/\" \\\n -H \"Authorization: Token your-api-key\" \\\n -H \"Content-Type: application/json\" \\\n -d '{\n \"memories\": [\n {\n \"memory_id\": \"285ed74b-6e05-4043-b16b-3abd5b533496\"\n },\n {\n \"memory_id\": \"2c9bd859-d1b7-4d33-a6b8-94e0147c4f07\"\n }\n ]\n }'"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -4743,7 +4844,7 @@
|
||||
"nullable": true
|
||||
},
|
||||
"metadata": {
|
||||
"description": "Additional metadata associated with the memory, which can be used to store any additional information or context about the memory.",
|
||||
"description": "Additional metadata associated with the memory, which can be used to store any additional information or context about the memory. Best practice for incorporating additional information is through metadata (e.g. location, time, ids, etc.). During retrieval, you can either use these metadata alongside the query to fetch relevant memories or retrieve memories based on the query first and then refine the results using metadata during post-processing.",
|
||||
"title": "Metadata",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -4772,10 +4873,11 @@
|
||||
"default": true
|
||||
},
|
||||
"output_format": {
|
||||
"description": "It two output formats: `v1.0` (default) and `v1.1`. To enable the latest format, which provides enhanced detail for each memory operation, set the output_format parameter to `v1.1`. Note that `v1.0` will be deprecated in version 0.1.35.",
|
||||
"description": "It two output formats: `v1.0` (default) and `v1.1`. We recommend using `v1.1` as `v1.0` will be deprecated soon.",
|
||||
"title": "Output format",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
"nullable": true,
|
||||
"default": "v1.0"
|
||||
},
|
||||
"custom_categories": {
|
||||
"description": "A list of categories with category name and it's description.",
|
||||
@@ -4798,6 +4900,13 @@
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"expiration_date": {
|
||||
"description": "The date and time when the memory will expire. Format: YYYY-MM-DD",
|
||||
"title": "Expiration date",
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"default": null
|
||||
},
|
||||
"org_id": {
|
||||
"description": "The unique identifier of the organization associated with this memory.",
|
||||
"title": "Organization id",
|
||||
@@ -4809,6 +4918,12 @@
|
||||
"title": "Project id",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"version": {
|
||||
"description": "The version of the memory to use. The default version is v1, which is deprecated. We recommend using v2 for new applications.",
|
||||
"title": "Version",
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4887,7 +5002,8 @@
|
||||
"title": "Output format",
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "The search method supports two output formats: `v1.0` (default) and `v1.1`."
|
||||
"default": "v1.0",
|
||||
"description": "The search method supports two output formats: `v1.0` (default) and `v1.1`. We recommend using `v1.1` as `v1.0` will be deprecated soon."
|
||||
},
|
||||
"org_id": {
|
||||
"title": "Organization id",
|
||||
|
||||
@@ -5,7 +5,7 @@ iconType: "solid"
|
||||
---
|
||||
|
||||
<Note type="info">
|
||||
🎉 We now support [Claude 3.7 Sonnet](components/llms/models/anthropic)! Enhance your AI assistants with the latest and most capable language model from Anthropic.
|
||||
🎉 We now support [Grok 3](components/llms/models/xAI)! Enhance your AI assistants with the latest and most capable language model from xAI.
|
||||
</Note>
|
||||
|
||||
# Introduction
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import os
|
||||
import warnings
|
||||
from typing import Optional
|
||||
|
||||
from chromadb.utils.embedding_functions import OpenAIEmbeddingFunction
|
||||
@@ -16,7 +17,18 @@ class OpenAIEmbedder(BaseEmbedder):
|
||||
self.config.model = "text-embedding-ada-002"
|
||||
|
||||
api_key = self.config.api_key or os.environ["OPENAI_API_KEY"]
|
||||
api_base = self.config.api_base or os.environ.get("OPENAI_API_BASE")
|
||||
api_base = (
|
||||
self.config.api_base
|
||||
or os.environ.get("OPENAI_API_BASE")
|
||||
or os.getenv("OPENAI_BASE_URL")
|
||||
or "https://api.openai.com/v1"
|
||||
)
|
||||
if os.environ.get("OPENAI_API_BASE"):
|
||||
warnings.warn(
|
||||
"The environment variable 'OPENAI_API_BASE' is deprecated and will be removed in the 0.1.140. "
|
||||
"Please use 'OPENAI_BASE_URL' instead.",
|
||||
DeprecationWarning
|
||||
)
|
||||
|
||||
if api_key is None and os.getenv("OPENAI_ORGANIZATION") is None:
|
||||
raise ValueError("OPENAI_API_KEY or OPENAI_ORGANIZATION environment variables not provided") # noqa:E501
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import json
|
||||
import os
|
||||
import warnings
|
||||
from typing import Any, Callable, Dict, Optional, Type, Union
|
||||
|
||||
from langchain.callbacks.streaming_stdout import StreamingStdOutCallbackHandler
|
||||
@@ -58,7 +59,19 @@ class OpenAILlm(BaseLlm):
|
||||
"model_kwargs": config.model_kwargs or {},
|
||||
}
|
||||
api_key = config.api_key or os.environ["OPENAI_API_KEY"]
|
||||
base_url = config.base_url or os.environ.get("OPENAI_API_BASE", None)
|
||||
base_url = (
|
||||
config.base_url
|
||||
or os.getenv("OPENAI_API_BASE")
|
||||
or os.getenv("OPENAI_BASE_URL")
|
||||
or "https://api.openai.com/v1"
|
||||
)
|
||||
if os.environ.get("OPENAI_API_BASE"):
|
||||
warnings.warn(
|
||||
"The environment variable 'OPENAI_API_BASE' is deprecated and will be removed in the 0.1.140. "
|
||||
"Please use 'OPENAI_BASE_URL' instead.",
|
||||
DeprecationWarning
|
||||
)
|
||||
|
||||
if config.top_p:
|
||||
kwargs["top_p"] = config.top_p
|
||||
if config.default_headers:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "embedchain"
|
||||
version = "0.1.127"
|
||||
version = "0.1.128"
|
||||
description = "Simplest open source retrieval (RAG) framework"
|
||||
authors = [
|
||||
"Taranjeet Singh <taranjeet@embedchain.ai>",
|
||||
@@ -91,7 +91,7 @@ exclude = '''
|
||||
color = true
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.9,<=3.13"
|
||||
python = ">=3.9,<=3.13.2"
|
||||
python-dotenv = "^1.0.0"
|
||||
langchain = "^0.3.1"
|
||||
requests = "^2.31.0"
|
||||
@@ -139,7 +139,7 @@ alembic = "^1.13.1"
|
||||
langchain-cohere = "^0.3.0"
|
||||
langchain-community = "^0.3.1"
|
||||
langchain-aws = {version = "^0.2.1", optional = true}
|
||||
langsmith = "^0.1.17"
|
||||
langsmith = "^0.3.18"
|
||||
|
||||
[tool.poetry.group.dev.dependencies]
|
||||
black = "^23.3.0"
|
||||
|
||||
@@ -70,7 +70,7 @@ const retrieveMemories = (memories: any) => {
|
||||
export async function POST(req: Request) {
|
||||
const { messages, system, tools, userId } = await req.json();
|
||||
|
||||
const memories = await getMemories(messages, { user_id: userId });
|
||||
const memories = await getMemories(messages, { user_id: userId, rerank: true, threshold: 0.1 });
|
||||
const mem0Instructions = retrieveMemories(memories);
|
||||
|
||||
const result = streamText({
|
||||
|
||||
@@ -6,7 +6,7 @@ import { Thread } from "@/components/assistant-ui/thread";
|
||||
import { ThreadList } from "@/components/assistant-ui/thread-list";
|
||||
import { useEffect, useState } from "react";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import { Sun, Moon, MessageSquare } from "lucide-react";
|
||||
import { Sun, Moon, AlignJustify } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import ThemeAwareLogo from "@/components/mem0/theme-aware-logo";
|
||||
import Link from "next/link";
|
||||
@@ -45,7 +45,7 @@ const useUserId = () => {
|
||||
export const Assistant = () => {
|
||||
const { userId, resetUserId } = useUserId();
|
||||
const runtime = useChatRuntime({
|
||||
api: "/api/chat",
|
||||
api: "https://demo.mem0.ai/api/chat",
|
||||
body: { userId },
|
||||
});
|
||||
|
||||
@@ -63,7 +63,7 @@ export const Assistant = () => {
|
||||
|
||||
return (
|
||||
<AssistantRuntimeProvider runtime={runtime}>
|
||||
<div className={`h-dvh bg-[#f8fafc] dark:bg-zinc-900 text-[#1e293b] ${isDarkMode ? "dark" : ""}`}>
|
||||
<div className={`bg-[#f8fafc] dark:bg-zinc-900 text-[#1e293b] ${isDarkMode ? "dark" : ""}`}>
|
||||
<header className="h-16 border-b border-[#e2e8f0] flex items-center justify-between px-4 sm:px-6 bg-white dark:bg-zinc-900 dark:border-zinc-800 dark:text-white">
|
||||
<div className="flex items-center">
|
||||
<Link href="/" className="flex items-center">
|
||||
@@ -71,29 +71,34 @@ export const Assistant = () => {
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center">
|
||||
<Button
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setSidebarOpen(true)}
|
||||
className="text-[#475569] dark:text-zinc-300 md:hidden"
|
||||
>
|
||||
<MessageSquare className="w-10 h-10" />
|
||||
</Button>
|
||||
<AlignJustify size={24} className="md:hidden" />
|
||||
</Button>
|
||||
|
||||
|
||||
<div className="md:flex items-center hidden">
|
||||
<button
|
||||
className="p-2 rounded-full hover:bg-[#eef2ff] dark:hover:bg-zinc-800 text-[#475569] dark:text-zinc-300"
|
||||
onClick={toggleDarkMode}
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
{isDarkMode ? <Sun className="w-5 h-5" /> : <Moon className="w-5 h-5" />}
|
||||
{isDarkMode ? <Sun className="w-6 h-6" /> : <Moon className="w-6 h-6" />}
|
||||
</button>
|
||||
<GithubButton url="https://github.com/mem0ai/mem0/tree/main/examples" />
|
||||
|
||||
<Link href={"https://app.mem0.ai/"} target="_blank" className="py-2 ml-2 px-4 font-semibold dark:bg-zinc-100 dark:hover:bg-zinc-200 bg-zinc-800 text-white rounded-full hover:bg-zinc-900 dark:text-[#475569]">
|
||||
Save Memories
|
||||
</Link>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-[260px_1fr] gap-x-0 h-[calc(100vh-8rem)] md:h-[calc(100vh-4rem)]">
|
||||
<ThreadList onResetUserId={resetUserId} />
|
||||
<Thread sidebarOpen={sidebarOpen} setSidebarOpen={setSidebarOpen} onResetUserId={resetUserId} />
|
||||
<div className="grid grid-cols-1 md:grid-cols-[260px_1fr] gap-x-0 h-[calc(100dvh-4rem)]">
|
||||
<ThreadList onResetUserId={resetUserId} isDarkMode={isDarkMode} />
|
||||
<Thread sidebarOpen={sidebarOpen} setSidebarOpen={setSidebarOpen} onResetUserId={resetUserId} isDarkMode={isDarkMode} toggleDarkMode={toggleDarkMode} />
|
||||
</div>
|
||||
</div>
|
||||
</AssistantRuntimeProvider>
|
||||
|
||||
@@ -13,8 +13,8 @@ const geistMono = Geist_Mono({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Mem0-Demo",
|
||||
description: "Mem0-Demo: By Mem0",
|
||||
title: "Mem0 - ChatGPT with Memory",
|
||||
description: "Mem0 - ChatGPT with Memory is a personalized AI chat app powered by Mem0 that remembers your preferences, facts, and memories.",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import darkAssistantUi from "@/images/assistant-ui-dark.svg";
|
||||
import assistantUi from "@/images/assistant-ui.svg";
|
||||
import React from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
@@ -27,7 +28,7 @@ export default function ThemeAwareLogo({
|
||||
}
|
||||
|
||||
// For default variant, use the full logo image
|
||||
const logoSrc = isDarkMode ? "/images/assistant-ui-dark.svg" : "/images/assistant-ui.svg";
|
||||
const logoSrc = isDarkMode ? darkAssistantUi : assistantUi;
|
||||
|
||||
return (
|
||||
<Image
|
||||
|
||||
@@ -19,9 +19,11 @@ import {
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
|
||||
// import ThemeAwareLogo from "@/components/assistant-ui/theme-aware-logo";
|
||||
// import Link from "next/link";
|
||||
interface ThreadListProps {
|
||||
onResetUserId?: () => void;
|
||||
isDarkMode: boolean;
|
||||
}
|
||||
|
||||
export const ThreadList: FC<ThreadListProps> = ({ onResetUserId }) => {
|
||||
@@ -29,45 +31,55 @@ export const ThreadList: FC<ThreadListProps> = ({ onResetUserId }) => {
|
||||
|
||||
return (
|
||||
<div className="flex-col h-full border-r border-[#e2e8f0] bg-white dark:bg-zinc-900 dark:border-zinc-800 p-3 overflow-y-auto hidden md:flex">
|
||||
<ThreadListPrimitive.Root className="flex flex-col items-stretch gap-1.5">
|
||||
<ThreadListNew />
|
||||
<div className="mt-4 mb-2 flex justify-between items-center px-2.5">
|
||||
<h2 className="text-sm font-medium text-[#475569] dark:text-zinc-300">Recent Chats</h2>
|
||||
{onResetUserId && (
|
||||
<AlertDialog open={open} onOpenChange={setOpen}>
|
||||
<AlertDialogTrigger asChild>
|
||||
<TooltipIconButton
|
||||
tooltip="Reset Memory"
|
||||
className="hover:text-[#4f46e5] text-[#475569] dark:text-zinc-300 dark:hover:text-[#6366f1] size-4 p-0"
|
||||
variant="ghost"
|
||||
>
|
||||
<RefreshCwIcon className="w-4 h-4" />
|
||||
</TooltipIconButton>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent className="bg-white dark:bg-zinc-900 border-[#e2e8f0] dark:border-zinc-800">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle className="text-[#1e293b] dark:text-white">Reset Memory</AlertDialogTitle>
|
||||
<AlertDialogDescription className="text-[#475569] dark:text-zinc-300">
|
||||
This will permanently delete all your chat history and memories. This action cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel className="text-[#475569] dark:text-zinc-300 hover:bg-[#eef2ff] dark:hover:bg-zinc-800">Cancel</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={() => {
|
||||
onResetUserId();
|
||||
setOpen(false);
|
||||
}}
|
||||
className="bg-[#4f46e5] hover:bg-[#4338ca] dark:bg-[#6366f1] dark:hover:bg-[#4f46e5] text-white"
|
||||
<ThreadListPrimitive.Root className="flex flex-col justify-between h-full items-stretch gap-1.5">
|
||||
<div className="flex flex-col h-full items-stretch gap-1.5">
|
||||
<ThreadListNew />
|
||||
<div className="mt-4 mb-2 flex justify-between items-center px-2.5">
|
||||
<h2 className="text-sm font-medium text-[#475569] dark:text-zinc-300">
|
||||
Recent Chats
|
||||
</h2>
|
||||
{onResetUserId && (
|
||||
<AlertDialog open={open} onOpenChange={setOpen}>
|
||||
<AlertDialogTrigger asChild>
|
||||
<TooltipIconButton
|
||||
tooltip="Reset Memory"
|
||||
className="hover:text-[#4f46e5] text-[#475569] dark:text-zinc-300 dark:hover:text-[#6366f1] size-4 p-0"
|
||||
variant="ghost"
|
||||
>
|
||||
Reset
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
)}
|
||||
<RefreshCwIcon className="w-4 h-4" />
|
||||
</TooltipIconButton>
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent className="bg-white dark:bg-zinc-900 border-[#e2e8f0] dark:border-zinc-800">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle className="text-[#1e293b] dark:text-white">
|
||||
Reset Memory
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription className="text-[#475569] dark:text-zinc-300">
|
||||
This will permanently delete all your chat history and
|
||||
memories. This action cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel className="text-[#475569] dark:text-zinc-300 hover:bg-[#eef2ff] dark:hover:bg-zinc-800">
|
||||
Cancel
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={() => {
|
||||
onResetUserId();
|
||||
setOpen(false);
|
||||
}}
|
||||
className="bg-[#4f46e5] hover:bg-[#4338ca] dark:bg-[#6366f1] dark:hover:bg-[#4f46e5] text-white"
|
||||
>
|
||||
Reset
|
||||
</AlertDialogAction>
|
||||
</AlertDialogFooter>
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
)}
|
||||
</div>
|
||||
<ThreadListItems />
|
||||
</div>
|
||||
<ThreadListItems />
|
||||
|
||||
</ThreadListPrimitive.Root>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
"use client"
|
||||
"use client";
|
||||
|
||||
import {
|
||||
ActionBarPrimitive,
|
||||
@@ -22,9 +22,12 @@ import {
|
||||
SendHorizontalIcon,
|
||||
ArchiveIcon,
|
||||
PlusIcon,
|
||||
Sun,
|
||||
Moon,
|
||||
SaveIcon,
|
||||
} from "lucide-react";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Dispatch, SetStateAction, useState } from "react";
|
||||
import { Dispatch, SetStateAction, useState, useRef } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { ScrollArea } from "../ui/scroll-area";
|
||||
import { TooltipIconButton } from "@/components/assistant-ui/tooltip-icon-button";
|
||||
@@ -42,42 +45,57 @@ import {
|
||||
AlertDialogTitle,
|
||||
AlertDialogTrigger,
|
||||
} from "@/components/ui/alert-dialog";
|
||||
|
||||
import GithubButton from "../mem0/github-button";
|
||||
import Link from "next/link";
|
||||
interface ThreadProps {
|
||||
sidebarOpen: boolean;
|
||||
setSidebarOpen: Dispatch<SetStateAction<boolean>>;
|
||||
onResetUserId?: () => void;
|
||||
isDarkMode: boolean;
|
||||
toggleDarkMode: () => void;
|
||||
}
|
||||
|
||||
export const Thread: FC<ThreadProps> = ({ sidebarOpen, setSidebarOpen, onResetUserId }) => {
|
||||
export const Thread: FC<ThreadProps> = ({
|
||||
sidebarOpen,
|
||||
setSidebarOpen,
|
||||
onResetUserId,
|
||||
isDarkMode,
|
||||
toggleDarkMode
|
||||
}) => {
|
||||
const [resetDialogOpen, setResetDialogOpen] = useState(false);
|
||||
const composerInputRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
return (
|
||||
<ThreadPrimitive.Root
|
||||
className="bg-[#f8fafc] dark:bg-zinc-900 box-border h-full flex flex-col overflow-hidden relative"
|
||||
className="bg-[#f8fafc] dark:bg-zinc-900 box-border flex flex-col overflow-hidden relative h-[calc(100dvh-4rem)] pb-4 md:h-full"
|
||||
style={{
|
||||
["--thread-max-width" as string]: "42rem",
|
||||
}}
|
||||
>
|
||||
{/* Mobile sidebar overlay */}
|
||||
{sidebarOpen && (
|
||||
<div
|
||||
<div
|
||||
className="fixed inset-0 bg-black/40 z-30 md:hidden"
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
></div>
|
||||
)}
|
||||
|
||||
{/* Mobile sidebar drawer */}
|
||||
<div className={cn(
|
||||
"fixed inset-y-0 left-0 z-40 w-[85%] bg-white dark:bg-zinc-900 transform transition-transform duration-300 ease-in-out md:hidden",
|
||||
sidebarOpen ? "translate-x-0" : "-translate-x-full"
|
||||
)}>
|
||||
<div
|
||||
className={cn(
|
||||
"fixed inset-y-0 left-0 z-40 w-[75%] bg-white shadow-lg rounded-r-lg dark:bg-zinc-900 transform transition-transform duration-300 ease-in-out md:hidden",
|
||||
sidebarOpen ? "translate-x-0" : "-translate-x-full"
|
||||
)}
|
||||
>
|
||||
<div className="h-full flex flex-col">
|
||||
<div className="flex items-center justify-between border-b dark:text-white border-[#e2e8f0] dark:border-zinc-800 p-4">
|
||||
<h2 className="font-medium">Recent Chats</h2>
|
||||
<h2 className="font-medium">Settings</h2>
|
||||
<div className="flex items-center gap-2">
|
||||
{onResetUserId && (
|
||||
<AlertDialog open={resetDialogOpen} onOpenChange={setResetDialogOpen}>
|
||||
<AlertDialog
|
||||
open={resetDialogOpen}
|
||||
onOpenChange={setResetDialogOpen}
|
||||
>
|
||||
<AlertDialogTrigger asChild>
|
||||
<TooltipIconButton
|
||||
tooltip="Reset Memory"
|
||||
@@ -89,13 +107,18 @@ export const Thread: FC<ThreadProps> = ({ sidebarOpen, setSidebarOpen, onResetUs
|
||||
</AlertDialogTrigger>
|
||||
<AlertDialogContent className="bg-white dark:bg-zinc-900 border-[#e2e8f0] dark:border-zinc-800">
|
||||
<AlertDialogHeader>
|
||||
<AlertDialogTitle className="text-[#1e293b] dark:text-white">Reset Memory</AlertDialogTitle>
|
||||
<AlertDialogTitle className="text-[#1e293b] dark:text-white">
|
||||
Reset Memory
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription className="text-[#475569] dark:text-zinc-300">
|
||||
This will permanently delete all your chat history and memories. This action cannot be undone.
|
||||
This will permanently delete all your chat history and
|
||||
memories. This action cannot be undone.
|
||||
</AlertDialogDescription>
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter>
|
||||
<AlertDialogCancel className="text-[#475569] dark:text-zinc-300 hover:bg-[#eef2ff] dark:hover:bg-zinc-800">Cancel</AlertDialogCancel>
|
||||
<AlertDialogCancel className="text-[#475569] dark:text-zinc-300 hover:bg-[#eef2ff] dark:hover:bg-zinc-800">
|
||||
Cancel
|
||||
</AlertDialogCancel>
|
||||
<AlertDialogAction
|
||||
onClick={() => {
|
||||
onResetUserId();
|
||||
@@ -109,9 +132,9 @@ export const Thread: FC<ThreadProps> = ({ sidebarOpen, setSidebarOpen, onResetUs
|
||||
</AlertDialogContent>
|
||||
</AlertDialog>
|
||||
)}
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
className="text-[#475569] dark:text-zinc-300 hover:bg-[#eef2ff] dark:hover:bg-zinc-800 h-8 w-8 p-0"
|
||||
>
|
||||
@@ -120,28 +143,67 @@ export const Thread: FC<ThreadProps> = ({ sidebarOpen, setSidebarOpen, onResetUs
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex-1 overflow-y-auto p-3">
|
||||
<ThreadListPrimitive.Root className="flex flex-col items-stretch gap-1.5 h-full dark:text-white">
|
||||
<ThreadListPrimitive.New asChild>
|
||||
<Button
|
||||
className="hover:bg-[#eef2ff] dark:hover:bg-zinc-800 dark:data-[active]:bg-zinc-800 flex items-center justify-start gap-1 rounded-lg px-2.5 py-2 text-start bg-[#4f46e5] text-white dark:bg-[#6366f1]"
|
||||
variant="default"
|
||||
>
|
||||
<PlusIcon className="w-4 h-4" />
|
||||
New Thread
|
||||
</Button>
|
||||
</ThreadListPrimitive.New>
|
||||
<div className="mt-4 mb-2">
|
||||
<h2 className="text-sm font-medium text-[#475569] dark:text-zinc-300 px-2.5">Recent Chats</h2>
|
||||
</div>
|
||||
<ThreadListPrimitive.Items components={{ ThreadListItem }} />
|
||||
</ThreadListPrimitive.Root>
|
||||
<div className="flex flex-col justify-between items-stretch gap-1.5 h-full dark:text-white">
|
||||
<ThreadListPrimitive.Root className="flex flex-col items-stretch gap-1.5 h-full dark:text-white">
|
||||
<ThreadListPrimitive.New asChild>
|
||||
<div className="flex items-center flex-col gap-2 w-full">
|
||||
<Button
|
||||
className="hover:bg-zinc-600 w-full dark:hover:bg-zinc-800 dark:data-[active]:bg-zinc-800 flex items-center justify-start gap-1 rounded-lg px-2.5 py-2 text-start bg-[#4f46e5] text-white dark:bg-[#6366f1]"
|
||||
variant="default"
|
||||
>
|
||||
<PlusIcon className="w-4 h-4" />
|
||||
New Thread
|
||||
</Button>
|
||||
<Button
|
||||
className="hover:bg-zinc-600 w-full dark:hover:bg-zinc-700 dark:data-[active]:bg-zinc-800 flex items-center justify-start gap-1 rounded-lg px-2.5 py-2 text-start bg-zinc-800 text-white"
|
||||
onClick={toggleDarkMode}
|
||||
aria-label="Toggle theme"
|
||||
>
|
||||
{isDarkMode ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<Sun className="w-6 h-6" />
|
||||
<span>Toggle Light Mode</span>
|
||||
</div>
|
||||
) : (
|
||||
<div className="flex items-center gap-2">
|
||||
<Moon className="w-6 h-6" />
|
||||
<span>Toggle Dark Mode</span>
|
||||
</div>
|
||||
)}
|
||||
</Button>
|
||||
<GithubButton url="https://github.com/mem0ai/mem0/tree/main/examples" className="w-full rounded-lg h-9 pl-2 text-sm font-semibold bg-zinc-800 dark:border-zinc-800 dark:text-white text-white hover:bg-zinc-900" text="View on Github" />
|
||||
|
||||
<Link
|
||||
href={"https://app.mem0.ai/"}
|
||||
target="_blank"
|
||||
className="py-2 px-4 w-full rounded-lg h-9 pl-3 text-sm font-semibold dark:bg-zinc-800 dark:hover:bg-zinc-700 bg-zinc-800 text-white hover:bg-zinc-900 dark:text-white"
|
||||
>
|
||||
<span className="flex items-center gap-2">
|
||||
<SaveIcon className="w-4 h-4" />
|
||||
Save Memories
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
</ThreadListPrimitive.New>
|
||||
<div className="mt-4 mb-2">
|
||||
<h2 className="text-sm font-medium text-[#475569] dark:text-zinc-300 px-2.5">
|
||||
Recent Chats
|
||||
</h2>
|
||||
</div>
|
||||
<ThreadListPrimitive.Items components={{ ThreadListItem }} />
|
||||
</ThreadListPrimitive.Root>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ScrollArea className="flex-1">
|
||||
<div className="flex h-full flex-col items-center px-4 pt-8 justify-end">
|
||||
<ThreadWelcome />
|
||||
<ScrollArea className="flex-1 w-full">
|
||||
<div className="flex h-full flex-col w-full items-center px-4 pt-8 justify-end">
|
||||
<ThreadWelcome
|
||||
composerInputRef={
|
||||
composerInputRef as React.RefObject<HTMLTextAreaElement>
|
||||
}
|
||||
/>
|
||||
|
||||
<ThreadPrimitive.Messages
|
||||
components={{
|
||||
@@ -157,9 +219,13 @@ export const Thread: FC<ThreadProps> = ({ sidebarOpen, setSidebarOpen, onResetUs
|
||||
</div>
|
||||
</ScrollArea>
|
||||
|
||||
<div className="sticky bottom-0 mt-3 flex w-full max-w-[var(--thread-max-width)] flex-col items-center justify-end rounded-t-lg bg-inherit px-4 pb-4 mx-auto">
|
||||
<div className="sticky bottom-0 flex w-full max-w-[var(--thread-max-width)] flex-col items-center justify-end rounded-t-lg bg-inherit px-4 md:pb-4 mx-auto">
|
||||
<ThreadScrollToBottom />
|
||||
<Composer />
|
||||
<Composer
|
||||
composerInputRef={
|
||||
composerInputRef as React.RefObject<HTMLTextAreaElement>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</ThreadPrimitive.Root>
|
||||
);
|
||||
@@ -179,60 +245,88 @@ const ThreadScrollToBottom: FC = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const ThreadWelcome: FC = () => {
|
||||
interface ThreadWelcomeProps {
|
||||
composerInputRef: React.RefObject<HTMLTextAreaElement>;
|
||||
}
|
||||
|
||||
const ThreadWelcome: FC<ThreadWelcomeProps> = ({ composerInputRef }) => {
|
||||
return (
|
||||
<ThreadPrimitive.Empty>
|
||||
<div className="flex w-full max-w-[var(--thread-max-width)] flex-grow flex-col">
|
||||
<div className="flex w-full flex-grow flex-col items-center justify-start h-[calc(100vh-23rem)] md:h-[calc(100vh-18rem)]">
|
||||
<div className="flex w-full flex-grow flex-col mt-8 md:h-[calc(100vh-15rem)]">
|
||||
<div className="flex w-full flex-grow flex-col items-center justify-start">
|
||||
<div className="flex flex-col items-center justify-center h-full">
|
||||
<div className="text-5xl font-bold text-[#1e293b] dark:text-white mb-2">
|
||||
Mem0 Demo
|
||||
<div className="text-[2rem] leading-[1] tracking-[-0.02em] md:text-4xl font-bold text-[#1e293b] dark:text-white mb-2 text-center md:w-full w-5/6">
|
||||
Mem0 - ChatGPT with memory
|
||||
</div>
|
||||
<p className="text-center text-sm text-[#1e293b] dark:text-white mb-2 w-3/4">
|
||||
A personalized AI chat app powered by Mem0 that remembers your preferences, facts, and memories.
|
||||
<p className="text-center text-md text-[#1e293b] dark:text-white mb-2 md:w-3/4 w-5/6">
|
||||
A personalized AI chat app powered by Mem0 that remembers your
|
||||
preferences, facts, and memories.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center justify-center">
|
||||
<p className="mt-4 font-medium text-[#1e293b] dark:text-white">
|
||||
<div className="flex flex-col items-center justify-center mt-16">
|
||||
<p className="mt-4 font-medium text-[#1e293b] dark:text-white">
|
||||
How can I help you today?
|
||||
</p>
|
||||
<ThreadWelcomeSuggestions />
|
||||
<ThreadWelcomeSuggestions composerInputRef={composerInputRef} />
|
||||
</div>
|
||||
</div>
|
||||
</ThreadPrimitive.Empty>
|
||||
);
|
||||
};
|
||||
|
||||
const ThreadWelcomeSuggestions: FC = () => {
|
||||
interface ThreadWelcomeSuggestionsProps {
|
||||
composerInputRef: React.RefObject<HTMLTextAreaElement>;
|
||||
}
|
||||
|
||||
const ThreadWelcomeSuggestions: FC<ThreadWelcomeSuggestionsProps> = ({ composerInputRef }) => {
|
||||
return (
|
||||
<div className="mt-3 flex w-full items-stretch justify-center gap-4 dark:text-white">
|
||||
<div className="mt-3 flex flex-col md:flex-row w-full md:items-stretch justify-center gap-4 dark:text-white items-center">
|
||||
<ThreadPrimitive.Suggestion
|
||||
className="hover:bg-[#eef2ff] dark:hover:bg-zinc-800 flex max-w-sm grow basis-0 flex-col items-center justify-center rounded-[2rem] border border-[#e2e8f0] dark:border-zinc-700 p-3 transition-colors ease-in"
|
||||
className="hover:bg-[#eef2ff] w-full dark:hover:bg-zinc-800 flex max-w-sm grow basis-0 flex-col items-center justify-center rounded-[2rem] border border-[#e2e8f0] dark:border-zinc-700 p-3 transition-colors ease-in"
|
||||
prompt="I like to travel to "
|
||||
method="replace"
|
||||
onClick={() => {
|
||||
composerInputRef.current?.focus();
|
||||
}}
|
||||
>
|
||||
<span className="line-clamp-2 text-ellipsis text-sm font-semibold">Travel</span>
|
||||
<span className="line-clamp-2 text-ellipsis text-sm font-semibold">
|
||||
Travel
|
||||
</span>
|
||||
</ThreadPrimitive.Suggestion>
|
||||
<ThreadPrimitive.Suggestion
|
||||
className="hover:bg-[#eef2ff] dark:hover:bg-zinc-800 flex max-w-sm grow basis-0 flex-col items-center justify-center rounded-[2rem] border border-[#e2e8f0] dark:border-zinc-700 p-3 transition-colors ease-in"
|
||||
className="hover:bg-[#eef2ff] w-full dark:hover:bg-zinc-800 flex max-w-sm grow basis-0 flex-col items-center justify-center rounded-[2rem] border border-[#e2e8f0] dark:border-zinc-700 p-3 transition-colors ease-in"
|
||||
prompt="I like to eat "
|
||||
method="replace"
|
||||
onClick={() => {
|
||||
composerInputRef.current?.focus();
|
||||
}}
|
||||
>
|
||||
<span className="line-clamp-2 text-ellipsis text-sm font-semibold">Food</span>
|
||||
<span className="line-clamp-2 text-ellipsis text-sm font-semibold">
|
||||
Food
|
||||
</span>
|
||||
</ThreadPrimitive.Suggestion>
|
||||
<ThreadPrimitive.Suggestion
|
||||
className="hover:bg-[#eef2ff] dark:hover:bg-zinc-800 flex max-w-sm grow basis-0 flex-col items-center justify-center rounded-[2rem] border border-[#e2e8f0] dark:border-zinc-700 p-3 transition-colors ease-in"
|
||||
className="hover:bg-[#eef2ff] w-full dark:hover:bg-zinc-800 flex max-w-sm grow basis-0 flex-col items-center justify-center rounded-[2rem] border border-[#e2e8f0] dark:border-zinc-700 p-3 transition-colors ease-in"
|
||||
prompt="I am working on "
|
||||
method="replace"
|
||||
onClick={() => {
|
||||
composerInputRef.current?.focus();
|
||||
}}
|
||||
>
|
||||
<span className="line-clamp-2 text-ellipsis text-sm font-semibold">Project details</span>
|
||||
<span className="line-clamp-2 text-ellipsis text-sm font-semibold">
|
||||
Project details
|
||||
</span>
|
||||
</ThreadPrimitive.Suggestion>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const Composer: FC = () => {
|
||||
interface ComposerProps {
|
||||
composerInputRef: React.RefObject<HTMLTextAreaElement>;
|
||||
}
|
||||
|
||||
const Composer: FC<ComposerProps> = ({ composerInputRef }) => {
|
||||
return (
|
||||
<ComposerPrimitive.Root className="focus-within:border-[#4f46e5]/20 dark:focus-within:border-[#6366f1]/20 flex w-full flex-wrap items-end rounded-full border border-[#e2e8f0] dark:border-zinc-700 bg-white dark:bg-zinc-800 px-2.5 shadow-sm transition-colors ease-in">
|
||||
<ComposerPrimitive.Input
|
||||
@@ -240,6 +334,7 @@ const Composer: FC = () => {
|
||||
autoFocus
|
||||
placeholder="Message to Mem0..."
|
||||
className="placeholder:text-zinc-400 dark:placeholder:text-zinc-500 max-h-40 flex-grow resize-none border-none bg-transparent px-2 py-4 text-sm outline-none focus:ring-0 disabled:cursor-not-allowed text-[#1e293b] dark:text-zinc-200"
|
||||
ref={composerInputRef}
|
||||
/>
|
||||
<ComposerAction />
|
||||
</ComposerPrimitive.Root>
|
||||
@@ -335,22 +430,22 @@ const EditComposer: FC = () => {
|
||||
const AssistantMessage: FC = () => {
|
||||
const content = useMessage((m) => m.content);
|
||||
const markdownText = React.useMemo(() => {
|
||||
if (!content) return '';
|
||||
if (typeof content === 'string') return content;
|
||||
if (Array.isArray(content) && content.length > 0 && 'text' in content[0]) {
|
||||
return content[0].text || '';
|
||||
if (!content) return "";
|
||||
if (typeof content === "string") return content;
|
||||
if (Array.isArray(content) && content.length > 0 && "text" in content[0]) {
|
||||
return content[0].text || "";
|
||||
}
|
||||
return '';
|
||||
return "";
|
||||
}, [content]);
|
||||
|
||||
return (
|
||||
<MessagePrimitive.Root className="grid grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr] relative w-full max-w-[var(--thread-max-width)] py-4">
|
||||
<div className="text-[#1e293b] dark:text-zinc-200 max-w-[calc(var(--thread-max-width)*0.8)] break-words leading-7 col-span-2 col-start-2 row-start-1 my-1.5 bg-white dark:bg-zinc-800 rounded-3xl px-5 py-2.5 border border-[#e2e8f0] dark:border-zinc-700 shadow-sm">
|
||||
<MemoryUI />
|
||||
<MarkdownRenderer
|
||||
<MarkdownRenderer
|
||||
markdownText={markdownText}
|
||||
showCopyButton={true}
|
||||
isDarkMode={document.documentElement.classList.contains('dark')}
|
||||
isDarkMode={document.documentElement.classList.contains("dark")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -400,7 +495,10 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
|
||||
return (
|
||||
<BranchPickerPrimitive.Root
|
||||
hideWhenSingleBranch
|
||||
className={cn("text-[#475569] dark:text-zinc-300 inline-flex items-center text-xs", className)}
|
||||
className={cn(
|
||||
"text-[#475569] dark:text-zinc-300 inline-flex items-center text-xs",
|
||||
className
|
||||
)}
|
||||
{...rest}
|
||||
>
|
||||
<BranchPickerPrimitive.Previous asChild>
|
||||
@@ -428,7 +526,13 @@ const BranchPicker: FC<BranchPickerPrimitive.Root.Props> = ({
|
||||
|
||||
const CircleStopIcon = () => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="currentColor" width="16" height="16">
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16 16"
|
||||
fill="currentColor"
|
||||
width="16"
|
||||
height="16"
|
||||
>
|
||||
<rect width="10" height="10" x="3" y="3" rx="2" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
||||
const GithubButton = ({ url }: { url: string }) => {
|
||||
const GithubButton = ({ url, className, text }: { url: string, className?: string, text?: string }) => {
|
||||
return (
|
||||
<a
|
||||
href={url}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center bg-black text-white rounded-full shadow-lg hover:bg-gray-800 transition border border-gray-700"
|
||||
className={cn("flex items-center bg-black text-white rounded-full shadow-lg hover:bg-gray-800 transition border border-gray-700", className)}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 24 24"
|
||||
fill="white"
|
||||
className="w-6 h-6"
|
||||
className="w-5 h-5 md:w-6 md:h-6"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
@@ -20,6 +20,7 @@ const GithubButton = ({ url }: { url: string }) => {
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{text && <span className="ml-2">{text}</span>}
|
||||
</a>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import darkLogo from "@/images/dark.svg";
|
||||
import lightLogo from "@/images/light.svg";
|
||||
import React from "react";
|
||||
import Image from "next/image";
|
||||
|
||||
@@ -27,7 +29,7 @@ export default function ThemeAwareLogo({
|
||||
}
|
||||
|
||||
// For default variant, use the full logo image
|
||||
const logoSrc = isDarkMode ? "/images/dark.svg" : "/images/light.svg";
|
||||
const logoSrc = isDarkMode ? darkLogo : lightLogo;
|
||||
|
||||
return (
|
||||
<Image
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-messages-square">
|
||||
<path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2z">
|
||||
</path>
|
||||
<path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1">
|
||||
</path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 371 B |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-messages-square">
|
||||
<path d="M14 9a2 2 0 0 1-2 2H6l-4 4V4c0-1.1.9-2 2-2h8a2 2 0 0 1 2 2z">
|
||||
</path>
|
||||
<path d="M18 9h2a2 2 0 0 1 2 2v11l-4-4h-6a2 2 0 0 1-2-2v-1">
|
||||
</path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 378 B |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
@@ -2,6 +2,24 @@ import type { NextConfig } from "next";
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
/* config options here */
|
||||
assetPrefix: "https://demo.mem0.ai",
|
||||
images: {
|
||||
path: "https://demo.mem0.ai",
|
||||
},
|
||||
async headers() {
|
||||
return [
|
||||
{
|
||||
// matching all API routes
|
||||
source: "/api/:path*",
|
||||
headers: [
|
||||
{ key: "Access-Control-Allow-Credentials", value: "true" },
|
||||
{ key: "Access-Control-Allow-Origin", value: "*" },
|
||||
{ key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT" },
|
||||
{ key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" },
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
export default nextConfig;
|
||||
|
||||