Initial release: Mem0 local server memory provider for Hermes-Agent
- Self-hosted Mem0 integration (no cloud dependency) - Async prefetch with ~40ms latency - Automatic context injection via pre_llm_call hook - Circuit breaker for server resilience - Full tool support: profile, search, conclude
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
# Mem0 Local Hermes Plugin
|
||||
|
||||
Self-hosted Mem0 memory provider for Hermes-Agent. Provides semantic memory search, automatic fact extraction, and context injection without tool calls.
|
||||
|
||||
## Features
|
||||
|
||||
- **Local Mem0 server** — No cloud dependency, full data privacy
|
||||
- **Async prefetch** — Memory retrieval happens in background (~40ms)
|
||||
- **Context injection** — Relevant memories injected directly into LLM prompt
|
||||
- **Automatic fact extraction** — Server-side LLM extracts facts from conversations
|
||||
- **Semantic search** — Find memories by meaning, not keywords
|
||||
- **Circuit breaker** — Automatic failover on server unavailability
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Mem0 server running locally**:
|
||||
|
||||
Using Docker:
|
||||
```bash
|
||||
docker run -d -p 8000:8000 mem0ai/mem0:latest
|
||||
```
|
||||
|
||||
Or via Docker Compose with custom config:
|
||||
```yaml
|
||||
version: "3.8"
|
||||
services:
|
||||
mem0:
|
||||
image: mem0ai/mem0:latest
|
||||
ports:
|
||||
- "8000:8000"
|
||||
environment:
|
||||
- MEM0_CONFIG_PATH=/app/config.yaml
|
||||
volumes:
|
||||
- ./mem0-config.yaml:/app/config.yaml
|
||||
- mem0_data:/app/data
|
||||
volumes:
|
||||
mem0_data:
|
||||
```
|
||||
|
||||
2. **Verify server is reachable**:
|
||||
```bash
|
||||
curl http://localhost:8000/health
|
||||
```
|
||||
|
||||
Your setup uses port 8889:
|
||||
```bash
|
||||
curl http://10.0.0.150:8889/health
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
From GitHub repository:
|
||||
```bash
|
||||
hermes plugins install https://github.com/yourusername/mem0-local-hermes-plugin.git
|
||||
```
|
||||
|
||||
Or with shorthand:
|
||||
```bash
|
||||
hermes plugins install yourusername/mem0-local-hermes-plugin
|
||||
```
|
||||
|
||||
From local directory (during development):
|
||||
```bash
|
||||
hermes plugins install /path/to/mem0-local-hermes-plugin
|
||||
```
|
||||
|
||||
The installer will prompt for:
|
||||
- `MEM0_BASE_URL` — Your local Mem0 server URL (default: `http://localhost:8000`)
|
||||
- `MEM0_USER_ID` — User identifier for memory scoping (default: `hermes-user`)
|
||||
|
||||
## Configuration
|
||||
|
||||
The plugin supports two configuration methods that work together:
|
||||
|
||||
1. **Environment variables** (`~/.hermes/.env`) - Primary configuration
|
||||
2. **Config file** (`~/.hermes/mem0-local.json`) - Optional overrides
|
||||
|
||||
**Precedence**: Config file values override environment variables. This allows you to set defaults in `.env` and override specific values in the JSON file.
|
||||
|
||||
### Method 1: Environment Variables (Recommended)
|
||||
|
||||
Set in `~/.hermes/.env`:
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `MEM0_BASE_URL` | Local Mem0 server URL | `http://localhost:8000` |
|
||||
| `MEM0_USER_ID` | User identifier | `hermes-user` |
|
||||
| `MEM0_AGENT_ID` | Agent identifier | `hermes` |
|
||||
|
||||
Example:
|
||||
```env
|
||||
MEM0_BASE_URL=http://10.0.0.150:8889
|
||||
MEM0_USER_ID=henry_hofmann
|
||||
MEM0_AGENT_ID=hermes
|
||||
```
|
||||
|
||||
### Method 2: Config File (Optional Overrides)
|
||||
|
||||
Create `~/.hermes/mem0-local.json` to override specific settings:
|
||||
```json
|
||||
{
|
||||
"base_url": "http://10.0.0.150:8889",
|
||||
"user_id": "henry_hofmann",
|
||||
"agent_id": "hermes",
|
||||
"rerank": true,
|
||||
"timeout": 10.0
|
||||
}
|
||||
```
|
||||
|
||||
Example for your setup:
|
||||
```json
|
||||
{
|
||||
"base_url": "http://10.0.0.150:8889",
|
||||
"user_id": "henry_hofmann",
|
||||
"agent_id": "hermes",
|
||||
"rerank": true,
|
||||
"timeout": 10.0
|
||||
}
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Activate the Memory Provider
|
||||
|
||||
```bash
|
||||
hermes memory mem0-local
|
||||
```
|
||||
|
||||
### Restart Gateway
|
||||
|
||||
```bash
|
||||
hermes gateway restart
|
||||
```
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **User message received** → `queue_prefetch()` spawns background thread
|
||||
2. **Mem0 search** → Semantic search for relevant memories (~40ms)
|
||||
3. **Context injection** → Results injected via `pre_llm_call` hook
|
||||
4. **LLM receives** → User message + memory context (no tool call needed!)
|
||||
|
||||
**Example**:
|
||||
```
|
||||
User: "Hey, is a new episode out from my favorite anime?"
|
||||
|
||||
↓ [Background: mem0.prefetch() searches for "favorite anime"]
|
||||
|
||||
LLM receives:
|
||||
"""
|
||||
Hey, is a new episode out from my favorite anime?
|
||||
|
||||
## Mem0 Memory
|
||||
- My favorite animes are Naruto, One Piece, and Demon Slayer (score: 0.87)
|
||||
"""
|
||||
|
||||
Assistant: "Let me check for new episodes of Naruto, One Piece, and Demon Slayer..."
|
||||
```
|
||||
|
||||
### Available Tools
|
||||
|
||||
The plugin also provides explicit memory tools:
|
||||
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `mem0_profile` | Retrieve all stored memories about the user |
|
||||
| `mem0_search` | Search memories by semantic similarity |
|
||||
| `mem0_conclude` | Store a fact verbatim (no LLM extraction) |
|
||||
|
||||
**Tool usage examples**:
|
||||
|
||||
```
|
||||
# Get all memories
|
||||
mem0_profile()
|
||||
|
||||
# Search with reranking
|
||||
mem0_search(query="project deadlines", rerank=true, top_k=5)
|
||||
|
||||
# Store a fact explicitly
|
||||
mem0_conclude(conclusion="I prefer Python over JavaScript for backend development")
|
||||
```
|
||||
|
||||
## Circuit Breaker
|
||||
|
||||
After 5 consecutive API failures, the plugin pauses requests for 120 seconds to avoid hammering a down server. The breaker resets automatically.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Mem0 server temporarily unavailable"
|
||||
|
||||
- Check server is running: `curl http://your-server:port/health`
|
||||
- Verify `MEM0_BASE_URL` is correct
|
||||
- Wait 2 minutes for circuit breaker to reset
|
||||
|
||||
### "No memories stored yet"
|
||||
|
||||
- Mem0 extracts facts automatically from conversations
|
||||
- Or use `mem0_conclude` to store facts explicitly
|
||||
|
||||
### Memory not injected
|
||||
|
||||
- Check `is_available()` returns `True` in logs
|
||||
- Verify `prefetch()` is being called (debug logs)
|
||||
- Ensure Mem0 server has indexed memories
|
||||
- Check network connectivity to your local server
|
||||
|
||||
### Connection issues
|
||||
|
||||
If your Mem0 server is on a different machine (like your 10.0.0.150):
|
||||
- Ensure firewall allows connections on port 8889
|
||||
- Verify the server binds to 0.0.0.0, not just localhost
|
||||
- Check network routing between Hermes-Agent and Mem0 server
|
||||
|
||||
## Differences from Cloud Version
|
||||
|
||||
| Aspect | Cloud Version | Local Version |
|
||||
|--------|--------------|---------------|
|
||||
| **Client** | `mem0.MemoryClient(api_key=...)` | HTTP requests to local server |
|
||||
| **Auth** | API key | None (local network) |
|
||||
| **Config** | `MEM0_API_KEY` | `MEM0_BASE_URL` |
|
||||
| **Latency** | Network-dependent | ~40ms (local) |
|
||||
| **Privacy** | Cloud processing | Full local control |
|
||||
| **Cost** | Pay-per-use | Free (self-hosted) |
|
||||
|
||||
## Development
|
||||
|
||||
For development, install from local path:
|
||||
```bash
|
||||
hermes plugins install /path/to/mem0-local-hermes-plugin
|
||||
```
|
||||
|
||||
Watch for changes:
|
||||
```bash
|
||||
# In plugin directory
|
||||
hermes gateway restart # After each change
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
Reference in New Issue
Block a user