Clean up release highlights copy and removing emdash from the docs (#5984)
This commit is contained in:
@@ -18,7 +18,7 @@ icon: "bolt"
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
Working in TypeScript? The OSS `Memory` class in the Node SDK (`mem0ai/oss`) is also fully async — every method returns a `Promise` and must be `await`ed. Python’s `AsyncMemory` serves the same purpose within Python async frameworks like FastAPI. Both runtimes support awaited memory operations; choose the SDK that matches your language.
|
||||
Working in TypeScript? The OSS `Memory` class in the Node SDK (`mem0ai/oss`) is also fully async: every method returns a `Promise` and must be `await`ed. Python’s `AsyncMemory` serves the same purpose within Python async frameworks like FastAPI. Both runtimes support awaited memory operations; choose the SDK that matches your language.
|
||||
</Note>
|
||||
|
||||
## Feature anatomy
|
||||
@@ -151,7 +151,7 @@ async def robust_memory_search():
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Always cap retries—runaway loops can keep the event loop busy and block other tasks.
|
||||
Always cap retries. Runaway loops can keep the event loop busy and block other tasks.
|
||||
</Warning>
|
||||
|
||||
---
|
||||
@@ -301,7 +301,7 @@ async def handle_memory_operation_errors():
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Catch and log `ValueError` exceptions from invalid inputs—async stack traces can otherwise disappear inside background tasks.
|
||||
Catch and log `ValueError` exceptions from invalid inputs: async stack traces can otherwise disappear inside background tasks.
|
||||
</Warning>
|
||||
|
||||
### Serve through FastAPI
|
||||
@@ -331,7 +331,7 @@ async def search_memories(query: str, user_id: str, limit: int = 10):
|
||||
```
|
||||
|
||||
<Tip>
|
||||
Create one `AsyncMemory` instance per process when using FastAPI—startup hooks are a good place to configure and reuse it.
|
||||
Create one `AsyncMemory` instance per process when using FastAPI: startup hooks are a good place to configure and reuse it.
|
||||
</Tip>
|
||||
|
||||
### Instrument logging
|
||||
@@ -378,13 +378,13 @@ async def logged_memory_add(memory, messages, user_id):
|
||||
- Run a quick add/search cycle and confirm the returned memory content matches your input.
|
||||
- Inspect application logs to ensure async tasks complete without blocking the event loop.
|
||||
- In FastAPI or other frameworks, hit health endpoints to verify the shared client handles concurrent requests.
|
||||
- Monitor retry counters—unexpected spikes indicate configuration or connectivity issues.
|
||||
- Monitor retry counters: unexpected spikes indicate configuration or connectivity issues.
|
||||
|
||||
---
|
||||
|
||||
## Best practices
|
||||
|
||||
1. **Keep operations awaited:** Forgetting `await` is the fastest way to miss writes—lint for it or add helper wrappers.
|
||||
1. **Keep operations awaited:** Forgetting `await` is the fastest way to miss writes: lint for it or add helper wrappers.
|
||||
2. **Scope deletions carefully:** Always supply `user_id`, `agent_id`, or `run_id` to avoid purging too much data.
|
||||
3. **Batch writes thoughtfully:** Use `asyncio.gather` for throughput but cap concurrency based on backend capacity.
|
||||
4. **Log errors with context:** Capture user and agent scopes to triage failures quickly.
|
||||
|
||||
@@ -111,7 +111,7 @@ results = m.search(
|
||||
|
||||
### Wildcard matching
|
||||
|
||||
Allow any value for a field while still requiring the field to exist—handy when the mere presence of a field matters.
|
||||
Allow any value for a field while still requiring the field to exist: handy when the mere presence of a field matters.
|
||||
|
||||
```python
|
||||
# Match any value for a field
|
||||
@@ -191,7 +191,7 @@ results = m.search(
|
||||
```
|
||||
|
||||
<Info icon="check">
|
||||
Inspect the response metadata—each returned memory should satisfy the combined logic tree exactly. If results look too broad, log the raw filters sent to your vector store.
|
||||
Inspect the response metadata: each returned memory should satisfy the combined logic tree exactly. If results look too broad, log the raw filters sent to your vector store.
|
||||
</Info>
|
||||
|
||||
---
|
||||
@@ -215,7 +215,7 @@ config = {
|
||||
```
|
||||
|
||||
<Info icon="check">
|
||||
After enabling indexing, benchmark the same query—latency should drop once the store can prune documents on indexed fields before vector scoring.
|
||||
After enabling indexing, benchmark the same query: latency should drop once the store can prune documents on indexed fields before vector scoring.
|
||||
</Info>
|
||||
|
||||
<Tip>
|
||||
@@ -252,7 +252,7 @@ Vector store support varies. Confirm operator coverage before shipping:
|
||||
Full comparison, list, and logical support. Handles deeply nested boolean logic efficiently.
|
||||
</Accordion>
|
||||
<Accordion title="Chroma">
|
||||
Equality and basic comparisons only. Limited nesting—break large trees into smaller calls.
|
||||
Equality and basic comparisons only. Limited nesting: break large trees into smaller calls.
|
||||
</Accordion>
|
||||
<Accordion title="Pinecone">
|
||||
Comparisons plus `in`/`nin`. Text operators are constrained; rely on tags where possible.
|
||||
@@ -413,7 +413,7 @@ except ValueError as e:
|
||||
## Best practices
|
||||
|
||||
1. **Use indexed fields first:** Order filters so equality checks run before complex string operations.
|
||||
2. **Combine operators intentionally:** Keep logical trees readable—large nests are harder to debug.
|
||||
2. **Combine operators intentionally:** Keep logical trees readable: large nests are harder to debug.
|
||||
3. **Test performance regularly:** Benchmark critical queries with production-like payloads.
|
||||
4. **Plan graceful degradation:** Provide fallback filters when an operator isn’t available.
|
||||
5. **Validate syntax early:** Catch malformed filters during development to protect agents at runtime.
|
||||
|
||||
@@ -94,7 +94,7 @@ await client.add(messages, { userId: "alice" });
|
||||
</CodeGroup>
|
||||
|
||||
<Info icon="check">
|
||||
Inspect the response payload—the memories list should include entries extracted from the menu image as well as the text turns.
|
||||
Inspect the response payload: the memories list should include entries extracted from the menu image as well as the text turns.
|
||||
</Info>
|
||||
|
||||
### Upload local images as base64
|
||||
@@ -294,7 +294,7 @@ try {
|
||||
|
||||
- After calling `add`, inspect the returned memories and confirm they include image-derived text (menu items, receipt totals, etc.).
|
||||
- Run a follow-up `search` for a detail from the image; the memory should surface alongside related text.
|
||||
- Monitor image upload latency—large files should still complete under your acceptable response time.
|
||||
- Monitor image upload latency: large files should still complete under your acceptable response time.
|
||||
- Log file size and URL sources to troubleshoot repeated failures.
|
||||
|
||||
---
|
||||
|
||||
@@ -107,7 +107,7 @@ print(response.choices[0].message.content)
|
||||
|
||||
## Verify the feature is working
|
||||
|
||||
- Compare responses from Mem0 vs. OpenAI for identical prompts—both should return the same structure (`choices`, `usage`, etc.).
|
||||
- Compare responses from Mem0 vs. OpenAI for identical prompts. Both should return the same structure (`choices`, `usage`, etc.).
|
||||
- Inspect stored memories after each request to confirm the fact extraction captured the right details.
|
||||
- Test switching between hosted (`Mem0(api_key=...)`) and OSS configurations to ensure both respect the same request body.
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ icon: "list"
|
||||
|
||||
# Self-Hosting Features Overview
|
||||
|
||||
Mem0 Open Source ships with capabilities that adapt memory behavior for production workloads—async operations, multimodal inputs, and fine-tuned retrieval. Configure these features with code or YAML to match your application's needs.
|
||||
Mem0 Open Source ships with capabilities that adapt memory behavior for production workloads: async operations, multimodal inputs, and fine-tuned retrieval. Configure these features with code or YAML to match your application's needs.
|
||||
|
||||
<Info>
|
||||
Start with the <Link href="/open-source/python-quickstart">Python quickstart</Link> to validate basic memory operations, then enable the features below when you need them.
|
||||
|
||||
@@ -18,7 +18,7 @@ Reranker-enhanced search adds a second scoring pass after vector retrieval so Me
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
All configuration snippets translate directly to the TypeScript SDK—swap dictionaries for objects while keeping the same keys (`provider`, `config`, `rerank` flags).
|
||||
All configuration snippets translate directly to the TypeScript SDK: swap dictionaries for objects while keeping the same keys (`provider`, `config`, `rerank` flags).
|
||||
</Note>
|
||||
|
||||
---
|
||||
@@ -71,7 +71,7 @@ m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
<Info icon="check">
|
||||
Confirm `results["results"][0]["score"]` reflects the reranker output—if the field is missing, the reranker was not applied.
|
||||
Confirm `results["results"][0]["score"]` reflects the reranker output: if the field is missing, the reranker was not applied.
|
||||
</Info>
|
||||
|
||||
<Tip>
|
||||
@@ -240,7 +240,7 @@ except Exception as exc:
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Always fall back to vector-only search—dropped queries introduce bigger accuracy issues than slightly less relevant ordering.
|
||||
Always fall back to vector-only search: dropped queries introduce bigger accuracy issues than slightly less relevant ordering.
|
||||
</Warning>
|
||||
|
||||
### Migrate from v0.x
|
||||
@@ -326,7 +326,7 @@ results = m.search(
|
||||
```
|
||||
|
||||
<Info icon="check">
|
||||
Verify filtered reranked searches still respect every metadata clause—reranking only reorders candidates, it never bypasses filters.
|
||||
Verify filtered reranked searches still respect every metadata clause: reranking only reorders candidates, it never bypasses filters.
|
||||
</Info>
|
||||
|
||||
### Real-world playbooks
|
||||
@@ -394,7 +394,7 @@ results = m.search(
|
||||
```
|
||||
|
||||
<Tip>
|
||||
Reuse this pattern for other lifestyle queries—swap the filters and prompt text without changing the rerank configuration.
|
||||
Reuse this pattern for other lifestyle queries: swap the filters and prompt text without changing the rerank configuration.
|
||||
</Tip>
|
||||
|
||||
<Note>
|
||||
|
||||
@@ -18,7 +18,7 @@ The Mem0 REST API server exposes every OSS memory operation over HTTP. Run it al
|
||||
</Warning>
|
||||
|
||||
<Warning>
|
||||
**OSS vs Platform API paths:** The self-hosted OSS server does **not** use the `/v1/` prefix. For example, the endpoint is `POST /memories`, not `POST /v1/memories/`. The [API Reference](/api-reference) documents the hosted platform at `api.mem0.ai` which uses `/v1/` paths — those do not apply to the OSS server.
|
||||
**OSS vs Platform API paths:** The self-hosted OSS server does **not** use the `/v1/` prefix. For example, the endpoint is `POST /memories`, not `POST /v1/memories/`. The [API Reference](/api-reference) documents the hosted platform at `api.mem0.ai` which uses `/v1/` paths: those do not apply to the OSS server.
|
||||
</Warning>
|
||||
|
||||
<Warning>
|
||||
@@ -111,7 +111,7 @@ docker build -t mem0-api-server .
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
`JWT_SECRET` is required once auth is enabled — the server returns `500` on auth endpoints if it's unset. Generate one with `openssl rand -base64 48`. See [Self-Hosted Setup](/open-source/setup#configure-the-environment) for the full env var table.
|
||||
`JWT_SECRET` is required once auth is enabled: the server returns `500` on auth endpoints if it's unset. Generate one with `openssl rand -base64 48`. See [Self-Hosted Setup](/open-source/setup#configure-the-environment) for the full env var table.
|
||||
</Note>
|
||||
|
||||
<Tip>
|
||||
@@ -133,7 +133,7 @@ Auth is on by default. Protected endpoints require either a JWT (from the dashbo
|
||||
| Bearer JWT | `Authorization: Bearer <access_token>` | Dashboard sessions; tokens come from `POST /auth/login` and refresh via `POST /auth/refresh` |
|
||||
| Per-user API key | `X-API-Key: m0sk_...` | Programmatic access scoped to a single dashboard user |
|
||||
| Legacy `ADMIN_API_KEY` | `X-API-Key: <env value>` | Back-compat for deployments that set the `ADMIN_API_KEY` env var |
|
||||
| `AUTH_DISABLED=true` | — | Local development only; bypasses auth entirely |
|
||||
| `AUTH_DISABLED=true` | N/A | Local development only; bypasses auth entirely |
|
||||
|
||||
The `/docs` OpenAPI explorer supports both auth modes. Click **Authorize** at the top of the page and paste either `Bearer <access_token>` (JWT) or your `X-API-Key` value. Protected endpoints return `401` until you authorize.
|
||||
|
||||
@@ -142,7 +142,7 @@ The `/docs` OpenAPI explorer supports both auth modes. Click **Authorize** at th
|
||||
Register the first admin (only works when no user exists yet), then log in:
|
||||
|
||||
```bash
|
||||
# First admin only — returns 403 after the first admin is registered
|
||||
# First admin only: returns 403 after the first admin is registered
|
||||
curl -X POST http://localhost:8888/auth/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"name": "Admin", "email": "admin@example.com", "password": "strong-password"}'
|
||||
@@ -170,7 +170,7 @@ When the access token expires, exchange the refresh token at `POST /auth/refresh
|
||||
|
||||
### Create and use a per-user API key
|
||||
|
||||
Create a key from the dashboard **API Keys** page, or call `POST /api-keys` with a JWT. The full `m0sk_...` value is returned **once** at creation time — store it securely.
|
||||
Create a key from the dashboard **API Keys** page, or call `POST /api-keys` with a JWT. The full `m0sk_...` value is returned **once** at creation time: store it securely.
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8888/memories \
|
||||
@@ -186,14 +186,14 @@ Per-user keys inherit the creating user's scope. List or revoke them via `GET /a
|
||||
|
||||
### Legacy `ADMIN_API_KEY`
|
||||
|
||||
Set the `ADMIN_API_KEY` environment variable and send it as `X-API-Key`. The request is treated as admin-level and is not tied to a dashboard user. This mode is kept for back-compat with older self-hosted deployments — prefer JWT or per-user keys for new setups.
|
||||
Set the `ADMIN_API_KEY` environment variable and send it as `X-API-Key`. The request is treated as admin-level and is not tied to a dashboard user. This mode is kept for back-compat with older self-hosted deployments: prefer JWT or per-user keys for new setups.
|
||||
|
||||
```bash
|
||||
ADMIN_API_KEY=your-long-admin-key
|
||||
```
|
||||
|
||||
<Warning>
|
||||
Setting `AUTH_DISABLED=true` makes every protected endpoint open — the server logs a warning at startup when it's enabled. The server also warns when `ADMIN_API_KEY` is shorter than 16 characters. Never enable `AUTH_DISABLED` in production, and always use a long `ADMIN_API_KEY` if you rely on the legacy fallback.
|
||||
Setting `AUTH_DISABLED=true` makes every protected endpoint open: the server logs a warning at startup when it's enabled. The server also warns when `ADMIN_API_KEY` is shorter than 16 characters. Never enable `AUTH_DISABLED` in production, and always use a long `ADMIN_API_KEY` if you rely on the legacy fallback.
|
||||
</Warning>
|
||||
|
||||
---
|
||||
|
||||
@@ -79,7 +79,7 @@ Mem0 Open Source delivers the same adaptive memory engine as the platform, but p
|
||||
- LLM: OpenAI `gpt-4.1-nano-2025-04-14` (override with `MEM0_DEFAULT_LLM_MODEL`)
|
||||
- Embeddings: OpenAI `text-embedding-3-small` (override with `MEM0_DEFAULT_EMBEDDER_MODEL`)
|
||||
- Vector store: Postgres + pgvector
|
||||
- Bundled providers: `openai`, `anthropic`, `gemini` — switch from the Configuration page
|
||||
- Bundled providers: `openai`, `anthropic`, `gemini`: switch from the Configuration page
|
||||
|
||||
See <Link href="/open-source/setup#supported-providers">Self-Hosted Setup</Link> for the full provider list and how to extend it.
|
||||
</Note>
|
||||
|
||||
+12
-12
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: "Self-Hosted Setup"
|
||||
description: "Stand up the Mem0 REST server and dashboard in a few minutes — admin account, API keys, and a live audit log included."
|
||||
description: "Stand up the Mem0 REST server and dashboard in a few minutes, with an admin account, API keys, and a live audit log included."
|
||||
icon: "rocket-launch"
|
||||
---
|
||||
|
||||
@@ -22,7 +22,7 @@ The self-hosted bundle ships the REST API and a web dashboard together. Configur
|
||||
## Prerequisites
|
||||
|
||||
- Docker and Docker Compose (the reference path).
|
||||
- An `OPENAI_API_KEY` (or equivalent — the server reads the same component config as the library).
|
||||
- An `OPENAI_API_KEY` (or equivalent: the server reads the same component config as the library).
|
||||
- A free port `8888` for the API and `3000` for the dashboard.
|
||||
|
||||
---
|
||||
@@ -59,7 +59,7 @@ make up
|
||||
|
||||
This starts the containers and runs database migrations. The REST API listens on `http://localhost:8888` and the dashboard on `http://localhost:3000`.
|
||||
|
||||
Open `http://localhost:3000` — since no admin account exists yet, the dashboard redirects to the one-time setup wizard at `/setup`. See [Run the setup wizard](#run-the-setup-wizard) below.
|
||||
Open `http://localhost:3000`. Since no admin account exists yet, the dashboard redirects to the one-time setup wizard at `/setup`. See [Run the setup wizard](#run-the-setup-wizard) below.
|
||||
|
||||
### Agent-first (command line)
|
||||
|
||||
@@ -70,7 +70,7 @@ cd server
|
||||
make bootstrap
|
||||
```
|
||||
|
||||
`make bootstrap` starts the same containers, then automatically creates the admin account and generates the first API key via the CLI. The admin credentials and API key are printed to your terminal — no browser required.
|
||||
`make bootstrap` starts the same containers, then automatically creates the admin account and generates the first API key via the CLI. The admin credentials and API key are printed to your terminal: no browser required.
|
||||
|
||||
You can override the generated credentials:
|
||||
|
||||
@@ -89,16 +89,16 @@ Because `make bootstrap` already creates the admin, the setup wizard is skipped.
|
||||
## Run the setup wizard
|
||||
|
||||
<Info>
|
||||
This section applies to the **browser-first** path (`make up`). If you used `make bootstrap`, the admin and API key were already created — skip ahead to [What the dashboard gives you](#what-the-dashboard-gives-you).
|
||||
This section applies to the **browser-first** path (`make up`). If you used `make bootstrap`, the admin and API key were already created: skip ahead to [What the dashboard gives you](#what-the-dashboard-gives-you).
|
||||
</Info>
|
||||
|
||||
On a fresh install the dashboard redirects to `/setup`. Each step submits on Enter.
|
||||
|
||||
**1. Create the admin account.** Name, email, password. This account becomes the first admin. Registration closes after the first admin is created; additional accounts are provisioned by the existing admin.
|
||||
|
||||
**2. Review the effective config.** Read-only display of the LLM and embedder the server is running with, sourced from your environment. If anything is wrong here, stop the stack, fix the `.env`, and restart — the dashboard intentionally does not let you change provider secrets at runtime.
|
||||
**2. Review the effective config.** Read-only display of the LLM and embedder the server is running with, sourced from your environment. If anything is wrong here, stop the stack, fix the `.env`, and restart: the dashboard intentionally does not let you change provider secrets at runtime.
|
||||
|
||||
**3. Generate your first API key.** The full `m0sk_...` value is shown **once**. Copy it immediately — the server only stores the prefix and a bcrypt hash.
|
||||
**3. Generate your first API key.** The full `m0sk_...` value is shown **once**. Copy it immediately: the server only stores the prefix and a bcrypt hash.
|
||||
|
||||
**4. Tell us your use case.** Pick a preset or describe your use case in a few words. Mem0 generates custom instructions that tell the memory system what to prioritize. You can edit the instructions before saving, or skip this step entirely.
|
||||
|
||||
@@ -125,8 +125,8 @@ For the underlying endpoints (including `/auth/*`, `/api-keys`, `/requests`, `/e
|
||||
|
||||
The shipped container bundles the Python packages for:
|
||||
|
||||
- **LLMs** — `openai`, `anthropic`, `gemini`
|
||||
- **Embedders** — `openai`, `gemini`
|
||||
- **LLMs**: `openai`, `anthropic`, `gemini`
|
||||
- **Embedders**: `openai`, `gemini`
|
||||
|
||||
The Configuration page and `POST /configure` only accept providers from these lists. Anything else returns a 400 up front instead of failing at the first memory write.
|
||||
|
||||
@@ -146,9 +146,9 @@ Heavy providers (`sentence-transformers` pulls in PyTorch, ~2 GB) are intentiona
|
||||
|
||||
Previous self-hosted builds allowed open access when `ADMIN_API_KEY` was unset. This build enables auth by default. After pulling the new image, pick **one**:
|
||||
|
||||
1. **Fastest, zero client changes** — set `ADMIN_API_KEY` to a long random value (16+ characters). Existing clients that send `X-API-Key: <your-key>` keep working unchanged.
|
||||
2. **Recommended for teams** — visit `http://<host>:3000`, run the setup wizard, and switch clients to per-user API keys. You get the audit log and revocation for free.
|
||||
3. **Local development only** — set `AUTH_DISABLED=true`. The server logs a warning on every boot. Never use this in production.
|
||||
1. **Fastest, zero client changes**: set `ADMIN_API_KEY` to a long random value (16+ characters). Existing clients that send `X-API-Key: <your-key>` keep working unchanged.
|
||||
2. **Recommended for teams**: visit `http://<host>:3000`, run the setup wizard, and switch clients to per-user API keys. You get the audit log and revocation for free.
|
||||
3. **Local development only**: set `AUTH_DISABLED=true`. The server logs a warning on every boot. Never use this in production.
|
||||
|
||||
The server prints an unmissable startup banner when it detects the "upgraded but not configured" state so you know exactly which option to pick.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user