Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1418ce93f | ||
|
|
ab4c76f197 | ||
|
|
14fa2ec49b |
@@ -12,7 +12,7 @@
|
||||
"name": "mem0",
|
||||
"source": "./integrations/mem0-plugin",
|
||||
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search to Claude workflows.",
|
||||
"version": "0.2.11"
|
||||
"version": "0.2.10"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"name": "mem0",
|
||||
"source": "./integrations/mem0-plugin",
|
||||
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search.",
|
||||
"version": "0.2.11"
|
||||
"version": "0.2.10"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
+43
-130
@@ -1,157 +1,72 @@
|
||||
# Contributing to Mem0
|
||||
# Contributing to mem0
|
||||
|
||||
First off, thank you for taking the time to contribute! 🎉 Mem0 is a
|
||||
community-driven project and we welcome contributions of all kinds — bug fixes,
|
||||
new features, documentation, examples, and integrations.
|
||||
Let us make contribution easy, collaborative and fun.
|
||||
|
||||
Mem0 is a polyglot monorepo, and this guide covers contributing to both the
|
||||
**Python SDK** and the **TypeScript SDK** (and the rest of the repository).
|
||||
## Submit your Contribution through PR
|
||||
|
||||
## Before You Start
|
||||
To make a contribution, follow these steps:
|
||||
|
||||
### 1. Open an Issue First
|
||||
1. Fork and clone this repository
|
||||
2. Do the changes on your fork with dedicated feature branch `feature/f1`
|
||||
3. If you modified the code (new feature or bug-fix), please add tests for it
|
||||
4. Include proper documentation / docstring and examples to run the feature
|
||||
5. Ensure that all tests pass
|
||||
6. Submit a pull request
|
||||
|
||||
**Always open an issue before opening a pull request.** This lets us discuss the
|
||||
change, avoid duplicate effort, and agree on the approach before you invest time
|
||||
in code.
|
||||
For more details about pull requests, please read [GitHub's guides](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
|
||||
|
||||
- Search [existing issues](https://github.com/mem0ai/mem0/issues) first to see if
|
||||
your bug or idea already exists.
|
||||
- If it doesn't, open a
|
||||
[bug report](https://github.com/mem0ai/mem0/issues/new?template=bug_report.yml) or
|
||||
[feature request](https://github.com/mem0ai/mem0/issues/new?template=feature_request.yml).
|
||||
- For anything beyond a trivial fix, wait for a maintainer to confirm the approach
|
||||
before starting significant work.
|
||||
|
||||
Every pull request must link to an issue using `Closes #<issue-number>`.
|
||||
### 📦 Development Environment
|
||||
|
||||
### 2. Sign the Contributor License Agreement (CLA)
|
||||
|
||||
**We cannot accept or merge any pull request until you have signed our Contributor
|
||||
License Agreement (CLA).**
|
||||
|
||||
When you open your first PR, the CLA bot will automatically comment with a link to
|
||||
sign. Signing takes less than a minute and only needs to be done once. Pull
|
||||
requests from contributors who have not signed the CLA will be blocked from
|
||||
merging.
|
||||
|
||||
## Repository Layout
|
||||
|
||||
The two most common contribution targets are the SDKs:
|
||||
|
||||
| Package | Path | Language | Package manager |
|
||||
| --------------------- | ---------- | ------------ | --------------- |
|
||||
| Python SDK (`mem0ai`) | `mem0/` | Python 3.9+ | `hatch` |
|
||||
| TypeScript SDK (`mem0ai`) | `mem0-ts/` | TypeScript | `pnpm` |
|
||||
|
||||
Other packages include the CLIs (`cli/python/`, `cli/node/`), integrations
|
||||
(`integrations/`), the self-hosted `server/`, `openmemory/`, and the docs site
|
||||
(`docs/`). See [AGENTS.md](./AGENTS.md) for a full map of the repository.
|
||||
|
||||
## Development Workflow
|
||||
|
||||
1. **Fork** the repository and **clone** your fork.
|
||||
2. Create a **feature branch** from `main` (e.g. `feature/my-new-feature` or
|
||||
`fix/issue-1234`).
|
||||
3. Make your changes — add **tests**, **documentation**, and **examples** as
|
||||
appropriate.
|
||||
4. Run **linting and tests** for every package you touched (see below).
|
||||
5. Commit using [Conventional Commits](https://www.conventionalcommits.org/)
|
||||
(e.g. `feat:`, `fix:`, `docs:`, `refactor:`, `test:`).
|
||||
6. Push and open a **pull request** against `main`, linking the issue with
|
||||
`Closes #<number>` and filling out the
|
||||
[PR template](./.github/PULL_REQUEST_TEMPLATE.md).
|
||||
|
||||
### Contributing to the Python SDK (`mem0/`)
|
||||
|
||||
We use [`hatch`](https://hatch.pypa.io/latest/install/) to manage environments.
|
||||
**Do not use `pip` or `conda` for dependency management.**
|
||||
We use `hatch` for managing development environments. To set up:
|
||||
|
||||
```bash
|
||||
# Activate a dev environment (3.9 / 3.10 / 3.11 / 3.12)
|
||||
hatch shell dev_py_3_11
|
||||
# Activate environment for specific Python version:
|
||||
hatch shell dev_py_3_9 # Python 3.9
|
||||
hatch shell dev_py_3_10 # Python 3.10
|
||||
hatch shell dev_py_3_11 # Python 3.11
|
||||
hatch shell dev_py_3_12 # Python 3.12
|
||||
|
||||
# Install pre-commit hooks (runs ruff + isort on commit)
|
||||
pre-commit install
|
||||
|
||||
# Lint, format, and sort imports
|
||||
make lint
|
||||
make format
|
||||
make sort
|
||||
|
||||
# Run the test suite (run `make install_all` first if deps are missing)
|
||||
# The environment will automatically install all dev dependencies
|
||||
# Run tests within the activated shell:
|
||||
make test
|
||||
```
|
||||
|
||||
- **Linter / formatter:** Ruff (line length **120**)
|
||||
- **Import sorting:** isort (`profile = "black"`)
|
||||
- **Tests:** pytest (in `tests/`)
|
||||
### 📌 Pre-commit
|
||||
|
||||
See the full [Development guide](https://docs.mem0.ai/contributing/development) for
|
||||
environment details.
|
||||
|
||||
### Contributing to the TypeScript SDK (`mem0-ts/`)
|
||||
|
||||
We use [`pnpm`](https://pnpm.io/) (v10+) for all TypeScript packages. **Do not use
|
||||
`npm` or `yarn`.**
|
||||
To ensure our standards, make sure to install pre-commit before starting to contribute.
|
||||
|
||||
```bash
|
||||
cd mem0-ts
|
||||
pnpm install
|
||||
|
||||
pnpm run build # tsup (CJS + ESM)
|
||||
pnpm run test # jest (all tests)
|
||||
pnpm run test:unit # unit tests with coverage
|
||||
pre-commit install
|
||||
```
|
||||
|
||||
- **Build:** tsup
|
||||
- **Formatter:** Prettier
|
||||
- **Tests:** jest
|
||||
- Always run type checking after changes: `pnpm run typecheck` (or `tsc --noEmit`).
|
||||
- Use ES module `import` syntax — never `require()`.
|
||||
### 🧪 Testing
|
||||
|
||||
## Good Contribution Practices
|
||||
We use `pytest` to test our code across multiple Python versions. You can run tests using:
|
||||
|
||||
- **Keep PRs small and focused.** One logical change per PR is easier to review and
|
||||
merge.
|
||||
- **Follow existing patterns.** Match the style, structure, and conventions of the
|
||||
code around you. Don't introduce new frameworks or abstractions without
|
||||
discussion.
|
||||
- **Write tests** that would fail without your change — regression tests for bugs,
|
||||
coverage for new features.
|
||||
- **Update documentation** in `docs/` for any user-facing change. New `.mdx` pages
|
||||
must be added to `docs/llms.txt` (run
|
||||
`python scripts/check-llms-txt-coverage.py --write` to scaffold entries).
|
||||
- **Add examples** when introducing new user-facing behavior.
|
||||
- **Run linters and tests locally** before pushing — CI re-runs them on every PR
|
||||
via the CI Gate.
|
||||
- **Never commit secrets** — no `.env` files, API keys, or credentials.
|
||||
- **Don't add core dependencies lightly.** New Python dependencies belong in an
|
||||
optional group in `pyproject.toml`, not the core `dependencies` list.
|
||||
- **Be responsive** to review feedback and keep your branch up to date with `main`.
|
||||
```bash
|
||||
# Run tests with default Python version
|
||||
make test
|
||||
|
||||
## Pull Request Checklist
|
||||
# Test specific Python versions:
|
||||
make test-py-3.9 # Python 3.9 environment
|
||||
make test-py-3.10 # Python 3.10 environment
|
||||
make test-py-3.11 # Python 3.11 environment
|
||||
make test-py-3.12 # Python 3.12 environment
|
||||
|
||||
Before requesting review, make sure:
|
||||
# When using hatch shells, run tests with:
|
||||
make test # After activating a shell with hatch shell test_XX
|
||||
```
|
||||
|
||||
- [ ] An issue exists and is linked with `Closes #<number>`
|
||||
- [ ] You have signed the CLA
|
||||
- [ ] Your code follows the project's style guidelines (lint passes)
|
||||
- [ ] You performed a self-review of your changes
|
||||
- [ ] Tests are added/updated and pass locally
|
||||
- [ ] Documentation is updated if needed
|
||||
Make sure that all tests pass across all supported Python versions before submitting a pull request.
|
||||
|
||||
## Reporting Security Issues
|
||||
We look forward to your pull requests and can't wait to see your contributions!
|
||||
|
||||
**Do not report security vulnerabilities through public issues or pull requests.**
|
||||
Please follow our [Security Policy](./SECURITY.md) to report them privately.
|
||||
### 🚀 Releasing
|
||||
|
||||
## Releasing
|
||||
All packages are published automatically via GitHub Actions when a GitHub Release is created with the correct tag prefix.
|
||||
|
||||
All packages are published automatically via GitHub Actions when a GitHub Release
|
||||
is created with the correct tag prefix.
|
||||
|
||||
### Tag Prefixes
|
||||
#### Tag Prefixes
|
||||
|
||||
| Package | Registry | Tag Prefix | Example |
|
||||
|---------|----------|------------|---------|
|
||||
@@ -162,17 +77,15 @@ is created with the correct tag prefix.
|
||||
| `@mem0/vercel-ai-provider` | npm | `vercel-ai-v*` | `vercel-ai-v2.0.6` |
|
||||
| `@mem0/openclaw-mem0` | npm | `openclaw-v*` | `openclaw-v1.0.1` |
|
||||
|
||||
### How to Release
|
||||
#### How to Release
|
||||
|
||||
1. Bump the version in `pyproject.toml` (Python) or `package.json` (Node)
|
||||
2. Create a [GitHub Release](https://github.com/mem0ai/mem0/releases/new) with the matching tag prefix
|
||||
3. The correct workflow will trigger automatically — verify in the [Actions tab](https://github.com/mem0ai/mem0/actions)
|
||||
|
||||
### Publishing Details
|
||||
#### Publishing Details
|
||||
|
||||
- **PyPI packages** use OIDC trusted publishing via `pypa/gh-action-pypi-publish`
|
||||
- **npm packages** use OIDC trusted publishing via npm CLI (>= 11.5.1) — no tokens or secrets required
|
||||
- All workflows require `permissions: id-token: write` for OIDC authentication
|
||||
- First publish of a new npm package must be done manually; OIDC works for subsequent versions
|
||||
|
||||
We look forward to your pull requests and can't wait to see your contributions!
|
||||
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
# Security Policy
|
||||
|
||||
We take the security of Mem0 and our community seriously. Thank you for helping
|
||||
keep Mem0 and its users safe by disclosing vulnerabilities responsibly.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
Please **do not** report security vulnerabilities through public GitHub issues,
|
||||
pull requests, or discussions.
|
||||
|
||||
If you believe you have found a security vulnerability in Mem0, please report it
|
||||
privately through one of the following channels:
|
||||
|
||||
1. **GitHub Private Vulnerability Reporting** — open a
|
||||
[private security advisory](https://github.com/mem0ai/mem0/security/advisories/new)
|
||||
directly on this repository.
|
||||
2. **Email** the maintainers at **support@mem0.ai** with the subject line:
|
||||
|
||||
`SECURITY: Mem0 vulnerability report`
|
||||
|
||||
To help us triage and resolve the issue quickly, please include as much of the
|
||||
following as you can:
|
||||
|
||||
- Affected component or package (e.g. Python SDK, TypeScript SDK, server, OpenMemory)
|
||||
- Affected version, tag, or commit
|
||||
- Clear, step-by-step reproduction instructions
|
||||
- The security impact and a proof of concept, if available
|
||||
- Any suggested fix or mitigation
|
||||
|
||||
## Response Process
|
||||
|
||||
- We will acknowledge receipt of your report within **72 hours**.
|
||||
- We will work with you privately to confirm the issue and assess its impact.
|
||||
- Once a fix or mitigation is ready, we will coordinate a disclosure timeline
|
||||
with you and credit you for the discovery, unless you prefer to remain anonymous.
|
||||
|
||||
## Public Disclosure
|
||||
|
||||
Please avoid sharing technical details of the vulnerability publicly until the
|
||||
maintainers have reviewed the issue and a fix or mitigation has been released. We
|
||||
are committed to resolving valid reports promptly and keeping you informed
|
||||
throughout the process.
|
||||
|
||||
## Supported Versions
|
||||
|
||||
We release security fixes against the latest published version of each package.
|
||||
Whenever possible, please reproduce the issue on the most recent release before
|
||||
reporting.
|
||||
@@ -50,7 +50,6 @@ Provide conversation messages for Mem0 to extract memories from. At least one en
|
||||
| `app_id` | string | No* | Associates the memory with an app. |
|
||||
| `metadata` | object | Optional | Custom key/value metadata (e.g., `{"topic": "preferences"}`). |
|
||||
| `infer` | boolean (default `true`) | Optional | Set to `false` to skip inference and store the provided text as-is. |
|
||||
| `expiration_date` | string | Optional | Date in `YYYY-MM-DD` format. The memory is visible through this date and hidden by default after it passes. |
|
||||
|
||||
> \* At least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`) is required.
|
||||
|
||||
@@ -84,11 +83,3 @@ The request is queued for background processing. The response contains an `event
|
||||
<Info>
|
||||
Poll the event status via `GET /v1/event/{event_id}/`. Status will be `SUCCEEDED` or `FAILED` once processing completes.
|
||||
</Info>
|
||||
|
||||
<Info>
|
||||
Memories with `expiration_date` remain stored after they expire. Search and get-all hide them by default; pass `show_expired: true` to include them.
|
||||
</Info>
|
||||
|
||||
<Info>
|
||||
Python uses `expiration_date`; TypeScript uses `expirationDate`.
|
||||
</Info>
|
||||
|
||||
@@ -4,4 +4,4 @@ description: "Submit an export job to create a structured memory export using a
|
||||
openapi: post /v1/exports/
|
||||
---
|
||||
|
||||
Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you're exporting a large number of memories. You can tailor the export by applying various filters (e.g., `user_id`, `agent_id`, `app_id`, or `run_id`) and by modifying the Pydantic schema to ensure the final data matches your exact needs.
|
||||
Submit a job to create a structured export of memories using a customizable Pydantic schema. This process may take some time to complete, especially if you're exporting a large number of memories. You can tailor the export by applying various filters (e.g., `user_id`, `agent_id`, `run_id`, or `session_id`) and by modifying the Pydantic schema to ensure the final data matches your exact needs.
|
||||
|
||||
@@ -6,10 +6,6 @@ openapi: post /v3/memories/
|
||||
|
||||
List memories scoped by filters with paginated results. Entity IDs (`user_id`, `agent_id`, `app_id`, `run_id`) **must** be passed inside the `filters` object — top-level entity IDs are rejected with 400.
|
||||
|
||||
Expired memories are hidden by default. Pass `show_expired: true` to include memories whose `expiration_date` has passed.
|
||||
|
||||
Python uses `show_expired`; TypeScript uses `showExpired`.
|
||||
|
||||
The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators:
|
||||
|
||||
- `in`: Matches any of the values specified
|
||||
@@ -36,7 +32,6 @@ memories = client.get_all(
|
||||
}
|
||||
]
|
||||
},
|
||||
show_expired=False,
|
||||
page=1,
|
||||
page_size=50
|
||||
)
|
||||
@@ -51,14 +46,12 @@ memories = client.get_all(
|
||||
{
|
||||
"id": "f4cbdb08-7062-4f3e-8eb2-9f5c80dfe64c",
|
||||
"memory": "Alex is planning a trip to San Francisco from July 1st to July 10th",
|
||||
"expiration_date": null,
|
||||
"created_at": "2024-07-01T12:00:00Z",
|
||||
"updated_at": "2024-07-01T12:00:00Z"
|
||||
},
|
||||
{
|
||||
"id": "a2b8c3d4-5e6f-7g8h-9i0j-1k2l3m4n5o6p",
|
||||
"memory": "Alex prefers vegetarian restaurants",
|
||||
"expiration_date": null,
|
||||
"created_at": "2024-07-05T15:30:00Z",
|
||||
"updated_at": "2024-07-05T15:30:00Z"
|
||||
}
|
||||
|
||||
@@ -4,4 +4,4 @@ description: "Retrieve the latest structured memory export after submitting an e
|
||||
openapi: post /v1/exports/get
|
||||
---
|
||||
|
||||
Retrieve the latest structured memory export after submitting an export job. You can filter the export by `user_id`, `agent_id`, `app_id`, `run_id`, `created_at`, or `updated_at` to get the most recent export matching your filters.
|
||||
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.
|
||||
@@ -8,10 +8,6 @@ Relevance-ranked hybrid search across stored memories. V3 uses multi-signal retr
|
||||
|
||||
Entity IDs (`user_id`, `agent_id`, `app_id`, `run_id`) **must** be passed inside the `filters` object — top-level entity IDs are rejected with 400. At least one entity ID is required.
|
||||
|
||||
Expired memories are hidden by default. Pass `show_expired: true` to include memories whose `expiration_date` has passed.
|
||||
|
||||
Python uses `show_expired`; TypeScript uses `showExpired`.
|
||||
|
||||
The `filters` object supports complex logical operations (AND, OR, NOT) and comparison operators:
|
||||
- `in`: Matches any of the values specified
|
||||
- `gte`: Greater than or equal to
|
||||
@@ -24,17 +20,16 @@ The `filters` object supports complex logical operations (AND, OR, NOT) and comp
|
||||
|
||||
### Search parameter defaults
|
||||
|
||||
| Parameter | Default |
|
||||
| --- | --- |
|
||||
| `top_k` | `10` (range 1–1000) |
|
||||
| `threshold` | `0.1` (pass `0.0` to disable) |
|
||||
| `rerank` | `false` (pass `true` to enable) |
|
||||
| Parameter | V1/V2 | V3 |
|
||||
| --- | --- | --- |
|
||||
| `top_k` | Supported (default 10) | Supported (1-1000, default 10) |
|
||||
| `threshold` | No default | Default `0.1` (pass `0.0` to disable) |
|
||||
| `rerank` | Default `true` | Default `false` (pass `true` to enable) |
|
||||
|
||||
<CodeGroup>
|
||||
```python Platform API Example
|
||||
related_memories = client.search(
|
||||
query="What are Alice's hobbies?",
|
||||
show_expired=False,
|
||||
filters={
|
||||
"OR": [
|
||||
{
|
||||
@@ -59,7 +54,6 @@ related_memories = client.search(
|
||||
"category": "hobbies"
|
||||
},
|
||||
"score": 0.82,
|
||||
"expiration_date": null,
|
||||
"created_at": "2024-07-26T10:29:36.630547-07:00",
|
||||
"updated_at": null,
|
||||
"categories": ["hobbies"]
|
||||
|
||||
@@ -1,14 +1,5 @@
|
||||
---
|
||||
title: 'Update Memory'
|
||||
description: "Update the content, metadata, timestamp, or expiration date of a single memory by its unique ID using the PUT endpoint."
|
||||
description: "Update the content or metadata of a single memory by its unique ID using the PUT endpoint."
|
||||
openapi: put /v1/memories/{memory_id}/
|
||||
---
|
||||
|
||||
Use this endpoint to update mutable memory fields. To make a memory expire, set `expiration_date` to a `YYYY-MM-DD` date. To make it permanent again, send `expiration_date: null`.
|
||||
|
||||
```python
|
||||
client.update("mem_123", expiration_date="2030-01-31")
|
||||
client.update("mem_123", expiration_date=None)
|
||||
```
|
||||
|
||||
TypeScript uses `expirationDate`.
|
||||
---
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
title: "Remove Organization Member"
|
||||
description: "Remove a member from an organization to revoke their access to its projects and resources."
|
||||
openapi: "delete /api/v1/orgs/organizations/{org_id}/members/"
|
||||
---
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
title: "Update Organization Member"
|
||||
description: "Update an existing member's role within an organization to change their permissions and access level."
|
||||
openapi: "put /api/v1/orgs/organizations/{org_id}/members/"
|
||||
---
|
||||
@@ -14,7 +14,7 @@ Organizations and projects are **optional** features. You can use Mem0 without t
|
||||
|
||||
## Key Capabilities
|
||||
|
||||
- **Multi-org/project Support**: Organization and project are resolved automatically from your API key via `/v1/ping/` — no org or project params are accepted by `MemoryClient.__init__`. Use a project-specific API key to target a particular project.
|
||||
- **Multi-org/project Support**: Specify organization and project when initializing the Mem0 client to attribute API usage appropriately
|
||||
- **Member Management**: Control access to data through organization and project membership
|
||||
- **Access Control**: Only members can access memories and data within their organization/project scope
|
||||
- **Team Isolation**: Maintain data separation between different teams and projects for secure collaboration
|
||||
@@ -79,7 +79,7 @@ new_project = client.project.create(
|
||||
|
||||
### Update Project Settings
|
||||
|
||||
Modify project configuration including custom instructions, categories, language preferences, retrieval criteria, and memory decay:
|
||||
Modify project configuration including custom instructions, categories, and language preferences:
|
||||
|
||||
```python
|
||||
# Update project with custom categories
|
||||
@@ -98,17 +98,6 @@ client.project.update(
|
||||
# Use the input language for memory storage and retrieval
|
||||
client.project.update(multilingual=True)
|
||||
|
||||
# Set retrieval criteria to control which memories are surfaced in search
|
||||
client.project.update(
|
||||
retrieval_criteria=[
|
||||
{"name": "relevance", "description": "How directly relevant this memory is to the current topic or user query", "weight": 3},
|
||||
{"name": "access_frequency", "description": "How often this memory has been accessed or surfaced recently", "weight": 1}
|
||||
]
|
||||
)
|
||||
|
||||
# Enable Memory Decay (boosts recently-accessed memories at search time)
|
||||
client.project.update(decay=True)
|
||||
|
||||
# Update multiple settings at once
|
||||
client.project.update(
|
||||
custom_instructions="...",
|
||||
@@ -120,34 +109,6 @@ client.project.update(
|
||||
)
|
||||
```
|
||||
|
||||
#### Set Retrieval Criteria
|
||||
|
||||
`retrieval_criteria` is a per-project list of dictionaries (`List[Dict]`) that shapes how memories are ranked and filtered during search. Each dictionary has three fields: `name` (identifier), `description` (interpreted by the LLM to score each memory), and `weight` (relative influence on the final score). Use this to focus retrieval on intent-aligned or signal-specific memories:
|
||||
|
||||
```python
|
||||
client.project.update(
|
||||
retrieval_criteria=[
|
||||
{
|
||||
"name": "joy",
|
||||
"description": "Measure the intensity of positive emotions such as happiness, excitement, or amusement expressed in the memory. A higher score reflects greater joy.",
|
||||
"weight": 3
|
||||
},
|
||||
{
|
||||
"name": "curiosity",
|
||||
"description": "Assess the extent to which the memory reflects inquisitiveness or interest in exploring new information. A higher score reflects stronger curiosity.",
|
||||
"weight": 2
|
||||
},
|
||||
{
|
||||
"name": "access_frequency",
|
||||
"description": "How often this memory has been accessed or surfaced recently.",
|
||||
"weight": 1
|
||||
}
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
Pass an empty list to clear all criteria and restore default retrieval behaviour.
|
||||
|
||||
#### Toggle Memory Decay
|
||||
|
||||
`decay` is a per-project boolean that turns on [Memory Decay](/platform/features/memory-decay) — a search-time ranking bias that reinforces recently-accessed memories and gently dampens stale ones. The flag is `false` by default; set it via the same project-update endpoint:
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
title: "Remove Project Member"
|
||||
description: "Remove a member from a project to revoke their access to its memories, configuration, and resources."
|
||||
openapi: "delete /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/"
|
||||
---
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
title: "Update Project Member"
|
||||
description: "Update an existing member's role within a project to change their permissions and access level."
|
||||
openapi: "put /api/v1/orgs/organizations/{org_id}/projects/{project_id}/members/"
|
||||
---
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
title: "Update Project"
|
||||
description: "Update a project's settings, including name, custom instructions, and other configuration options."
|
||||
openapi: "patch /api/v1/orgs/organizations/{org_id}/projects/{project_id}/"
|
||||
---
|
||||
@@ -113,7 +113,7 @@ Launched a unified Mem0 plugin across three major AI development environments
|
||||
|
||||
Major expansion of the provider ecosystem:
|
||||
|
||||
- **Apache AGE** — New graph store support, bringing the total to 4 graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE). **Note:** All external graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE) were subsequently removed in v2.0.0 (2026-04-14). Graph memory is now built-in entity linking with no external graph store required; see the [v2.0.0 entry above](#mem0-sdk-v2-0-0-v3-0-0).
|
||||
- **Apache AGE** — New graph store support, bringing the total to 4 graph store backends (Neo4j, Memgraph, Kuzu, Apache AGE)
|
||||
- **Turbopuffer** — New vector database provider for Python SDK
|
||||
- **MiniMax** — New LLM provider with dedicated AWS Bedrock support
|
||||
- **pgvector for Node.js** — PostgreSQL vector support added to the TypeScript OSS SDK
|
||||
|
||||
+2
-118
@@ -7,80 +7,6 @@ mode: "wide"
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
|
||||
<Update label="2026-06-27" description="v2.0.10">
|
||||
|
||||
**New Features:**
|
||||
- **Client:** Expose `expiration_date` on `MemoryClient.update()` and `AsyncMemoryClient.update()` — callers can now set or clear a memory's expiration date; `None` is preserved and forwarded to the API ([#5874](https://github.com/mem0ai/mem0/pull/5874))
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Memory (OSS):** Apply `remove_code_blocks()` to the LangChain path in async `_create_procedural_memory` so code fences are stripped consistently ([#5711](https://github.com/mem0ai/mem0/pull/5711))
|
||||
- **Rerankers:** Score HuggingFace cross-encoder results with per-document sigmoid instead of set-relative min-max, preventing a single low-score document from collapsing all relevance scores to zero ([#5715](https://github.com/mem0ai/mem0/pull/5715))
|
||||
- **Core:** Validate and trim entity IDs (`user_id`, `agent_id`, `run_id`) in `delete_all()` for both sync and async `Memory` ([#5735](https://github.com/mem0ai/mem0/pull/5735))
|
||||
- **Vector Stores:** Use `.get()` for `hash` and `created_at` in the Redis `insert()` and `update()` paths so entity payloads that omit those fields no longer raise `KeyError` ([#5709](https://github.com/mem0ai/mem0/pull/5709))
|
||||
- **Memory:** Fix scale-threshold notices not firing for Redis and search-engine backends by resolving `col_info()` signature differences and adding `num_docs` to the count-extraction lookup ([#5687](https://github.com/mem0ai/mem0/pull/5687))
|
||||
- **Vector Stores:** Escape special characters in Valkey FT.SEARCH tag filter values to prevent wildcard and operator injection through tenant-isolation filters ([#5750](https://github.com/mem0ai/mem0/pull/5750))
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-06-24" description="v2.0.9">
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Memory (OSS):** Improve entity extraction precision by avoiding sentence-start common noun noise, preserving useful topic phrases, and exact-deduplicating entity links before semantic matching ([#5829](https://github.com/mem0ai/mem0/pull/5829))
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-06-24" description="v2.0.8">
|
||||
|
||||
**New Features:**
|
||||
- **Embeddings:** Add native `embed_batch` to five embedders — LM Studio, Together, HuggingFace, Vertex AI, and Google GenAI — for batched embedding requests ([#5609](https://github.com/mem0ai/mem0/pull/5609))
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Core:** Guard against malformed `image_url` entries in `parse_vision_messages` to prevent crashes ([#5631](https://github.com/mem0ai/mem0/pull/5631))
|
||||
- **Core:** Return `attributed_to` from `get()`, `get_all()`, and `search()` ([#5629](https://github.com/mem0ai/mem0/pull/5629))
|
||||
- **Core:** Fix `reset()` only dropping the history table and leaving stale messages behind ([#5541](https://github.com/mem0ai/mem0/pull/5541))
|
||||
- **Core:** Guard against an entity `embed_batch` count mismatch in the v3 add pipeline ([#5604](https://github.com/mem0ai/mem0/pull/5604))
|
||||
- **Core:** Fix an async `delete_all` race condition that corrupted the entity store's `linked_memory_ids` ([#5553](https://github.com/mem0ai/mem0/pull/5553))
|
||||
- **LLMs:** Skip the JSON `response_format` for Groq compound models that reject it ([#5513](https://github.com/mem0ai/mem0/pull/5513))
|
||||
- **LLMs:** Preserve reasoning fields during base-to-provider config conversion ([#5638](https://github.com/mem0ai/mem0/pull/5638))
|
||||
- **LLMs:** Pass the configured `anthropic_base_url` to the Anthropic client ([#5626](https://github.com/mem0ai/mem0/pull/5626))
|
||||
- **LLMs:** Stop the Azure provider from mutating and corrupting caller messages during content rewrite ([#5731](https://github.com/mem0ai/mem0/pull/5731))
|
||||
- **LLMs & Embeddings:** Repair HTTP proxy support for `httpx>=0.28` and preserve `proxies` in `LlmFactory` ([#5447](https://github.com/mem0ai/mem0/pull/5447))
|
||||
- **Embeddings:** Forward `embedding_dims` to Titan V2 in the AWS Bedrock embedder ([#5671](https://github.com/mem0ai/mem0/pull/5671))
|
||||
- **Rerankers:** Log reranking failures instead of swallowing them silently ([#5717](https://github.com/mem0ai/mem0/pull/5717))
|
||||
- **Rerankers:** Clamp out-of-range LLM scores instead of mis-parsing them ([#5635](https://github.com/mem0ai/mem0/pull/5635))
|
||||
- **Rerankers:** Export all five rerankers from the package root ([#5636](https://github.com/mem0ai/mem0/pull/5636))
|
||||
- **Vector Stores:** Point the FastEmbed-missing warning at `mem0ai[extras]` ([#5622](https://github.com/mem0ai/mem0/pull/5622))
|
||||
- **Vector Stores:** Preserve empty Azure AI Search update values ([#5524](https://github.com/mem0ai/mem0/pull/5524))
|
||||
- **Vector Stores:** Add an `auto_refresh` option for OpenSearch Serverless compatibility ([#3893](https://github.com/mem0ai/mem0/pull/3893))
|
||||
- **Vector Stores:** Wrap a scalar `vector_id` in a list for Chroma `delete()` ([#5703](https://github.com/mem0ai/mem0/pull/5703))
|
||||
- **Vector Stores:** Wrap Chroma `update()` ids, embeddings, and metadatas in lists ([#5757](https://github.com/mem0ai/mem0/pull/5757))
|
||||
- **Vector Stores:** Wrap a scalar `vector_id` in a list for Milvus `delete()` ([#5704](https://github.com/mem0ai/mem0/pull/5704))
|
||||
- **Vector Stores:** Map all comparison operators in the Pinecone `_create_filter()` ([#5707](https://github.com/mem0ai/mem0/pull/5707))
|
||||
- **Vector Stores:** Return `None` instead of `{}` from Chroma `_generate_where_clause` for empty filters ([#5713](https://github.com/mem0ai/mem0/pull/5713))
|
||||
- **Vector Stores:** Return `[[]]` from the OpenSearch `list()` error path to honor the `list()` contract ([#5727](https://github.com/mem0ai/mem0/pull/5727))
|
||||
- **Vector Stores:** Return `[[]]` from the Pinecone `list()` error path instead of a dict ([#5706](https://github.com/mem0ai/mem0/pull/5706))
|
||||
- **Vector Stores:** Return `[[]]` for an uninitialized FAISS index to honor the `list()` contract ([#5725](https://github.com/mem0ai/mem0/pull/5725))
|
||||
- **Vector Stores:** Wrap the MongoDB `list()` return in an outer list to match the interface contract ([#5729](https://github.com/mem0ai/mem0/pull/5729))
|
||||
- **Vector Stores:** Deep-copy Redis `DEFAULT_FIELDS` so instances keep distinct dims ([#5633](https://github.com/mem0ai/mem0/pull/5633))
|
||||
- **Vector Stores:** Pass the required `vectors` arg in Vertex AI `list()` and similarity search ([#5627](https://github.com/mem0ai/mem0/pull/5627))
|
||||
- **Vector Stores:** Return `None` from Redis `get()` for missing IDs ([#5625](https://github.com/mem0ai/mem0/pull/5625))
|
||||
- **Vector Stores:** Drop a stray `print` in Weaviate `list_cols` ([#5637](https://github.com/mem0ai/mem0/pull/5637))
|
||||
- **Graph:** Keep distinct entities that share a substring prefix ([#5630](https://github.com/mem0ai/mem0/pull/5630))
|
||||
- **Client:** Check the HTTP status before parsing the ping response in `_validate_api_key` ([#5639](https://github.com/mem0ai/mem0/pull/5639))
|
||||
- **Server:** Fetch filtered dashboard memories beyond the default page ([#5753](https://github.com/mem0ai/mem0/pull/5753))
|
||||
- **Server:** Return 404/400 instead of 502 for not-found and invalid input ([#5634](https://github.com/mem0ai/mem0/pull/5634))
|
||||
- **Server:** Return 404 instead of 500 for a malformed API key id on revoke ([#5640](https://github.com/mem0ai/mem0/pull/5640))
|
||||
- **Server:** Use `127.0.0.1` in the dashboard healthcheck to avoid IPv6 localhost resolution ([#5612](https://github.com/mem0ai/mem0/pull/5612))
|
||||
|
||||
**Improvements:**
|
||||
- **Vector Stores:** Batch BM25 sparse encoding in Qdrant insert ([#5592](https://github.com/mem0ai/mem0/pull/5592))
|
||||
|
||||
**Security:**
|
||||
- **Vector Stores:** Sanitize Milvus and Baidu filter values to prevent expression injection ([#5746](https://github.com/mem0ai/mem0/pull/5746))
|
||||
- **Vector Stores:** Reject dict filter values in MongoDB to prevent NoSQL operator injection ([#5748](https://github.com/mem0ai/mem0/pull/5748))
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-06-17" description="v2.0.7">
|
||||
|
||||
**New Features:**
|
||||
@@ -136,7 +62,7 @@ mode: "wide"
|
||||
|
||||
**New Features:**
|
||||
- **Memory:** Warn at init time when hybrid/BM25 search silently degrades to semantic-only because the configured vector store does not implement `keyword_search`. Affected stores: Chroma, FAISS, Cassandra, LangChain, Neptune Analytics, S3 Vectors, Supabase, TurboPuffer, Valkey ([#5444](https://github.com/mem0ai/mem0/pull/5444))
|
||||
- **Memory:** Add opt-in `explain=True` parameter to `Memory.search()` and `AsyncMemory.search()`. When enabled, each result includes a `score_details` dict with `semantic_score`, `bm25_score`, `entity_boost`, `raw_score`, `max_possible_score`, `final_score`, and `threshold` so callers can understand and tune retrieval ranking ([#5102](https://github.com/mem0ai/mem0/pull/5102))
|
||||
- **Memory:** Add opt-in `explain=True` parameter to `Memory.search()` and `AsyncMemory.search()`. When enabled, each result includes a `score_breakdown` dict with `semantic`, `keyword` (normalized BM25), `entity_boost`, and `temporal_boost` signals so callers can understand and tune retrieval ranking ([#5102](https://github.com/mem0ai/mem0/pull/5102))
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Vector Stores:** Normalize similarity scores to `[0, 1]` (higher = better) consistently across all backends. 11 adapters previously returned raw distance metrics (lower = better) — FAISS, Chroma, Milvus, Redis, Cassandra, PGVector, S3 Vectors, Supabase, Valkey, Azure MySQL, and Vertex AI Vector Search — causing incorrect ranking in multi-store setups ([#5391](https://github.com/mem0ai/mem0/pull/5391))
|
||||
@@ -244,7 +170,7 @@ mode: "wide"
|
||||
**Improvements:**
|
||||
- **Telemetry:** Sample OSS hot-path events at 10% via PostHog `before_send` hook to reduce event volume ([#4771](https://github.com/mem0ai/mem0/pull/4771))
|
||||
|
||||
See the [OSS v2 to v3 migration guide](https://docs.mem0.ai/migration/oss-v2-to-v3) and [Platform migration guide](https://docs.mem0.ai/migration/platform-v2-to-v3) for upgrade instructions.
|
||||
See the [OSS v1 to v2 migration guide](https://docs.mem0.ai/migration/oss-v1-to-v2) and [Platform migration guide](https://docs.mem0.ai/migration/platform-v2-to-v3) for upgrade instructions.
|
||||
|
||||
</Update>
|
||||
|
||||
@@ -1085,48 +1011,6 @@ See the [OSS v2 to v3 migration guide](https://docs.mem0.ai/migration/oss-v2-to-
|
||||
|
||||
<Tab title="TypeScript">
|
||||
|
||||
<Update label="2026-06-27" description="v3.0.12">
|
||||
|
||||
**New Features:**
|
||||
- **Client:** Add `expirationDate` to `AddMemoryOptions`, `update()`, and the `Memory` interface; add `showExpired` to `SearchMemoryOptions` and `GetAllMemoryOptions` ([#5874](https://github.com/mem0ai/mem0/pull/5874))
|
||||
- **LLMs:** Add `MiniMaxLLM` provider backed by the OpenAI-compatible MiniMax API (`api.minimax.io/v1`, default model `MiniMax-M2.7`) ([#5858](https://github.com/mem0ai/mem0/pull/5858))
|
||||
- **LLMs:** Add `LiteLLM` provider for routing requests through a local or hosted LiteLLM proxy ([#5830](https://github.com/mem0ai/mem0/pull/5830))
|
||||
- **Vector Stores:** Add `connectionString` and `ssl` options to the PGVector config, allowing connection via URI instead of individual host/user/password/port fields ([#5789](https://github.com/mem0ai/mem0/pull/5789))
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Memory (OSS):** Validate and trim entity IDs (`userId`, `agentId`, `runId`) in `deleteAll()` via `validateAndTrimEntityId` ([#5735](https://github.com/mem0ai/mem0/pull/5735))
|
||||
- **Vector Stores:** Use nullish coalescing for `hash` and timestamps in the Redis `insert()` and `update()` paths so entity payloads that omit those fields no longer crash ([#5860](https://github.com/mem0ai/mem0/pull/5860))
|
||||
|
||||
**Security:**
|
||||
- **Dependencies:** Bump `undici` to `>=6.27.0` via pnpm override to remediate CVE-2026-12151 ([#5861](https://github.com/mem0ai/mem0/pull/5861))
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-06-24" description="v3.0.11">
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Memory (OSS):** Align entity extraction with Python by reducing generic entity noise, preserving useful topic phrases, and exact-deduplicating entity links before semantic matching ([#5829](https://github.com/mem0ai/mem0/pull/5829))
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-06-24" description="v3.0.10">
|
||||
|
||||
**Bug Fixes:**
|
||||
- **Memory (OSS):** Guard against malformed `image_url` entries in `parseVisionMessages` to prevent crashes ([#5631](https://github.com/mem0ai/mem0/pull/5631))
|
||||
- **Memory (OSS):** Return `attributedTo` from `get()`, `search()`, and `getAll()` ([#5675](https://github.com/mem0ai/mem0/pull/5675))
|
||||
- **Memory (OSS):** Preserve message roles in the extraction input so assistant facts aren't attributed to the user ([#5643](https://github.com/mem0ai/mem0/pull/5643))
|
||||
- **Memory (OSS):** Reject empty or blank messages in `Memory.add()` to prevent hallucinated memories ([#5545](https://github.com/mem0ai/mem0/pull/5545))
|
||||
- **Memory (OSS):** Check `message.role` instead of `content` when detecting system messages ([#3921](https://github.com/mem0ai/mem0/pull/3921))
|
||||
- **LLMs:** Honor the configured `baseURL` in `AnthropicLLM` ([#5740](https://github.com/mem0ai/mem0/pull/5740))
|
||||
- **Client:** Preserve `customCategories` names through key conversion ([#5741](https://github.com/mem0ai/mem0/pull/5741))
|
||||
- **Client:** Prevent hallucinated memories on an empty messages payload ([#5613](https://github.com/mem0ai/mem0/pull/5613))
|
||||
- **Client:** Preserve user metadata keys across the case-conversion round-trip ([#5515](https://github.com/mem0ai/mem0/pull/5515))
|
||||
|
||||
**Security:**
|
||||
- **Dependencies:** Upgrade `form-data` to `>=4.0.6` across pnpm workspaces to remediate CVE-2026-12143 ([#5618](https://github.com/mem0ai/mem0/pull/5618))
|
||||
|
||||
</Update>
|
||||
|
||||
<Update label="2026-06-17" description="v3.0.9">
|
||||
|
||||
**Bug Fixes:**
|
||||
|
||||
@@ -59,9 +59,5 @@ Here are the parameters available for configuring AWS Bedrock embedder:
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the embedding model to use | `amazon.titan-embed-text-v1` |
|
||||
| `aws_region` | AWS region for the Bedrock client | `us-west-2` |
|
||||
| `aws_access_key_id` | AWS access key ID for authentication | `None` |
|
||||
| `aws_secret_access_key` | AWS secret access key for authentication | `None` |
|
||||
| `aws_session_token` | AWS session token for temporary credentials | `None` |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
title: "FastEmbed"
|
||||
description: "Configure FastEmbed as an embedding provider in Mem0 to generate embeddings locally using ONNX-based models without a GPU."
|
||||
---
|
||||
|
||||
You can use FastEmbed to run embedding models locally in Mem0. FastEmbed is an ONNX-based embedding library that runs efficiently on CPU without requiring a GPU or an external API key.
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
pip install fastembed
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
os.environ["OPENAI_API_KEY"] = "your_api_key" # For LLM
|
||||
|
||||
config = {
|
||||
"embedder": {
|
||||
"provider": "fastembed",
|
||||
"config": {
|
||||
"model": "thenlper/gte-large"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m = Memory.from_config(config)
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about 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")
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
### Config
|
||||
|
||||
Here are the parameters available for configuring FastEmbed embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the FastEmbed model to use | `thenlper/gte-large` |
|
||||
| `embedding_dims` | Dimensions of the embedding model (auto-derived from the model if not set) | `None` |
|
||||
@@ -67,15 +67,14 @@ Here are the parameters available for configuring Gemini embedder:
|
||||
| Parameter | Description | Default Value |
|
||||
| ---------------- | ------------------------------------ | ----------------------- |
|
||||
| `model` | The name of the embedding model to use| `models/gemini-embedding-001` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `768` |
|
||||
| `embedding_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `api_key` | The Google API key | `None` |
|
||||
| `output_dimensionality` | Output dimensionality for the embedding model (Gemini-specific; used when `embedding_dims` is not set) | `None` |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
| Parameter | Description | Default Value |
|
||||
| ----------------- | --------------------------------------------- | -------------------------- |
|
||||
| `model` | The name of the embedding model to use | `gemini-embedding-001` |
|
||||
| `embeddingDims` | Dimensions of the embedding model. When not set, uses the model's native output dimensionality (3072 for `gemini-embedding-001`; MRL truncation to 768, 1536, or 3072 is supported) | `None` |
|
||||
| `embeddingDims` | Dimensions of the embedding model | `1536` |
|
||||
| `apiKey` | Google API key | `None` |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@@ -16,7 +16,7 @@ config = {
|
||||
"embedder": {
|
||||
"provider": "lmstudio",
|
||||
"config": {
|
||||
"model": "nomic-ai/nomic-embed-text-v1.5-GGUF"
|
||||
"model": "nomic-embed-text-v1.5-GGUF/nomic-embed-text-v1.5.f16.gguf"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,6 @@ Here are the parameters available for configuring LM Studio embedder:
|
||||
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `model` | The name of the LM Studio model to use | `nomic-ai/nomic-embed-text-v1.5-GGUF` |
|
||||
| `model` | The name of the LM Studio 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` |
|
||||
@@ -10,7 +10,7 @@ Mem0 offers support for various embedding models, allowing users to choose the o
|
||||
See the list of supported embedders below.
|
||||
|
||||
<Note>
|
||||
All embedders listed below are supported in the Python implementation. The TypeScript implementation supports: **OpenAI**, **Azure OpenAI**, **Google AI**, **Langchain**, **LM Studio**, and **Ollama**.
|
||||
The following embedders are supported in the Python implementation. The TypeScript implementation currently only supports OpenAI.
|
||||
</Note>
|
||||
|
||||
<CardGroup cols={4}>
|
||||
@@ -24,7 +24,6 @@ See the list of supported embedders below.
|
||||
<Card title="LM Studio" href="/components/embedders/models/lmstudio"></Card>
|
||||
<Card title="Langchain" href="/components/embedders/models/langchain"></Card>
|
||||
<Card title="AWS Bedrock" href="/components/embedders/models/aws_bedrock"></Card>
|
||||
<Card title="FastEmbed" href="/components/embedders/models/fastembed"></Card>
|
||||
</CardGroup>
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -98,7 +98,7 @@ Here's a comprehensive list of all parameters that can be used across different
|
||||
| `max_tokens` | Tokens to generate | All |
|
||||
| `top_p` | Probability threshold for nucleus sampling | All |
|
||||
| `top_k` | Number of highest probability tokens to keep | All |
|
||||
| `http_client_proxies`| Allow proxy server settings | All |
|
||||
| `http_client_proxies`| Allow proxy server settings | AzureOpenAI |
|
||||
| `models` | List of models | Openrouter |
|
||||
| `route` | Routing strategy | Openrouter |
|
||||
| `openrouter_base_url`| Base URL for Openrouter API | Openrouter |
|
||||
@@ -110,7 +110,7 @@ Here's a comprehensive list of all parameters that can be used across different
|
||||
| `deepseek_base_url` | Base URL for DeepSeek API | DeepSeek |
|
||||
| `xai_base_url` | Base URL for XAI API | XAI |
|
||||
| `sarvam_base_url` | Base URL for Sarvam API | Sarvam |
|
||||
| `reasoning_effort` | Reasoning level (low, medium, high) | All |
|
||||
| `reasoning_effort` | Reasoning level (low, medium, high) | Sarvam |
|
||||
| `frequency_penalty` | Penalize frequent tokens (-2.0 to 2.0) | Sarvam |
|
||||
| `presence_penalty` | Penalize existing tokens (-2.0 to 2.0) | Sarvam |
|
||||
| `seed` | Seed for deterministic sampling | Sarvam |
|
||||
|
||||
@@ -20,7 +20,7 @@ config = {
|
||||
"llm": {
|
||||
"provider": "anthropic",
|
||||
"config": {
|
||||
"model": "claude-sonnet-4-6",
|
||||
"model": "claude-sonnet-4-20250514",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
@@ -45,7 +45,7 @@ const config = {
|
||||
provider: 'anthropic',
|
||||
config: {
|
||||
apiKey: process.env.ANTHROPIC_API_KEY || '',
|
||||
model: 'claude-sonnet-4-6',
|
||||
model: 'claude-sonnet-4-20250514',
|
||||
temperature: 0.1,
|
||||
maxTokens: 2000,
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ description: "Configure AWS Bedrock as an LLM provider in Mem0 with IAM authenti
|
||||
### Setup
|
||||
- Before using the AWS Bedrock LLM, make sure you have the appropriate model access from [Bedrock Console](https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess).
|
||||
- You will also need to authenticate the `boto3` client by using a method in the [AWS documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/guide/credentials.html#configuring-credentials)
|
||||
- You will have to export `AWS_REGION`, `AWS_ACCESS_KEY_ID`, and `AWS_SECRET_ACCESS_KEY` to set environment variables.
|
||||
- You will have to export `AWS_REGION`, `AWS_ACCESS_KEY`, and `AWS_SECRET_ACCESS_KEY` to set environment variables.
|
||||
|
||||
### Usage
|
||||
|
||||
|
||||
@@ -7,8 +7,7 @@ To use DeepSeek LLM models, you have to set the `DEEPSEEK_API_KEY` environment v
|
||||
|
||||
## Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -37,32 +36,6 @@ messages = [
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'deepseek',
|
||||
config: {
|
||||
apiKey: process.env.DEEPSEEK_API_KEY || '',
|
||||
model: 'deepseek-chat',
|
||||
temperature: 0.2,
|
||||
maxTokens: 2000,
|
||||
top_p: 1.0,
|
||||
},
|
||||
},
|
||||
};
|
||||
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 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>
|
||||
|
||||
You can also configure the API base URL in the config:
|
||||
|
||||
```python
|
||||
|
||||
@@ -21,7 +21,7 @@ config = {
|
||||
"llm": {
|
||||
"provider": "groq",
|
||||
"config": {
|
||||
"model": "llama-3.3-70b-versatile",
|
||||
"model": "mixtral-8x7b-32768",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
@@ -46,7 +46,7 @@ const config = {
|
||||
provider: 'groq',
|
||||
config: {
|
||||
apiKey: process.env.GROQ_API_KEY || '',
|
||||
model: 'llama3-70b-8192',
|
||||
model: 'mixtral-8x7b-32768',
|
||||
temperature: 0.1,
|
||||
maxTokens: 1000,
|
||||
},
|
||||
|
||||
@@ -4,12 +4,9 @@ description: "Use LiteLLM as an LLM provider in Mem0 to access over 100 language
|
||||
---
|
||||
[Litellm](https://litellm.vercel.app/docs/) is compatible with over 100 large language models (LLMs), all using a standardized input/output format. You can explore the [available models](https://litellm.vercel.app/docs/providers) to use with Litellm. Ensure you set the `API_KEY` for the model you choose to use.
|
||||
|
||||
In the TypeScript SDK, run LiteLLM as a [proxy server](https://docs.litellm.ai/docs/simple_proxy) (an OpenAI-compatible endpoint) and point Mem0 at it via `LITELLM_API_BASE` (defaults to `http://localhost:4000`).
|
||||
|
||||
## Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -36,33 +33,6 @@ messages = [
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
// Point Mem0 at your LiteLLM proxy. apiKey defaults to "sk-anything"
|
||||
// (the proxy handles real auth); baseURL defaults to http://localhost:4000.
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'litellm',
|
||||
config: {
|
||||
apiKey: process.env.LITELLM_API_KEY || 'sk-anything',
|
||||
baseURL: process.env.LITELLM_API_BASE || 'http://localhost:4000',
|
||||
model: 'gpt-5-mini',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
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 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).
|
||||
@@ -7,8 +7,7 @@ To use MiniMax LLM models, you have to set the `MINIMAX_API_KEY` environment var
|
||||
|
||||
## Usage
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
```python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
@@ -37,37 +36,9 @@ messages = [
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'minimax',
|
||||
config: {
|
||||
apiKey: process.env.MINIMAX_API_KEY || '',
|
||||
model: 'MiniMax-M2.7',
|
||||
temperature: 0.2,
|
||||
maxTokens: 2000,
|
||||
topP: 1.0,
|
||||
},
|
||||
},
|
||||
};
|
||||
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 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>
|
||||
|
||||
You can also configure the API base URL in the config:
|
||||
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
```python
|
||||
config = {
|
||||
"llm": {
|
||||
"provider": "minimax",
|
||||
@@ -80,20 +51,6 @@ config = {
|
||||
}
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
const config = {
|
||||
llm: {
|
||||
provider: 'minimax',
|
||||
config: {
|
||||
model: 'MiniMax-M2.7',
|
||||
baseURL: 'https://your-custom-endpoint.com',
|
||||
apiKey: 'your-api-key', // alternatively to using the environment variable
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
## Config
|
||||
|
||||
All available parameters for the `minimax` config are present in [Master List of All Params in Config](../config).
|
||||
|
||||
@@ -20,7 +20,7 @@ config = {
|
||||
"llm": {
|
||||
"provider": "xai",
|
||||
"config": {
|
||||
"model": "grok-4.3",
|
||||
"model": "grok-3-beta",
|
||||
"temperature": 0.1,
|
||||
"max_tokens": 2000,
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ For a comprehensive list of available parameters for llm configuration, please r
|
||||
See the list of supported LLMs below.
|
||||
|
||||
<Note>
|
||||
All LLMs are supported in Python. The following LLMs are also supported in TypeScript: **OpenAI**, **Anthropic**, **Groq**, **Azure OpenAI**, **DeepSeek**, **Google AI**, **Langchain**, **LM Studio**, **Mistral AI**, and **Ollama**.
|
||||
All LLMs are supported in Python. The following LLMs are also supported in TypeScript: **OpenAI**, **Anthropic**, and **Groq**.
|
||||
</Note>
|
||||
|
||||
<CardGroup cols={4}>
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
---
|
||||
title: LLM as Reranker
|
||||
description: "Use any LLM as a flexible reranker in Mem0 with custom prompts and domain-specific scoring logic."
|
||||
---
|
||||
|
||||
<Warning>
|
||||
**This page has been superseded.** Please see [LLM Reranker](/components/rerankers/models/llm_reranker) for the complete and up-to-date documentation on using LLMs for reranking.
|
||||
</Warning>
|
||||
|
||||
LLM-based reranker provides maximum flexibility by using any Large Language Model to score document relevance. This approach allows for custom prompts and domain-specific scoring logic.
|
||||
|
||||
## Supported LLM Providers
|
||||
|
||||
Any LLM provider supported by Mem0 can be used for reranking:
|
||||
|
||||
- **OpenAI**: GPT-4, GPT-3.5-turbo, etc.
|
||||
- **Anthropic**: Claude models
|
||||
- **Together**: Open-source models
|
||||
- **Groq**: Fast inference
|
||||
- **Ollama**: Local models
|
||||
- And more...
|
||||
|
||||
## Configuration
|
||||
|
||||
```python Python
|
||||
from mem0 import Memory
|
||||
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "chroma",
|
||||
"config": {
|
||||
"collection_name": "my_memories",
|
||||
"path": "./chroma_db"
|
||||
}
|
||||
},
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini"
|
||||
}
|
||||
},
|
||||
"reranker": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"provider": "openai",
|
||||
"api_key": "your-openai-api-key", # or set OPENAI_API_KEY
|
||||
"top_k": 5,
|
||||
"temperature": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memory = Memory.from_config(config)
|
||||
```
|
||||
|
||||
## Custom Scoring Prompt
|
||||
|
||||
You can provide a custom prompt for relevance scoring:
|
||||
|
||||
```python Python
|
||||
custom_prompt = """You are a relevance scoring assistant. Rate how well this document answers the query.
|
||||
|
||||
Query: "{query}"
|
||||
Document: "{document}"
|
||||
|
||||
Score from 0.0 to 1.0 where:
|
||||
- 1.0: Perfect match, directly answers the query
|
||||
- 0.8-0.9: Highly relevant, good match
|
||||
- 0.6-0.7: Moderately relevant, partial match
|
||||
- 0.4-0.5: Slightly relevant, limited useful information
|
||||
- 0.0-0.3: Not relevant or no useful information
|
||||
|
||||
Provide only a single numerical score between 0.0 and 1.0."""
|
||||
|
||||
config["reranker"]["config"]["scoring_prompt"] = custom_prompt
|
||||
```
|
||||
|
||||
## Usage Example
|
||||
|
||||
```python Python
|
||||
import os
|
||||
from mem0 import Memory
|
||||
|
||||
# Set API key
|
||||
os.environ["OPENAI_API_KEY"] = "your-api-key"
|
||||
|
||||
# Initialize memory with LLM reranker
|
||||
config = {
|
||||
"vector_store": {"provider": "chroma"},
|
||||
"llm": {"provider": "openai", "config": {"model": "gpt-4o-mini"}},
|
||||
"reranker": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"provider": "openai",
|
||||
"temperature": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
memory = Memory.from_config(config)
|
||||
|
||||
# Add memories
|
||||
messages = [
|
||||
{"role": "user", "content": "I'm learning Python programming"},
|
||||
{"role": "user", "content": "I find object-oriented programming challenging"},
|
||||
{"role": "user", "content": "I love hiking in national parks"}
|
||||
]
|
||||
|
||||
memory.add(messages, user_id="david")
|
||||
|
||||
# Search with LLM reranking
|
||||
results = memory.search("What programming topics is the user studying?", filters={"user_id": "david"})
|
||||
|
||||
for result in results['results']:
|
||||
print(f"Memory: {result['memory']}")
|
||||
print(f"Vector Score: {result['score']:.3f}")
|
||||
print(f"Rerank Score: {result['rerank_score']:.3f}")
|
||||
print()
|
||||
```
|
||||
|
||||
```text Output
|
||||
Memory: I'm learning Python programming
|
||||
Vector Score: 0.856
|
||||
Rerank Score: 0.920
|
||||
|
||||
Memory: I find object-oriented programming challenging
|
||||
Vector Score: 0.782
|
||||
Rerank Score: 0.850
|
||||
```
|
||||
|
||||
## Domain-Specific Scoring
|
||||
|
||||
Create specialized scoring for your domain:
|
||||
|
||||
```python Python
|
||||
medical_prompt = """You are a medical relevance expert. Score how relevant this medical record is to the clinical query.
|
||||
|
||||
Clinical Query: "{query}"
|
||||
Medical Record: "{document}"
|
||||
|
||||
Consider:
|
||||
- Clinical relevance and accuracy
|
||||
- Patient safety implications
|
||||
- Diagnostic value
|
||||
- Treatment relevance
|
||||
|
||||
Score from 0.0 to 1.0. Provide only the numerical score."""
|
||||
|
||||
config = {
|
||||
"reranker": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "gpt-4o-mini",
|
||||
"provider": "openai",
|
||||
"scoring_prompt": medical_prompt,
|
||||
"temperature": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Multiple LLM Providers
|
||||
|
||||
Use different LLM providers for reranking:
|
||||
|
||||
```python Python
|
||||
# Using Anthropic Claude
|
||||
anthropic_config = {
|
||||
"reranker": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "claude-3-haiku-20240307",
|
||||
"provider": "anthropic",
|
||||
"temperature": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Using local Ollama model
|
||||
ollama_config = {
|
||||
"reranker": {
|
||||
"provider": "llm",
|
||||
"config": {
|
||||
"model": "llama2:7b",
|
||||
"provider": "ollama",
|
||||
"temperature": 0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration Parameters
|
||||
|
||||
| Parameter | Description | Type | Default |
|
||||
|-----------|-------------|------|---------|
|
||||
| `model` | LLM model to use for scoring | `str` | `"gpt-4o-mini"` |
|
||||
| `provider` | LLM provider name | `str` | `"openai"` |
|
||||
| `api_key` | API key for the LLM provider | `str` | `None` |
|
||||
| `top_k` | Maximum documents to return | `int` | `None` |
|
||||
| `temperature` | Temperature for LLM generation | `float` | `0.0` |
|
||||
| `max_tokens` | Maximum tokens for LLM response | `int` | `100` |
|
||||
| `scoring_prompt` | Custom prompt template | `str` | Default prompt |
|
||||
|
||||
## Advantages
|
||||
|
||||
- **Maximum Flexibility**: Custom prompts for any use case
|
||||
- **Domain Expertise**: Leverage LLM knowledge for specialized domains
|
||||
- **Interpretability**: Understand scoring through prompt engineering
|
||||
- **Multi-criteria**: Score based on multiple relevance factors
|
||||
|
||||
## Considerations
|
||||
|
||||
- **Latency**: Higher latency than specialized rerankers
|
||||
- **Cost**: LLM API costs per reranking operation
|
||||
- **Consistency**: May have slight variations in scoring
|
||||
- **Prompt Engineering**: Requires careful prompt design
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Temperature**: Use 0.0 for consistent scoring
|
||||
2. **Prompt Design**: Be specific about scoring criteria
|
||||
3. **Token Efficiency**: Keep prompts concise to reduce costs
|
||||
4. **Caching**: Cache results for repeated queries when possible
|
||||
5. **Fallback**: Handle API errors gracefully
|
||||
@@ -46,7 +46,7 @@ Here are the parameters available for configuring Baidu VectorDB:
|
||||
| `account` | Baidu VectorDB account name | `root` |
|
||||
| `api_key` | API key for accessing Baidu VectorDB | Required |
|
||||
| `database_name` | Name of the database | `mem0` |
|
||||
| `table_name` | Name of the table | `mem0` |
|
||||
| `table_name` | Name of the table | `mem0_table` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `metric_type` | Distance metric for similarity search | `L2` |
|
||||
|
||||
|
||||
@@ -56,8 +56,6 @@ Here are the parameters available for configuring Elasticsearch:
|
||||
| `api_key` | API key for authentication | `None` |
|
||||
| `user` | Username for basic authentication | `None` |
|
||||
| `password` | Password for basic authentication | `None` |
|
||||
| `use_ssl` | Whether to use SSL for the connection | `True` |
|
||||
| `ca_certs` | Path to CA bundle for SSL certificate verification | `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` |
|
||||
|
||||
@@ -55,7 +55,6 @@ Here are the parameters available for configuring FAISS:
|
||||
| `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` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
|
||||
### Performance Considerations
|
||||
|
||||
|
||||
@@ -47,12 +47,12 @@ m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from "mem0ai/oss";
|
||||
import { Memory } from "mem0ai";
|
||||
import { OpenAIEmbeddings } from "@langchain/openai";
|
||||
import { MemoryVectorStore } from "langchain/vectorstores/memory";
|
||||
import { MemoryVectorStore as LangchainMemoryStore } from "langchain/vectorstores/memory";
|
||||
|
||||
const embeddings = new OpenAIEmbeddings();
|
||||
const vectorStore = new MemoryVectorStore(embeddings);
|
||||
const vectorStore = new LangchainVectorStore(embeddings);
|
||||
|
||||
const config = {
|
||||
"vector_store": {
|
||||
|
||||
@@ -42,8 +42,8 @@ Here are the parameters available for configuring MongoDB:
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| db_name | Name of the MongoDB database | `"mem0_db"` |
|
||||
| collection_name | Name of the MongoDB collection | `"mem0"` |
|
||||
| collection_name | Name of the MongoDB collection | `"mem0_collection"` |
|
||||
| embedding_model_dims | Dimensions of the embedding vectors | `1536` |
|
||||
| mongo_uri | The MongoDB URI connection string | `mongodb://localhost:27017` |
|
||||
| mongo_uri | The MongoDB URI connection string | `mongodb://username:password@localhost:27017` |
|
||||
|
||||
> **Note**: If `mongo_uri` is not provided, it will default to `mongodb://localhost:27017`.
|
||||
> **Note**: If `mongo_uri` is not provided, it will default to `mongodb://username:password@localhost:27017`.
|
||||
|
||||
@@ -53,14 +53,17 @@ print(results)
|
||||
import "dotenv/config";
|
||||
import { Memory } from "mem0ai/oss";
|
||||
|
||||
const databaseUrl = new URL(process.env.DATABASE_URL!);
|
||||
|
||||
const m = new Memory({
|
||||
vectorStore: {
|
||||
provider: "pgvector",
|
||||
config: {
|
||||
connectionString: process.env.DATABASE_URL!,
|
||||
ssl: {
|
||||
rejectUnauthorized: false,
|
||||
},
|
||||
user: decodeURIComponent(databaseUrl.username),
|
||||
password: decodeURIComponent(databaseUrl.password),
|
||||
host: databaseUrl.hostname,
|
||||
port: Number(databaseUrl.port || 5432),
|
||||
dbname: databaseUrl.pathname.slice(1) || "neondb",
|
||||
collectionName: "memories",
|
||||
dimension: 1536,
|
||||
embeddingModelDims: 1536,
|
||||
@@ -87,7 +90,6 @@ const results = await m.search("What movies should I recommend?", {
|
||||
|
||||
console.log(results);
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
## SQL Migration
|
||||
@@ -114,19 +116,20 @@ DATABASE_URL=postgresql://user:password@ep-example.us-east-2.aws.neon.tech/neond
|
||||
| `sslmode` | PostgreSQL SSL mode. Use `require` for Neon. | Driver default |
|
||||
</Tab>
|
||||
<Tab title="TypeScript">
|
||||
Use the Neon `DATABASE_URL` directly with `connectionString`. Set `ssl` if your runtime needs an explicit TLS config object.
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| -------------------- | ---------------------------------------------- | -------------- |
|
||||
| `connectionString` | Neon Postgres connection string. | Required |
|
||||
| `ssl` | Optional TLS settings passed directly to `pg`. | Driver default |
|
||||
| `collectionName` | Name for the vector collection. | `memories` |
|
||||
| `dimension` | Vector dimension for Mem0 config. | Auto-detected |
|
||||
| `embeddingModelDims` | Embedding model dimensions for table creation. | Required |
|
||||
| `hnsw` | Enables HNSW indexing. | `false` |
|
||||
|
||||
**TLS note:** `ssl: true` is sufficient for most Neon connections since Neon uses valid certificates. Use `ssl: { rejectUnauthorized: false }` only when connecting through Neon's connection pooler on certain edge runtimes (e.g. Cloudflare Workers) that require it, or when your environment does not trust the Neon CA chain.
|
||||
The current Mem0 TypeScript `pgvector` adapter takes individual Postgres fields,
|
||||
so parse `DATABASE_URL` before creating `Memory`.
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| --- | --- | --- |
|
||||
| `user` | Database user. | Required |
|
||||
| `password` | Database password. | Required |
|
||||
| `host` | Database host. | Required |
|
||||
| `port` | Database port. | `5432` |
|
||||
| `dbname` | Database name. | `vector_store` |
|
||||
| `collectionName` | Name for the vector collection. | `memories` |
|
||||
| `dimension` | Vector dimension for Mem0 config. | Auto-detected |
|
||||
| `embeddingModelDims` | Embedding model dimensions for table creation. | Required |
|
||||
| `hnsw` | Enables HNSW indexing. | `false` |
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ description: "Use AWS Neptune Analytics as a vector store in Mem0, combining gra
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install mem0ai[vector-stores]
|
||||
pip install mem0ai[vector_stores]
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
@@ -56,30 +56,6 @@ config = {
|
||||
}
|
||||
```
|
||||
|
||||
### Configuration Options
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
|-----------|------|---------|-------------|
|
||||
| `collection_name` | string | required | Name of the OpenSearch index |
|
||||
| `host` | string | required | OpenSearch endpoint URL |
|
||||
| `port` | int | 9200 | Port number |
|
||||
| `http_auth` | object | None | Authentication credentials (e.g., AWSV4SignerAuth) |
|
||||
| `embedding_model_dims` | int | 1536 | Dimension of embedding vectors |
|
||||
| `use_ssl` | bool | False | Enable SSL/TLS connection |
|
||||
| `verify_certs` | bool | False | Verify SSL certificates |
|
||||
| `auto_refresh` | bool | False | Automatically refresh index after insert. OpenSearch refreshes every ~1 second by default, so this is rarely needed. |
|
||||
|
||||
<Note>
|
||||
The defaults above match a local OpenSearch instance. The AWS OpenSearch Serverless
|
||||
example earlier on this page intentionally overrides them with `port=443`, `use_ssl=True`,
|
||||
and `verify_certs=True`, which are required when connecting to a Serverless collection.
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
For **AWS OpenSearch Serverless**, keep `auto_refresh=False` (the default).
|
||||
The `indices.refresh()` API is not supported on Serverless collections.
|
||||
</Note>
|
||||
|
||||
### Add Memories
|
||||
|
||||
```python
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
title: "pgvector"
|
||||
description: "Use pgvector as a vector store in Mem0 for PostgreSQL-based vector similarity search with open-source simplicity."
|
||||
---
|
||||
|
||||
[pgvector](https://github.com/pgvector/pgvector) is an open-source vector similarity search extension for Postgres. After connecting to Postgres, run `CREATE EXTENSION IF NOT EXISTS vector;` to create the vector extension.
|
||||
|
||||
### Usage
|
||||
@@ -22,7 +21,7 @@ config = {
|
||||
"password": "123",
|
||||
"host": "127.0.0.1",
|
||||
"port": "5432",
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,22 +30,25 @@ messages = [
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about 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."},
|
||||
{"role": "assistant", "content": "Got it! I'll avoid thriller recommendations and suggest sci-fi movies in the future."}
|
||||
]
|
||||
m.add(messages, user_id="alice", metadata={"category": "movies"})
|
||||
|
||||
```
|
||||
|
||||
```typescript TypeScript
|
||||
import { Memory } from "mem0ai/oss";
|
||||
import { Memory } from 'mem0ai/oss';
|
||||
|
||||
const config = {
|
||||
vectorStore: {
|
||||
provider: "pgvector",
|
||||
provider: 'pgvector',
|
||||
config: {
|
||||
collectionName: "memories",
|
||||
collectionName: 'memories',
|
||||
embeddingModelDims: 1536,
|
||||
connectionString: "postgresql://test:123@localhost:5432/vector_store",
|
||||
user: 'test',
|
||||
password: '123',
|
||||
host: '127.0.0.1',
|
||||
port: 5432,
|
||||
dbname: 'vector_store', // Optional; TypeScript OSS defaults to `vector_store` when omitted
|
||||
diskann: false, // Optional, requires pgvectorscale extension
|
||||
hnsw: false, // Optional, for HNSW indexing
|
||||
},
|
||||
@@ -55,44 +57,37 @@ const config = {
|
||||
|
||||
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 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." },
|
||||
];
|
||||
|
||||
{"role": "user", "content": "I'm planning to watch a movie tonight. Any recommendations?"},
|
||||
{"role": "assistant", "content": "How about 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
|
||||
|
||||
Here are the parameters available for configuring pgvector:
|
||||
|
||||
| Parameter | SDK | Description | Default Value |
|
||||
| -------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
|
||||
| `connectionString` | TypeScript OSS | PostgreSQL connection string for direct connections. When set, Mem0 connects to the target database directly and skips the bootstrap `postgres` database flow. | `None` |
|
||||
| `ssl` | TypeScript OSS | SSL option passed directly to `pg`, either `true` or an SSL config object, for both `connectionString` and split-field connections. | `None` |
|
||||
| `dbname` | TypeScript OSS | Split-field database name. This is only used when `connectionString` is absent. | `vector_store` |
|
||||
| `collectionName` | TypeScript OSS | Collection name. | `memories` |
|
||||
| `embeddingModelDims` | TypeScript OSS | Dimensions of the embedding model. | Required |
|
||||
| `user` | TypeScript OSS + Python | Database user for split-field connections. | `None` |
|
||||
| `password` | TypeScript OSS + Python | Database password for split-field connections. | `None` |
|
||||
| `host` | TypeScript OSS + Python | Database host for split-field connections. | `None` |
|
||||
| `port` | TypeScript OSS + Python | Database port for split-field connections. | `None` |
|
||||
| `diskann` | TypeScript OSS + Python | Whether to use DiskANN for vector similarity search, requires pgvectorscale. | `False` |
|
||||
| `hnsw` | TypeScript OSS + Python | Whether to use HNSW for vector similarity search. | TypeScript OSS: `False`, Python: `True` |
|
||||
| `connection_string` | Python only | PostgreSQL connection string, overrides individual connection parameters. | `None` |
|
||||
| `sslmode` | Python only | SSL mode for PostgreSQL connections, such as `require`, `prefer`, or `disable`. | `None` |
|
||||
| `connection_pool` | Python only | psycopg connection pool object, overrides connection string and individual connection parameters. | `None` |
|
||||
| Parameter | Description | Default Value |
|
||||
| --- | --- | --- |
|
||||
| `dbname` | The name of the database | `postgres` |
|
||||
| `collection_name` | The name of the collection | `mem0` |
|
||||
| `embedding_model_dims` | Dimensions of the embedding model | `1536` |
|
||||
| `user` | User name to connect to the database | `None` |
|
||||
| `password` | Password to connect to the database | `None` |
|
||||
| `host` | The host where the Postgres server is running | `None` |
|
||||
| `port` | The port where the Postgres server is running | `None` |
|
||||
| `diskann` | Whether to use diskann for vector similarity search (requires pgvectorscale) | `True` |
|
||||
| `hnsw` | Whether to use hnsw for vector similarity search | `False` |
|
||||
| `sslmode` | SSL mode for PostgreSQL connection (e.g., 'require', 'prefer', 'disable') | `None` |
|
||||
| `connection_string` | PostgreSQL connection string (overrides individual connection parameters) | `None` |
|
||||
| `connection_pool` | psycopg2 connection pool object (overrides connection string and individual parameters) | `None` |
|
||||
|
||||
**TypeScript OSS:** Use `connectionString` plus optional `ssl` for managed Postgres setups. If you omit `connectionString`, Mem0 falls back to split fields and uses `dbname`, `user`, `password`, `host`, `port`, and optional `ssl`.
|
||||
|
||||
**Python:** The Python SDK uses snake_case keys such as `connection_string`, `sslmode`, `collection_name`, and `embedding_model_dims`.
|
||||
|
||||
**Python connection priority**:
|
||||
**Note (TypeScript OSS):** If you omit `dbname`, the TypeScript client uses the database name `vector_store`. Python defaults to `postgres` for `dbname`, as in the table above.
|
||||
|
||||
**Note**: The connection parameters have the following priority:
|
||||
1. `connection_pool` (highest priority)
|
||||
2. `connection_string`
|
||||
3. Individual connection parameters (`user`, `password`, `host`, `port`, `sslmode`)
|
||||
3. Individual connection parameters (`user`, `password`, `host`, `port`, `sslmode`)
|
||||
@@ -18,9 +18,7 @@ os.environ["UPSTASH_VECTOR_REST_TOKEN"] = "..."
|
||||
config = {
|
||||
"vector_store": {
|
||||
"provider": "upstash_vector",
|
||||
"config": {
|
||||
"enable_embeddings": True,
|
||||
}
|
||||
"enable_embeddings": True,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ description: "Use Valkey as an open-source vector store in Mem0 for high-perform
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install mem0ai[vector-stores]
|
||||
pip install mem0ai[vector_stores]
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -51,7 +51,7 @@ Here are the parameters available for configuring Valkey:
|
||||
| `hnsw_ef_construction` | Size of dynamic candidate list for HNSW | `200` |
|
||||
| `hnsw_ef_runtime` | Size of dynamic candidate list for search | `10` |
|
||||
| `cluster_mode` | Enable cluster mode for Valkey cluster (CME) deployments | `false` |
|
||||
| `timezone` | Timezone for timestamp handling | `UTC` |
|
||||
| `distance_metric` | Distance metric for vector similarity | `cosine` |
|
||||
|
||||
## Cluster Mode
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ config = {
|
||||
"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", # Required: Google Cloud region
|
||||
"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
|
||||
}
|
||||
@@ -45,6 +45,5 @@ m.add("Your text here", user_id="user", metadata={"category": "example"})
|
||||
| `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 | Yes |
|
||||
| `region` | Google Cloud region | No (defaults to GOOGLE_CLOUD_REGION) |
|
||||
| `credentials_path` | Path to service account credentials | No (defaults to GOOGLE_APPLICATION_CREDENTIALS) |
|
||||
| `service_account_json` | Service account credentials as a dictionary (alternative to `credentials_path`) | `None` |
|
||||
|
||||
@@ -7,7 +7,7 @@ description: "Use Weaviate as an open-source vector search engine in Mem0 for st
|
||||
|
||||
### Installation
|
||||
```bash
|
||||
pip install weaviate-client
|
||||
pip install weaviate weaviate-client
|
||||
```
|
||||
|
||||
### Usage
|
||||
@@ -48,5 +48,4 @@ Here are the parameters available for configuring Weaviate:
|
||||
| `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` |
|
||||
| `additional_headers` | Additional headers to include in requests (`Dict[str, str]`) | `None` |
|
||||
| `auth_client_secret` | API key for Weaviate authentication | `None` |
|
||||
@@ -10,7 +10,7 @@ Mem0 includes built-in support for various popular databases. Memory can utilize
|
||||
See the list of supported vector databases below.
|
||||
|
||||
<Note>
|
||||
The following vector databases are supported in the Python implementation. The TypeScript implementation currently supports Qdrant, Redis, PGVector, Supabase, LangChain, Azure AI Search, Vectorize, and an in-memory store.
|
||||
The following vector databases are supported in the Python implementation. The TypeScript implementation currently only supports Qdrant, Redis, Valkey, Vectorize and in-memory vector database.
|
||||
</Note>
|
||||
|
||||
<CardGroup cols={3}>
|
||||
|
||||
@@ -1,65 +1,32 @@
|
||||
---
|
||||
title: Development
|
||||
description: "Guide to contributing code to Mem0, covering the issue-first workflow, the CLA, environment setup for the Python and TypeScript SDKs, and code quality checks."
|
||||
description: "Guide to contributing code to Mem0, covering the fork and clone workflow, PR submission, and code quality checks."
|
||||
icon: "code"
|
||||
---
|
||||
|
||||
# Development Contributions
|
||||
|
||||
We strive to make contributions **easy, collaborative, and enjoyable**. Mem0 is a
|
||||
polyglot monorepo containing the **Python SDK** (`mem0/`), the **TypeScript SDK**
|
||||
(`mem0-ts/`), CLIs, integrations, the self-hosted server, and the docs site.
|
||||
Follow the steps below for a smooth contribution process.
|
||||
We strive to make contributions **easy, collaborative, and enjoyable**. Follow the steps below to ensure a smooth contribution process.
|
||||
|
||||
<Note>
|
||||
For the complete contributor checklist, see
|
||||
[CONTRIBUTING.md](https://github.com/mem0ai/mem0/blob/main/CONTRIBUTING.md) in
|
||||
the repository root.
|
||||
</Note>
|
||||
## Submitting Your Contribution through PR
|
||||
|
||||
## Before You Start
|
||||
|
||||
### 1. Open an Issue First
|
||||
|
||||
**Always open an issue before opening a pull request.** This lets us discuss the
|
||||
change, avoid duplicate work, and agree on the approach before you write code.
|
||||
|
||||
- Search [existing issues](https://github.com/mem0ai/mem0/issues) first.
|
||||
- If none match, open a
|
||||
[bug report](https://github.com/mem0ai/mem0/issues/new?template=bug_report.yml)
|
||||
or [feature request](https://github.com/mem0ai/mem0/issues/new?template=feature_request.yml).
|
||||
- For anything beyond a trivial fix, wait for a maintainer to confirm the approach.
|
||||
|
||||
Every pull request must link to an issue using `Closes #<issue-number>`.
|
||||
|
||||
### 2. Sign the Contributor License Agreement (CLA)
|
||||
|
||||
**We cannot merge any pull request until you have signed our Contributor License
|
||||
Agreement (CLA).** When you open your first PR, the CLA bot will comment with a
|
||||
link to sign — it takes less than a minute and only needs to be done once.
|
||||
|
||||
## Submitting Your Contribution through a PR
|
||||
To contribute, follow these steps:
|
||||
|
||||
1. **Fork & Clone** the repository: [Mem0 on GitHub](https://github.com/mem0ai/mem0)
|
||||
2. **Create a Feature Branch**: Use a dedicated branch, e.g., `feature/my-new-feature`
|
||||
3. **Implement Changes**: If adding a feature or fixing a bug, be sure to:
|
||||
2. **Create a Feature Branch**: Use a dedicated branch for your changes, e.g., `feature/my-new-feature`
|
||||
3. **Implement Changes**: If adding a feature or fixing a bug, ensure to:
|
||||
- Write necessary **tests**
|
||||
- Add **documentation, docstrings, and runnable examples**
|
||||
4. **Code Quality Checks**:
|
||||
- Run **linting** to catch style issues
|
||||
- Ensure **all tests pass**
|
||||
5. **Commit** using [Conventional Commits](https://www.conventionalcommits.org/)
|
||||
(`feat:`, `fix:`, `docs:`, `refactor:`, `test:`)
|
||||
6. **Submit a Pull Request** against `main`, linking the issue and filling out the
|
||||
PR template.
|
||||
5. **Submit a Pull Request**
|
||||
|
||||
For detailed guidance on pull requests, refer to [GitHub's documentation](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
|
||||
|
||||
---
|
||||
|
||||
## Python SDK (`mem0/`)
|
||||
|
||||
### Dependency Management
|
||||
## Dependency Management
|
||||
|
||||
We use `hatch` as our package manager. Install it by following the [official instructions](https://hatch.pypa.io/latest/install/).
|
||||
|
||||
@@ -77,9 +44,13 @@ hatch -e dev_py_3_11 shell # For dev_py_3_11 (differences are mentioned in pypr
|
||||
make install_all
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Development Standards
|
||||
|
||||
### Pre-commit Hooks
|
||||
|
||||
Ensure `pre-commit` is installed before contributing (hooks run ruff + isort):
|
||||
Ensure `pre-commit` is installed before contributing:
|
||||
|
||||
```bash
|
||||
pre-commit install
|
||||
@@ -87,7 +58,7 @@ pre-commit install
|
||||
|
||||
### Linting with `ruff`
|
||||
|
||||
Run the linter and fix any reported issues before submitting your PR (line length **120**):
|
||||
Run the linter and fix any reported issues before submitting your PR:
|
||||
|
||||
```bash
|
||||
make lint
|
||||
@@ -95,11 +66,10 @@ make lint
|
||||
|
||||
### Code Formatting
|
||||
|
||||
To maintain a consistent code style, format your code and sort imports (isort, `profile = "black"`):
|
||||
To maintain a consistent code style, format your code:
|
||||
|
||||
```bash
|
||||
make format
|
||||
make sort
|
||||
```
|
||||
|
||||
### Testing with `pytest`
|
||||
@@ -114,46 +84,10 @@ make test
|
||||
|
||||
---
|
||||
|
||||
## TypeScript SDK (`mem0-ts/`)
|
||||
|
||||
We use [`pnpm`](https://pnpm.io/) (v10+) for all TypeScript packages. **Do NOT use
|
||||
`npm` or `yarn`.**
|
||||
|
||||
```bash
|
||||
cd mem0-ts
|
||||
pnpm install
|
||||
|
||||
pnpm run build # tsup (CJS + ESM)
|
||||
pnpm run test # jest (all tests)
|
||||
pnpm run test:unit # unit tests with coverage
|
||||
```
|
||||
|
||||
### Standards
|
||||
|
||||
- **Build:** tsup
|
||||
- **Formatter:** Prettier
|
||||
- **Tests:** jest
|
||||
- Always run type checking after changes: `pnpm run typecheck` (or `tsc --noEmit`)
|
||||
- Use ES module `import` syntax — never `require()`
|
||||
|
||||
---
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
**Do not report security vulnerabilities through public issues or pull requests.**
|
||||
Please follow our [Security Policy](https://github.com/mem0ai/mem0/blob/main/SECURITY.md)
|
||||
to report them privately.
|
||||
|
||||
---
|
||||
|
||||
## Release Process
|
||||
|
||||
Packages are published automatically via GitHub Actions when a GitHub Release is
|
||||
created with the correct tag prefix (e.g. `v*` for the Python SDK, `ts-v*` for the
|
||||
TypeScript SDK). See
|
||||
[CONTRIBUTING.md](https://github.com/mem0ai/mem0/blob/main/CONTRIBUTING.md#releasing)
|
||||
for the full tag-prefix table and publishing details.
|
||||
Currently, releases are handled manually. We aim for frequent releases, typically when new features or bug fixes are introduced.
|
||||
|
||||
---
|
||||
|
||||
Thank you for contributing to Mem0!
|
||||
Thank you for contributing to Mem0!
|
||||
@@ -31,7 +31,7 @@ const openaiClient = new OpenAI();
|
||||
const memory = new Memory();
|
||||
|
||||
async function chatWithMemories(message, userId = "default_user") {
|
||||
const relevantMemories = await memory.search(message, { filters: { user_id: userId } });
|
||||
const relevantMemories = await memory.search(message, { userId: userId });
|
||||
|
||||
const memoriesStr = relevantMemories.results
|
||||
.map(entry => `- ${entry.memory}`)
|
||||
|
||||
@@ -289,7 +289,8 @@ print([m["memory"] for m in constraints["results"]])
|
||||
```python
|
||||
constraints = memory.search(
|
||||
query="injury concerns",
|
||||
filters={"user_id": "max", "memory_bucket": {"in": ["constraints"]}},
|
||||
user_id="max",
|
||||
filters={"memory_bucket": {"in": ["constraints"]}},
|
||||
threshold=0.0 # optional: widen recall for short phrases
|
||||
)
|
||||
print([m["memory"] for m in constraints["results"]])
|
||||
@@ -735,7 +736,8 @@ mem0_client.add(messages, user_id="max", run_id="nyc-2025")
|
||||
# Retrieve only Boston memories
|
||||
boston_memories = mem0_client.search(
|
||||
"training plan",
|
||||
filters={"user_id": "max", "run_id": "boston-2025"}
|
||||
user_id="max",
|
||||
run_id="boston-2025"
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
@@ -747,7 +749,8 @@ memory.add(messages, user_id="max", run_id="nyc-2025")
|
||||
# Retrieve only Boston memories
|
||||
boston_memories = memory.search(
|
||||
"training plan",
|
||||
filters={"user_id": "max", "run_id": "boston-2025"},
|
||||
user_id="max",
|
||||
run_id="boston-2025",
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
@@ -843,7 +846,8 @@ Prioritize recent training over old data:
|
||||
```python
|
||||
recent = mem0_client.search(
|
||||
"training progress",
|
||||
filters={"user_id": "max", "created_at": {"gte": "2025-10-01"}}
|
||||
user_id="max",
|
||||
filters={"created_at": {"gte": "2025-10-01"}}
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
@@ -862,7 +866,8 @@ memory.add(
|
||||
cutoff = int(datetime(2025, 10, 1).timestamp())
|
||||
recent = memory.search(
|
||||
"training progress",
|
||||
filters={"user_id": "max", "logged_epoch": {"gte": cutoff}},
|
||||
user_id="max",
|
||||
filters={"logged_epoch": {"gte": cutoff}},
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
@@ -884,7 +889,8 @@ mem0_client.add(
|
||||
# Later, find all speed workouts
|
||||
speed_sessions = mem0_client.search(
|
||||
"speed work",
|
||||
filters={"user_id": "max", "metadata": {"workout_type": "speed"}}
|
||||
user_id="max",
|
||||
filters={"metadata": {"workout_type": "speed"}}
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
@@ -899,7 +905,8 @@ memory.add(
|
||||
# Later, find all speed workouts
|
||||
speed_sessions = memory.search(
|
||||
"speed work",
|
||||
filters={"user_id": "max", "workout_type": "speed"},
|
||||
user_id="max",
|
||||
filters={"workout_type": "speed"},
|
||||
)
|
||||
```
|
||||
</Tab>
|
||||
|
||||
@@ -58,7 +58,6 @@ Use `get_all()` with filters to retrieve everything for a specific user:
|
||||
```python
|
||||
dev_memories = client.get_all(
|
||||
filters={"user_id": "dev"},
|
||||
page=1,
|
||||
page_size=50
|
||||
)
|
||||
|
||||
|
||||
@@ -211,8 +211,8 @@ class MultiAgentLearningSystem:
|
||||
try:
|
||||
# Search memory for learning patterns
|
||||
memories = self.memory.search(
|
||||
query="learning machine learning",
|
||||
filters={"user_id": self.student_id}
|
||||
user_id=self.student_id,
|
||||
query="learning machine learning"
|
||||
)
|
||||
|
||||
if memories and memories.get('results'):
|
||||
|
||||
@@ -50,7 +50,7 @@ load_dotenv()
|
||||
USER_ID = "Alex"
|
||||
|
||||
# Initialize Mem0 client
|
||||
mem0_client = MemoryClient()
|
||||
mem0 = MemoryClient()
|
||||
```
|
||||
|
||||
## Define Memory Tools
|
||||
@@ -76,7 +76,7 @@ def retrieve_patient_info(query: str) -> dict:
|
||||
# Search Mem0
|
||||
results = mem0_client.search(
|
||||
query,
|
||||
filters={"user_id": USER_ID},
|
||||
user_id=USER_ID,
|
||||
top_k=5,
|
||||
threshold=0.7 # Higher threshold for more relevant results
|
||||
)
|
||||
|
||||
@@ -53,12 +53,34 @@ async function addUserPreferences() {
|
||||
await addUserPreferences();
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"message": "Memory processing has been queued for background execution",
|
||||
"status": "PENDING",
|
||||
"event_id": "9f8c2b1a-4e7d-4c3a-9b21-1a2b3c4d5e6f"
|
||||
}
|
||||
```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
|
||||
@@ -66,7 +88,7 @@ await addUserPreferences();
|
||||
Search for relevant memories based on the current user input:
|
||||
|
||||
```javascript
|
||||
const relevantMemories = await mem0Client.search(userInput, { filters: { user_id: USER_ID } });
|
||||
const relevantMemories = await mem0Client.search(userInput, { userId: USER_ID });
|
||||
```
|
||||
|
||||
## Structured Responses with Zod
|
||||
@@ -172,7 +194,7 @@ async function main(memory = false) {
|
||||
// Search for relevant memories
|
||||
let relevantMemories = []
|
||||
if (memory) {
|
||||
relevantMemories = await mem0Client.search(input, { filters: { user_id: USER_ID } });
|
||||
relevantMemories = await mem0Client.search(input, { userId: USER_ID });
|
||||
}
|
||||
|
||||
const response = await openAIClient.responses.create({
|
||||
|
||||
@@ -4,6 +4,8 @@ description: "Blend Tavily's realtime results with personal context stored in Me
|
||||
---
|
||||
|
||||
|
||||
<Snippet file="security-compliance.mdx" />
|
||||
|
||||
Imagine asking a search assistant for "coffee shops nearby" and instead of generic results, it shows remote-work-friendly cafes with great WiFi in your city because it remembers you mentioned working remotely before. Or when you search for "lunchbox ideas for kids" it knows you have a 7-year-old daughter and recommends peanut-free options that align with her allergy.
|
||||
|
||||
That's what we are going to build today, a Personalized Search Assistant powered by Mem0 for memory and [Tavily](https://tavily.com) for real-time search.
|
||||
|
||||
@@ -217,7 +217,8 @@ def apply_writing_style(original_content):
|
||||
|
||||
results = memory.search(
|
||||
query="What are my writing style preferences?",
|
||||
filters={"user_id": USER_ID, "run_id": RUN_ID},
|
||||
user_id=USER_ID,
|
||||
run_id=RUN_ID,
|
||||
)
|
||||
|
||||
if not results:
|
||||
|
||||
@@ -314,16 +314,18 @@ class EmailProcessor:
|
||||
user_id (str): User identifier
|
||||
sender (str, optional): Filter by sender email address
|
||||
"""
|
||||
# In OSS, user_id is an explicit parameter (not inside filters)
|
||||
if not sender:
|
||||
results = self.memory.search(
|
||||
query=query,
|
||||
filters={"user_id": user_id, "memory_category": "email"},
|
||||
user_id=user_id,
|
||||
filters={"memory_category": "email"},
|
||||
)
|
||||
else:
|
||||
results = self.memory.search(
|
||||
query=query,
|
||||
user_id=user_id,
|
||||
filters={
|
||||
"user_id": user_id,
|
||||
"AND": [
|
||||
{"memory_category": "email"},
|
||||
{"sender": sender},
|
||||
@@ -341,9 +343,10 @@ class EmailProcessor:
|
||||
subject (str): Email subject to match
|
||||
user_id (str): User identifier
|
||||
"""
|
||||
# In OSS, user_id is an explicit parameter
|
||||
thread = self.memory.get_all(
|
||||
user_id=user_id,
|
||||
filters={
|
||||
"user_id": user_id,
|
||||
"AND": [
|
||||
{"memory_category": "email"},
|
||||
{"subject": {"icontains": subject}},
|
||||
|
||||
@@ -57,7 +57,7 @@ class CustomerSupportAIAgent:
|
||||
"""
|
||||
# Start a streaming chat completion request to the AI
|
||||
stream = self.client.chat.completions.create(
|
||||
model="gpt-5-mini",
|
||||
model="gpt-4",
|
||||
stream=True,
|
||||
messages=[
|
||||
{"role": "system", "content": "You are a customer support AI agent."},
|
||||
|
||||
@@ -345,7 +345,7 @@ When evaluating memory systems, keep these considerations in mind:
|
||||
<Card title="Research" icon="flask" href="https://mem0.ai/research">
|
||||
Published research papers and technical reports
|
||||
</Card>
|
||||
<Card title="Blog Post" icon="newspaper" href="https://mem0.ai/blog/the-token-efficient-memory-algorithm-now-has-temporal-reasoning">
|
||||
<Card title="Blog Post" icon="newspaper" href="https://mem0.ai/blog/new-algorithm">
|
||||
Detailed writeup of the new algorithm design and results
|
||||
</Card>
|
||||
<Card title="Platform Migration" icon="arrow-right" href="/migration/platform-v2-to-v3">
|
||||
|
||||
@@ -238,11 +238,11 @@ client.search("preferences", filters={
|
||||
- **Use natural language**: Mem0 understands intent, so describe what you're looking for naturally
|
||||
- **Scope with user ID**: Always provide `user_id` to scope search to relevant memories
|
||||
- **Platform API**: Use `filters={"user_id": "alice"}`
|
||||
- **OSS**: Use `filters={"user_id": "alice"}` (passing `user_id` as a top-level kwarg raises `ValueError` in v3)
|
||||
- **OSS**: Use `user_id="alice"` as parameter
|
||||
- **Combine filters**: Use AND/OR logic to create precise queries (Platform)
|
||||
- **Consider wildcard filters**: Use wildcard filters (e.g., `run_id: "*"`) for broader matches
|
||||
- **Tune parameters**: Adjust `top_k` for result count, `threshold` for relevance cutoff
|
||||
- **Enable reranking**: Use `rerank=True` (default is `False`) when you have a reranker configured
|
||||
- **Enable reranking**: Use `rerank=True` (default) when you have a reranker configured
|
||||
|
||||
<Callout type="tip" icon="plug">
|
||||
**MCP Alternative**: With <Link href="/platform/mem0-mcp">Mem0 MCP</Link>, AI agents can search their own memories proactively when needed.
|
||||
|
||||
@@ -60,7 +60,7 @@ import os
|
||||
|
||||
from mem0 import Memory
|
||||
|
||||
memory = Memory()
|
||||
memory = Memory(api_key=os.environ["MEM0_API_KEY"])
|
||||
|
||||
# Sticky note: conversation memory
|
||||
memory.add(
|
||||
@@ -72,7 +72,8 @@ memory.add(
|
||||
# Later in the session, pull long-term + session context
|
||||
results = memory.search(
|
||||
"Any hotel preferences?",
|
||||
filters={"user_id": "alex", "run_id": "trip-planning-2025"},
|
||||
user_id="alex",
|
||||
run_id="trip-planning-2025",
|
||||
)
|
||||
```
|
||||
|
||||
|
||||
+3
-16
@@ -123,7 +123,8 @@
|
||||
"icon": "arrow-right",
|
||||
"pages": [
|
||||
"migration/platform-v2-to-v3",
|
||||
"migration/oss-to-platform"
|
||||
"migration/oss-to-platform",
|
||||
"migration/api-changes"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -272,8 +273,7 @@
|
||||
"components/embedders/models/lmstudio",
|
||||
"components/embedders/models/together",
|
||||
"components/embedders/models/langchain",
|
||||
"components/embedders/models/aws_bedrock",
|
||||
"components/embedders/models/fastembed"
|
||||
"components/embedders/models/aws_bedrock"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -533,8 +533,6 @@
|
||||
"api-reference/organization/get-org",
|
||||
"api-reference/organization/get-org-members",
|
||||
"api-reference/organization/add-org-member",
|
||||
"api-reference/organization/update-org-member",
|
||||
"api-reference/organization/remove-org-member",
|
||||
"api-reference/organization/delete-org"
|
||||
]
|
||||
},
|
||||
@@ -547,9 +545,6 @@
|
||||
"api-reference/project/get-project",
|
||||
"api-reference/project/get-project-members",
|
||||
"api-reference/project/add-project-member",
|
||||
"api-reference/project/update-project",
|
||||
"api-reference/project/update-project-member",
|
||||
"api-reference/project/remove-project-member",
|
||||
"api-reference/project/delete-project"
|
||||
]
|
||||
},
|
||||
@@ -629,10 +624,6 @@
|
||||
]
|
||||
},
|
||||
"redirects": [
|
||||
{
|
||||
"source": "/components/rerankers/models/llm",
|
||||
"destination": "/components/rerankers/models/llm_reranker"
|
||||
},
|
||||
{
|
||||
"source": "/migration/breaking-changes",
|
||||
"destination": "/"
|
||||
@@ -641,10 +632,6 @@
|
||||
"source": "/migration/v0-to-v1",
|
||||
"destination": "/"
|
||||
},
|
||||
{
|
||||
"source": "/migration/api-changes",
|
||||
"destination": "/migration/oss-v2-to-v3"
|
||||
},
|
||||
{
|
||||
"source": "/platform/features/expiration-date",
|
||||
"destination": "/"
|
||||
|
||||
@@ -73,7 +73,7 @@ client = MemoryClient()
|
||||
# Define the agent
|
||||
agent = Agent(
|
||||
name="Personal Agent",
|
||||
model=OpenAIChat(id="gpt-5-mini"),
|
||||
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
|
||||
|
||||
@@ -65,7 +65,6 @@ The plugin uses the same shell scripts as Claude Code, Cursor, and Codex — hoo
|
||||
| **User prompt** | `UserPromptSubmit` | Searches relevant memories before each message |
|
||||
| **Pre-tool** | `PreToolUse` | Blocks MEMORY.md writes, enforces `user_id`/`app_id` on mem0 tools |
|
||||
| **Post-tool** | `PostToolUse` | Tracks stats, scans bash errors for related memories |
|
||||
| **Stop** | `Stop` | Stores a session summary when the session ends |
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ OPENAI_API_KEY = os.environ.get('OPENAI_API_KEY')
|
||||
memory_client = MemoryClient()
|
||||
agent = ConversableAgent(
|
||||
"chatbot",
|
||||
llm_config={"config_list": [{"model": "gpt-5-mini", "api_key": OPENAI_API_KEY}]},
|
||||
llm_config={"config_list": [{"model": "gpt-4", "api_key": OPENAI_API_KEY}]},
|
||||
code_execution_config=False,
|
||||
human_input_mode="NEVER",
|
||||
)
|
||||
@@ -99,7 +99,7 @@ For more complex scenarios, you can create multiple agents:
|
||||
manager = ConversableAgent(
|
||||
"manager",
|
||||
system_message="You are a manager who helps in resolving complex customer issues.",
|
||||
llm_config={"config_list": [{"model": "gpt-5-mini", "api_key": OPENAI_API_KEY}]},
|
||||
llm_config={"config_list": [{"model": "gpt-4", "api_key": OPENAI_API_KEY}]},
|
||||
human_input_mode="NEVER"
|
||||
)
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ Add the Mem0 MCP server directly with a single command:
|
||||
npx mcp-add \
|
||||
--name mem0-mcp \
|
||||
--type http \
|
||||
--url "https://mcp.mem0.ai/mcp/" \
|
||||
--url "https://mcp.mem0.ai/mcp" \
|
||||
--clients "claude code"
|
||||
```
|
||||
|
||||
@@ -138,13 +138,11 @@ When installed via the plugin marketplace, Mem0 hooks into Claude Code's lifecyc
|
||||
|
||||
| Hook | Event | What it does |
|
||||
|------|-------|-------------|
|
||||
| **Setup** | `Setup` | Installs the mem0 SDK and dependencies (runs on init and maintenance) |
|
||||
| **Session start** | `SessionStart` | Loads prior memories and displays status banner |
|
||||
| **User prompt** | `UserPromptSubmit` | Searches relevant memories before each message; skips short prompts |
|
||||
| **Pre-tool (3 handlers)** | `PreToolUse` | Blocks MEMORY.md writes; enforces `user_id`/`app_id` on mem0 tool calls; scans files being read for relevant memory context |
|
||||
| **Pre-tool** | `PreToolUse` | Blocks MEMORY.md writes, enforces `user_id`/`app_id` on mem0 tool calls |
|
||||
| **Post-tool** | `PostToolUse` | Tracks stats, scans bash errors for related memories |
|
||||
| **Stop** | `Stop` | Stores a session summary when the session ends |
|
||||
| **Pre-compact** | `PreCompact` | Stores a summary before the context is compacted |
|
||||
| **Pre-compact** | `PreCompact` | Stores a session summary before context compaction |
|
||||
|
||||
## Example Workflow
|
||||
|
||||
|
||||
+10
-24
@@ -41,17 +41,7 @@ Install the full plugin including MCP server, lifecycle hooks, and SDK skill.
|
||||
codex plugin marketplace add mem0ai/mem0
|
||||
```
|
||||
|
||||
2. Install the plugin:
|
||||
|
||||
```bash
|
||||
codex plugin add mem0@mem0-plugins
|
||||
```
|
||||
|
||||
Or, in the app: restart Codex, open the Plugin Directory, browse the **Mem0 Plugins** marketplace, and install **Mem0**.
|
||||
|
||||
<Note>
|
||||
Step 1 is required for the app UI. Mem0 isn't in OpenAI's curated directory yet, so **without `codex plugin marketplace add`, Mem0 won't appear in the Codex app's Plugin Directory** — searching for it returns nothing. Adding the marketplace surfaces it (under **Created by you**) and makes it installable.
|
||||
</Note>
|
||||
2. Restart Codex, open the Plugin Directory, browse the **Mem0 Plugins** marketplace, and install **Mem0**.
|
||||
|
||||
<Info>
|
||||
Do not combine with Option B. The plugin manifest auto-registers the `mem0` MCP server, so adding both will create a duplicate registration.
|
||||
@@ -59,30 +49,27 @@ Install the full plugin including MCP server, lifecycle hooks, and SDK skill.
|
||||
|
||||
### Option B — Direct MCP
|
||||
|
||||
The fastest way to connect Codex to Mem0 — no plugin, no marketplace. Add the MCP server with a single command:
|
||||
|
||||
```bash
|
||||
codex mcp add mem0 --url https://mcp.mem0.ai/mcp/ --bearer-token-env-var MEM0_API_KEY
|
||||
```
|
||||
|
||||
Or add it manually to `~/.codex/config.toml`:
|
||||
The fastest way to connect Codex to Mem0 — no plugin, no marketplace. Add to `~/.codex/config.toml`:
|
||||
|
||||
```toml
|
||||
[mcp_servers.mem0]
|
||||
url = "https://mcp.mem0.ai/mcp/"
|
||||
url = "https://mcp.mem0.ai/mcp"
|
||||
bearer_token_env_var = "MEM0_API_KEY"
|
||||
```
|
||||
|
||||
Make sure `MEM0_API_KEY` is exported in the shell you launch Codex from, then restart Codex.
|
||||
|
||||
<Info>
|
||||
Codex's `codex mcp add` CLI only supports stdio MCP servers. Because Mem0's MCP is HTTP/streamable, you configure it by editing `config.toml` directly (or via the **Plugins → Connect to a custom MCP → Streamable HTTP** UI in the Codex app).
|
||||
</Info>
|
||||
|
||||
This gives you the MCP tools but not the lifecycle hooks or SDK skill.
|
||||
|
||||
### Managing the Plugin
|
||||
|
||||
```bash
|
||||
codex plugin marketplace upgrade # pull latest plugin versions
|
||||
codex plugin remove mem0@mem0-plugins # uninstall the plugin (keeps the marketplace)
|
||||
codex plugin marketplace remove mem0-plugins # unregister the marketplace entirely
|
||||
codex plugin marketplace remove mem0-plugins # unregister the marketplace
|
||||
```
|
||||
|
||||
To update, run `codex plugin marketplace upgrade` to pull the latest from the Mem0 repo.
|
||||
@@ -123,10 +110,9 @@ When installed via the plugin marketplace, Mem0 hooks into Codex's lifecycle to
|
||||
|------|-------|-------------|
|
||||
| **Session start** | `SessionStart` | Loads prior memories and displays status banner |
|
||||
| **User prompt** | `UserPromptSubmit` | Searches relevant memories before each message |
|
||||
| **Pre-tool (3 handlers)** | `PreToolUse` | Blocks MEMORY.md writes; enforces `user_id`/`app_id` on mem0 tool calls; scans files being read for relevant memory context |
|
||||
| **Pre-tool** | `PreToolUse` | Blocks MEMORY.md writes, enforces `user_id`/`app_id` on mem0 tool calls |
|
||||
| **Post-tool** | `PostToolUse` | Tracks stats, scans bash errors for related memories |
|
||||
| **Stop** | `Stop` | Stores a session summary when the session ends |
|
||||
| **Pre-compact** | `PreCompact` | Stores a summary before the context is compacted |
|
||||
| **Pre-compact** | `PreCompact` | Stores a session summary before context compaction |
|
||||
|
||||
## Example Workflow
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ The fastest way to get started. Click the link below to install the Mem0 MCP ser
|
||||
npx mcp-add \
|
||||
--name mem0-mcp \
|
||||
--type http \
|
||||
--url "https://mcp.mem0.ai/mcp/" \
|
||||
--url "https://mcp.mem0.ai/mcp" \
|
||||
--clients "cursor"
|
||||
```
|
||||
|
||||
@@ -108,10 +108,9 @@ When installed via the Cursor Marketplace, Mem0 hooks into Cursor's lifecycle:
|
||||
|------|-------|-------------|
|
||||
| **Session start** | `sessionStart` | Loads prior memories and displays status banner |
|
||||
| **User prompt** | `beforeSubmitPrompt` | Searches relevant memories before each message; skips short prompts |
|
||||
| **Pre-tool (3 handlers)** | `preToolUse` | Blocks MEMORY.md writes; enforces `user_id`/`app_id` on mem0 tool calls; scans files being read for relevant memory context |
|
||||
| **Pre-tool (2 handlers)** | `preToolUse` | Blocks MEMORY.md writes, enforces `user_id`/`app_id` on mem0 tool calls |
|
||||
| **Post-tool (2 handlers)** | `postToolUse` | Tracks stats, scans bash errors for related memories |
|
||||
| **Stop** | `stop` | Stores a session summary when the session ends |
|
||||
| **Pre-compact** | `preCompact` | Stores a summary before the context is compacted |
|
||||
| **Pre-compact** | `preCompact` | Stores a session summary before context compaction |
|
||||
|
||||
## Example Workflow
|
||||
|
||||
|
||||
@@ -100,12 +100,12 @@ This section:
|
||||
Initialize both the ElevenLabs and Mem0 clients:
|
||||
|
||||
```python
|
||||
# Initialize ElevenLabs client
|
||||
client = ElevenLabs(api_key=API_KEY)
|
||||
# Initialize ElevenLabs client
|
||||
client = ElevenLabs(api_key=API_KEY)
|
||||
|
||||
# Initialize memory client and tools
|
||||
client_tools = ClientTools()
|
||||
mem0_client = AsyncMemoryClient()
|
||||
# Initialize memory client and tools
|
||||
client_tools = ClientTools()
|
||||
mem0_client = AsyncMemoryClient()
|
||||
```
|
||||
|
||||
Here we:
|
||||
@@ -118,36 +118,36 @@ Here we:
|
||||
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
|
||||
)
|
||||
return "Memory added successfully"
|
||||
# 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
|
||||
)
|
||||
return "Memory added successfully"
|
||||
|
||||
async def retrieve_memories(parameters):
|
||||
"""Retrieve relevant memories based on the input message"""
|
||||
message = parameters.get("message")
|
||||
async def retrieve_memories(parameters):
|
||||
"""Retrieve relevant memories based on the input message"""
|
||||
message = parameters.get("message")
|
||||
|
||||
# For Platform API, user_id goes in filters
|
||||
filters = {"user_id": USER_ID}
|
||||
# For Platform API, user_id goes in filters
|
||||
filters = {"user_id": USER_ID}
|
||||
|
||||
# Search for relevant memories using the message as a query
|
||||
results = await mem0_client.search(
|
||||
query=message,
|
||||
filters=filters
|
||||
)
|
||||
# Search for relevant memories using the message as a query
|
||||
results = await mem0_client.search(
|
||||
query=message,
|
||||
filters=filters
|
||||
)
|
||||
|
||||
# Extract and join the memory texts
|
||||
memories = ' '.join([result["memory"] for result in results.get('results', [])])
|
||||
print("[ Memories ]", memories)
|
||||
# Extract and join the memory texts
|
||||
memories = ' '.join([result["memory"] for result in results.get('results', [])])
|
||||
print("[ Memories ]", memories)
|
||||
|
||||
if memories:
|
||||
return memories
|
||||
return "No memories found"
|
||||
if memories:
|
||||
return memories
|
||||
return "No memories found"
|
||||
```
|
||||
|
||||
These functions:
|
||||
@@ -171,9 +171,9 @@ These functions:
|
||||
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)
|
||||
# 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:
|
||||
@@ -186,19 +186,19 @@ This allows the ElevenLabs agent to:
|
||||
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"),
|
||||
)
|
||||
# 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:
|
||||
@@ -217,16 +217,16 @@ This sets up the conversation with:
|
||||
Start and manage the conversation:
|
||||
|
||||
```python
|
||||
# Start the conversation
|
||||
print(f"Starting conversation with user_id: {USER_ID}")
|
||||
conversation.start_session()
|
||||
# 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())
|
||||
# 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}")
|
||||
# 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__':
|
||||
@@ -445,3 +445,4 @@ By integrating ElevenLabs Conversational AI with Mem0, you can create voice agen
|
||||
Create voice-first AI applications
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
|
||||
+37
-164
@@ -1,42 +1,35 @@
|
||||
---
|
||||
title: Hermes Agent
|
||||
description: "Add long-term memory to Hermes agents with Mem0, on managed Mem0 Cloud or fully self-hosted (OSS), with automatic background sync and zero-latency prefetch."
|
||||
description: "Add long-term memory to Hermes agents using Mem0 as a pluggable memory provider with automatic background sync and zero-latency prefetch."
|
||||
---
|
||||
|
||||
Add long-term memory to [Hermes Agent](https://github.com/NousResearch/hermes-agent), a self-improving AI agent CLI by Nous Research. Hermes has a pluggable memory system, and Mem0 is one of the supported providers. Once enabled, Mem0 learns facts from your conversations and surfaces relevant ones before each turn, without slowing down the chat.
|
||||
Add long-term memory to [Hermes Agent](https://github.com/NousResearch/hermes-agent) — a self-improving AI agent CLI by Nous Research. Hermes has a pluggable memory system, and Mem0 is one of the supported providers. Once enabled, Mem0 automatically learns facts from your conversations and surfaces relevant ones before each turn — all without slowing down the chat.
|
||||
|
||||
You can run Mem0 in two ways:
|
||||
## Overview
|
||||
|
||||
- **Platform mode** (default): managed Mem0 Cloud. Add your API key and you are ready.
|
||||
- **OSS mode**: fully self-hosted with your own LLM, embedder, and vector store. No data leaves your machine.
|
||||
Hermes runs a built-in memory system (file-based `MEMORY.md` and `USER.md`) alongside one external provider. When Mem0 is active, it works additively with the built-in system at three key moments in every conversation turn:
|
||||
|
||||
## How It Works
|
||||
### 1. Before the Agent Responds (Prefetch)
|
||||
|
||||
Hermes runs a built-in memory system (file-based `MEMORY.md` and `USER.md`) alongside one external provider. When Mem0 is active, it works additively with the built-in system at three points in every conversation turn.
|
||||
When you send a message, Hermes checks if it already has cached Mem0 search results from the previous turn. If so, those memories are injected into the system prompt so the LLM can see them. This is **zero-latency** — no waiting for an API call.
|
||||
|
||||
### 1. Before the agent responds (prefetch)
|
||||
### 2. After the Agent Responds (Sync)
|
||||
|
||||
When you send a message, Hermes checks for cached Mem0 search results from the previous turn. If they exist, those memories are injected into the system prompt so the model can see them. This is zero-latency, with no waiting on an API call.
|
||||
Once the LLM finishes responding, Hermes sends the `(user message, assistant response)` pair to Mem0's API in a **background thread**. Mem0's server-side LLM automatically extracts facts (e.g., "user prefers Python", "user works at Acme Corp") — you don't have to tell it what to remember.
|
||||
|
||||
### 2. After the agent responds (sync)
|
||||
### 3. Background Prefetch for Next Turn
|
||||
|
||||
Once the model finishes, Hermes sends the `(user message, assistant response)` pair to Mem0 in a background thread. Mem0 extracts facts automatically (for example, "user prefers Python" or "user works at Acme Corp"), so you never have to tell it what to remember. Each write is tagged with the gateway channel it came from.
|
||||
|
||||
### 3. Background prefetch for the next turn
|
||||
|
||||
At the same time, Hermes runs a background search to pre-load relevant memories for your next message. By the time you type, the results are already cached.
|
||||
At the same time as sync, Hermes kicks off a background search on Mem0 to pre-load relevant memories for the next turn. By the time you type your next message, the memories are already cached.
|
||||
|
||||
## Agent Tools
|
||||
|
||||
When Mem0 is active, the model gets five tools it can call during a conversation:
|
||||
When Mem0 is active, the LLM gets three extra tools it can call during conversations:
|
||||
|
||||
| Tool | Description | Parameters |
|
||||
|------|-------------|------------|
|
||||
| `mem0_list` | List all stored memories, for a full overview | `page`, `page_size` (default 100, max 200) |
|
||||
| `mem0_search` | Semantic search by meaning, ranked by relevance | `query` (required), `top_k` (default 10, max 50), `rerank` (default `true`, Platform mode only) |
|
||||
| `mem0_add` | Store a fact verbatim, with no LLM extraction | `content` (required) |
|
||||
| `mem0_update` | Update a memory's text by ID | `memory_id`, `text` (both required) |
|
||||
| `mem0_delete` | Delete a memory by ID | `memory_id` (required) |
|
||||
| Tool | Description |
|
||||
|------|-------------|
|
||||
| `mem0_profile` | Fetch all stored memories about the user |
|
||||
| `mem0_search` | Semantic search through memories (supports optional reranking via `rerank` and `top_k` parameters) |
|
||||
| `mem0_conclude` | Store a specific fact verbatim — uses `infer=False` so no server-side LLM extraction happens |
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -47,19 +40,17 @@ curl -fsSL https://raw.githubusercontent.com/NousResearch/hermes-agent/main/scri
|
||||
source ~/.bashrc
|
||||
```
|
||||
|
||||
The `mem0ai` package is installed automatically when you enable the Mem0 provider, so there is no manual pip step. OSS providers may need extra packages (for example `qdrant-client`, `psycopg2-binary`, or `ollama`), which the setup flow installs for you when you pick them.
|
||||
The `mem0ai` Python package is automatically installed when you enable the Mem0 provider — no manual pip install needed.
|
||||
|
||||
## Platform Setup
|
||||
## Setup
|
||||
|
||||
Platform mode uses managed Mem0 Cloud and is the fastest way to start.
|
||||
|
||||
### Option 1: Interactive wizard (recommended)
|
||||
### Option 1: Interactive Setup Wizard (Recommended)
|
||||
|
||||
```bash
|
||||
hermes memory setup
|
||||
```
|
||||
|
||||
Select **mem0**, choose **Platform**, and paste your API key when prompted. The wizard writes the non-secret settings to `~/.hermes/mem0.json` and keeps the key in `~/.hermes/.env`.
|
||||
Select **mem0** as the provider and enter your Mem0 API key when prompted. The wizard writes your config to `~/.hermes/mem0.json`.
|
||||
|
||||
<Note>Get your API key from <a href="https://app.mem0.ai?utm_source=oss&utm_medium=integration-hermes" rel="nofollow">app.mem0.ai</a>.</Note>
|
||||
|
||||
@@ -77,151 +68,33 @@ memory:
|
||||
provider: mem0
|
||||
```
|
||||
|
||||
That's it. Mem0 runs automatically from here.
|
||||
That's it — Mem0 runs automatically from this point.
|
||||
|
||||
## OSS (Self-Hosted) Setup
|
||||
## Configuration Options
|
||||
|
||||
OSS mode runs Mem0 entirely on your own infrastructure: your LLM, your embedder, and your vector store. No data is sent to Mem0 Cloud, and no Mem0 API key is required.
|
||||
Configuration is stored in `~/.hermes/mem0.json`. Values can also be set via environment variables.
|
||||
|
||||
### Interactive
|
||||
|
||||
```bash
|
||||
hermes memory setup
|
||||
# Select "mem0", then "Open Source (self-hosted)"
|
||||
# Follow the prompts for LLM, embedder, and vector store
|
||||
```
|
||||
|
||||
### With flags
|
||||
|
||||
```bash
|
||||
hermes memory setup mem0 --mode oss \
|
||||
--oss-llm openai --oss-llm-key sk-... \
|
||||
--oss-vector qdrant
|
||||
```
|
||||
|
||||
### Supported providers
|
||||
|
||||
| Component | Providers |
|
||||
|-----------|-----------|
|
||||
| LLM | `openai` (default model `gpt-5-mini`), `ollama` (local, default `llama3.1:8b`) |
|
||||
| Embedder | `openai` (default `text-embedding-3-small`), `ollama` (local, default `nomic-embed-text`) |
|
||||
| Vector store | `qdrant` (local path or server), `pgvector` |
|
||||
|
||||
### Flag reference
|
||||
|
||||
| Flag | Description |
|
||||
|------|-------------|
|
||||
| `--mode` | `platform` or `oss` |
|
||||
| `--oss-llm` | LLM provider (`openai` or `ollama`, default `openai`) |
|
||||
| `--oss-llm-key` | LLM API key (for `openai`) |
|
||||
| `--oss-llm-model` | Override the LLM model |
|
||||
| `--oss-llm-url` | LLM base URL (for `ollama` or a custom endpoint) |
|
||||
| `--oss-embedder` | Embedder provider (default `openai`) |
|
||||
| `--oss-embedder-key` | Embedder API key |
|
||||
| `--oss-vector` | Vector store (`qdrant` or `pgvector`, default `qdrant`) |
|
||||
| `--oss-vector-path` | Local Qdrant storage path |
|
||||
| `--oss-vector-host`, `--oss-vector-port` | PGVector or remote Qdrant host and port |
|
||||
| `--oss-vector-user`, `--oss-vector-password`, `--oss-vector-dbname` | PGVector connection details |
|
||||
| `--user-id` | Canonical user identifier |
|
||||
| `--dry-run` | Preview the resolved config without writing it |
|
||||
|
||||
## Switching Modes
|
||||
|
||||
You can move between Platform and OSS at any time. Run the setup command again, or edit `~/.hermes/mem0.json` directly.
|
||||
|
||||
```bash
|
||||
# Platform to OSS
|
||||
hermes memory setup mem0 --mode oss --oss-llm-key sk-...
|
||||
|
||||
# OSS to Platform
|
||||
hermes memory setup mem0 --mode platform --api-key sk-...
|
||||
|
||||
# Preview without writing anything
|
||||
hermes memory setup mem0 --mode oss --oss-llm-key sk-... --dry-run
|
||||
```
|
||||
|
||||
A self-hosted `~/.hermes/mem0.json` looks like this:
|
||||
|
||||
```json
|
||||
{
|
||||
"mode": "oss",
|
||||
"oss": {
|
||||
"llm": {"provider": "openai", "config": {"model": "gpt-5-mini"}},
|
||||
"embedder": {"provider": "openai", "config": {"model": "text-embedding-3-small"}},
|
||||
"vector_store": {"provider": "qdrant", "config": {"path": "~/.hermes/mem0_qdrant"}}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Behavioral settings live in `~/.hermes/mem0.json` and are written for you by `hermes memory setup`. Only the secret `MEM0_API_KEY` belongs in `~/.hermes/.env`.
|
||||
|
||||
| Key | Default | Description |
|
||||
|-----|---------|-------------|
|
||||
| `mode` | `platform` | `platform` (Mem0 Cloud) or `oss` (self-hosted) |
|
||||
| `api_key` | none | Mem0 Platform API key, required in Platform mode. Stored in `.env` as `MEM0_API_KEY` |
|
||||
| `user_id` | `hermes-user` | Identifier that scopes memories. See cross-channel behavior below |
|
||||
| `agent_id` | `hermes` | Agent identifier attached to writes |
|
||||
| `rerank` | `true` | Rerank search results for relevance (Platform mode only) |
|
||||
|
||||
### Cross-channel memories
|
||||
|
||||
Hermes can run from the CLI and from gateways like Telegram, Slack, and Discord. The `user_id` setting controls how memories are scoped across them:
|
||||
|
||||
- **Set a `user_id`** and it applies to every gateway, so one person gets a single merged memory store no matter where they talk to the agent.
|
||||
- **Leave it unset** (or at the default `hermes-user`) and each gateway uses its own native id, keeping per-platform memories separate.
|
||||
|
||||
Either way, every write is tagged with `metadata.channel` (for example `telegram` or `cli`), so per-channel views are still possible at query time.
|
||||
| Key | Env Variable | Default | Description |
|
||||
|-----|-------------|---------|-------------|
|
||||
| `api_key` | `MEM0_API_KEY` | — | **Required.** Mem0 Platform API key |
|
||||
| `user_id` | `MEM0_USER_ID` | `hermes-user` | User identifier for scoping memories |
|
||||
| `agent_id` | `MEM0_AGENT_ID` | `hermes` | Agent identifier |
|
||||
| `rerank` | — | `true` | Enable reranking for memory recall |
|
||||
|
||||
|
||||
## Reliability
|
||||
|
||||
- **Circuit breaker**: if Mem0 fails five times in a row, Hermes pauses calls for two minutes, then retries. The agent keeps working without memory during that window. Expected client errors, like a 404 on a missing memory id, do not count toward tripping the breaker.
|
||||
- **Non-blocking**: every Mem0 call runs in a background daemon thread, so a slow or failed call never blocks your conversation.
|
||||
- **Thread-safe**: the client uses lazy initialization with locking, and the background sync and prefetch threads are guarded so concurrent gateway messages cannot produce duplicate memories.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "Mem0 temporarily unavailable"
|
||||
|
||||
The circuit breaker tripped after five consecutive failures and resets after two minutes.
|
||||
|
||||
- **Platform mode**: check your API key and internet connection.
|
||||
- **OSS mode**: make sure your vector store (Qdrant or PGVector) is running and reachable.
|
||||
|
||||
### OSS: vector store connection refused
|
||||
|
||||
```bash
|
||||
# Local Qdrant: confirm the storage path is writable
|
||||
ls -la ~/.hermes/mem0_qdrant
|
||||
|
||||
# Qdrant server: confirm it is reachable
|
||||
curl http://localhost:6333/healthz
|
||||
|
||||
# PGVector: confirm PostgreSQL is accepting connections
|
||||
pg_isready -h localhost -p 5432
|
||||
```
|
||||
|
||||
### OSS: Ollama not reachable
|
||||
|
||||
```bash
|
||||
curl http://localhost:11434/api/tags
|
||||
```
|
||||
|
||||
### Memories not appearing
|
||||
|
||||
- `mem0_add` stores text verbatim with no extraction. Ordinary conversation turns are extracted automatically by the background sync.
|
||||
- Search is semantic, so try a broader query.
|
||||
- Confirm `user_id` is the same across sessions (check `~/.hermes/mem0.json`).
|
||||
- **Circuit Breaker** — If Mem0's API fails 5 times in a row, Hermes stops calling it for 2 minutes, then retries. The agent keeps working fine without memory during that time.
|
||||
- **Non-blocking** — All Mem0 API calls happen in background daemon threads. A slow or failed API call never blocks your conversation.
|
||||
- **Thread-safe** — The Mem0 client uses lazy initialization with locking, safe for concurrent access.
|
||||
|
||||
## Key Features
|
||||
|
||||
1. **Two ways to run**: managed Platform or fully self-hosted OSS, switchable at any time.
|
||||
2. **Zero-latency recall**: memories are prefetched in the background and cached before you type.
|
||||
3. **Automatic extraction**: Mem0 extracts and deduplicates facts from each exchange for you.
|
||||
4. **Non-blocking and fault tolerant**: background threads plus a circuit breaker keep the agent responsive even when Mem0 is unreachable.
|
||||
5. **Additive memory**: works alongside Hermes' built-in file memory (`MEMORY.md`, `USER.md`).
|
||||
1. **Zero-Latency Recall** — Memories are prefetched in the background and cached, ready before you type
|
||||
2. **Server-side Extraction** — Mem0's API automatically extracts and deduplicates facts from each exchange
|
||||
3. **Non-blocking** — All API calls run in background daemon threads
|
||||
4. **Fault Tolerant** — Circuit breaker ensures the agent works even if Mem0 is temporarily unreachable
|
||||
5. **Additive Memory** — Works alongside Hermes' built-in file-based memory system (MEMORY.md, USER.md)
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="OpenClaw Integration" icon={<svg width="24" height="24" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="m153.5 173.5q24.62 1.46 46 13.5 12.11 8.1 17.5 21.5 0.74 2.45 0.5 5 0.09 0.81 1 1 1.48-4.9 1-10 5.04 10.48 1.5 22-9.81 27.86-35.5 42.5-26.17 14.97-56 19.5-2.77-0.4-2 1 2.86 1.27 6 1 25.64 1.53 48.5-10 0.34 10.08 2 20 1.08 5.76 5 10 1 1.5 0 3-31.11 20.84-68.5 17.5-23.7-5.7-32.5-28.5-4.39-9.18-3.5-19 15.41 6.23 32 4.5-20.68-6.39-39-18-34.81-27.22-12.5-65.5 11.84-14.83 29-23 4.21 7.66 11.5 12.5 3 1 6 0-26.04-34.62-29-78-0.13-8.46 2-16.5 1 6.5 2 13 3.43 39.53 24.5 73 2.03 2.28 4.5 4 0.5-1.25 1-2.5-1.27-6.54-5-12 0.5-0.75 1-1.5 9.72-3.43 20-4 0.55 10.34 8 17.5 1.94 0.74 4 0.5-17.8-64.6 16.5-122 0.98-1.79 1.5 0-28.21 56.64-13.5 118 1.08 1.43 2.5 0.5 2.21-4.98 2-10.5z" fill="currentColor"/><path fill-rule="evenodd" d="m454.5 97.5q-1.33 11.18-8.5 20-21.81 26.28-55.5 32-1.11-0.2-2 0.5 2.31 2.82 5.5 4.5 1 2 0 4-9.56 11.3-19.5 20 19.71-8.72 31-27 2.68-0.43 5 1-14.24 30.97-48 36.5-9.93 1.71-20 1.5-6.8-0.48-13 1 5.81 6.92 14 11-10.78 16.03-27 26.5 27.16-7.4 38-33.5 4.34 1.35 9 1-9.08 23.84-33 33.5-18.45 6.41-38 7 22.59 8.92 45-1 12.05-5.52 24-11 9.01-1.79 17 2.5 5.28-4.38 11-8 12.8-6.07 27-5 0 0.5 0 1-19.34 2.69-34 15.5 0.5 0.25 1 0.5 17.79-8.09 36-15 2.71-0.79 5-2 2.5-1 5-2 5.53-4.04 11-8 11.7-4.18 24-6.5 7.78-1.36 15 1.5-2.97 18.45-13.5 34-34.92 49.37-94.5 62.5-59.27 12.45-108-23-15.53-12.52-21.5-31.5-2.47-14.26 4-27-3.15 24.41 14 42-4.92-10.28-7-22-1.97-17.63 7-33 47.28-69.5 125.5-100 15.86-3.42 32-5.5 18.63-1.47 37 1.5z" fill="currentColor"/><path fill-rule="evenodd" d="m231.5 238.5q1.31-0.2 2 1-3.13 28.62 15 51-16.25 6.75-27-7.5-1-1-2 0 14.73 29.34 46 18.5 1.79 0.52 0 1.5-37.63 16.82-50.5-22.5-5.1-26.48 16.5-42z" fill="currentColor"/><path fill-rule="evenodd" d="m203.5 266.5q1.31-0.2 2 1-2.48 22.08 12 39-6.99 1.35-14 0.5 4.59 4.08 10 7-8.71 0.28-14.5-6.5-16.98-22.76 4.5-41z" fill="currentColor"/><path fill-rule="evenodd" d="m58.5 284.5q9.6-2.17 14.5 6 5.15 14.18-1 28-11.05-13.14-27.5-17.5 5.15-9.9 14-16.5z" fill="currentColor"/><path fill-rule="evenodd" d="m56.5 313.5q3.43 5.43 8 10-4.88 0.44-8 4-1.11-0.2-2 0.5 28.91 1.65 38 28.5 0.45 3.16-1 6-11.02-7.01-23-12.5-4.75-3.75-9.5-7.5 1.47 7.42 7 13 8.34 27.18 32 43 0.99 2.41-1.5 3.5-40.25 5.58-66.5-25.5-15.67-22.01-8-48 10.46-23.87 34.5-15z" fill="currentColor"/><path fill-rule="evenodd" d="m198.5 319.5q1.44 0.68 2.5 2 2.41 8.23 6 16 1.2 2.64-0.5 5-30.65 21.41-68 18.5-25.16-6.17-32.5-30.5 6.96 4.99 15.5 6.5 8.99 0.75 18 0.5 16.25 2.38 32-2.5 15.9-3.94 27-15.5z" fill="currentColor"/><path fill-rule="evenodd" d="m239.5 342.5q7.02-0.25 14 0.5 4.46 1.06 8 3.5-5.2 2.35-10 5.5-3.88 4.65-9 7.5-9.89-3.09-9.5-13 2.36-3.63 6.5-4z" fill="currentColor"/><path fill-rule="evenodd" d="m214.5 349.5q5.96 7.2 13.5 13 1 1 0 2-28.58 23.34-65.5 20.5-18.15-4.24-27.5-19.5 1.13 0.94 2.5 1.5 14.7 1.42 29-1.5 26.57-0.52 48-16z" fill="currentColor"/><path fill-rule="evenodd" d="m302.5 373.5q0.21 2.44-2 3.5-28.69 7.6-50.5-12.5-0.06-6.71 6.5-9 4.45-0.75 9-1 22.26 2.27 37 19z" fill="currentColor"/><path fill-rule="evenodd" d="m232.5 365.5q17.6 6.19 10.5 23-10.6 10.42-25.5 11.5-25.94 3.21-49-9 36.75-1.65 64-25.5z" fill="currentColor"/><path fill-rule="evenodd" d="m113.5 367.5q7.7-0.01 9.5 7-9.69 7.19-18.5 15.5-7.23 5.76-5.5-3.5 3.12-12.84 14.5-19z" fill="currentColor"/><path fill-rule="evenodd" d="m126.5 380.5q7.88-0.4 12 6.5-8.5 7.25-17 14.5-5.62-12.55 5-21z" fill="currentColor"/><path fill-rule="evenodd" d="m283.5 385.5q3.22 2.95 7 5.5 2.8 4.03 6 7.5 0.42 2.77-2 4-15.5-9.75-31-19.5-1.79-0.98 0-1.5 9.96 2.49 20 4z" fill="currentColor"/></svg>} href="/integrations/openclaw">
|
||||
|
||||
@@ -98,9 +98,20 @@ add_result = add_tool.invoke(add_input)
|
||||
|
||||
```json Output
|
||||
{
|
||||
"message": "Memory processing has been queued for background execution",
|
||||
"status": "PENDING",
|
||||
"event_id": "3a1b2c3d-4e5f-6789-abcd-ef0123456789"
|
||||
"results": [
|
||||
{
|
||||
"memory": "Name is Alex",
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"memory": "Is a vegetarian",
|
||||
"event": "ADD"
|
||||
},
|
||||
{
|
||||
"memory": "Is allergic to nuts",
|
||||
"event": "ADD"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -162,25 +173,23 @@ result = search_tool.invoke(search_input)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "1a75e827-7eca-45ea-8c5c-cfd43299f061",
|
||||
"memory": "Name is Alex",
|
||||
"user_id": "alex",
|
||||
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
},
|
||||
"categories": [
|
||||
"personal_details"
|
||||
],
|
||||
"created_at": "2024-11-27T16:53:43.276872-08:00",
|
||||
"updated_at": "2024-11-27T16:53:43.276885-08:00",
|
||||
"score": 0.3810526501504994
|
||||
}
|
||||
]
|
||||
}
|
||||
[
|
||||
{
|
||||
"id": "1a75e827-7eca-45ea-8c5c-cfd43299f061",
|
||||
"memory": "Name is Alex",
|
||||
"user_id": "alex",
|
||||
"hash": "d0fccc8fa47f7a149ee95750c37bb0ca",
|
||||
"metadata": {
|
||||
"food": "vegan"
|
||||
},
|
||||
"categories": [
|
||||
"personal_details"
|
||||
],
|
||||
"created_at": "2024-11-27T16:53:43.276872-08:00",
|
||||
"updated_at": "2024-11-27T16:53:43.276885-08:00",
|
||||
"score": 0.3810526501504994
|
||||
}
|
||||
]
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ load_dotenv()
|
||||
# MEM0_API_KEY = 'your-mem0-key' # Replace with your actual Mem0 API key
|
||||
|
||||
# Initialize LangChain and Mem0
|
||||
llm = ChatOpenAI(model="gpt-5-mini")
|
||||
llm = ChatOpenAI(model="gpt-4")
|
||||
mem0 = MemoryClient()
|
||||
```
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ async def websocket_endpoint(websocket: WebSocket):
|
||||
# LLM for response generation
|
||||
llm = OpenAILLMService(
|
||||
api_key=os.getenv("OPENAI_API_KEY"),
|
||||
model="gpt-5-mini",
|
||||
model="gpt-3.5-turbo",
|
||||
system_prompt="You are a helpful assistant that remembers past conversations."
|
||||
)
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@ Install the SDK provider and AI SDK:
|
||||
npm install @mem0/vercel-ai-provider ai@^6
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
### Peer Dependencies
|
||||
|
||||
`@mem0/vercel-ai-provider` bundles `ai`, all `@ai-sdk/*` provider packages, and `@ai-sdk/provider` as regular dependencies — you do **not** need to install them separately. The install command above (`npm install @mem0/vercel-ai-provider ai@^6`) is sufficient.
|
||||
|
||||
The only true peer dependency is `zod` (optional):
|
||||
- `zod` v3+ (`^3.0.0`) — required only if you use Zod schemas in tool definitions
|
||||
`@mem0/vercel-ai-provider` v3.0.0 requires:
|
||||
- `ai` v6+ (`^6.0.199`)
|
||||
- `@ai-sdk/provider` v3+ (`^3.0.10`)
|
||||
- Provider packages at v3+: `@ai-sdk/openai@^3`, `@ai-sdk/anthropic@^3`, `@ai-sdk/google@^3`, `@ai-sdk/groq@^3`, `@ai-sdk/cohere@^3`
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -305,8 +305,6 @@ These options can be passed per-request when creating a model instance:
|
||||
| `rerank` | `boolean` | Enable reranking of results |
|
||||
| `page` | `number` | Page number for pagination |
|
||||
| `page_size` | `number` | Results per page |
|
||||
| `mem0ApiKey` | `string` | Mem0 API key; overrides the `MEM0_API_KEY` env var |
|
||||
| `host` | `string` | Custom Mem0 API base URL for self-hosted deployments |
|
||||
|
||||
## Key Features
|
||||
|
||||
@@ -314,7 +312,6 @@ These options can be passed per-request when creating a model instance:
|
||||
- `retrieveMemories()`: Retrieves memory context for prompts as a formatted system prompt string.
|
||||
- `getMemories()`: Get memories from your profile in array format.
|
||||
- `addMemories()`: Adds user memories to enhance contextual responses.
|
||||
- `searchMemories()`: Searches memories and returns the raw results array (semantic search rather than the full retrieval pipeline).
|
||||
|
||||
## Migrating from v2.x
|
||||
|
||||
|
||||
+4
-7
@@ -228,6 +228,7 @@ If the user is on a pre-current major (Python < 2, TS < 3, or Platform `output_f
|
||||
- [OSS to Platform Migration](https://docs.mem0.ai/migration/oss-to-platform) [Both]: Use when moving from self-hosted to managed.
|
||||
- [OSS v2 to v3 Migration](https://docs.mem0.ai/migration/oss-v2-to-v3) [OSS]: Use when upgrading a self-hosted deployment across major versions.
|
||||
- [Platform v2 to v3 Migration](https://docs.mem0.ai/migration/platform-v2-to-v3) [Platform]: Use when upgrading a Platform integration across major versions.
|
||||
- [API Changes](https://docs.mem0.ai/migration/api-changes) [Both]: Use when the upgrade involves API surface changes.
|
||||
- [Server pgvector Image Upgrade](https://docs.mem0.ai/migration/server-pgvector-upgrade) [OSS]: Use when upgrading the self-hosted server Docker image from ankane/pgvector to pgvector/pgvector.
|
||||
- [Changelog](https://docs.mem0.ai/changelog/highlights) [Both]: Use when the user asks what shipped recently.
|
||||
|
||||
@@ -366,8 +367,6 @@ All API Reference docs describe Mem0 Platform REST endpoints (requires API key).
|
||||
- [Get Organization](https://docs.mem0.ai/api-reference/organization/get-org) [Platform]: Use when fetching one org.
|
||||
- [Get Organization Members](https://docs.mem0.ai/api-reference/organization/get-org-members) [Platform]: Use when listing org members.
|
||||
- [Add Organization Member](https://docs.mem0.ai/api-reference/organization/add-org-member) [Platform]: Use when inviting a member to an org.
|
||||
- [Update Organization Member](https://docs.mem0.ai/api-reference/organization/update-org-member) [Platform]: Use when updating an org member's role.
|
||||
- [Remove Organization Member](https://docs.mem0.ai/api-reference/organization/remove-org-member) [Platform]: Use when removing a member from an organization.
|
||||
- [Delete Organization](https://docs.mem0.ai/api-reference/organization/delete-org) [Platform]: Use when removing an org.
|
||||
|
||||
### Projects
|
||||
@@ -376,9 +375,6 @@ All API Reference docs describe Mem0 Platform REST endpoints (requires API key).
|
||||
- [Get Project](https://docs.mem0.ai/api-reference/project/get-project) [Platform]: Use when fetching one project.
|
||||
- [Get Project Members](https://docs.mem0.ai/api-reference/project/get-project-members) [Platform]: Use when listing project members.
|
||||
- [Add Project Member](https://docs.mem0.ai/api-reference/project/add-project-member) [Platform]: Use when inviting a member to a project.
|
||||
- [Update Project](https://docs.mem0.ai/api-reference/project/update-project) [Platform]: Use when updating project settings.
|
||||
- [Update Project Member](https://docs.mem0.ai/api-reference/project/update-project-member) [Platform]: Use when updating a project member's role.
|
||||
- [Remove Project Member](https://docs.mem0.ai/api-reference/project/remove-project-member) [Platform]: Use when removing a member from a project.
|
||||
- [Delete Project](https://docs.mem0.ai/api-reference/project/delete-project) [Platform]: Use when removing a project.
|
||||
|
||||
### Webhooks
|
||||
@@ -464,7 +460,6 @@ Everything below is OSS-only provider configuration. Skip this entire section wh
|
||||
- [LM Studio Embeddings](https://docs.mem0.ai/components/embedders/models/lmstudio) [OSS]: Use when embeddings run through LM Studio.
|
||||
- [Together Embeddings](https://docs.mem0.ai/components/embedders/models/together) [OSS]: Use when embeddings run on Together.
|
||||
- [LangChain Embeddings](https://docs.mem0.ai/components/embedders/models/langchain) [OSS]: Use when embeddings are wrapped behind a LangChain adapter.
|
||||
- [FastEmbed](https://docs.mem0.ai/components/embedders/models/fastembed) [OSS]: Use when embeddings run locally via FastEmbed (ONNX).
|
||||
|
||||
### Vector Databases [OSS]
|
||||
- [Vector Database Overview](https://docs.mem0.ai/components/vectordbs/overview) [OSS]: Use when choosing a vector store.
|
||||
@@ -503,5 +498,7 @@ Everything below is OSS-only provider configuration. Skip this entire section wh
|
||||
- [Custom Reranker Prompts](https://docs.mem0.ai/components/rerankers/custom-prompts) [OSS]: Use when rewriting reranker prompts.
|
||||
- [Cohere Reranker](https://docs.mem0.ai/components/rerankers/models/cohere) [OSS]: Use for Cohere Rerank.
|
||||
- [Sentence Transformer Reranker](https://docs.mem0.ai/components/rerankers/models/sentence_transformer) [OSS]: Use for local cross-encoder rerankers.
|
||||
- [Hugging Face Reranker](https://docs.mem0.ai/components/rerankers/models/huggingface) [OSS]: Use for HF-hosted reranker models.- [LLM Reranker](https://docs.mem0.ai/components/rerankers/models/llm_reranker) [OSS]: Use when the reranker is a prompted LLM (implementation reference).
|
||||
- [Hugging Face Reranker](https://docs.mem0.ai/components/rerankers/models/huggingface) [OSS]: Use for HF-hosted reranker models.
|
||||
- [LLM Reranker (prompt)](https://docs.mem0.ai/components/rerankers/models/llm) [OSS]: Use when the reranker is a prompted LLM (config guide).
|
||||
- [LLM Reranker](https://docs.mem0.ai/components/rerankers/models/llm_reranker) [OSS]: Use when the reranker is a prompted LLM (implementation reference).
|
||||
- [Zero Entropy Reranker](https://docs.mem0.ai/components/rerankers/models/zero_entropy) [OSS]: Use for the Zero Entropy reranker.
|
||||
|
||||
@@ -0,0 +1,566 @@
|
||||
---
|
||||
title: API Reference Changes
|
||||
description: "Comprehensive reference of all API changes between Mem0 v0.x and v1.0.0 Beta, organized by component and method."
|
||||
icon: "code"
|
||||
iconType: "solid"
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
This page documents all API changes between Mem0 v0.x and v1.0.0 Beta, organized by component and method.
|
||||
|
||||
## Memory Class Changes
|
||||
|
||||
### Constructor
|
||||
|
||||
#### v0.x
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
# Basic initialization
|
||||
m = Memory()
|
||||
|
||||
# With configuration
|
||||
config = {
|
||||
"version": "v1.0", # Supported in v0.x
|
||||
"vector_store": {...}
|
||||
}
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
#### v1.0.0
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
# Basic initialization (same)
|
||||
m = Memory()
|
||||
|
||||
# With configuration
|
||||
config = {
|
||||
"version": "v1.1", # v1.1+ only
|
||||
"vector_store": {...},
|
||||
# New optional features
|
||||
"reranker": {
|
||||
"provider": "cohere",
|
||||
"config": {...}
|
||||
}
|
||||
}
|
||||
m = Memory.from_config(config)
|
||||
```
|
||||
|
||||
### add() Method
|
||||
|
||||
#### v0.x Signature
|
||||
```python
|
||||
def add(
|
||||
self,
|
||||
messages,
|
||||
user_id: str = None,
|
||||
agent_id: str = None,
|
||||
run_id: str = None,
|
||||
metadata: dict = None,
|
||||
filters: dict = None,
|
||||
output_format: str = None, # ❌ REMOVED
|
||||
version: str = None # ❌ REMOVED
|
||||
) -> Union[List[dict], dict]
|
||||
```
|
||||
|
||||
#### v1.0.0 Signature
|
||||
```python
|
||||
def add(
|
||||
self,
|
||||
messages,
|
||||
user_id: str = None,
|
||||
agent_id: str = None,
|
||||
run_id: str = None,
|
||||
metadata: dict = None,
|
||||
filters: dict = None,
|
||||
infer: bool = True # ✅ NEW: Control memory inference
|
||||
) -> dict # Always returns dict with "results" key
|
||||
```
|
||||
|
||||
#### Changes Summary
|
||||
|
||||
| Parameter | v0.x | v1.0.0 | Change |
|
||||
|-----------|------|-----------|---------|
|
||||
| `messages` | ✅ | ✅ | Unchanged |
|
||||
| `user_id` | ✅ | ✅ | Unchanged |
|
||||
| `agent_id` | ✅ | ✅ | Unchanged |
|
||||
| `run_id` | ✅ | ✅ | Unchanged |
|
||||
| `metadata` | ✅ | ✅ | Unchanged |
|
||||
| `filters` | ✅ | ✅ | Unchanged |
|
||||
| `output_format` | ✅ | ❌ | **REMOVED** |
|
||||
| `version` | ✅ | ❌ | **REMOVED** |
|
||||
| `infer` | ❌ | ✅ | **NEW** |
|
||||
|
||||
#### Response Format Changes
|
||||
|
||||
**v0.x Response (variable format):**
|
||||
```python
|
||||
# With output_format="v1.0"
|
||||
[
|
||||
{
|
||||
"id": "mem_123",
|
||||
"memory": "User loves pizza",
|
||||
"event": "ADD"
|
||||
}
|
||||
]
|
||||
|
||||
# With output_format="v1.1"
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "mem_123",
|
||||
"memory": "User loves pizza",
|
||||
"event": "ADD"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**v1.0.0 Response (standardized):**
|
||||
```python
|
||||
# Always returns this format
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "mem_123",
|
||||
"memory": "User loves pizza",
|
||||
"metadata": {...},
|
||||
"event": "ADD"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### search() Method
|
||||
|
||||
#### v0.x Signature
|
||||
```python
|
||||
def search(
|
||||
self,
|
||||
query: str,
|
||||
user_id: str = None,
|
||||
agent_id: str = None,
|
||||
run_id: str = None,
|
||||
limit: int = 100,
|
||||
filters: dict = None, # Basic key-value only
|
||||
output_format: str = None, # ❌ REMOVED
|
||||
version: str = None # ❌ REMOVED
|
||||
) -> Union[List[dict], dict]
|
||||
```
|
||||
|
||||
#### v1.0.0 Signature
|
||||
```python
|
||||
def search(
|
||||
self,
|
||||
query: str,
|
||||
user_id: str = None,
|
||||
agent_id: str = None,
|
||||
run_id: str = None,
|
||||
limit: int = 100,
|
||||
filters: dict = None, # ✅ ENHANCED: Advanced operators
|
||||
rerank: bool = True # ✅ NEW: Reranking support
|
||||
) -> dict # Always returns dict with "results" key
|
||||
```
|
||||
|
||||
#### Enhanced Filtering
|
||||
|
||||
**v0.x Filters (basic):**
|
||||
```python
|
||||
# Simple key-value filtering only
|
||||
filters = {
|
||||
"category": "food",
|
||||
"user_id": "alice"
|
||||
}
|
||||
```
|
||||
|
||||
**v1.0.0 Filters (enhanced):**
|
||||
```python
|
||||
# Advanced filtering with operators
|
||||
filters = {
|
||||
"AND": [
|
||||
{"category": "food"},
|
||||
{"score": {"gte": 0.8}},
|
||||
{
|
||||
"OR": [
|
||||
{"priority": "high"},
|
||||
{"urgent": True}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# Comparison operators
|
||||
filters = {
|
||||
"score": {"gt": 0.5}, # Greater than
|
||||
"priority": {"gte": 5}, # Greater than or equal
|
||||
"rating": {"lt": 3}, # Less than
|
||||
"confidence": {"lte": 0.9}, # Less than or equal
|
||||
"status": {"eq": "active"}, # Equal
|
||||
"archived": {"ne": True}, # Not equal
|
||||
"tags": {"in": ["work", "personal"]}, # In list
|
||||
"category": {"nin": ["spam", "deleted"]} # Not in list
|
||||
}
|
||||
```
|
||||
|
||||
### get_all() Method
|
||||
|
||||
#### v0.x Signature
|
||||
```python
|
||||
def get_all(
|
||||
self,
|
||||
user_id: str = None,
|
||||
agent_id: str = None,
|
||||
run_id: str = None,
|
||||
filters: dict = None,
|
||||
output_format: str = None, # ❌ REMOVED
|
||||
version: str = None # ❌ REMOVED
|
||||
) -> Union[List[dict], dict]
|
||||
```
|
||||
|
||||
#### v1.0.0 Signature
|
||||
```python
|
||||
def get_all(
|
||||
self,
|
||||
user_id: str = None,
|
||||
agent_id: str = None,
|
||||
run_id: str = None,
|
||||
filters: dict = None # ✅ ENHANCED: Advanced operators
|
||||
) -> dict # Always returns dict with "results" key
|
||||
```
|
||||
|
||||
### update() Method
|
||||
|
||||
#### No Breaking Changes
|
||||
```python
|
||||
# Same signature in both versions
|
||||
def update(
|
||||
self,
|
||||
memory_id: str,
|
||||
data: str
|
||||
) -> dict
|
||||
```
|
||||
|
||||
### delete() Method
|
||||
|
||||
#### No Breaking Changes
|
||||
```python
|
||||
# Same signature in both versions
|
||||
def delete(
|
||||
self,
|
||||
memory_id: str
|
||||
) -> dict
|
||||
```
|
||||
|
||||
### delete_all() Method
|
||||
|
||||
#### Breaking Change — Empty filter no longer silently deletes everything
|
||||
|
||||
**Before:** calling `delete_all()` with no filters silently deleted **all memories in the project**.
|
||||
|
||||
**After:**
|
||||
- No filters → raises a validation error (prevents accidental full-project wipe).
|
||||
- Concrete ID (e.g. `user_id="alice"`) → deletes memories for that entity (unchanged).
|
||||
- `"*"` for a filter → deletes all memories for that entity type across the project (new).
|
||||
- All four filters set to `"*"` → explicit full project wipe (new, requires opt-in on every parameter).
|
||||
|
||||
This change replaces the silent full-project delete (triggered by an empty or missing filter) with a validation error, and introduces `"*"` wildcards as the intentional path for bulk deletion.
|
||||
|
||||
```python
|
||||
# v0.x — no filter silently wiped all project memories
|
||||
m.delete_all() # DANGER: deleted everything
|
||||
m.delete_all(user_id="alice") # deleted alice's memories
|
||||
|
||||
# v1.x — no filter now raises an error; use "*" for intentional bulk deletes
|
||||
m.delete_all() # ERROR: at least one filter required
|
||||
m.delete_all(user_id="alice") # unchanged
|
||||
m.delete_all(user_id="*") # NEW — delete all users' memories
|
||||
m.delete_all(user_id="*", agent_id="*", app_id="*", run_id="*") # NEW — full project wipe
|
||||
```
|
||||
|
||||
## Platform Client (MemoryClient) Changes
|
||||
|
||||
### async_mode Default Changed
|
||||
|
||||
#### v0.x
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="your-key")
|
||||
|
||||
# async_mode had to be explicitly set or had different default
|
||||
result = client.add("content", user_id="alice", async_mode=True)
|
||||
```
|
||||
|
||||
#### v1.0.0
|
||||
```python
|
||||
from mem0 import MemoryClient
|
||||
|
||||
client = MemoryClient(api_key="your-key")
|
||||
|
||||
# async_mode defaults to True now (better performance)
|
||||
result = client.add("content", user_id="alice") # Uses async_mode=True by default
|
||||
|
||||
# Can still override if needed
|
||||
result = client.add("content", user_id="alice", async_mode=False)
|
||||
```
|
||||
|
||||
## Configuration Changes
|
||||
|
||||
### Memory Configuration
|
||||
|
||||
#### v0.x Config Options
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {...},
|
||||
"llm": {...},
|
||||
"embedder": {...},
|
||||
"graph_store": {...},
|
||||
"version": "v1.0", # ❌ v1.0 no longer supported
|
||||
"history_db_path": "...",
|
||||
"custom_instructions": "..."
|
||||
}
|
||||
```
|
||||
|
||||
#### v1.0.0 Config Options
|
||||
```python
|
||||
config = {
|
||||
"vector_store": {...},
|
||||
"llm": {...},
|
||||
"embedder": {...},
|
||||
"graph_store": {...},
|
||||
"reranker": { # ✅ NEW: Reranker support
|
||||
"provider": "cohere",
|
||||
"config": {...}
|
||||
},
|
||||
"version": "v1.1", # ✅ v1.1+ only
|
||||
"history_db_path": "...",
|
||||
"custom_instructions": "...",
|
||||
"custom_update_memory_prompt": "..." # ✅ NEW: Custom update prompt
|
||||
}
|
||||
```
|
||||
|
||||
### New Configuration Options
|
||||
|
||||
#### Reranker Configuration
|
||||
```python
|
||||
# Cohere reranker
|
||||
"reranker": {
|
||||
"provider": "cohere",
|
||||
"config": {
|
||||
"model": "rerank-english-v3.0",
|
||||
"api_key": "your-api-key",
|
||||
"top_k": 10
|
||||
}
|
||||
}
|
||||
|
||||
# Sentence Transformer reranker
|
||||
"reranker": {
|
||||
"provider": "sentence_transformer",
|
||||
"config": {
|
||||
"model": "cross-encoder/ms-marco-MiniLM-L-6-v2",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
|
||||
# Hugging Face reranker
|
||||
"reranker": {
|
||||
"provider": "huggingface",
|
||||
"config": {
|
||||
"model": "BAAI/bge-reranker-base",
|
||||
"device": "cuda"
|
||||
}
|
||||
}
|
||||
|
||||
# LLM-based reranker
|
||||
"reranker": {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-4",
|
||||
"api_key": "your-api-key"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Error Handling Changes
|
||||
|
||||
### New Error Types
|
||||
|
||||
#### v0.x Errors
|
||||
```python
|
||||
# Generic exceptions
|
||||
try:
|
||||
result = m.add("content", user_id="alice", version="v1.0")
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
```
|
||||
|
||||
#### v1.0.0 Errors
|
||||
```python
|
||||
# More specific error handling
|
||||
try:
|
||||
result = m.add("content", user_id="alice")
|
||||
except ValueError as e:
|
||||
if "v1.0 API format is no longer supported" in str(e):
|
||||
# Handle version compatibility error
|
||||
pass
|
||||
elif "Invalid filter operator" in str(e):
|
||||
# Handle filter syntax error
|
||||
pass
|
||||
except TypeError as e:
|
||||
# Handle parameter errors
|
||||
pass
|
||||
except Exception as e:
|
||||
# Handle unexpected errors
|
||||
pass
|
||||
```
|
||||
|
||||
### Validation Changes
|
||||
|
||||
#### Stricter Parameter Validation
|
||||
|
||||
**v0.x (Lenient):**
|
||||
```python
|
||||
# Unknown parameters might be ignored
|
||||
result = m.add("content", user_id="alice", unknown_param="value")
|
||||
```
|
||||
|
||||
**v1.0.0 (Strict):**
|
||||
```python
|
||||
# Unknown parameters raise TypeError
|
||||
try:
|
||||
result = m.add("content", user_id="alice", unknown_param="value")
|
||||
except TypeError as e:
|
||||
print(f"Invalid parameter: {e}")
|
||||
```
|
||||
|
||||
## Response Schema Changes
|
||||
|
||||
### Memory Object Schema
|
||||
|
||||
#### v0.x Schema
|
||||
```python
|
||||
{
|
||||
"id": "mem_123",
|
||||
"memory": "User loves pizza",
|
||||
"user_id": "alice",
|
||||
"metadata": {...},
|
||||
"created_at": "2024-01-01T00:00:00Z",
|
||||
"updated_at": "2024-01-01T00:00:00Z",
|
||||
"score": 0.95 # In search results
|
||||
}
|
||||
```
|
||||
|
||||
#### v1.0.0 Schema (Enhanced)
|
||||
```python
|
||||
{
|
||||
"id": "mem_123",
|
||||
"memory": "User loves pizza",
|
||||
"user_id": "alice",
|
||||
"agent_id": "assistant", # ✅ More context
|
||||
"run_id": "session_001", # ✅ More context
|
||||
"metadata": {...},
|
||||
"categories": ["food"], # ✅ NEW: Auto-categorization
|
||||
"immutable": false, # ✅ NEW: Immutability flag
|
||||
"created_at": "2024-01-01T00:00:00Z",
|
||||
"updated_at": "2024-01-01T00:00:00Z",
|
||||
"score": 0.95, # In search results
|
||||
"rerank_score": 0.98 # ✅ NEW: If reranking used
|
||||
}
|
||||
```
|
||||
|
||||
## Migration Code Examples
|
||||
|
||||
### Simple Migration
|
||||
|
||||
#### Before (v0.x)
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
m = Memory()
|
||||
|
||||
# Add with deprecated parameters
|
||||
result = m.add(
|
||||
"I love pizza",
|
||||
user_id="alice",
|
||||
output_format="v1.1",
|
||||
version="v1.0"
|
||||
)
|
||||
|
||||
# Handle variable response format
|
||||
if isinstance(result, list):
|
||||
memories = result
|
||||
else:
|
||||
memories = result.get("results", [])
|
||||
|
||||
for memory in memories:
|
||||
print(memory["memory"])
|
||||
```
|
||||
|
||||
#### After (v1.0.0 )
|
||||
```python
|
||||
from mem0 import Memory
|
||||
|
||||
m = Memory()
|
||||
|
||||
# Add without deprecated parameters
|
||||
result = m.add(
|
||||
"I love pizza",
|
||||
user_id="alice"
|
||||
)
|
||||
|
||||
# Always dict format with "results" key
|
||||
for memory in result["results"]:
|
||||
print(memory["memory"])
|
||||
```
|
||||
|
||||
### Advanced Migration
|
||||
|
||||
#### Before (v0.x)
|
||||
```python
|
||||
# Basic filtering
|
||||
results = m.search(
|
||||
"food preferences",
|
||||
user_id="alice",
|
||||
filters={"category": "food"},
|
||||
output_format="v1.1"
|
||||
)
|
||||
```
|
||||
|
||||
#### After (v1.0.0 )
|
||||
```python
|
||||
# Enhanced filtering with reranking
|
||||
results = m.search(
|
||||
"food preferences",
|
||||
user_id="alice",
|
||||
filters={
|
||||
"AND": [
|
||||
{"category": "food"},
|
||||
{"score": {"gte": 0.8}}
|
||||
]
|
||||
},
|
||||
rerank=True
|
||||
)
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
| Component | v0.x | v1.0.0 | Status |
|
||||
|-----------|------|-----------|---------|
|
||||
| `add()` method | Variable response | Standardized response | ⚠️ Breaking |
|
||||
| `search()` method | Basic filtering | Enhanced filtering + reranking | ⚠️ Breaking |
|
||||
| `get_all()` method | Variable response | Standardized response | ⚠️ Breaking |
|
||||
| Response format | Variable | Always `{"results": [...]}` | ⚠️ Breaking |
|
||||
| Reranking | ❌ Not available | ✅ Full support | ✅ New feature |
|
||||
| Advanced filtering | ❌ Basic only | ✅ Full operators | ✅ Enhancement |
|
||||
| Error handling | Generic | Specific error types | ✅ Improvement |
|
||||
|
||||
<Info>
|
||||
Use this reference to systematically update your codebase. Test each change thoroughly before deploying to production.
|
||||
</Info>
|
||||
@@ -62,7 +62,7 @@ These changes produce a **+20 point improvement on LoCoMo** (71.4 → 91.6) and
|
||||
|---|---|---|---|
|
||||
| Constructor | `MemoryClient(api_key, org_id, project_id)` | `MemoryClient(api_key)` | Remove `org_id`, `project_id` from constructor |
|
||||
| Method options | `client.add(messages, **kwargs)` | `client.add(messages, options=AddMemoryOptions(...))` | Use typed option classes (or `**kwargs` still works) |
|
||||
| Removed params | `api_version`, `output_format`, `async_mode`, `filter_memories`, `keyword_search`, `force_add_only`, `batch_size`, `immutable`, `includes`, `excludes`, `enable_graph`, `org_name`, `project_name` | — | Remove from all calls |
|
||||
| Removed params | `api_version`, `output_format`, `async_mode`, `filter_memories`, `expiration_date`, `keyword_search`, `force_add_only`, `batch_size`, `immutable`, `includes`, `excludes`, `enable_graph`, `org_name`, `project_name` | — | Remove from all calls |
|
||||
|
||||
### TypeScript Client SDK
|
||||
|
||||
@@ -70,7 +70,7 @@ These changes produce a **+20 point improvement on LoCoMo** (71.4 → 91.6) and
|
||||
|---|---|---|---|
|
||||
| Constructor | `new MemoryClient({ apiKey, organizationId, projectId })` | `new MemoryClient({ apiKey })` | Remove `organizationId`, `projectId`, `organizationName`, `projectName` |
|
||||
| All params | snake_case: `user_id`, `agent_id`, `top_k` | camelCase: `userId`, `agentId`, `topK` | Rename all params to camelCase |
|
||||
| Removed params | `api_version`, `output_format`, `async_mode`, `enable_graph`, `org_id`, `project_id`, `org_name`, `project_name`, `filter_memories`, `batch_size`, `force_add_only`, `immutable`, `includes`, `excludes`, `keyword_search` | — | Remove from all calls |
|
||||
| Removed params | `api_version`, `output_format`, `async_mode`, `enable_graph`, `org_id`, `project_id`, `org_name`, `project_name`, `filter_memories`, `batch_size`, `force_add_only`, `immutable`, `expiration_date`, `includes`, `excludes`, `keyword_search` | — | Remove from all calls |
|
||||
| Output format enum | `OutputFormat.V1`, `OutputFormat.V1_1` | Removed | v1.1 is now always used |
|
||||
| API version enum | `API_VERSION.V1`, `API_VERSION.V2` | Removed | Handled internally |
|
||||
|
||||
@@ -423,7 +423,7 @@ These parameters have been removed across all SDKs. Remove them from your code:
|
||||
|
||||
**All methods:** `api_version`, `output_format`, `async_mode`, `org_name`, `project_name`, `org_id`, `project_id`
|
||||
|
||||
**add():** `enable_graph`, `immutable`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`
|
||||
**add():** `enable_graph`, `immutable`, `expiration_date`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`
|
||||
|
||||
**search():** `enable_graph`
|
||||
|
||||
@@ -437,7 +437,7 @@ These parameters have been removed across all SDKs. Remove them from your code:
|
||||
|
||||
**All methods:** `OutputFormat` enum, `API_VERSION` enum
|
||||
|
||||
**add():** `enable_graph` / `enableGraph`, `async_mode` / `asyncMode`, `output_format` / `outputFormat`, `immutable`, `filter_memories` / `filterMemories`, `batch_size` / `batchSize`, `force_add_only` / `forceAddOnly`, `includes`, `excludes`, `keyword_search` / `keywordSearch`
|
||||
**add():** `enable_graph` / `enableGraph`, `async_mode` / `asyncMode`, `output_format` / `outputFormat`, `immutable`, `expiration_date` / `expirationDate`, `filter_memories` / `filterMemories`, `batch_size` / `batchSize`, `force_add_only` / `forceAddOnly`, `includes`, `excludes`, `keyword_search` / `keywordSearch`
|
||||
|
||||
**search():** `enable_graph` / `enableGraph`
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ client.add(messages, user_id="alice")
|
||||
# async_mode and output_format removed (async by default, v1.1 always)
|
||||
```
|
||||
|
||||
**Removed parameters:** `org_id`, `project_id`, `api_version`, `output_format`, `async_mode`, `enable_graph`, `immutable`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`, `org_name`, `project_name`
|
||||
**Removed parameters:** `org_id`, `project_id`, `api_version`, `output_format`, `async_mode`, `enable_graph`, `immutable`, `expiration_date`, `filter_memories`, `batch_size`, `force_add_only`, `includes`, `excludes`, `keyword_search`, `org_name`, `project_name`
|
||||
|
||||
### TypeScript Client SDK
|
||||
|
||||
@@ -242,7 +242,7 @@ await client.search("query", {
|
||||
});
|
||||
```
|
||||
|
||||
**Removed:** `OutputFormat` enum, `API_VERSION` enum, `organizationId`, `projectId`, `organizationName`, `projectName`, `enableGraph`, `asyncMode`, `outputFormat`, `immutable`, `filterMemories`, `batchSize`, `forceAddOnly`, `includes`, `excludes`, `keywordSearch`
|
||||
**Removed:** `OutputFormat` enum, `API_VERSION` enum, `organizationId`, `projectId`, `organizationName`, `projectName`, `enableGraph`, `asyncMode`, `outputFormat`, `immutable`, `expirationDate`, `filterMemories`, `batchSize`, `forceAddOnly`, `includes`, `excludes`, `keywordSearch`
|
||||
|
||||
<Info>
|
||||
For the full list of parameter changes across all SDKs, see the [OSS migration guide](/migration/oss-v2-to-v3#removed-parameters-reference).
|
||||
|
||||
@@ -130,7 +130,7 @@ memory = Memory.from_config_file("config.yaml")
|
||||
</Tabs>
|
||||
|
||||
<Info icon="check">
|
||||
Run `memory.add("Remember my favorite cafe in Tokyo.", user_id="alex")` and then `memory.search("favorite cafe", filters={"user_id": "alex"})`. You should see the Qdrant collection populate and the reranker mark the memory as a top hit.
|
||||
Run `memory.add(["Remember my favorite cafe in Tokyo."], user_id="alex")` and then `memory.search("favorite cafe", filters={"user_id": "alex"})`. You should see the Qdrant collection populate and the reranker mark the memory as a top hit.
|
||||
</Info>
|
||||
|
||||
## Tune component settings
|
||||
|
||||
@@ -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 Node SDK still uses synchronous calls—use `Memory` there and rely on Python’s `AsyncMemory` when you need awaited operations.
|
||||
</Note>
|
||||
|
||||
## Feature anatomy
|
||||
|
||||
@@ -165,7 +165,8 @@ await memory.add("Yesterday, I ordered a laptop, the order id is 12345", { userI
|
||||
{"memory": "Ordered a laptop", "event": "ADD"},
|
||||
{"memory": "Order ID: 12345", "event": "ADD"},
|
||||
{"memory": "Order placed yesterday", "event": "ADD"}
|
||||
]
|
||||
],
|
||||
"relations": []
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -187,7 +188,8 @@ await memory.add("I like going to hikes", { userId: "user123" });
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": []
|
||||
"results": [],
|
||||
"relations": []
|
||||
}
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
@@ -41,14 +41,6 @@ Multimodal support lets Mem0 extract facts from images alongside regular text. A
|
||||
|
||||
## Configure it
|
||||
|
||||
<Warning>
|
||||
You must set `enable_vision: True` in your LLM config for image content to be processed. Without it, image turns are silently dropped and no vision memories are created. Example:
|
||||
```python
|
||||
config = {"llm": {"provider": "openai", "config": {"enable_vision": True, "vision_details": "auto"}}}
|
||||
client = Memory.from_config(config)
|
||||
```
|
||||
</Warning>
|
||||
|
||||
### Add image messages from URLs
|
||||
|
||||
<CodeGroup>
|
||||
@@ -74,7 +66,7 @@ client.add(messages, user_id="alice")
|
||||
```
|
||||
|
||||
```ts TypeScript
|
||||
import { Memory } from "mem0ai/oss";
|
||||
import { Memory } from "mem0ai";
|
||||
|
||||
const client = new Memory();
|
||||
|
||||
@@ -131,7 +123,7 @@ client.add(messages, user_id="alice")
|
||||
|
||||
```ts TypeScript
|
||||
import fs from "fs";
|
||||
import { Memory } from "mem0ai/oss";
|
||||
import { Memory } from "mem0ai";
|
||||
|
||||
function encodeImage(imagePath: string) {
|
||||
const buffer = fs.readFileSync(imagePath);
|
||||
@@ -234,7 +226,7 @@ client.add(messages, user_id="user123")
|
||||
<CodeGroup>
|
||||
```python Python
|
||||
from mem0 import Memory
|
||||
from mem0.exceptions import ValidationError
|
||||
from mem0.exceptions import InvalidImageError, FileSizeError
|
||||
|
||||
client = Memory()
|
||||
|
||||
@@ -250,14 +242,16 @@ try:
|
||||
client.add(messages, user_id="user123")
|
||||
print("Image processed successfully")
|
||||
|
||||
except ValidationError as exc:
|
||||
print(f"Image validation error: {exc}")
|
||||
except InvalidImageError:
|
||||
print("Invalid image format or corrupted file")
|
||||
except FileSizeError:
|
||||
print("Image file too large")
|
||||
except Exception as exc:
|
||||
print(f"Unexpected error: {exc}")
|
||||
```
|
||||
|
||||
```ts TypeScript
|
||||
import { Memory } from "mem0ai/oss";
|
||||
import { Memory } from "mem0ai";
|
||||
|
||||
const client = new Memory();
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ config = {
|
||||
"provider": "llm_reranker",
|
||||
"config": {
|
||||
"provider": "openai",
|
||||
"model": "gpt-5-mini",
|
||||
"model": "gpt-4o-mini",
|
||||
"api_key": "your-openai-api-key",
|
||||
"top_k": 5
|
||||
}
|
||||
@@ -150,7 +150,7 @@ config = {
|
||||
"llm": {
|
||||
"provider": "openai",
|
||||
"config": {
|
||||
"model": "gpt-5-mini",
|
||||
"model": "gpt-4",
|
||||
"api_key": "your-openai-api-key"
|
||||
}
|
||||
},
|
||||
|
||||
+8
-43
@@ -1779,11 +1779,6 @@
|
||||
"type": "object",
|
||||
"description": "Entity and metadata filters. Must include at least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`).",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"show_expired": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "When true, include memories whose `expiration_date` has passed. Expired memories are hidden by default."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1982,12 +1977,6 @@
|
||||
"additionalProperties": true,
|
||||
"description": "User-supplied metadata to attach to each extracted memory."
|
||||
},
|
||||
"expiration_date": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"nullable": true,
|
||||
"description": "Optional expiration date in YYYY-MM-DD format. After this date, memories are hidden from search and get-all unless `show_expired` is true."
|
||||
},
|
||||
"custom_instructions": {
|
||||
"type": "string",
|
||||
"description": "Project-level instructions that guide extraction for this call."
|
||||
@@ -2105,11 +2094,6 @@
|
||||
"description": "Entity and metadata filters. Must include at least one entity ID (`user_id`, `agent_id`, `app_id`, or `run_id`). Supports `AND`, `OR`, `NOT`, and comparison operators (`in`, `gte`, `lte`, `gt`, `lt`, `contains`, `icontains`, `ne`).",
|
||||
"additionalProperties": true
|
||||
},
|
||||
"show_expired": {
|
||||
"type": "boolean",
|
||||
"default": false,
|
||||
"description": "When true, include memories whose `expiration_date` has passed. Expired memories are hidden by default."
|
||||
},
|
||||
"top_k": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
@@ -2448,12 +2432,6 @@
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"description": "Additional metadata associated with the memory"
|
||||
},
|
||||
"expiration_date": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"nullable": true,
|
||||
"description": "Expiration date in YYYY-MM-DD format, or null to clear the expiration date."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4883,7 +4861,8 @@
|
||||
"items": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"memory_id"
|
||||
"memory_id",
|
||||
"text"
|
||||
],
|
||||
"properties": {
|
||||
"memory_id": {
|
||||
@@ -4894,11 +4873,6 @@
|
||||
"text": {
|
||||
"type": "string",
|
||||
"description": "The new text content for the memory"
|
||||
},
|
||||
"metadata": {
|
||||
"type": "object",
|
||||
"additionalProperties": true,
|
||||
"description": "Updated metadata to associate with the memory."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -4974,27 +4948,18 @@
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memories": {
|
||||
"memory_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"memory_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "The unique identifier of the memory to delete."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"memory_id"
|
||||
]
|
||||
"type": "string",
|
||||
"format": "uuid"
|
||||
},
|
||||
"maxItems": 1000,
|
||||
"description": "Array of memory objects to delete."
|
||||
"description": "Array of memory IDs to delete."
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"memories"
|
||||
"memory_ids"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -6291,4 +6256,4 @@
|
||||
}
|
||||
},
|
||||
"x-original-swagger-version": "2.0"
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ description: "Run richer add/search/update/delete flows on the managed platform
|
||||
**Prerequisites**
|
||||
- Platform workspace with API key
|
||||
- Python 3.10+ and Node.js 18+
|
||||
- Async memories enabled in your dashboard (Settings → Memory Options)
|
||||
</Info>
|
||||
|
||||
<Tip>
|
||||
@@ -20,9 +21,9 @@ description: "Run richer add/search/update/delete flows on the managed platform
|
||||
<Tabs>
|
||||
<Tab title="Python">
|
||||
<Steps>
|
||||
<Step title="Install the SDK">
|
||||
<Step title="Install the SDK with async extras">
|
||||
```bash
|
||||
pip install mem0ai
|
||||
pip install "mem0ai[async]"
|
||||
```
|
||||
</Step>
|
||||
<Step title="Export your API key">
|
||||
@@ -54,9 +55,9 @@ export MEM0_API_KEY="sk-platform-..."
|
||||
</Step>
|
||||
<Step title="Instantiate the client">
|
||||
```typescript
|
||||
import MemoryClient from 'mem0ai';
|
||||
import { Memory } from "mem0ai";
|
||||
|
||||
const memory = new MemoryClient({ apiKey: process.env.MEM0_API_KEY! });
|
||||
const memory = new Memory({ apiKey: process.env.MEM0_API_KEY!, async: true });
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
@@ -120,8 +121,10 @@ const result = await memory.add(conversation, {
|
||||
```python
|
||||
matches = await memory.search(
|
||||
"Any food alerts?",
|
||||
filters={"user_id": "traveler-42", "metadata.trip": "japan-2025"},
|
||||
user_id="traveler-42",
|
||||
filters={"metadata.trip": "japan-2025"},
|
||||
rerank=True,
|
||||
include_vectors=False,
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
@@ -129,7 +132,7 @@ matches = await memory.search(
|
||||
```python
|
||||
await memory.update(
|
||||
memory_id=matches["results"][0]["id"],
|
||||
data="Morgan avoids shellfish and prefers boutique hotels in central Tokyo.",
|
||||
content="Morgan avoids shellfish and prefers boutique hotels in central Tokyo.",
|
||||
)
|
||||
```
|
||||
</Step>
|
||||
@@ -140,15 +143,17 @@ await memory.update(
|
||||
<Step title="Search with metadata filters">
|
||||
```typescript
|
||||
const matches = await memory.search("Any food alerts?", {
|
||||
filters: { user_id: "traveler-42", "metadata.trip": "japan-2025" },
|
||||
userId: "traveler-42",
|
||||
filters: { "metadata.trip": "japan-2025" },
|
||||
rerank: true,
|
||||
includeVectors: false,
|
||||
});
|
||||
```
|
||||
</Step>
|
||||
<Step title="Apply an update">
|
||||
```typescript
|
||||
await memory.update(matches.results[0].id, {
|
||||
text: "Morgan avoids shellfish and prefers boutique hotels in central Tokyo.",
|
||||
content: "Morgan avoids shellfish and prefers boutique hotels in central Tokyo.",
|
||||
});
|
||||
```
|
||||
</Step>
|
||||
|
||||
@@ -26,7 +26,7 @@ Reorders results using deep semantic understanding to put the most relevant memo
|
||||
results = client.search(
|
||||
query="What are my upcoming travel plans?",
|
||||
rerank=True,
|
||||
filters={"user_id": "user123"},
|
||||
user_id="user123"
|
||||
)
|
||||
|
||||
# Before reranking: After reranking:
|
||||
@@ -52,7 +52,7 @@ results = client.search(
|
||||
results = client.search(
|
||||
query="How do I like my bedroom temperature?",
|
||||
rerank=True, # Get most recent preferences first
|
||||
filters={"user_id": "user123"},
|
||||
user_id="user123"
|
||||
)
|
||||
|
||||
# Finds: "Keep bedroom at 68°F", "Too cold last night at 65°F", etc.
|
||||
@@ -63,7 +63,7 @@ results = client.search(
|
||||
# Find specific product issues with high precision
|
||||
results = client.search(
|
||||
query="Problems with premium subscription billing",
|
||||
filters={"user_id": "customer456"},
|
||||
user_id="customer456"
|
||||
)
|
||||
|
||||
# Returns only relevant billing problems, not general questions
|
||||
@@ -75,7 +75,7 @@ results = client.search(
|
||||
results = client.search(
|
||||
query="Patient allergies and contraindications",
|
||||
rerank=True, # Most important info first
|
||||
filters={"user_id": "patient789"},
|
||||
user_id="patient789"
|
||||
)
|
||||
|
||||
# Ensures critical allergy info appears first
|
||||
@@ -87,7 +87,7 @@ results = client.search(
|
||||
results = client.search(
|
||||
query="Python programming progress and difficulties",
|
||||
rerank=True, # Recent progress first
|
||||
filters={"user_id": "student123"},
|
||||
user_id="student123"
|
||||
)
|
||||
|
||||
# Gets comprehensive view of Python learning journey
|
||||
@@ -105,7 +105,7 @@ results = client.search(
|
||||
def quick_search(query, user_id):
|
||||
return client.search(
|
||||
query=query,
|
||||
filters={"user_id": user_id},
|
||||
user_id=user_id
|
||||
)
|
||||
|
||||
# Reranked search - good for most applications
|
||||
@@ -113,7 +113,7 @@ def standard_search(query, user_id):
|
||||
return client.search(
|
||||
query=query,
|
||||
rerank=True,
|
||||
filters={"user_id": user_id},
|
||||
user_id=user_id
|
||||
)
|
||||
|
||||
# Reranked search - good for critical applications
|
||||
@@ -121,7 +121,7 @@ def precise_search(query, user_id):
|
||||
return client.search(
|
||||
query=query,
|
||||
rerank=True,
|
||||
filters={"user_id": user_id},
|
||||
user_id=user_id
|
||||
)
|
||||
```
|
||||
|
||||
@@ -129,23 +129,23 @@ def precise_search(query, user_id):
|
||||
// Basic search - good for exploration
|
||||
function quickSearch(query, userId) {
|
||||
return client.search(query, {
|
||||
filters: { user_id: userId },
|
||||
user_id: userId
|
||||
});
|
||||
}
|
||||
|
||||
// Reranked search - good for most applications
|
||||
function standardSearch(query, userId) {
|
||||
return client.search(query, {
|
||||
filters: { user_id: userId },
|
||||
rerank: true,
|
||||
user_id: userId,
|
||||
rerank: true
|
||||
});
|
||||
}
|
||||
|
||||
// Reranked search - good for critical applications
|
||||
function preciseSearch(query, userId) {
|
||||
return client.search(query, {
|
||||
filters: { user_id: userId },
|
||||
rerank: true,
|
||||
user_id: userId,
|
||||
rerank: true
|
||||
});
|
||||
}
|
||||
```
|
||||
@@ -178,7 +178,7 @@ start_time = time.time()
|
||||
results = client.search(
|
||||
query="user preferences",
|
||||
rerank=True, # +150ms
|
||||
filters={"user_id": "user123"},
|
||||
user_id="user123"
|
||||
)
|
||||
latency = time.time() - start_time
|
||||
print(f"Search completed in {latency:.2f}s")
|
||||
|
||||
@@ -25,7 +25,7 @@ const messages = [
|
||||
{"role": "assistant", "content": "Great! I'll remember your preference for Italian cuisine."}
|
||||
];
|
||||
|
||||
await client.add(messages, { userId: "user123" });
|
||||
await client.add(messages, { userId: "user123", version: "v2" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
@@ -65,14 +65,14 @@ const messages1 = [
|
||||
{"role": "user", "content": "Hi, I'm Sarah from New York"},
|
||||
{"role": "assistant", "content": "Hello Sarah! Nice to meet you."}
|
||||
];
|
||||
await client.add(messages1, { userId: "sarah" });
|
||||
await client.add(messages1, { userId: "sarah", version: "v2" });
|
||||
|
||||
// Later interaction - just send new messages
|
||||
const messages2 = [
|
||||
{"role": "user", "content": "I'm planning a trip to Italy next month"},
|
||||
{"role": "assistant", "content": "How exciting! Italy is beautiful this time of year."}
|
||||
];
|
||||
await client.add(messages2, { userId: "sarah" });
|
||||
await client.add(messages2, { userId: "sarah", version: "v2" });
|
||||
// Mem0 automatically knows Sarah is from New York and can use this context
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -104,7 +104,7 @@ const messages = [
|
||||
{"role": "assistant", "content": "I've noted your allergies for future reference."}
|
||||
];
|
||||
|
||||
await client.add(messages, { userId: "user123" });
|
||||
await client.add(messages, { userId: "user123", version: "v2" });
|
||||
// This allergy info will be available in ALL future interactions
|
||||
```
|
||||
</CodeGroup>
|
||||
@@ -143,21 +143,21 @@ const messages1 = [
|
||||
{"role": "user", "content": "I want to plan a 5-day trip to Tokyo"},
|
||||
{"role": "assistant", "content": "Perfect! Let's plan your Tokyo adventure."}
|
||||
];
|
||||
await client.add(messages1, { userId: "user123", runId: "tokyo-trip-2024" });
|
||||
await client.add(messages1, { userId: "user123", runId: "tokyo-trip-2024", version: "v2" });
|
||||
|
||||
// Later in the same trip planning session
|
||||
const messages2 = [
|
||||
{"role": "user", "content": "I prefer staying near Shibuya"},
|
||||
{"role": "assistant", "content": "Great choice! Shibuya is very convenient."}
|
||||
];
|
||||
await client.add(messages2, { userId: "user123", runId: "tokyo-trip-2024" });
|
||||
await client.add(messages2, { userId: "user123", runId: "tokyo-trip-2024", version: "v2" });
|
||||
|
||||
// Different session for work project (separate context)
|
||||
const workMessages = [
|
||||
{"role": "user", "content": "Let's discuss the Q4 marketing strategy"},
|
||||
{"role": "assistant", "content": "Sure! What are your main goals for Q4?"}
|
||||
];
|
||||
await client.add(workMessages, { userId: "user123", runId: "q4-marketing" });
|
||||
await client.add(workMessages, { userId: "user123", runId: "q4-marketing", version: "v2" });
|
||||
```
|
||||
</CodeGroup>
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ results_without_criteria = client.search(
|
||||
### Compare Results
|
||||
|
||||
### Search Results (with Criteria)
|
||||
```text
|
||||
```python
|
||||
[
|
||||
{"memory": "User feels refreshed and ready to take on anything on a beautiful sunny day", "score": 0.666, ...},
|
||||
{"memory": "User finally has time to draw something after a long time", "score": 0.616, ...},
|
||||
@@ -128,7 +128,7 @@ results_without_criteria = client.search(
|
||||
```
|
||||
|
||||
### Search Results (without Criteria)
|
||||
```text
|
||||
```python
|
||||
[
|
||||
{"memory": "User is happy today", "score": 0.607, ...},
|
||||
{"memory": "User feels refreshed and ready to take on anything on a beautiful sunny day", "score": 0.512, ...},
|
||||
@@ -182,7 +182,7 @@ If no criteria are defined for a project, search behaves normally based on seman
|
||||
This lets you prioritize memories that align with your agent's goals and not just those that look similar to the query.
|
||||
|
||||
<Note>
|
||||
Criteria retrieval is automatically enabled when criteria are defined in your project. Use `use_criteria=False` in search to temporarily disable it for a specific query. `use_criteria` is a server-side parameter passed through to the Platform API — it is not a typed option in the SDK's `SearchMemoryOptions` interface, but the server accepts and processes it when included in the request body.
|
||||
Criteria retrieval is automatically enabled when criteria are defined in your project. Use `use_criteria=False` in search to temporarily disable it for a specific query.
|
||||
</Note>
|
||||
|
||||
|
||||
|
||||
@@ -190,7 +190,7 @@ messages = [
|
||||
client.add(messages, user_id='alice')
|
||||
```
|
||||
|
||||
```text Memories with categories
|
||||
```python Memories with categories
|
||||
# Following categories will be created for the memories added
|
||||
Sometimes draws and sketches in free time (hobbies)
|
||||
Is quite athletic (sports)
|
||||
|
||||
@@ -150,7 +150,7 @@ Handle potential errors when submitting feedback:
|
||||
|
||||
```python Python
|
||||
from mem0 import MemoryClient
|
||||
from mem0.exceptions import MemoryNotFoundError, NetworkError
|
||||
from mem0.exceptions import MemoryNotFoundError, APIError
|
||||
|
||||
client = MemoryClient(api_key="your_api_key")
|
||||
|
||||
@@ -163,8 +163,8 @@ try:
|
||||
print("Feedback submitted successfully")
|
||||
except MemoryNotFoundError:
|
||||
print("Memory not found")
|
||||
except NetworkError as e:
|
||||
print(f"Network error: {e}")
|
||||
except APIError as e:
|
||||
print(f"API error: {e}")
|
||||
except Exception as e:
|
||||
print(f"Unexpected error: {e}")
|
||||
```
|
||||
|
||||
@@ -111,37 +111,32 @@ print(all_memories)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"count": 3,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
|
||||
"memory": "suggests considering Angular because it has great enterprise support",
|
||||
"user_id": "charlie",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:11.007223-07:00",
|
||||
"updated_at": "2025-06-21T05:51:11.626562-07:00"
|
||||
},
|
||||
{
|
||||
"id": "1d8b8f39-7b17-4d18-8632-ab1c64fa35b9",
|
||||
"memory": "prefers Vue.js for our use case",
|
||||
"user_id": "bob",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:08.675301-07:00",
|
||||
"updated_at": "2025-06-21T05:51:09.319269-07:00"
|
||||
},
|
||||
{
|
||||
"id": "4d82478a-8d50-47e6-9324-1f65efff5829",
|
||||
"memory": "prefers using React for the frontend",
|
||||
"user_id": "alice",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:05.943223-07:00",
|
||||
"updated_at": "2025-06-21T05:51:06.982539-07:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
[
|
||||
{
|
||||
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
|
||||
"memory": "suggests considering Angular because it has great enterprise support",
|
||||
"user_id": "charlie",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:11.007223-07:00",
|
||||
"updated_at": "2025-06-21T05:51:11.626562-07:00"
|
||||
},
|
||||
{
|
||||
"id": "1d8b8f39-7b17-4d18-8632-ab1c64fa35b9",
|
||||
"memory": "prefers Vue.js for our use case",
|
||||
"user_id": "bob",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:08.675301-07:00",
|
||||
"updated_at": "2025-06-21T05:51:09.319269-07:00",
|
||||
},
|
||||
{
|
||||
"id": "4d82478a-8d50-47e6-9324-1f65efff5829",
|
||||
"memory": "prefers using React for the frontend",
|
||||
"user_id": "alice",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:05.943223-07:00",
|
||||
"updated_at": "2025-06-21T05:51:06.982539-07:00",
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
@@ -166,21 +161,17 @@ print(charlie_memories)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"count": 1,
|
||||
"next": null,
|
||||
"previous": null,
|
||||
"results": [
|
||||
{
|
||||
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
|
||||
"memory": "suggests considering Angular because it has great enterprise support",
|
||||
"user_id": "charlie",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:11.007223-07:00",
|
||||
"updated_at": "2025-06-21T05:51:11.626562-07:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
[
|
||||
{
|
||||
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
|
||||
"memory": "suggests considering Angular because it has great enterprise support",
|
||||
"user_id": "charlie",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:11.007223-07:00",
|
||||
"updated_at": "2025-06-21T05:51:11.626562-07:00",
|
||||
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
@@ -208,18 +199,16 @@ print(search_response)
|
||||
```
|
||||
|
||||
```json Output
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
|
||||
"memory": "suggests considering Angular because it has great enterprise support",
|
||||
"user_id": "charlie",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:11.007223-07:00",
|
||||
"updated_at": "2025-06-21T05:51:11.626562-07:00"
|
||||
}
|
||||
]
|
||||
}
|
||||
[
|
||||
{
|
||||
"id": "147559a8-c5f7-44d0-9418-91f53f7a89a4",
|
||||
"memory": "suggests considering Angular because it has great enterprise support",
|
||||
"user_id": "charlie",
|
||||
"run_id": "group_chat_1",
|
||||
"created_at": "2025-06-21T05:51:11.007223-07:00",
|
||||
"updated_at": "2025-06-21T05:51:11.626562-07:00",
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
</CodeGroup>
|
||||
|
||||
@@ -108,10 +108,10 @@ print(response)
|
||||
|
||||
```javascript JavaScript
|
||||
// Basic Export request
|
||||
const basicFilters = {"user_id": "alice"};
|
||||
const filters = {"user_id": "alice"};
|
||||
const response = await client.createMemoryExport({
|
||||
schema: json_schema,
|
||||
filters: basicFilters
|
||||
filters: filters
|
||||
});
|
||||
|
||||
// Export with custom instructions and additional filters
|
||||
@@ -124,16 +124,16 @@ const export_instructions = `
|
||||
`;
|
||||
|
||||
// For create operation, using only user_id filter as requested
|
||||
const exportFilters = {
|
||||
const filters = {
|
||||
"AND": [
|
||||
{"user_id": "alex"},
|
||||
{"created_at": {"gte": "2024-01-01"}}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
const responseWithInstructions = await client.createMemoryExport({
|
||||
schema: json_schema,
|
||||
filters: exportFilters,
|
||||
filters: filters,
|
||||
exportInstructions: export_instructions
|
||||
});
|
||||
|
||||
@@ -251,6 +251,7 @@ You can apply various filters to customize which memories are included in the ex
|
||||
- `user_id`: Filter memories by specific user
|
||||
- `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>
|
||||
|
||||
@@ -9,7 +9,7 @@ estimatedTime: "~2 minutes"
|
||||
**Prerequisites**
|
||||
- Mem0 Platform account (<a href="https://app.mem0.ai?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Sign up here</a>)
|
||||
- API key (<a href="https://app.mem0.ai/settings/api-keys?utm_source=oss&utm_medium=platform-mem0-mcp" rel="nofollow">Get one from dashboard</a>)
|
||||
- Node.js 18+ (for npx)
|
||||
- Node.js 14+ (for npx)
|
||||
- An MCP-compatible client (Claude, Claude Code, Codex, Cursor, Windsurf, VS Code, OpenCode)
|
||||
</Info>
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ Get started with Mem0 Platform's hosted API in under 5 minutes. This guide shows
|
||||
|
||||
- Mem0 Platform account (<a href="https://app.mem0.ai?utm_source=oss&utm_medium=platform-quickstart" rel="nofollow">Sign up here</a>)
|
||||
- API key (<a href="https://app.mem0.ai/dashboard/settings?tab=api-keys&subtab=configuration" rel="nofollow">Get one from dashboard</a>)
|
||||
- Python 3.10+, Node.js 18+, or cURL
|
||||
- Python 3.10+, Node.js 14+, or cURL
|
||||
|
||||
## Installation
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mem0",
|
||||
"version": "0.2.11",
|
||||
"version": "0.2.10",
|
||||
"description": "Persistent memory for Claude Code. Remembers decisions, patterns, and preferences across sessions.",
|
||||
"author": {
|
||||
"name": "Mem0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mem0",
|
||||
"version": "0.2.11",
|
||||
"version": "0.2.10",
|
||||
"description": "Persistent memory for Codex. Remembers decisions, patterns, and preferences across sessions.",
|
||||
"author": {
|
||||
"name": "Mem0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mem0",
|
||||
"version": "0.2.11",
|
||||
"version": "0.2.10",
|
||||
"description": "Mem0 memory layer for AI applications. Add persistent memory, personalization, and semantic search using the Mem0 Platform MCP server.",
|
||||
"author": {
|
||||
"name": "Mem0",
|
||||
|
||||
@@ -2,18 +2,6 @@
|
||||
|
||||
All notable changes to the Mem0 plugin will be documented in this file.
|
||||
|
||||
## 0.2.11 — Session-summary metadata fix + rerank auto-injected context by default
|
||||
|
||||
> Versions: Claude Code / Cursor / Codex `0.2.11`; Antigravity `0.1.3`. All four editors share `scripts/`, so the fix below applies to every editor.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`files_touched` was double-JSON-encoded in session summaries (`scripts/capture_session_summary.py`):** the Stop-hook summary set `metadata["files_touched"] = json.dumps(files[:20])` — a pre-serialized JSON string — and then serialized the whole request body again with `json.dumps(body)`. The stored memory therefore carried an escaped string blob (`"[\"mem0/memory/main.py\", \"src/client/index.ts\"]"`) instead of a real array, so file paths surfaced as backslash- and slash-heavy escaped text when those memories were returned by `search_memories`/`get_memories` and shown in Claude Code, Cursor, Codex, and Antigravity. The fix stores the list directly (`metadata["files_touched"] = files[:20]`) so the body is encoded exactly once. New `tests/test_capture_session_summary.py` asserts the posted body contains a JSON array and no escaped-string artifact.
|
||||
|
||||
### Changed
|
||||
|
||||
- **Auto-injected memory context is now reranked by default (`scripts/_search.py`, `scripts/file_context.py`, `scripts/on_bash_output.sh`, `scripts/on_user_prompt.sh`):** the REST search endpoint does not rerank when `rerank` is omitted, so hook-injected context (file-context, bash-error lookup, session-resume prefetch) was ordered by raw vector similarity and the single most relevant memory could fall outside the injected `top_k` window. A new `should_rerank()` helper turns reranking on for every auto-injection path; the extra ~150–200 ms stays within the hook's curl budget. Opt out with `MEM0_RERANK=0` (also accepts `false`/`no`/`off`). (#5690)
|
||||
|
||||
## 0.2.10 — Accurate per-editor telemetry attribution
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"id": "mem0",
|
||||
"name": "mem0",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.2",
|
||||
"description": "Persistent semantic memory for Antigravity agents. Cross-session, user-level recall via the Mem0 Platform MCP server. 16 slash commands, lifecycle hooks for auto-capture and metadata enforcement.",
|
||||
"author": { "name": "Mem0", "email": "support@mem0.ai" },
|
||||
"publisher": "mem0ai",
|
||||
|
||||
@@ -173,7 +173,7 @@ def store_summary(
|
||||
if branch:
|
||||
metadata["branch"] = branch
|
||||
if files:
|
||||
metadata["files_touched"] = files[:20]
|
||||
metadata["files_touched"] = json.dumps(files[:20])
|
||||
|
||||
body = {
|
||||
"messages": [{"role": "user", "content": summary_prompt}],
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user